Skip to content

Commit

Permalink
feat: add custom root selector support for CSS variables
Browse files Browse the repository at this point in the history
  • Loading branch information
cheton committed Nov 29, 2024
1 parent d8d0171 commit 83288bc
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 deletions.
14 changes: 6 additions & 8 deletions packages/react/src/theme/CSSVariables.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { Global } from '@emotion/react';
import { ensureArray, ensurePlainObject } from 'ensure-type';
import { ensurePlainObject } from 'ensure-type';
import React, { useCallback } from 'react';

const CSSVariables = ({
root = [':root'],
}) => {
const CSSVariables = () => {
const styles = useCallback((theme) => {
const rootSelector = theme?.rootSelector;
const cssVariables = ensurePlainObject(theme?.cssVariables);
if (Object.keys(cssVariables) === 0) {
if (!rootSelector || Object.keys(cssVariables) === 0) {
return {};

Check warning on line 10 in packages/react/src/theme/CSSVariables.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/theme/CSSVariables.js#L10

Added line #L10 was not covered by tests
}
const selector = ensureArray(root).join(',');
return {
[selector]: cssVariables,
[rootSelector]: cssVariables,
};
}, [root]);
}, []);

return (
<Global styles={styles} />
Expand Down
19 changes: 12 additions & 7 deletions packages/react/src/theme/createTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import { ensurePlainObject } from 'ensure-type';
import { mapThemeToCSSVariables } from './utils/css-vars';

const defaultCSSVariablePrefix = 'tonic';
const defaultCSSVariableRootSelector = ':root';

const createTheme = (options = {}, ...args) => {
const {
// Configure CSS variables for the theme:
// - `false` (default): Disable CSS variables.
// - `true`: Enable CSS variables with default settings.
// - `{ prefix: 'tonic' }`: Enable CSS variables with a custom prefix.
// CSS variables configuration for the theme:
// - false (default): Disables CSS variables.
// - true: Enables CSS variables with default settings.
// - Object: Enables CSS variables with custom settings:
// - prefix: 'tonic' (default) — Custom prefix for CSS variables.
// - rootSelector: ':root' (default) — Root selector where CSS variables are defined.
cssVariables: cssVariableConfig = false,
...rest
} = options;
Expand All @@ -30,10 +33,11 @@ const createTheme = (options = {}, ...args) => {
throw new Error('The `cssVariables` config must be a boolean or an object');

Check warning on line 33 in packages/react/src/theme/createTheme.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/theme/createTheme.js#L33

Added line #L33 was not covered by tests
}

// Determine the prefix for CSS variables:
// - Uses the `prefix` property if provided (e.g., `createTheme({ cssVariables: { prefix: 'tonic' } })`).
// - Defaults to `defaultCSSVariablePrefix` if no custom prefix is specified.
// Configure the prefix and root selector for CSS variables:
// - `cssVariablePrefix`: Uses `cssVariables.prefix` if available; otherwise, defaults to 'tonic'.
// - `rootSelector`: Uses `cssVariables.rootSelector` if available; otherwise, defaults to ':root'.
const cssVariablePrefix = cssVariableConfig?.prefix ?? defaultCSSVariablePrefix;
const rootSelector = cssVariableConfig?.rootSelector ?? defaultCSSVariableRootSelector;

// Generate a theme object filtered to include only scales supported by CSS variables
const cssVariableScales = Object.keys(tonicTheme);
Expand All @@ -50,6 +54,7 @@ const createTheme = (options = {}, ...args) => {
theme = merge(theme, {
cssVariablePrefix,
cssVariables,
rootSelector,
});
}

Expand Down

0 comments on commit 83288bc

Please sign in to comment.