diff --git a/.changeset/four-bikes-explode.md b/.changeset/four-bikes-explode.md new file mode 100644 index 00000000..129dd241 --- /dev/null +++ b/.changeset/four-bikes-explode.md @@ -0,0 +1,5 @@ +--- +"@spear-ai/tailwind-config": major +--- + +Refactored Tailwind Theme plugin to take a collection of themes. This is a breaking change. To update, pass in a dictionary. e.g. `themes: { DEFAULT: {} }`. diff --git a/packages/tailwind-config/src/tailwind-radix-color-theme-plugin.ts b/packages/tailwind-config/src/tailwind-radix-color-theme-plugin.ts index 9236735e..8e5bffbf 100644 --- a/packages/tailwind-config/src/tailwind-radix-color-theme-plugin.ts +++ b/packages/tailwind-config/src/tailwind-radix-color-theme-plugin.ts @@ -9,70 +9,73 @@ import { stepList, } from "./tailwind-radix-colors"; -export type RadixColorThemeOptions = { - /** A radix color scale for the application’s background color. Defaults to the `primary` color scale. */ - canvas?: RadixHueColorScaleName | undefined; +export type RadixColorThemePluginOptions = Record< + string, + { + /** A radix color scale for the application’s background color. Defaults to the `primary` color scale. */ + canvas?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `canvas` color’s scale. */ - canvasDark?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `canvas` color’s scale. */ + canvasDark?: RadixHueColorScaleName | undefined; - /** Defaults to the light variant of the `canvas` color’s scale. */ - canvasLight?: RadixHueColorScaleName | undefined; + /** Defaults to the light variant of the `canvas` color’s scale. */ + canvasLight?: RadixHueColorScaleName | undefined; - /** A negative valence color (e.g. Warning, Paused). Defaults to `"yellow"`. */ - negative?: RadixHueColorScaleName | undefined; + /** A negative valence color (e.g. Warning, Paused). Defaults to `"yellow"`. */ + negative?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `negative` color’s scale. */ - negativeDark?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `negative` color’s scale. */ + negativeDark?: RadixHueColorScaleName | undefined; - /** Defaults to the light variant of the `negative` color’s scale. */ - negativeLight?: RadixHueColorScaleName | undefined; + /** Defaults to the light variant of the `negative` color’s scale. */ + negativeLight?: RadixHueColorScaleName | undefined; - /** A [gray](https://www.radix-ui.com/docs/colors/palette-composition/scales#grays) Radix color scale. Defaults to `"grey"`. */ - neutral?: RadixGrayColorScaleName | undefined; + /** A [gray](https://www.radix-ui.com/docs/colors/palette-composition/scales#grays) Radix color scale. Defaults to `"grey"`. */ + neutral?: RadixGrayColorScaleName | undefined; - /** Defaults to the dark variant of the `neutral` color’s scale. */ - neutralDark?: RadixGrayColorScaleName | undefined; + /** Defaults to the dark variant of the `neutral` color’s scale. */ + neutralDark?: RadixGrayColorScaleName | undefined; - /** Defaults to the light variant of the `neutral` color’s scale. */ - neutralLight?: RadixGrayColorScaleName | undefined; + /** Defaults to the light variant of the `neutral` color’s scale. */ + neutralLight?: RadixGrayColorScaleName | undefined; - /** A positive valence color (Info, Loading, Pending). Defaults to `"blue"`. */ - positive?: RadixHueColorScaleName | undefined; + /** A positive valence color (Info, Loading, Pending). Defaults to `"blue"`. */ + positive?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `positive` color’s scale. */ - positiveDark?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `positive` color’s scale. */ + positiveDark?: RadixHueColorScaleName | undefined; - /** Defaults to the light variant of the `positive` color’s scale. */ - positiveLight?: RadixHueColorScaleName | undefined; + /** Defaults to the light variant of the `positive` color’s scale. */ + positiveLight?: RadixHueColorScaleName | undefined; - /** A Radix color scale for the application’s primary accent color. Defaults to the `neutral` color scale. */ - primary?: RadixHueColorScaleName | undefined; + /** A Radix color scale for the application’s primary accent color. Defaults to the `neutral` color scale. */ + primary?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `primary` color’s scale. */ - primaryDark?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `primary` color’s scale. */ + primaryDark?: RadixHueColorScaleName | undefined; - /** Defaults to the light variant of the `primary` color’s scale. */ - primaryLight?: RadixHueColorScaleName | undefined; + /** Defaults to the light variant of the `primary` color’s scale. */ + primaryLight?: RadixHueColorScaleName | undefined; - /** An extra negative valence color (e.g. Error, Danger). Defaults to `"red"`. */ - xNegative?: RadixHueColorScaleName | undefined; + /** An extra negative valence color (e.g. Error, Danger). Defaults to `"red"`. */ + xNegative?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `x-negative` color’s scale. */ - xNegativeDark?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `x-negative` color’s scale. */ + xNegativeDark?: RadixHueColorScaleName | undefined; - /** Defaults to the light variant of the `x-negative` color’s scale. */ - xNegativeLight?: RadixHueColorScaleName | undefined; + /** Defaults to the light variant of the `x-negative` color’s scale. */ + xNegativeLight?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `x-negative` color’s scale. */ - xPositive?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `x-negative` color’s scale. */ + xPositive?: RadixHueColorScaleName | undefined; - /** Defaults to the dark variant of the `x-positive` color’s scale. */ - xPositiveDark?: RadixHueColorScaleName | undefined; + /** Defaults to the dark variant of the `x-positive` color’s scale. */ + xPositiveDark?: RadixHueColorScaleName | undefined; - /** Defaults to the light variant of the `x-positive` color’s scale. */ - xPositiveLight?: RadixHueColorScaleName | undefined; -}; + /** Defaults to the light variant of the `x-positive` color’s scale. */ + xPositiveLight?: RadixHueColorScaleName | undefined; + } +>; export const themeColorNameList = [ "canvas", @@ -84,9 +87,7 @@ export const themeColorNameList = [ "x-positive", ]; -type Variables = { - DEFAULT: { colors: Colors }; -}; +type Variables = { colors: Colors }; const colors: Colors = {}; @@ -173,225 +174,198 @@ for (const themeColorName of themeColorNameList) { export const radixColorThemePlugin = plugin( ({ addComponents, config, theme }) => { - const options: RadixColorThemeOptions = theme("theme", {}); - const { canvas, negative, neutral, positive, primary, xNegative, xPositive } = options; - const neutralLight = options.neutralLight ?? neutral ?? "gray"; - const neutralDark = options.neutralDark ?? neutral ?? "gray"; - const primaryLight = options.primaryLight ?? primary ?? neutralLight; - const primaryDark = options.primaryDark ?? primary ?? neutralDark; - const canvasLight = options.canvasLight ?? canvas ?? primaryLight; - const canvasDark = options.canvasDark ?? canvas ?? primaryDark; - const negativeLight = options.negativeLight ?? negative ?? "yellow"; - const negativeDark = options.negativeDark ?? negative ?? "yellow"; - const xNegativeLight = options.xNegativeLight ?? xNegative ?? "red"; - const xNegativeDark = options.xNegativeDark ?? xNegative ?? "red"; - const positiveLight = options.positiveLight ?? positive ?? "blue"; - const positiveDark = options.positiveDark ?? positive ?? "blue"; - const xPositiveLight = options.xPositiveLight ?? xPositive ?? "green"; - const xPositiveDark = options.xPositiveDark ?? xPositive ?? "green"; - - const themeVariableList = [ - { darkScaleName: canvasDark, lightScaleName: canvasLight, name: "canvas" }, - { darkScaleName: neutralDark, lightScaleName: neutralLight, name: "neutral" }, - { darkScaleName: primaryDark, lightScaleName: primaryLight, name: "primary" }, - { darkScaleName: negativeDark, lightScaleName: negativeLight, name: "negative" }, - { darkScaleName: positiveDark, lightScaleName: positiveLight, name: "positive" }, - { darkScaleName: xNegativeDark, lightScaleName: xNegativeLight, name: "x-negative" }, - { darkScaleName: xPositiveDark, lightScaleName: xPositiveLight, name: "x-positive" }, - ]; - - const rootVariables: Variables = { - DEFAULT: { - colors: {}, - }, - }; + const options: RadixColorThemePluginOptions = theme("themes", {}); + const rootVariables: Record = {}; + const lightVariables: Record = {}; + const darkVariables: Record = {}; - const lightVariables: Variables = { - DEFAULT: { - colors: {}, - }, + lightVariables["*"] = { + colors: {}, }; - const darkVariables: Variables = { - DEFAULT: { - colors: {}, - }, + darkVariables["*"] = { + colors: {}, }; - for (const variable of themeVariableList) { - // { - // "primary-light": { - // 1: "{l} {c} {h}", - // 2: "{l} {c} {h}", - // ⋮ - // 12: "{l} {c} {h}", - // }, - // } - rootVariables.DEFAULT.colors[`${variable.name}-light`] = Object.fromEntries( - stepList.map((step) => [ - step, - getColorValue({ - isAlpha: false, - isDark: false, - isVariable: true, - scaleName: variable.lightScaleName, + for (const [themeName, themeOptions] of Object.entries(options)) { + const themeSelector = themeName === "DEFAULT" ? "*" : `.is-product-${themeName}`; + + rootVariables[themeSelector] = { + colors: {}, + }; + + const { canvas, negative, neutral, positive, primary, xNegative, xPositive } = themeOptions; + const neutralLight = themeOptions.neutralLight ?? neutral ?? "gray"; + const neutralDark = themeOptions.neutralDark ?? neutral ?? "gray"; + const primaryLight = themeOptions.primaryLight ?? primary ?? neutralLight; + const primaryDark = themeOptions.primaryDark ?? primary ?? neutralDark; + const canvasLight = themeOptions.canvasLight ?? canvas ?? primaryLight; + const canvasDark = themeOptions.canvasDark ?? canvas ?? primaryDark; + const negativeLight = themeOptions.negativeLight ?? negative ?? "yellow"; + const negativeDark = themeOptions.negativeDark ?? negative ?? "yellow"; + const xNegativeLight = themeOptions.xNegativeLight ?? xNegative ?? "red"; + const xNegativeDark = themeOptions.xNegativeDark ?? xNegative ?? "red"; + const positiveLight = themeOptions.positiveLight ?? positive ?? "blue"; + const positiveDark = themeOptions.positiveDark ?? positive ?? "blue"; + const xPositiveLight = themeOptions.xPositiveLight ?? xPositive ?? "green"; + const xPositiveDark = themeOptions.xPositiveDark ?? xPositive ?? "green"; + + const themeVariableList = [ + { darkScaleName: canvasDark, lightScaleName: canvasLight, name: "canvas" }, + { darkScaleName: neutralDark, lightScaleName: neutralLight, name: "neutral" }, + { darkScaleName: primaryDark, lightScaleName: primaryLight, name: "primary" }, + { darkScaleName: negativeDark, lightScaleName: negativeLight, name: "negative" }, + { darkScaleName: positiveDark, lightScaleName: positiveLight, name: "positive" }, + { darkScaleName: xNegativeDark, lightScaleName: xNegativeLight, name: "x-negative" }, + { darkScaleName: xPositiveDark, lightScaleName: xPositiveLight, name: "x-positive" }, + ]; + + for (const variable of themeVariableList) { + // :root { + // --primary-light-1: "{l} {c} {h}"; + // --primary-light-2: "{l} {c} {h}"; + // ⋮ + // --primary-light-12: "{l} {c} {h}"; + // } + rootVariables[themeSelector].colors[`${variable.name}-light`] = Object.fromEntries( + stepList.map((step) => [ step, - }), - ]), - ); - - // { - // "primary-light-a": { - // 1: "{l} {c} {h} / {a}", - // 2: "{l} {c} {h} / {a}", - // ⋮ - // 12: "{l} {c} {h} / {a}", - // }, - // } - rootVariables.DEFAULT.colors[`${variable.name}-light-a`] = Object.fromEntries( - stepList.map((step) => [ - step, - getColorValue({ - isAlpha: true, - isDark: false, - isVariable: true, - scaleName: variable.lightScaleName, + getColorValue({ + isAlpha: false, + isDark: false, + isVariable: true, + scaleName: variable.lightScaleName, + step, + }), + ]), + ); + + // :root { + // --primary-light-a-1: "{l} {c} {h}"; + // --primary-light-a-2: "{l} {c} {h}"; + // ⋮ + // --primary-light-a-12: "{l} {c} {h}"; + // } + rootVariables[themeSelector].colors[`${variable.name}-light-a`] = Object.fromEntries( + stepList.map((step) => [ step, - }), - ]), - ); - - // { - // "primary-light-contrast": "black", - // } - rootVariables.DEFAULT.colors[`${variable.name}-light-contrast`] = getContrastColorValue( - variable.lightScaleName, - ); - - // { - // "primary-dark": { - // 1: "{l} {c} {h}", - // 2: "{l} {c} {h}", - // ⋮ - // 12: "{l} {c} {h}", - // }, - // } - rootVariables.DEFAULT.colors[`${variable.name}-dark`] = Object.fromEntries( - stepList.map((step) => [ - step, - getColorValue({ - isAlpha: false, - isDark: true, - isVariable: true, - scaleName: variable.darkScaleName, + getColorValue({ + isAlpha: true, + isDark: false, + isVariable: true, + scaleName: variable.lightScaleName, + step, + }), + ]), + ); + + // :root { + // --primary-dark-1: "{l} {c} {h}"; + // --primary-dark-2: "{l} {c} {h}"; + // ⋮ + // --primary-dark-12: "{l} {c} {h}"; + // } + rootVariables[themeSelector].colors[`${variable.name}-dark`] = Object.fromEntries( + stepList.map((step) => [ step, - }), - ]), - ); - - // { - // "primary-dark-a": { - // 1: "{l} {c} {h} / {a}", - // 2: "{l} {c} {h} / {a}", - // ⋮ - // 12: "{l} {c} {h} / {a}", - // }, - // } - rootVariables.DEFAULT.colors[`${variable.name}-dark-a`] = Object.fromEntries( - stepList.map((step) => [ - step, - getColorValue({ - isAlpha: true, - isDark: true, - isVariable: true, - scaleName: variable.darkScaleName, + getColorValue({ + isAlpha: false, + isDark: true, + isVariable: true, + scaleName: variable.darkScaleName, + step, + }), + ]), + ); + + // :root { + // --primary-dark-a-1: "{l} {c} {h}"; + // --primary-dark-a-2: "{l} {c} {h}"; + // ⋮ + // --primary-dark-a-12: "{l} {c} {h}"; + // } + rootVariables[themeSelector].colors[`${variable.name}-dark-a`] = Object.fromEntries( + stepList.map((step) => [ step, - }), - ]), - ); - - // { - // "primary-dark-contrast": "black", - // } - rootVariables.DEFAULT.colors[`${variable.name}-dark-contrast`] = getContrastColorValue( - variable.darkScaleName, - ); - - // { - // ".light": { - // "primary": { - // 1: "var(--colors-primary-light-1)", - // 2: "var(--colors-primary-light-2)", - // ⋮ - // 12: "var(--colors-primary-light-12)", - // }, - // }, - // } - lightVariables.DEFAULT.colors[variable.name] = Object.fromEntries( - stepList.map((step) => [step, `var(--colors-${variable.name}-light-${step})`]), - ); - - // { - // ".light": { - // "primary-a": { - // 1: "var(--colors-primary-light-a-1)", - // 2: "var(--colors-primary-light-a-2)", - // ⋮ - // 12: "var(--colors-primary-light-a-12)", - // }, - // }, - // } - lightVariables.DEFAULT.colors[`${variable.name}-a`] = Object.fromEntries( - stepList.map((step) => [step, `var(--colors-${variable.name}-light-a-${step})`]), - ); - - // { - // ".light": { - // "primary-contrast": var(--colors-primary-light-contrast), - // }, - // } - lightVariables.DEFAULT.colors[`${variable.name}-contrast`] = - `var(--colors-${variable.name}-light-contrast)`; - - // { - // ".dark": { - // "primary": { - // 1: "var(--colors-primary-dark-1)", - // 2: "var(--colors-primary-dark-2)", - // ⋮ - // 12: "var(--colors-primary-dark-12)", - // }, - // }, - // } - darkVariables.DEFAULT.colors[variable.name] = Object.fromEntries( - stepList.map((step) => [step, `var(--colors-${variable.name}-dark-${step})`]), - ); - - // { - // ".dark": { - // "primary-a": { - // 1: "var(--colors-primary-dark-a-1)", - // 2: "var(--colors-primary-dark-a-2)", - // ⋮ - // 12: "var(--colors-primary-dark-a-12)", - // }, - // }, - // } - darkVariables.DEFAULT.colors[`${variable.name}-a`] = Object.fromEntries( - stepList.map((step) => [step, `var(--colors-${variable.name}-dark-a-${step})`]), - ); - - // { - // ".dark": { - // "primary-contrast": var(--colors-primary-dark-contrast), - // }, - // } - darkVariables.DEFAULT.colors[`${variable.name}-contrast`] = - `var(--colors-${variable.name}-dark-contrast)`; + getColorValue({ + isAlpha: true, + isDark: true, + isVariable: true, + scaleName: variable.darkScaleName, + step, + }), + ]), + ); + + // :root { + // --primary-light-contrast: black; + // } + rootVariables[themeSelector].colors[`${variable.name}-light-contrast`] = getContrastColorValue( + variable.lightScaleName, + ); + + // :root { + // --primary-dark-contrast: white; + // } + rootVariables[themeSelector].colors[`${variable.name}-dark-contrast`] = getContrastColorValue( + variable.darkScaleName, + ); + + // :root { + // --colors-primary-1: var(--colors-primary-light-1); + // --colors-primary-2: var(--colors-primary-light-2); + // ⋮ + // --colors-primary-12: var(--colors-primary-light-12); + // } + lightVariables["*"].colors[variable.name] = Object.fromEntries( + stepList.map((step) => [step, `var(--colors-${variable.name}-light-${step})`]), + ); + + // :root { + // --colors-primary-a-1: var(--colors-primary-light-a-1); + // --colors-primary-a-2: var(--colors-primary-light-a-2); + // ⋮ + // --colors-primary-a-12: var(--colors-primary-light-a-12); + // } + lightVariables["*"].colors[`${variable.name}-a`] = Object.fromEntries( + stepList.map((step) => [step, `var(--colors-${variable.name}-light-a-${step})`]), + ); + + // :root { + // --colors-primary-contrast: var(--colors-primary-light-contrast); + // } + lightVariables["*"].colors[`${variable.name}-contrast`] = + `var(--colors-${variable.name}-light-contrast)`; + + // :root.dark { + // --colors-primary-1: var(--colors-primary-dark-1); + // --colors-primary-2: var(--colors-primary-dark-2); + // ⋮ + // --colors-primary-12: var(--colors-primary-dark-12); + // } + darkVariables["*"].colors[variable.name] = Object.fromEntries( + stepList.map((step) => [step, `var(--colors-${variable.name}-dark-${step})`]), + ); + + // :root.dark { + // --colors-primary-a-1: var(--colors-primary-dark-a-1); + // --colors-primary-a-2: var(--colors-primary-dark-a-2); + // ⋮ + // --colors-primary-a-12: var(--colors-primary-dark-a-12); + // } + darkVariables["*"].colors[`${variable.name}-a`] = Object.fromEntries( + stepList.map((step) => [step, `var(--colors-${variable.name}-dark-a-${step})`]), + ); + + // :root.dark { + // --colors-primary-contrast: var(--colors-primary-dark-contrast); + // } + darkVariables["*"].colors[`${variable.name}-contrast`] = + `var(--colors-${variable.name}-dark-contrast)`; + } } const darkModeSelector = (config("darkMode") as [string])[0]; - addComponents(variablesApi.variables(rootVariables)); addComponents(variablesApi.variables(lightVariables)); addComponents(variablesApi.darkVariables(darkVariables, {}, darkModeSelector));