Active Foundation · Example
A theme derived from a brand colour
A theme derived from a brand colourClient
Enough contrast: 6.09:1 on light, 3.03:1 on dark.
Light
backgroundforegroundprimaryprimary-foregroundmutedborder
Dark
backgroundforegroundprimaryprimary-foregroundmutedborder
Full source examples/ui/theme-derivation.tsx
// apps/docs/examples/ui/theme-derivation.tsx'use client';
import {useMemo, useState} from 'react';
import { Field, FieldDescription, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Input} from '@workspace/active-ui/components/primitives/input';import { deriveThemeTokens, hasInsufficientBrandContrast,} from '@workspace/active-ui/lib/theme-derivation';
const SWATCHES = [ 'background', 'foreground', 'primary', 'primary-foreground', 'muted', 'border',];
function Scheme({ name, tokens,}: { name: string; tokens: Readonly<Record<string, string>>;}) { return ( <div className="grid gap-2"> <p className="text-sm font-medium">{name}</p> <ul className="grid grid-cols-3 gap-2 text-xs"> {SWATCHES.map((token) => ( <li key={token} className="grid gap-1"> <span className="h-8 rounded-sm border" style={{background: tokens[token]}} aria-hidden /> <code className="truncate">{token}</code> </li> ))} </ul> </div> );}
/** * A theme derived from five seeds: change the brand colour to see both * schemes and the contrast check. The derivation is a pure function; nothing * on this page changes theme. */export default function ThemeDerivationExample() { const [brandColor, setBrandColor] = useState('#1d4ed8'); const valid = /^#[0-9a-f]{6}$/.test(brandColor); const theme = useMemo( () => valid ? deriveThemeTokens({ brandColor, neutral: {hue: 257, chromaScale: 1.8}, radius: '0.65rem', bodyFontFamily: 'Geist, sans-serif', headingFontFamily: null, }) : null, [brandColor, valid], ); return ( <div className="grid w-full max-w-lg gap-6"> <Field data-invalid={!valid || undefined}> <FieldLabel htmlFor="brand-color">Brand colour</FieldLabel> <Input id="brand-color" value={brandColor} onChange={(event) => setBrandColor(event.target.value.toLowerCase())} aria-describedby="brand-color-check" aria-invalid={!valid || undefined} /> <FieldDescription id="brand-color-check"> {!theme ? 'Write a colour as #rrggbb.' : hasInsufficientBrandContrast(theme) ? `Below the contrast threshold: ${theme.contrast.light.primaryOnBackground.toFixed(2)}:1 on light, ${theme.contrast.dark.primaryOnBackground.toFixed(2)}:1 on dark.` : `Enough contrast: ${theme.contrast.light.primaryOnBackground.toFixed(2)}:1 on light, ${theme.contrast.dark.primaryOnBackground.toFixed(2)}:1 on dark.`} </FieldDescription> </Field> {theme ? ( <div className="grid gap-6 sm:grid-cols-2"> <Scheme name="Light" tokens={theme.light.tokens} /> <Scheme name="Dark" tokens={theme.dark.tokens} /> </div> ) : null} </div> );}