diff --git a/packages/base-styles/CHANGELOG.md b/packages/base-styles/CHANGELOG.md index 44a91036d6c324..d64af560104e99 100644 --- a/packages/base-styles/CHANGELOG.md +++ b/packages/base-styles/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Regenerate the WPDS fallback map with the solid neutral interactive background state tokens. ([#82391](https://github.com/WordPress/gutenberg/pull/82391)) + ### Enhancements - Add a `$block-bg-padding` variable that resolves the default background padding through the `--wp--style--block-background-padding` custom property, keeping the existing values as its fallback ([#82024](https://github.com/WordPress/gutenberg/pull/82024)). diff --git a/packages/base-styles/internal/_wpds-token-fallbacks.scss b/packages/base-styles/internal/_wpds-token-fallbacks.scss index 31f8bb4e8da9c8..3ecba53d4045a2 100644 --- a/packages/base-styles/internal/_wpds-token-fallbacks.scss +++ b/packages/base-styles/internal/_wpds-token-fallbacks.scss @@ -33,6 +33,9 @@ $fallbacks: ( "--wpds-color-background-interactive-error-weak": "#0000", "--wpds-color-background-interactive-error-weak-active": "#f6e6e3", "--wpds-color-background-interactive-error-weak-disabled": "#0000", + "--wpds-color-background-interactive-neutral": "#fff", + "--wpds-color-background-interactive-neutral-active": "#fff", + "--wpds-color-background-interactive-neutral-disabled": "#fff", "--wpds-color-background-interactive-neutral-strong": "#2d2d2d", "--wpds-color-background-interactive-neutral-strong-active": "#1e1e1e", "--wpds-color-background-interactive-neutral-strong-disabled": "#e6e6e6", diff --git a/packages/dataviews/CHANGELOG.md b/packages/dataviews/CHANGELOG.md index 2759ff25158a79..3a19fdb7d599e4 100644 --- a/packages/dataviews/CHANGELOG.md +++ b/packages/dataviews/CHANGELOG.md @@ -36,6 +36,7 @@ ### Enhancements +- Give unselected multi-selection filter indicators solid, themed backgrounds. ([#82391](https://github.com/WordPress/gutenberg/pull/82391)) - Validated form controls: Use `--wpds-color-stroke-interactive-error` for the invalid-state focus ring and border ([#82410](https://github.com/WordPress/gutenberg/pull/82410)). - DataForm: Communicate the timezone a `datetime` value is edited in. When the site timezone differs from the visitor's, the control renders help text under the input naming the site timezone: the zone name (e.g. `(CEST) Europe/Madrid`) or the UTC offset for sites pinned to one ([#82291](https://github.com/WordPress/gutenberg/pull/82291)). - Export the `DataViewsProps` and `ItemWithId` types ([#82326](https://github.com/WordPress/gutenberg/pull/82326)). diff --git a/packages/dataviews/src/components/dataviews-filters/style.scss b/packages/dataviews/src/components/dataviews-filters/style.scss index 9665f83ea69878..a6d8e82062bba7 100644 --- a/packages/dataviews/src/components/dataviews-filters/style.scss +++ b/packages/dataviews/src/components/dataviews-filters/style.scss @@ -220,8 +220,9 @@ } .dataviews-filters__search-widget-listitem-multi-selection { + /* stylelint-disable-next-line plugin-wpds/no-token-fallback-values -- Preserve custom background theming with older @wordpress/theme runtimes that do not set this token. */ + background-color: var(--wpds-color-background-interactive-neutral, var(--wpds-color-background-surface-neutral-strong)); border-color: var(--wpds-color-stroke-interactive-brand-active); - background: var(--wpds-color-background-surface-neutral-strong); &.is-selected { border-color: var(--wpds-color-stroke-interactive-brand-active); @@ -289,7 +290,8 @@ @include checkbox-control; position: relative; - background: var(--wpds-color-background-interactive-neutral-weak); + /* stylelint-disable-next-line plugin-wpds/no-token-fallback-values -- Preserve custom background theming with older @wordpress/theme runtimes that do not set this token. */ + background: var(--wpds-color-background-interactive-neutral, var(--wpds-color-background-surface-neutral-strong)); color: var(--wpds-color-foreground-content-neutral); margin: 0; padding: 0; diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index c90d7d6699018f..a98f5eba4a8a9b 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Features + +- Add neutral interactive background tokens for resting, active, and disabled input and selection control states. ([#82391](https://github.com/WordPress/gutenberg/pull/82391)) + ### Documentation - Explain how consumers define light and dark themes through `ThemeProvider` color seeds ([#82039](https://github.com/WordPress/gutenberg/pull/82039)). diff --git a/packages/theme/docs/tokens.md b/packages/theme/docs/tokens.md index e1afce75ca219e..c64a26eadbc454 100644 --- a/packages/theme/docs/tokens.md +++ b/packages/theme/docs/tokens.md @@ -205,6 +205,9 @@ The semantic token set is role-based, not a complete matrix of every property, t | `--wpds-color-background-surface-caution-weak` | Background color for surfaces with caution tone and weak emphasis. | | `--wpds-color-background-surface-error` | Background color for surfaces with error tone and normal emphasis. | | `--wpds-color-background-surface-error-weak` | Background color for surfaces with error tone and weak emphasis. | +| `--wpds-color-background-interactive-neutral` | Solid background color for neutral interactive controls, such as input fields and unchecked checkboxes. | +| `--wpds-color-background-interactive-neutral-active` | Solid background color for neutral interactive controls that are hovered, focused, or active. | +| `--wpds-color-background-interactive-neutral-disabled` | Solid background color for neutral interactive controls in their disabled state. | | `--wpds-color-background-interactive-neutral-strong` | Background color for interactive elements with neutral tone and strong emphasis. | | `--wpds-color-background-interactive-neutral-strong-active` | Background color for interactive elements with neutral tone and strong emphasis that are hovered, focused, or active. | | `--wpds-color-background-interactive-neutral-strong-disabled` | Background color for interactive elements with neutral tone and strong emphasis, in their disabled state. | diff --git a/packages/theme/prebuilt/css/design-tokens.css b/packages/theme/prebuilt/css/design-tokens.css index 3bfcb3ffb76a89..f11bb96cb39f0d 100644 --- a/packages/theme/prebuilt/css/design-tokens.css +++ b/packages/theme/prebuilt/css/design-tokens.css @@ -51,6 +51,12 @@ --wpds-color-background-surface-error: #f6e6e3; /* Background color for surfaces with error tone and weak emphasis. */ --wpds-color-background-surface-error-weak: #fff6f5; + /* Solid background color for neutral interactive controls, such as input fields and unchecked checkboxes. */ + --wpds-color-background-interactive-neutral: #fff; + /* Solid background color for neutral interactive controls that are hovered, focused, or active. */ + --wpds-color-background-interactive-neutral-active: #fff; + /* Solid background color for neutral interactive controls in their disabled state. */ + --wpds-color-background-interactive-neutral-disabled: #fff; /* Background color for interactive elements with neutral tone and strong emphasis. */ --wpds-color-background-interactive-neutral-strong: #2d2d2d; /* Background color for interactive elements with neutral tone and strong emphasis that are hovered, focused, or active. */ diff --git a/packages/theme/prebuilt/js/design-token-fallbacks.mjs b/packages/theme/prebuilt/js/design-token-fallbacks.mjs index 5d00451a439ec1..1875cc80b91de5 100644 --- a/packages/theme/prebuilt/js/design-token-fallbacks.mjs +++ b/packages/theme/prebuilt/js/design-token-fallbacks.mjs @@ -31,6 +31,9 @@ export default { '--wpds-color-background-interactive-error-weak': '#0000', '--wpds-color-background-interactive-error-weak-active': '#f6e6e3', '--wpds-color-background-interactive-error-weak-disabled': '#0000', + '--wpds-color-background-interactive-neutral': '#fff', + '--wpds-color-background-interactive-neutral-active': '#fff', + '--wpds-color-background-interactive-neutral-disabled': '#fff', '--wpds-color-background-interactive-neutral-strong': '#2d2d2d', '--wpds-color-background-interactive-neutral-strong-active': '#1e1e1e', '--wpds-color-background-interactive-neutral-strong-disabled': '#e6e6e6', diff --git a/packages/theme/prebuilt/js/design-tokens.mjs b/packages/theme/prebuilt/js/design-tokens.mjs index a2871b424eb8f1..b0a15ca2c3facd 100644 --- a/packages/theme/prebuilt/js/design-tokens.mjs +++ b/packages/theme/prebuilt/js/design-tokens.mjs @@ -28,6 +28,9 @@ export default [ '--wpds-color-background-surface-caution-weak', '--wpds-color-background-surface-error', '--wpds-color-background-surface-error-weak', + '--wpds-color-background-interactive-neutral', + '--wpds-color-background-interactive-neutral-active', + '--wpds-color-background-interactive-neutral-disabled', '--wpds-color-background-interactive-neutral-strong', '--wpds-color-background-interactive-neutral-strong-active', '--wpds-color-background-interactive-neutral-strong-disabled', diff --git a/packages/theme/src/prebuilt/ts/color-tokens.ts b/packages/theme/src/prebuilt/ts/color-tokens.ts index 2e8c5486d318b9..d3b906c4b49991 100644 --- a/packages/theme/src/prebuilt/ts/color-tokens.ts +++ b/packages/theme/src/prebuilt/ts/color-tokens.ts @@ -87,7 +87,12 @@ export default { 'background-interactive-neutral-strong-disabled', ], 'bg-surface4': [ 'background-interactive-neutral-weak-active' ], - 'bg-surface3': [ 'background-surface-neutral-strong' ], + 'bg-surface3': [ + 'background-interactive-neutral', + 'background-interactive-neutral-active', + 'background-interactive-neutral-disabled', + 'background-surface-neutral-strong', + ], 'bg-fgSurface4': [ 'foreground-content-neutral', 'foreground-interactive-neutral', diff --git a/packages/theme/src/prebuilt/ts/token-types.ts b/packages/theme/src/prebuilt/ts/token-types.ts index de34c9d90d0b3b..3f4501890f6e26 100644 --- a/packages/theme/src/prebuilt/ts/token-types.ts +++ b/packages/theme/src/prebuilt/ts/token-types.ts @@ -79,6 +79,7 @@ export type SurfaceBackgroundColor = * Background color variants for interactive elements. */ export type InteractiveBackgroundColor = + | 'neutral' | 'neutral-strong' | 'neutral-weak' | 'brand-strong' diff --git a/packages/theme/src/semantic-color-contrast-pairs.ts b/packages/theme/src/semantic-color-contrast-pairs.ts index 3b3b73e77d4b27..3dcc6f818c5ee7 100644 --- a/packages/theme/src/semantic-color-contrast-pairs.ts +++ b/packages/theme/src/semantic-color-contrast-pairs.ts @@ -7,6 +7,26 @@ export const MINIMUM_TEXT_CONTRAST = 4.5; export const SEMANTIC_COLOR_CONTRAST_PAIRS = [ + { + background: 'background.interactive.neutral', + foreground: 'foreground.interactive.neutral', + }, + { + background: 'background.interactive.neutral', + foreground: 'foreground.interactive.neutral-weak', + }, + { + background: 'background.interactive.neutral-active', + foreground: 'foreground.interactive.neutral', + }, + { + background: 'background.interactive.neutral-active', + foreground: 'foreground.interactive.neutral-weak', + }, + { + background: 'background.interactive.neutral-weak-active', + foreground: 'foreground.interactive.neutral-active', + }, { background: 'background.surface.neutral', foreground: 'foreground.content.neutral', diff --git a/packages/theme/src/test/build-plugin-parity.test.ts b/packages/theme/src/test/build-plugin-parity.test.ts index 42fead4dc2e53f..5f5b36e7063095 100644 --- a/packages/theme/src/test/build-plugin-parity.test.ts +++ b/packages/theme/src/test/build-plugin-parity.test.ts @@ -119,6 +119,27 @@ describe( 'design token fallback build plugin parity', () => { ); } ); + it( 'keeps nested token fallbacks aligned across PostCSS and Lightning CSS', async () => { + const filename = join( fixturesDirectory, 'nested-fallback.css' ); + const source = ` +.fixture { + background: var(--wpds-color-background-interactive-neutral-active, var(--wpds-color-background-surface-neutral-strong)); +}`; + const postcssResult = await postcss( [ postcssPlugin ] ).process( + source, + { from: filename } + ); + const lightningcssResult = transformWithLightningcss( + source, + filename + ); + const expected = + 'var(--wpds-color-background-interactive-neutral-active, var(--wpds-color-background-surface-neutral-strong, #fff))'; + + expect( postcssResult.css ).toContain( expected ); + expect( lightningcssResult ).toContain( expected ); + } ); + it( 'leaves an empty var() fallback untouched in PostCSS', async () => { const source = await readFile( emptyFallbackCssFixture, 'utf8' ); const result = await postcss( [ postcssPlugin ] ).process( source, { diff --git a/packages/theme/src/test/use-theme-provider-styles.jsdom.test.tsx b/packages/theme/src/test/use-theme-provider-styles.jsdom.test.tsx index 18671cd32f8ba1..7c27922a2c78b9 100644 --- a/packages/theme/src/test/use-theme-provider-styles.jsdom.test.tsx +++ b/packages/theme/src/test/use-theme-provider-styles.jsdom.test.tsx @@ -135,6 +135,29 @@ describe( 'useThemeProviderStyles', () => { ).toBe( '#1e90ff' ); } ); + it( 'emits neutral interactive background state properties from the background ramp', () => { + const { result } = renderHook( () => + useThemeProviderStyles( { color: { background: '#222222' } } ) + ); + const styles = result.current.themeProviderStyles; + + expect( + styles[ '--wpds-color-background-interactive-neutral' ] + ).toBe( + styles[ '--wpds-color-background-surface-neutral-strong' ] + ); + expect( + styles[ '--wpds-color-background-interactive-neutral-active' ] + ).toBe( + styles[ '--wpds-color-background-surface-neutral-strong' ] + ); + expect( + styles[ '--wpds-color-background-interactive-neutral-disabled' ] + ).toBe( + styles[ '--wpds-color-background-surface-neutral-strong' ] + ); + } ); + it( 're-emits inherited color tokens so portaled subtrees can re-apply them', () => { const wrapper = ( { children }: { children: ReactNode } ) => (