diff --git a/packages/tokens/scripts/build_tokens.mjs b/packages/tokens/scripts/build_tokens.mjs index cdc73e3..c4e92a7 100644 --- a/packages/tokens/scripts/build_tokens.mjs +++ b/packages/tokens/scripts/build_tokens.mjs @@ -42,6 +42,7 @@ import { selectColorValuePreprocessor, convertClampStringToDimension, } from "./build_tokens_preprocessors.js"; +import { DARK_SELECTOR, LIGHT_SELECTOR } from "../src/color_mode.js"; /** * Design tokens @@ -234,7 +235,7 @@ const getStyleDictionaryConfigDefault = (buildPath) => ( destination: "tokens.css", format: "css/variables", options: { - selector: ":root, .gl-light-scope", + selector: LIGHT_SELECTOR, }, }, ], @@ -370,7 +371,7 @@ const getStyleDictionaryConfigDarkMode = (buildPath) => merge(getStyleDictionary { destination: "tokens.dark.css", options: { - selector: ":root.gl-dark, .gl-dark-scope", + selector: DARK_SELECTOR, }, }, ], diff --git a/packages/tokens/src/color_mode.js b/packages/tokens/src/color_mode.js new file mode 100644 index 0000000..20059f3 --- /dev/null +++ b/packages/tokens/src/color_mode.js @@ -0,0 +1,16 @@ +/** + * The classes that decide which set of token values applies to an element. + * + * Dark mode is applied either to the whole document, by putting `gl-dark` on the root, or to a + * subtree, by putting `gl-dark-scope` on any ancestor. `gl-light-scope` flips a subtree back. + * + * These are the single source of truth: `scripts/build_tokens.mjs` builds the CSS selectors from + * them, so the stylesheets and any JavaScript that has to reason about the colour mode cannot drift + * apart. Changing a name here changes both. + */ +export const DARK_ROOT_CLASS = "gl-dark"; +export const DARK_SCOPE_CLASS = "gl-dark-scope"; +export const LIGHT_SCOPE_CLASS = "gl-light-scope"; + +export const LIGHT_SELECTOR = `:root, .${LIGHT_SCOPE_CLASS}`; +export const DARK_SELECTOR = `:root.${DARK_ROOT_CLASS}, .${DARK_SCOPE_CLASS}`;