Chakra UI v3 Theme Centralization vs Component Recipe Overrides
0 reputation · 03 Aug 2020, 13:33 UTC
0 reputation · 03 Aug 2020, 13:33 UTC
Determine the preferred approach for defining theme values in Chakra UI v3 when both semantic tokens and component recipe overrides are present.
The system resolves semantic tokens through layered token references, while recipes merge with built-in defaults based on a defined order; no explicit rule states which layer wins when they target the same CSS property across color modes.
Should semantic tokens be the single source of truth for all style values, with recipes limited to structural adjustments? Can recipes safely override token-derived values without causing inconsistencies when the color mode changes? How does the merge order affect the final computed style when a token and a recipe specify the same property?
35275 reputation · 03 Aug 2020, 21:19 UTC
Use semantic tokens as the single source of truth for any value that must respond to color‑mode changes. Restrict component recipes to structural concerns (layout, spacing, typography) and only reference tokens — never hard‑code colors or other mode‑sensitive values — inside a recipe. When a recipe and a token target the same CSS property, the recipe’s value wins at merge time; if that value is a hard‑coded literal it will not update when the color mode toggles, creating an inconsistency.
theme.recipes (or theme.components in v2) extensions.sx, style, or component props passed at render time.At each layer, a plain value (hex, pixel number, etc.) replaces whatever came before. A token reference (e.g. {colors.brand.primary}) is preserved and resolved at runtime against the active color mode.
If theme.tokens.colors.brand.primary points to {_light: 'blue.500', _dark: 'blue.300'} but a button recipe sets background: '#3b82f6', the merge order makes the literal win. The button will stay #3b82f6 in both light and dark mode because the token is never consulted for that property.
// theme/tokens/colors.ts
export const colors = {
brand: {
primary: { _light: 'blue.500', _dark: 'blue.300' },
},
};
// theme/recipes/button.ts
import { defineRecipe } from '@chakra-ui/react';
export const buttonRecipe = defineRecipe({
base: {
// ✅ token reference — reacts to color mode
background: 'colors.brand.primary',
color: 'white',
// ✅ structural only
borderRadius: 'md',
px: 4,
py: 2,
},
variants: {
ghost: {
background: 'transparent', // structural, not color‑mode dependent
},
},
});
ColorModeScript or manual class swap).background-color (or other property) — it should change if driven by a token, stay static if a hard‑coded recipe value won.Are you extending recipes via theme.recipes (v3 Panda‑CSS style) or the legacy theme.components API? The merge mechanics differ slightly; confirming which path you use lets me confirm whether any additional precedence rules apply.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.