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:

  1. Primitives — raw values such as colours, sizes, and font weights
  2. Brand — brand-specific aliases (brand-a, brand-b, brand-c)
  3. Semantic — role-based mappings (color-text-default, color-fill-brand)
  4. 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.