From 6ec3ee49cb1ea4803064cc53b92a4c91c531fec9 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Mon, 13 Jul 2026 11:50:22 +0200 Subject: [PATCH] Add new theme tokens `bg-blend`, `bg-highlight`, and `border-strong` (#39786) --- .../components/_theme_playground/index.tsx | 60 ++++++++++++ .../theme_playground.module.scss | 98 +++++++++++++++++++ .../theme_playground.stories.tsx | 17 ++++ .../form_fields/combobox.module.scss | 2 +- .../collections/editor/styles.module.scss | 2 +- .../custom_homepage/styles.module.scss | 2 +- .../styles/mastodon/theme/_dark.scss | 6 +- .../styles/mastodon/theme/_light.scss | 6 +- 8 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 app/javascript/mastodon/components/_theme_playground/index.tsx create mode 100644 app/javascript/mastodon/components/_theme_playground/theme_playground.module.scss create mode 100644 app/javascript/mastodon/components/_theme_playground/theme_playground.stories.tsx diff --git a/app/javascript/mastodon/components/_theme_playground/index.tsx b/app/javascript/mastodon/components/_theme_playground/index.tsx new file mode 100644 index 00000000000..630ad15af59 --- /dev/null +++ b/app/javascript/mastodon/components/_theme_playground/index.tsx @@ -0,0 +1,60 @@ +/* eslint-disable jsx-a11y/anchor-is-valid */ + +import type { MouseEvent } from 'react'; +import { useCallback, useState } from 'react'; + +import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; + +import { Icon } from '../icon'; + +import classes from './theme_playground.module.scss'; + +/** + * This component is a temporary testing ground for new theme tokens. + * It's not to be used in-app. + */ +export const ThemePlayground: React.FC = () => { + const [activeLink, setActiveLink] = useState('Saved'); + + const handleLinkClick = useCallback((e: MouseEvent) => { + e.preventDefault(); + setActiveLink(e.currentTarget.innerText); + }, []); + + return ( +
+ +
Test 1 2 3
+
+ ); +}; diff --git a/app/javascript/mastodon/components/_theme_playground/theme_playground.module.scss b/app/javascript/mastodon/components/_theme_playground/theme_playground.module.scss new file mode 100644 index 00000000000..1e892f9d594 --- /dev/null +++ b/app/javascript/mastodon/components/_theme_playground/theme_playground.module.scss @@ -0,0 +1,98 @@ +.wrapper { + position: relative; + display: grid; + grid-template-columns: 250px 1fr; + gap: 1rem; + padding: 2rem; + font-size: 16px; + line-height: 1.5; + overflow-wrap: break-word; + color: var(--color-text-primary); + background-color: var(--color-bg-blend); + + * { + min-width: 0; + } + + nav { + display: block; + grid-template-rows: min-content; + font-size: 14px; + + input { + display: block; + box-sizing: border-box; + width: 100%; + margin-block-end: 1rem; + padding: 0.5rem 1rem; + color: var(--color-text-primary); + background: transparent; + border: 1px solid var(--color-border-primary); + border-radius: 0.5rem; + + &:focus { + border-color: var(--color-border-brand); + outline: 1px solid var(--color-border-brand); + } + } + + a { + display: block; + padding: 0.5rem 1rem 0.45rem; + border-radius: 0.5rem; + color: var(--color-text-secondary); + + &[aria-current='page'] { + color: var(--color-text-primary); + background-color: var(--color-bg-highlight); + } + } + + aside { + display: grid; + grid-template-areas: + 'title button' + 'subtitle button'; + grid-template-columns: 1fr min-content; + align-items: center; + gap: 0.125rem 0.5rem; + margin-block-start: 1rem; + padding: 0.75rem 1rem; + line-height: 1.2; + border-radius: 1rem; + background-color: var(--color-bg-highlight); + + h2 { + grid-area: title; + font-size: 16px; + font-weight: bold; + } + + .subtitle { + grid-area: subtitle; + font-size: 12px; + color: var(--color-text-secondary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .menuButton { + grid-area: button; + display: grid; + place-items: center; + width: 32px; + height: 32px; + border: none; + background-color: var(--color-bg-highlight); + border-radius: 99rem; + } + } + } + + main { + padding: 2rem; + background-color: var(--color-bg-primary); + border-radius: 1rem; + } +} diff --git a/app/javascript/mastodon/components/_theme_playground/theme_playground.stories.tsx b/app/javascript/mastodon/components/_theme_playground/theme_playground.stories.tsx new file mode 100644 index 00000000000..3935c6dc2ee --- /dev/null +++ b/app/javascript/mastodon/components/_theme_playground/theme_playground.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import { ThemePlayground } from './index'; + +const meta = { + title: 'Components/ThemePlayground', + component: ThemePlayground, + parameters: { + layout: 'fullscreen', + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/app/javascript/mastodon/components/form_fields/combobox.module.scss b/app/javascript/mastodon/components/form_fields/combobox.module.scss index e64c5e679e9..ca0767209cd 100644 --- a/app/javascript/mastodon/components/form_fields/combobox.module.scss +++ b/app/javascript/mastodon/components/form_fields/combobox.module.scss @@ -66,7 +66,7 @@ } &[data-highlighted='true'] { - background: var(--color-bg-overlay-highlight); + background: var(--color-bg-highlight); } &[aria-disabled='true'] { diff --git a/app/javascript/mastodon/features/collections/editor/styles.module.scss b/app/javascript/mastodon/features/collections/editor/styles.module.scss index 02d719699eb..354badfdbaa 100644 --- a/app/javascript/mastodon/features/collections/editor/styles.module.scss +++ b/app/javascript/mastodon/features/collections/editor/styles.module.scss @@ -65,7 +65,7 @@ border-bottom: 1px solid var(--color-border-primary); &[data-highlighted='true'] { - background: var(--color-bg-overlay-highlight); + background: var(--color-bg-highlight); } &[aria-disabled='true'] { diff --git a/app/javascript/mastodon/features/custom_homepage/styles.module.scss b/app/javascript/mastodon/features/custom_homepage/styles.module.scss index bbf834ffc9f..856f44b0e87 100644 --- a/app/javascript/mastodon/features/custom_homepage/styles.module.scss +++ b/app/javascript/mastodon/features/custom_homepage/styles.module.scss @@ -79,7 +79,7 @@ :global(.skeleton) { height: 40px; border-radius: 12px; - background: var(--color-bg-overlay-highlight); + background: var(--color-bg-highlight); } } diff --git a/app/javascript/styles/mastodon/theme/_dark.scss b/app/javascript/styles/mastodon/theme/_dark.scss index 657d7bd0901..a794c400446 100644 --- a/app/javascript/styles/mastodon/theme/_dark.scss +++ b/app/javascript/styles/mastodon/theme/_dark.scss @@ -40,11 +40,12 @@ --overlay-strength-secondary: 4%; --color-bg-secondary: var(--color-grey-900); --color-bg-tertiary: var(--color-grey-800); // legacy + --color-bg-blend: #{utils.css-alpha(var(--color-black), 30%)}; + --color-bg-highlight: #{utils.css-alpha(var(--color-text-primary), 5%)}; // Utility --color-bg-inverted: var(--color-grey-50); - --color-bg-overlay-base: #{utils.css-alpha(var(--color-grey-950), 60%)}; - --color-bg-overlay-highlight: #{utils.css-alpha(var(--color-white), 5%)}; + --color-bg-overlay-highlight: var(--color-bg-highlight); // legacy --color-bg-overlay: var(--color-black); // legacy --color-bg-media-base: var(--color-black); // legacy --color-bg-media: #{utils.css-alpha(var(--color-bg-media-base), 65%)}; // legacy @@ -75,6 +76,7 @@ /* BORDER TOKENS */ --color-border-primary: var(--color-grey-800); + --color-border-strong: var(--color-grey-100); --color-border-brand: var(--color-text-brand); --color-border-brand-soft: var(--color-indigo-800); --color-border-error: var(--color-red-300); diff --git a/app/javascript/styles/mastodon/theme/_light.scss b/app/javascript/styles/mastodon/theme/_light.scss index b4c19a16330..21b821a8d49 100644 --- a/app/javascript/styles/mastodon/theme/_light.scss +++ b/app/javascript/styles/mastodon/theme/_light.scss @@ -36,11 +36,12 @@ --overlay-strength-secondary: 4%; --color-bg-secondary: var(--color-grey-50); --color-bg-tertiary: var(--color-grey-100); // legacy + --color-bg-blend: #{utils.css-alpha(var(--color-text-primary), 4%)}; + --color-bg-highlight: #{utils.css-alpha(var(--color-text-primary), 4%)}; // Utility --color-bg-inverted: var(--color-grey-950); - --color-bg-overlay-base: #{utils.css-alpha(var(--color-grey-950), 60%)}; - --color-bg-overlay-highlight: #{utils.css-alpha(var(--color-grey-950), 5%)}; + --color-bg-overlay-highlight: var(--color-bg-highlight); // legacy --color-bg-overlay: var(--color-bg-primary); // legacy --color-bg-media-base: var(--color-black); // legacy --color-bg-media: #{utils.css-alpha(var(--color-bg-media-base), 65%)}; // legacy @@ -71,6 +72,7 @@ /* BORDER TOKENS */ --color-border-primary: var(--color-grey-200); + --color-border-strong: var(--color-grey-950); --color-border-brand: var(--color-text-brand); --color-border-brand-soft: var(--color-indigo-200); --color-border-error: var(--color-red-700);