Getting Started
How to install and use UI Foundations in your project.
UI Foundations is a token-first design system that provides CSS custom properties, HTML component patterns, Nunjucks macros, and optional React wrappers. Tokens are authored in Figma and generated into CSS, JSON, and TypeScript.
Install
npm install ui-foundations
Resources
CSS Setup
Import the full bundle for all tokens and components:
@import "ui-foundations/core.css";
@import "ui-foundations/ui.css";
Or import individual token layers for more control:
@import "ui-foundations/tokens/primitives.css";
@import "ui-foundations/tokens/brand-a.css";
@import "ui-foundations/tokens/color-light.css";
@import "ui-foundations/tokens/semantic.css";
@import "ui-foundations/tokens/components.css";
Brand and Mode Switching
Set data-brand and data-mode on the root element to control theming at
runtime:
<html data-brand="a" data-mode="light">
const root = document.documentElement;
root.dataset.brand = "a"; // "a" | "b" | "c"
root.dataset.mode = "light"; // "light" | "dark"
Using Components
Components are available as plain HTML classes, Nunjucks macros for static site generation, and optional React wrappers.
HTML
<button class="button" type="button">Label</button>
<input class="input" type="text" placeholder="Email" />
<a href="/page" class="link">Go to page</a>
Nunjucks Macros
{% import "macros/ui.njk" as ui %}
{{ ui.button("Label") }}
{{ ui.input(type="text", placeholder="Email") }}
{{ ui.link("Go to page", href="/page") }}
{{ ui.icon("search") }}
{{ ui.checkbox("Accept terms") }}
{{ ui.switch("Notifications") }}
React
import { Button } from "ui-foundations/react/button";
import { Input } from "ui-foundations/react/input";
import { Icon } from "ui-foundations/react/icon";
<Button>Label</Button>
<Input placeholder="Email" />
<Icon name="search" />
Macro Reference
| Macro | Description |
|---|---|
ui.button(label, variant, disabled) |
Button — solid, outline, or ghost variant |
ui.buttonGroup(attached, orientation, justify, ariaLabel) |
Groups related buttons |
ui.input(type, placeholder, value, state, disabled) |
Text input field |
ui.checkbox(label, checked, disabled) |
Checkbox with visible label |
ui.radio(label, name, value, checked, disabled) |
Radio button with visible label |
ui.switch(label, checked, disabled) |
Toggle switch with visible label |
ui.icon(name, label) |
Icon rendered via CSS mask |
ui.labelContent(text, startIcon, endIcon, iconOnly) |
Label primitive with optional icons |
ui.fieldLabel(text, htmlFor, required, startIcon) |
Form field label with required indicator |
ui.link(text, href, startIcon, endIcon, state, disabled) |
Link with optional start and end icons |
ui.badge(text, variant, size, startIcon) |
Status badge with optional icon |
Token Architecture
Tokens are layered in four levels:
- Primitives — raw values such as colours, sizes, and font weights
- Brand — brand-specific aliases (
brand-a,brand-b,brand-c) - Semantic — role-based mappings (
color-text-default,color-fill-brand) - Component — component-specific tokens (
button-border-radius,input-height)
See Token Overview for the full token reference.
Validation
npm run lint # JS syntax check
npm run test:unit # Unit tests
npm run ci:check # Full validation pipeline
Figma Integration
Design tokens are synced from Figma using the MCP integration. Token exports
live in figma/exports/ and are processed by npm run tokens:generate.