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
8 changes: 6 additions & 2 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
- `ExternalLink`: No longer sets the `rel` attribute by default. Consumers relying on the previous behavior should pass `rel` explicitly ([#79743](https://github.com/WordPress/gutenberg/pull/79743)).
- `View`: The legacy Emotion `css` prop no longer applies styles and is now accepted as a no-op for compatibility. Use `style` for inline styles or `className` for CSS-based styling instead ([#79443](https://github.com/WordPress/gutenberg/pull/79443)).
- Components that compose Emotion style fragments with `cx()` should pass source-order-dependent fragments in a single `css()` call. Passing separate fragments can change override order after the following components stopped rendering styles through Emotion:
- `Truncate` ([#79446](https://github.com/WordPress/gutenberg/pull/79446))
- `Divider` ([#79444](https://github.com/WordPress/gutenberg/pull/79444))
- `Flex` ([#79450](https://github.com/WordPress/gutenberg/pull/79450))
- `Surface` ([#79445](https://github.com/WordPress/gutenberg/pull/79445))
- `Theme` ([#79447](https://github.com/WordPress/gutenberg/pull/79447))
- `Truncate` ([#79446](https://github.com/WordPress/gutenberg/pull/79446))
- `View` ([#79443](https://github.com/WordPress/gutenberg/pull/79443))
- The `__next40pxDefaultSize` prop is now true by default. The prop can be safely removed from the following:
- `BorderBoxControl` ([#79420](https://github.com/WordPress/gutenberg/pull/79420))
Expand Down Expand Up @@ -49,6 +50,7 @@
- Update `@ariakit/react` to `0.4.32` ([#79860](https://github.com/WordPress/gutenberg/pull/79860)).
- `Flex`: Migrate styles from Emotion to SCSS Modules ([#79450](https://github.com/WordPress/gutenberg/pull/79450)).
- `Surface`: Migrate styles from Emotion to SCSS Modules and use WPDS tokens for migrated visual values ([#79445](https://github.com/WordPress/gutenberg/pull/79445)).
- `Theme`: Migrate styles from Emotion to SCSS Modules ([#79447](https://github.com/WordPress/gutenberg/pull/79447)).
- `Truncate`: Migrate styles from Emotion to SCSS Modules ([#79446](https://github.com/WordPress/gutenberg/pull/79446)).
- `View`: Migrate away from Emotion while preserving polymorphic `as` behavior and style cascade order ([#79443](https://github.com/WordPress/gutenberg/pull/79443)).

Expand All @@ -58,6 +60,8 @@

### Breaking Changes

- Components that compose Emotion style fragments with `cx()` should pass source-order-dependent fragments in a single `css()` call. Passing separate fragments can change override order after the following components stopped rendering styles through Emotion:
- `Divider` ([#79444](https://github.com/WordPress/gutenberg/pull/79444))
- The `__next40pxDefaultSize` prop is now true by default. The prop can be safely removed from the following:
- `BoxControl` ([#79419](https://github.com/WordPress/gutenberg/pull/79419))
- `TextControl` ([#79386](https://github.com/WordPress/gutenberg/pull/79386))
Expand Down
61 changes: 43 additions & 18 deletions packages/components/src/theme/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
/**
* WordPress dependencies
*/
import clsx from 'clsx';
import type { CSSProperties } from 'react';

import { useMemo } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { ThemeProps } from './types';
import type { ThemeOutputValues, ThemeProps } from './types';
import type { WordPressComponentProps } from '../context';
import { colorVariables, Wrapper } from './styles';
import { generateThemeVariables } from './color-algorithms';
import { useCx } from '../utils';
import styles from './style.module.scss';
import { PolymorphicElement } from '../utils/polymorphic-element';

const getColorVariables = ( {
colors,
}: ThemeOutputValues ): CSSProperties => ( {
'--wp-components-color-accent': colors.accent,
'--wp-components-color-accent-darker-10': colors.accentDarker10,
'--wp-components-color-accent-darker-20': colors.accentDarker20,
'--wp-components-color-accent-inverted': colors.accentInverted,
'--wp-components-color-background': colors.background,
'--wp-components-color-foreground': colors.foreground,
'--wp-components-color-foreground-inverted': colors.foregroundInverted,
...Object.fromEntries(
Object.entries( colors.gray ?? {} ).map( ( [ key, value ] ) => [
`--wp-components-color-gray-${ key }`,
value,
] )
),
} );

/**
* `Theme` allows defining theme variables for components in the `@wordpress/components` package.
Expand All @@ -35,21 +50,31 @@ function Theme( {
accent,
background,
className,
style,
...props
}: WordPressComponentProps< ThemeProps, 'div', true > ) {
const cx = useCx();
const classes = useMemo(
const themeVariables = useMemo(
() =>
cx(
...colorVariables(
generateThemeVariables( { accent, background } )
),
className
getColorVariables(
generateThemeVariables( { accent, background } )
),
[ accent, background, className, cx ]
[ accent, background ]
);
const wrapperStyle = useMemo(
() => ( {
...themeVariables,
...style,
} ),
[ style, themeVariables ]
);

return <Wrapper className={ classes } { ...props } />;
return (
<PolymorphicElement
className={ clsx( styles.wrapper, className ) }
style={ wrapperStyle }
{ ...props }
/>
);
}

export default Theme;
4 changes: 4 additions & 0 deletions packages/components/src/theme/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.wrapper {
/* stylelint-disable-next-line declaration-property-value-disallowed-list -- Preserve Theme's currentColor fallback when no foreground variable is generated. */
color: var(--wp-components-color-foreground, currentColor);
}
35 changes: 0 additions & 35 deletions packages/components/src/theme/styles.ts

This file was deleted.

29 changes: 23 additions & 6 deletions packages/components/src/theme/test/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
/**
* External dependencies
*/
import { render, screen } from '@testing-library/react';
import type { ReactNode } from 'react';

/**
* Internal dependencies
*/
import Theme from '../';

type MyThemableComponentProps = {
Expand All @@ -25,6 +19,29 @@ const MyThemableComponent = ( props: MyThemableComponentProps ) => {
};

describe( 'Theme', () => {
it( 'should support the as prop', () => {
render( <Theme as="section" data-testid="theme" /> );

expect( screen.getByTestId( 'theme' ) ).toHaveProperty(
'tagName',
'SECTION'
);
} );

it( 'lets user styles override generated theme variables', () => {
render(
<Theme
accent="#123abc"
style={ { '--wp-components-color-accent': '#654321' } }
data-testid="theme"
/>
);

expect( screen.getByTestId( 'theme' ) ).toHaveStyle( {
'--wp-components-color-accent': '#654321',
} );
} );

describe( 'accent color', () => {
it( 'does not define the accent color (and its variations) as a CSS variable when the `accent` prop is undefined', () => {
render(
Expand Down
5 changes: 0 additions & 5 deletions tools/eslint/suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -892,11 +892,6 @@
"count": 2
}
},
"packages/components/src/theme/styles.ts": {
"no-restricted-imports": {
"count": 2
}
},
"packages/components/src/toggle-group-control/toggle-group-control-option-base/styles.ts": {
"no-restricted-imports": {
"count": 2
Expand Down
Loading