From 284b46fee7ad682b52c99d0455a1134e1d4e3fc3 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Mon, 17 Nov 2025 10:44:55 +0100 Subject: [PATCH] Implement CSS theme tokens behind feature flag (#36861) --- .prettierignore | 1 + app/helpers/theme_helper.rb | 10 +- app/javascript/mastodon/components/status.jsx | 1 - .../components/status/boost_button.tsx | 2 + .../components/status_action_bar/index.jsx | 12 +- .../features/about/components/rules.tsx | 24 +- .../components/follow_request_note.jsx | 4 +- .../compose/components/text_icon_button.jsx | 38 - .../mastodon/features/compose/index.tsx | 2 +- .../components/disabled_account_banner.tsx | 2 +- .../components/sign_in_banner.tsx | 4 +- .../ui/components/bundle_column_error.jsx | 2 +- .../ui/components/modal_placeholder.tsx | 2 +- .../features/ui/components/navigation_bar.tsx | 4 +- app/javascript/styles/mastodon/admin.scss | 4 - app/javascript/styles_new/application.scss | 7 + app/javascript/styles_new/common.scss | 24 + app/javascript/styles_new/contrast.scss | 8 + app/javascript/styles_new/contrast/diff.scss | 54 + .../styles_new/entrypoints/inert.scss | 14 + .../styles_new/entrypoints/mailer.scss | 1030 ++ app/javascript/styles_new/fonts/inter.scss | 8 + .../styles_new/fonts/roboto-mono.scss | 13 + app/javascript/styles_new/fonts/roboto.scss | 55 + app/javascript/styles_new/mastodon-light.scss | 9 + .../mastodon-light/css_variables.scss | 214 + .../styles_new/mastodon/_mixins.scss | 45 + .../styles_new/mastodon/_theme_utils.scss | 3 + .../styles_new/mastodon/_variables.scss | 27 + app/javascript/styles_new/mastodon/about.scss | 130 + .../styles_new/mastodon/accessibility.scss | 13 + .../styles_new/mastodon/accounts.scss | 411 + app/javascript/styles_new/mastodon/admin.scss | 2173 +++ .../styles_new/mastodon/annual_reports.scss | 342 + .../styles_new/mastodon/basics.scss | 300 + .../styles_new/mastodon/branding.scss | 5 + .../styles_new/mastodon/components.scss | 11433 ++++++++++++++++ .../styles_new/mastodon/containers.scss | 166 + .../styles_new/mastodon/css_variables.scss | 228 + .../styles_new/mastodon/dashboard.scss | 120 + .../styles_new/mastodon/emoji_picker.scss | 248 + app/javascript/styles_new/mastodon/forms.scss | 1449 ++ app/javascript/styles_new/mastodon/lists.scss | 19 + app/javascript/styles_new/mastodon/modal.scss | 53 + app/javascript/styles_new/mastodon/polls.scss | 232 + app/javascript/styles_new/mastodon/reset.scss | 58 + .../styles_new/mastodon/rich_text.scss | 116 + app/javascript/styles_new/mastodon/rtl.scss | 50 + .../styles_new/mastodon/tables.scss | 375 + .../styles_new/mastodon/widgets.scss | 183 + .../confirm_suspension.html.haml | 2 +- .../admin/reports/actions/preview.html.haml | 2 +- app/views/admin/roles/_role.html.haml | 13 +- app/views/auth/registrations/rules.html.haml | 2 +- app/views/layouts/modal.html.haml | 2 +- app/views/settings/imports/show.html.haml | 2 +- config/vite/plugin-mastodon-themes.ts | 24 +- stylelint.config.js | 3 +- 58 files changed, 19690 insertions(+), 87 deletions(-) delete mode 100644 app/javascript/mastodon/features/compose/components/text_icon_button.jsx create mode 100644 app/javascript/styles_new/application.scss create mode 100644 app/javascript/styles_new/common.scss create mode 100644 app/javascript/styles_new/contrast.scss create mode 100644 app/javascript/styles_new/contrast/diff.scss create mode 100644 app/javascript/styles_new/entrypoints/inert.scss create mode 100644 app/javascript/styles_new/entrypoints/mailer.scss create mode 100644 app/javascript/styles_new/fonts/inter.scss create mode 100644 app/javascript/styles_new/fonts/roboto-mono.scss create mode 100644 app/javascript/styles_new/fonts/roboto.scss create mode 100644 app/javascript/styles_new/mastodon-light.scss create mode 100644 app/javascript/styles_new/mastodon-light/css_variables.scss create mode 100644 app/javascript/styles_new/mastodon/_mixins.scss create mode 100644 app/javascript/styles_new/mastodon/_theme_utils.scss create mode 100644 app/javascript/styles_new/mastodon/_variables.scss create mode 100644 app/javascript/styles_new/mastodon/about.scss create mode 100644 app/javascript/styles_new/mastodon/accessibility.scss create mode 100644 app/javascript/styles_new/mastodon/accounts.scss create mode 100644 app/javascript/styles_new/mastodon/admin.scss create mode 100644 app/javascript/styles_new/mastodon/annual_reports.scss create mode 100644 app/javascript/styles_new/mastodon/basics.scss create mode 100644 app/javascript/styles_new/mastodon/branding.scss create mode 100644 app/javascript/styles_new/mastodon/components.scss create mode 100644 app/javascript/styles_new/mastodon/containers.scss create mode 100644 app/javascript/styles_new/mastodon/css_variables.scss create mode 100644 app/javascript/styles_new/mastodon/dashboard.scss create mode 100644 app/javascript/styles_new/mastodon/emoji_picker.scss create mode 100644 app/javascript/styles_new/mastodon/forms.scss create mode 100644 app/javascript/styles_new/mastodon/lists.scss create mode 100644 app/javascript/styles_new/mastodon/modal.scss create mode 100644 app/javascript/styles_new/mastodon/polls.scss create mode 100644 app/javascript/styles_new/mastodon/reset.scss create mode 100644 app/javascript/styles_new/mastodon/rich_text.scss create mode 100644 app/javascript/styles_new/mastodon/rtl.scss create mode 100644 app/javascript/styles_new/mastodon/tables.scss create mode 100644 app/javascript/styles_new/mastodon/widgets.scss diff --git a/.prettierignore b/.prettierignore index 098dac67177..bd382506695 100644 --- a/.prettierignore +++ b/.prettierignore @@ -68,6 +68,7 @@ docker-compose.override.yml # Ignore vendored CSS reset app/javascript/styles/mastodon/reset.scss +app/javascript/styles_new/mastodon/reset.scss # Ignore Javascript pending https://github.com/mastodon/mastodon/pull/23631 *.js diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb index 00b4a6d2b3f..32734b93af9 100644 --- a/app/helpers/theme_helper.rb +++ b/app/helpers/theme_helper.rb @@ -4,11 +4,11 @@ module ThemeHelper def theme_style_tags(theme) if theme == 'system' ''.html_safe.tap do |tags| - tags << vite_stylesheet_tag('themes/mastodon-light', type: :virtual, media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') - tags << vite_stylesheet_tag('themes/default', type: :virtual, media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous') + tags << vite_stylesheet_tag(theme_path_for('mastodon-light'), type: :virtual, media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') + tags << vite_stylesheet_tag(theme_path_for('default'), type: :virtual, media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous') end else - vite_stylesheet_tag "themes/#{theme}", type: :virtual, media: 'all', crossorigin: 'anonymous' + vite_stylesheet_tag theme_path_for(theme), type: :virtual, media: 'all', crossorigin: 'anonymous' end end @@ -53,4 +53,8 @@ module ThemeHelper def theme_color_for(theme) theme == 'mastodon-light' ? Themes::THEME_COLORS[:light] : Themes::THEME_COLORS[:dark] end + + def theme_path_for(theme) + Mastodon::Feature.theme_tokens_enabled? ? "themes/#{theme}_theme_tokens" : "themes/#{theme}" + end end diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index 2a8c9bfb2d8..1e746e5f710 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -553,7 +553,6 @@ class Status extends ImmutablePureComponent { } const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status); - return (
diff --git a/app/javascript/mastodon/components/status/boost_button.tsx b/app/javascript/mastodon/components/status/boost_button.tsx index 7d5939de6d3..023ba8ff195 100644 --- a/app/javascript/mastodon/components/status/boost_button.tsx +++ b/app/javascript/mastodon/components/status/boost_button.tsx @@ -64,6 +64,7 @@ const StandaloneBoostButton: FC = ({ status, counters }) => { title={intl.formatMessage(meta ?? title)} icon='retweet' iconComponent={iconComponent} + className='status__action-bar__button' onClick={!disabled ? handleClick : undefined} counter={ counters @@ -195,6 +196,7 @@ const BoostOrQuoteMenu: FC = ({ status, counters }) => { isMenuDisabled ? messages.all_disabled : messages.reblog_or_quote, )} icon='retweet' + className='status__action-bar__button' iconComponent={boostIcon} counter={ counters diff --git a/app/javascript/mastodon/components/status_action_bar/index.jsx b/app/javascript/mastodon/components/status_action_bar/index.jsx index ba184f57544..5c79970e23f 100644 --- a/app/javascript/mastodon/components/status_action_bar/index.jsx +++ b/app/javascript/mastodon/components/status_action_bar/index.jsx @@ -406,15 +406,19 @@ class StatusActionBar extends ImmutablePureComponent { status={status} needsStatusRefresh={quickBoosting && status.get('quote_approval') === null} items={menu} - icon='ellipsis-h' - iconComponent={MoreHorizIcon} direction='right' - title={intl.formatMessage(messages.more)} onOpen={() => { dismissQuoteHint(); return true; }} - /> + > + + )}
diff --git a/app/javascript/mastodon/features/about/components/rules.tsx b/app/javascript/mastodon/features/about/components/rules.tsx index 07ca1039602..1b1e28a7ff2 100644 --- a/app/javascript/mastodon/features/about/components/rules.tsx +++ b/app/javascript/mastodon/features/about/components/rules.tsx @@ -104,17 +104,19 @@ export const RulesSection: FC = ({ isLoading = false }) => { defaultMessage='Language' /> - +
+ +
)} diff --git a/app/javascript/mastodon/features/account/components/follow_request_note.jsx b/app/javascript/mastodon/features/account/components/follow_request_note.jsx index 9c20f1e0626..27ebb8fd64b 100644 --- a/app/javascript/mastodon/features/account/components/follow_request_note.jsx +++ b/app/javascript/mastodon/features/account/components/follow_request_note.jsx @@ -24,12 +24,12 @@ export default class FollowRequestNote extends ImmutablePureComponent {
- - diff --git a/app/javascript/mastodon/features/compose/components/text_icon_button.jsx b/app/javascript/mastodon/features/compose/components/text_icon_button.jsx deleted file mode 100644 index 166d022b88a..00000000000 --- a/app/javascript/mastodon/features/compose/components/text_icon_button.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; - -const iconStyle = { - height: null, - lineHeight: '27px', - minWidth: `${18 * 1.28571429}px`, -}; - -export default class TextIconButton extends PureComponent { - - static propTypes = { - label: PropTypes.string.isRequired, - title: PropTypes.string, - active: PropTypes.bool, - onClick: PropTypes.func.isRequired, - ariaControls: PropTypes.string, - }; - - render () { - const { label, title, active, ariaControls } = this.props; - - return ( - - ); - } - -} diff --git a/app/javascript/mastodon/features/compose/index.tsx b/app/javascript/mastodon/features/compose/index.tsx index 892cbb97617..527e541e84d 100644 --- a/app/javascript/mastodon/features/compose/index.tsx +++ b/app/javascript/mastodon/features/compose/index.tsx @@ -166,7 +166,7 @@ const Compose: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
-
+
diff --git a/app/javascript/mastodon/features/navigation_panel/components/disabled_account_banner.tsx b/app/javascript/mastodon/features/navigation_panel/components/disabled_account_banner.tsx index 9103170fa75..6cb450d1d61 100644 --- a/app/javascript/mastodon/features/navigation_panel/components/disabled_account_banner.tsx +++ b/app/javascript/mastodon/features/navigation_panel/components/disabled_account_banner.tsx @@ -75,7 +75,7 @@ export const DisabledAccountBanner: React.FC = () => {
diff --git a/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx index beaf1856382..2461028d8be 100644 --- a/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx +++ b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx @@ -98,7 +98,7 @@ class BundleColumnError extends PureComponent {
{errorType === 'network' && } {errorType === 'error' && } - +
diff --git a/app/javascript/mastodon/features/ui/components/modal_placeholder.tsx b/app/javascript/mastodon/features/ui/components/modal_placeholder.tsx index 13ec6ca2c82..9901ab6492b 100644 --- a/app/javascript/mastodon/features/ui/components/modal_placeholder.tsx +++ b/app/javascript/mastodon/features/ui/components/modal_placeholder.tsx @@ -46,7 +46,7 @@ export const ModalPlaceholder: React.FC<{ defaultMessage='Try again' /> -