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 light-DOM Web Components. 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 framework-agnostic Custom Elements.
HTML
<button class="uif-button solid" type="button">Label</button>
<input class="uif-input" type="text" placeholder="Email" />
<a href="/page" class="uif-link">Go to page</a>
Nunjucks Macros
{% import "macros/ui.njk" as uif %}
{{ uif.button("Label") }}
{{ uif.input(type="text", placeholder="Email") }}
{{ uif.link("Go to page", href="/page") }}
{{ uif.icon("search") }}
{{ uif.checkbox("Accept terms") }}
{{ uif.switch("Notifications") }}
Web Components
import "ui-foundations/elements/ui-button";
import "ui-foundations/elements/ui-input";
import "ui-foundations/elements/ui-icon";
<uif-button>Label</uif-button>
<uif-input aria-label="Email" placeholder="Email"></uif-input>
<uif-icon name="search" decorative></uif-icon>
Custom Elements render into light DOM, so the package CSS, tokens, native events, and form controls remain visible to consuming frameworks.
Macro Reference
| Macro | Description |
|---|---|
uif.button(label, variant, disabled) |
Button — solid, outline, or ghost variant |
uif.buttonGroup(attached, orientation, justify, ariaLabel) |
Groups related buttons |
uif.input(type, placeholder, value, state, disabled) |
Text input field |
uif.checkbox(label, checked, disabled) |
Checkbox with visible label |
uif.radio(label, name, value, checked, disabled) |
Radio button with visible label |
uif.switch(label, checked, disabled) |
Toggle switch with visible label |
uif.icon(name, label) |
Icon rendered via CSS mask |
uif.labelContent(text, startIcon, endIcon, iconOnly) |
Label primitive with optional icons |
uif.fieldLabel(text, htmlFor, required, startIcon) |
Form field label with required indicator |
uif.link(text, href, startIcon, endIcon, state, disabled) |
Link with optional start and end icons |
uif.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.