@gamut-all/react
v0.1.1
Published
React bindings for `@gamut-all/core`. Provides a context provider, components, and hooks that read `data-theme` / `data-stack` / font-size from the DOM and resolve tokens automatically.
Readme
@gamut-all/react
React bindings for @gamut-all/core. Provides a context provider, components, and hooks that read data-theme / data-stack / font-size from the DOM and resolve tokens automatically.
Installation
npm install @gamut-all/react @gamut-all/coreRequires React 18+.
Quick start
import { TokenProvider } from '@gamut-all/react';
import { registry } from './tokens'; // generated by Vite plugin or built manually
export default function App() {
return (
<TokenProvider registry={registry}>
<html data-theme="light">
{/* CSS vars are live: --fg-primary, --bg-surface, etc. */}
<MyApp />
</html>
</TokenProvider>
);
}Set data-theme on the root element to activate a theme. Change it at runtime to switch themes — CSS vars update immediately.
Components
<TokenProvider>
Provides the registry and vision mode to all descendant hooks and components.
<TokenProvider
registry={registry}
defaultVisionMode="default" // optional, defaults to 'default'
>
{children}
</TokenProvider>Renders a <div data-vision={visionMode} style={{ display: 'contents' }}> wrapper. The data-vision attribute activates CVD-corrected CSS vars for the selected vision mode.
<StackLayer>
Marks an element as belonging to an elevation stack. Emits data-stack and optionally data-theme.
<StackLayer stack="modal" as="section" className="...">
{/* tokens inside resolve at modal elevation */}
</StackLayer>Props: stack (StackClass), bg? (sets data-theme), as? (defaults to div), any HTML attributes.
<TokenizedContainer>
Shorthand for <StackLayer> with data-theme and data-stack.
<TokenizedContainer bg="dark" stack="root" as="main">
{children}
</TokenizedContainer><TokenizedText>
Renders an element with its color style set to the resolved token hex.
<TokenizedText token="fgDanger" as="span">
Error: something went wrong
</TokenizedText>Props: token (token name), as? (defaults to span), style?, any HTML attributes.
<TokenResolver>
Render-prop component that exposes all resolved tokens and the current DesignContext.
<TokenResolver>
{(tokens, context) => (
<div style={{ color: tokens.fgPrimary }}>
Theme: {context.bgClass} / Stack: {context.stackDepth}
</div>
)}
</TokenResolver><TokenInspector>
Development overlay (fixed, bottom-right) showing the current design context and all resolved token hex values. Renders nothing outside development builds.
{import.meta.env.DEV && <TokenInspector />}withAutoContrast(Component, options)
HOC that injects resolved token values as props and CSS variables.
const StyledButton = withAutoContrast(Button, {
tokens: ['fgPrimary', 'borderMain'],
});Hooks
useTokenContext()
Access the registry, current vision mode, and the setter for vision mode.
const { registry, visionMode, setVisionMode } = useTokenContext();Throws if called outside <TokenProvider>.
useDesignContext(ref)
Detects the design context (theme, stack, font size, vision mode) from a DOM element. Updates on mutations and resize.
const ref = useRef<HTMLDivElement>(null);
const context = useDesignContext(ref); // DesignContext | nulluseToken(tokenName, ref)
Resolves a single token to its hex string in the element's detected context.
const ref = useRef<HTMLSpanElement>(null);
const hex = useToken('fgDanger', ref); // '#ef4444'useResolvedTokens(ref)
Resolves all tokens in the element's detected context.
const ref = useRef<HTMLDivElement>(null);
const tokens = useResolvedTokens(ref);
// { fgPrimary: '#0f172a', fgDanger: '#ef4444', ... }useTokenVars(ref)
Returns a CSSProperties object of all tokens as CSS custom properties, ready for use in a style prop.
const ref = useRef<HTMLDivElement>(null);
const vars = useTokenVars(ref);
// { '--fg-primary': '#0f172a', '--fg-danger': '#ef4444', ... }
return <div ref={ref} style={vars}>{children}</div>;useTokenColor(tokenName, opts?)
Direct resolution without DOM detection. Useful for canvas rendering, SVG, or situations where no element ref is available.
const color = useTokenColor('fgDanger', {
bg: 'dark',
stack: 'modal',
fontSize: '16px',
});DOM attributes
| Attribute | Where | Purpose |
|-----------|-------|---------|
| data-theme | <html> or any ancestor | Activates a theme (light, dark, etc.) |
| data-stack | Any element | Marks elevation context (root, nav, modal, etc.) |
| data-vision | Set by <TokenProvider> | Activates CVD-corrected token values |
Nesting data-theme inside another data-theme is not supported via CSS variable cascade. For nested theme demos, resolve tokens with registry.themes.get(bg)?.surfaces.get(stack)?.hex and use inline styles.
Vision mode
Change vision mode at runtime to preview accessibility for different users:
const { setVisionMode } = useTokenContext();
<select onChange={e => setVisionMode(e.target.value as VisionMode)}>
<option value="default">Normal vision</option>
<option value="deuteranopia">Green-blind</option>
<option value="protanopia">Red-blind</option>
<option value="tritanopia">Blue-blind</option>
{/* + anomaly variants and achromatopsia */}
</select>Audit helpers
import { warnMissingDataTheme, checkDataThemeCoverage } from '@gamut-all/react';
// Log a console warning for any element missing a data-theme ancestor
warnMissingDataTheme(document.body);
// Get a coverage percentage
const { coverage, totalElements } = checkDataThemeCoverage(document.body);