diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e829eaa1f..51cc6e833 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -5,6 +5,7 @@ module.exports = { 'eslint:recommended', 'plugin:import/typescript', 'plugin:compat/recommended', + 'plugin:tailwindcss/recommended', ], env: { @@ -61,6 +62,9 @@ module.exports = { 'URL', // core-js 'URLSearchParams', // core-js ], + tailwindcss: { + config: 'tailwind.config.cjs', + }, }, rules: { @@ -235,18 +239,7 @@ module.exports = { }, ], 'import/newline-after-import': 'error', - 'import/no-extraneous-dependencies': [ - 'error', - // { - // devDependencies: [ - // 'webpack/**', - // 'app/soapbox/test_setup.js', - // 'app/soapbox/test_helpers.js', - // 'app/**/__tests__/**', - // 'app/**/__mocks__/**', - // ], - // }, - ], + 'import/no-extraneous-dependencies': 'error', 'import/no-unresolved': 'error', 'import/no-webpack-loader-syntax': 'error', 'import/order': [ @@ -271,6 +264,9 @@ module.exports = { 'promise/catch-or-return': 'error', 'react-hooks/rules-of-hooks': 'error', + + 'tailwindcss/classnames-order': 'error', + 'tailwindcss/migration-from-tailwind-2': 'error', }, overrides: [ { diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 36a3084ea..f4b01b942 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -149,9 +149,9 @@ pages: docker: stage: deploy - image: docker:20.10.23 + image: docker:23.0.0 services: - - docker:20.10.23-dind + - docker:23.0.0-dind tags: - dind # https://medium.com/devops-with-valentine/how-to-build-a-docker-image-and-push-it-to-the-gitlab-container-registry-from-a-gitlab-ci-pipeline-acac0d1f26df diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 000000000..bb4c1d232 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,43 @@ +import sharedConfig from '../webpack/shared'; + +import type { StorybookConfig } from '@storybook/core-common'; + +const config: StorybookConfig = { + stories: [ + '../stories/**/*.stories.mdx', + '../stories/**/*.stories.@(js|jsx|ts|tsx)' + ], + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-interactions', + 'storybook-react-intl', + { + name: '@storybook/addon-postcss', + options: { + postcssLoaderOptions: { + implementation: require('postcss'), + }, + }, + }, + ], + framework: '@storybook/react', + core: { + builder: '@storybook/builder-webpack5', + }, + webpackFinal: async (config) => { + config.resolve!.alias = { + ...sharedConfig.resolve!.alias, + ...config.resolve!.alias, + }; + + config.resolve!.modules = [ + ...sharedConfig.resolve!.modules!, + ...config.resolve!.modules!, + ]; + + return config; + }, +}; + +export default config; \ No newline at end of file diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 000000000..df2195f0c --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,22 @@ +import '../app/styles/tailwind.css'; +import '../stories/theme.css'; + +import { addDecorator, Story } from '@storybook/react'; +import { IntlProvider } from 'react-intl'; +import React from 'react'; + +const withProvider = (Story: Story) => ( + +); + +addDecorator(withProvider); + +export const parameters = { + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +}; diff --git a/.tool-versions b/.tool-versions index efc600fbd..ab43e6ab2 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -nodejs 18.13.0 +nodejs 18.14.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 619a1d207..b0d0c5977 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Chats: improved display of media attachments. - ServiceWorker: switch to a network-first strategy. The "An update is available!" prompt goes away. - Posts: increased font size of focused status in threads. +- Posts: let "mute conversation" be clicked from any feed, not just noficiations. ### Fixed - Chats: media attachments rendering at the wrong size and/or causing the chat to scroll on load. diff --git a/app/soapbox/components/account-search.tsx b/app/soapbox/components/account-search.tsx index c519b0243..f69845dd3 100644 --- a/app/soapbox/components/account-search.tsx +++ b/app/soapbox/components/account-search.tsx @@ -1,4 +1,4 @@ -import classNames from 'clsx'; +import clsx from 'clsx'; import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; @@ -72,17 +72,17 @@ const AccountSearch: React.FC = ({ onSelected, ...rest }) => {
diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index e92569ebe..2901433ec 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -43,11 +43,11 @@ const InstanceFavicon: React.FC = ({ account, disabled }) => { return ( ); }; @@ -147,7 +147,7 @@ const Account = ({ src={actionIcon} title={actionTitle} onClick={handleAction} - className='bg-transparent text-gray-600 dark:text-gray-600 hover:text-gray-700 dark:hover:text-gray-500' + className='bg-transparent text-gray-600 hover:text-gray-700 dark:text-gray-600 dark:hover:text-gray-500' iconClassName='w-4 h-4' /> ); @@ -193,7 +193,7 @@ const Account = ({ const LinkEl: any = withLinkToProfile ? Link : 'div'; return ( -
+
{emoji && ( )} -
+
{children}} diff --git a/app/soapbox/components/animated-number.tsx b/app/soapbox/components/animated-number.tsx index 0f6908fde..e7dd82462 100644 --- a/app/soapbox/components/animated-number.tsx +++ b/app/soapbox/components/animated-number.tsx @@ -50,7 +50,7 @@ const AnimatedNumber: React.FC = ({ value, obfuscate }) => { return ( {items => ( - + {items.map(({ key, data, style }) => ( 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } ))} diff --git a/app/soapbox/components/announcements/announcements-panel.tsx b/app/soapbox/components/announcements/announcements-panel.tsx index 2febea40d..800328678 100644 --- a/app/soapbox/components/announcements/announcements-panel.tsx +++ b/app/soapbox/components/announcements/announcements-panel.tsx @@ -1,4 +1,4 @@ -import classNames from 'clsx'; +import clsx from 'clsx'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -52,7 +52,7 @@ const AnnouncementsPanel = () => { key={i} tabIndex={0} onClick={() => setIndex(i)} - className={classNames({ + className={clsx({ 'w-2 h-2 rounded-full focus:ring-primary-600 focus:ring-2 focus:ring-offset-2': true, 'bg-gray-200 hover:bg-gray-300': i !== index, 'bg-primary-600': i === index, diff --git a/app/soapbox/components/announcements/emoji.tsx b/app/soapbox/components/announcements/emoji.tsx index 64266639d..3628227df 100644 --- a/app/soapbox/components/announcements/emoji.tsx +++ b/app/soapbox/components/announcements/emoji.tsx @@ -24,7 +24,7 @@ const Emoji: React.FC = ({ emoji, emojiMap, hovered }) => { return ( {emoji} = ({ emoji, emojiMap, hovered }) => { return ( {shortCode} = ({ announcementId, reaction, addReaction, return (