Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/theme/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Breaking Changes

- Rename `--wpds-color-background-thumb-neutral-disabled` to `--wpds-color-background-thumb-neutral-weak-disabled` so the disabled token belongs to the existing neutral weak thumb family ([#79770](https://github.com/WordPress/gutenberg/pull/79770)).
- `ThemeProvider`: reject partially transparent and `transparent` seed colors. `color.primary` and `color.background` now only accept fully opaque seed colors ([#79773](https://github.com/WordPress/gutenberg/pull/79773)).

### Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion packages/theme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ The `color` prop accepts an object with the following optional properties:
- `primary`: The primary/accent seed color (default: `'#3858e9'`).
- `background`: The background seed color (default: `'#f8f8f8'`).

Both properties accept an sRGB-parseable string: a hex value (e.g. `#3858e9`), an `rgb()`/`rgba()` string, or a CSS named color (e.g. `'blue'`). Other CSS color spaces (e.g. `hsl()`, `oklch()`, `lab()`) are not accepted and will throw an error. The theme system automatically generates appropriate color ramps and determines light/dark mode based on these seed colors.
Both properties accept a fully opaque sRGB-parseable string: a hex value (e.g. `#3858e9`), an `rgb()`/`rgba()` string, or a CSS named color (e.g. `'blue'`). Non-opaque alpha values, `transparent`, and other CSS color spaces (e.g. `hsl()`, `oklch()`, `lab()`) are not accepted and will throw an error. The theme system automatically generates appropriate color ramps and determines light/dark mode based on these seed colors.

The `cursor` prop accepts an object with the following optional properties:

Expand Down
22 changes: 15 additions & 7 deletions packages/theme/src/color-ramps/lib/color-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,44 @@ export function getContrast(
}

/**
* Assert that a seed-color string is sRGB-parseable (hex, `rgb()`/`rgba()`, or
* a CSS named color), throwing otherwise.
* Assert that a seed-color string is sRGB-parseable and fully opaque (hex,
* `rgb()`/`rgba()`, or a CSS named color), throwing otherwise.
*
* Rejection is deterministic regardless of which `ColorSpace`s are globally
* registered: `clampToGamut` registers `OKLCH`, which would otherwise make
* `oklch()` strings parse, but their space id is `oklch` (not `srgb`) so they
* are still rejected.
*
* @param seed The seed-color string to validate.
* @throws If `seed` is not an sRGB-parseable string.
* @throws If `seed` is not an sRGB-parseable, fully opaque string.
*/
export function assertValidSeedColor( seed: string ): void {
ALLOWED_SEED_COLOR_SPACES.forEach( ( space ) =>
ColorSpace.register( space )
);

let spaceId: string;
let parsedColor: ReturnType< typeof parse >;
try {
( { spaceId } = parse( seed ) );
parsedColor = parse( seed );
} catch {
throw new Error(
`Unsupported seed color "${ seed }": expected a hex value, an \`rgb()\`/\`rgba()\` string, or a CSS named color.`
`Unsupported seed color "${ seed }": expected a fully opaque hex value, an \`rgb()\`/\`rgba()\` string, or a CSS named color.`
);
}

const { alpha = 1, spaceId } = parsedColor;

if (
! ALLOWED_SEED_COLOR_SPACES.some( ( space ) => space.id === spaceId )
) {
throw new Error(
`Unsupported seed color "${ seed }": expected a hex value, an \`rgb()\`/\`rgba()\` string, or a CSS named color, but received a \`${ spaceId }\` color.`
`Unsupported seed color "${ seed }": expected a fully opaque hex value, an \`rgb()\`/\`rgba()\` string, or a CSS named color, but received a \`${ spaceId }\` color.`
);
}

if ( alpha !== 1 ) {
throw new Error(
`Unsupported seed color "${ seed }": expected a fully opaque color.`
);
}
}
Expand Down
11 changes: 7 additions & 4 deletions packages/theme/src/color-ramps/test/seed-input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import { BG_RAMP_CONFIG } from '../lib/ramp-configs';

const ACCEPTED_SEEDS = [
'#3858e9',
'#3858e94d',
'#3858e9ff',
'rgb(56,88,233)',
'rgb(56 88 233 / 0.3)',
'rgba(56,88,233,0.3)',
'rgb(56 88 233 / 1)',
'rgba(56,88,233,1)',
'blue',
'transparent',
];

const REJECTED_SEEDS = [
'#3858e94d',
'rgb(56 88 233 / 0.3)',
'rgba(56,88,233,0.3)',
'transparent',
'oklch(0.7 0.15 250)',
'hsl(230 80% 56%)',
'lab(50% 40 59)',
Expand Down
20 changes: 11 additions & 9 deletions packages/theme/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ export interface ThemeProviderSettings {
*/
color?: {
/**
* The primary seed color to use for the theme. Accepts an
* The primary seed color to use for the theme. Accepts a fully opaque
* sRGB-parseable string: a hex value (e.g. `#3858e9`), an
* `rgb()`/`rgba()` string, or a CSS named color (e.g. `'blue'`). Other
* CSS color spaces (e.g. `hsl()`, `oklch()`, `lab()`) are not accepted
* and throw an error.
* `rgb()`/`rgba()` string, or a CSS named color (e.g. `'blue'`).
* Non-opaque alpha values, `transparent`, and other CSS color spaces
* (e.g. `hsl()`, `oklch()`, `lab()`) are not accepted and throw an
* error.
*
* By default, it inherits from parent `ThemeProvider`,
* and fallbacks to statically built CSS.
*/
primary?: string;
/**
* The background seed color to use for the theme. Accepts an
* sRGB-parseable string: a hex value (e.g. `#f8f8f8`), an
* `rgb()`/`rgba()` string, or a CSS named color (e.g. `'blue'`). Other
* CSS color spaces (e.g. `hsl()`, `oklch()`, `lab()`) are not accepted
* and throw an error.
* The background seed color to use for the theme. Accepts a fully
* opaque sRGB-parseable string: a hex value (e.g. `#f8f8f8`), an
* `rgb()`/`rgba()` string, or a CSS named color (e.g. `'blue'`).
* Non-opaque alpha values, `transparent`, and other CSS color spaces
* (e.g. `hsl()`, `oklch()`, `lab()`) are not accepted and throw an
* error.
*
* By default, it inherits from parent `ThemeProvider`,
* and fallbacks to statically built CSS.
Expand Down
Loading