Skip to content

sinanata/unity-ui-document-design-system

Repository files navigation

Unity UI Toolkit Design System

A drop-in design system for Unity 6 UI Toolkit (UIDocument + UXML + USS). Tokens, components, icons, mobile responsiveness, and a runtime helper — all themed dark, all keyboard-and-touch-ready, all editable from one stylesheet.

Leap of Legends Built for and battle-tested in Leap of Legends — a cross-platform multiplayer game in active development on Steam, Google Play (internal testing), TestFlight, and macOS. Every menu, HUD, lobby, and store screen in the game is built on this design system. Wishlist on Steam — public mobile store pages coming soon.

Live showcase

UI Toolkit Design System — interactive web showcase. Hover or tap to inspect, toggle day/night, click classes to copy.

Open the interactive web demo → (click the gif, too)

Hover (desktop) or tap (mobile) any component to surface its selector chain — every parent class on the way down to the leaf, plus the leaf's class list ready to copy. Click the classes line to copy to clipboard. Toggle day / night in the COLORS section header and the whole tree retheme over 240 ms via the var() cascade. Slim themed scrollbar throughout, mobile flip below 768 px.

Build the demo locally any time:

.\Tools\Build\Build-Showcase.ps1 -Serve

Serves at http://localhost:3000. See Tools/Build/README.md for the orchestrator — no cloud builds, no Unity license secret, entirely local.

The showcase covers 23 sections: colors, typography, buttons, icons, inputs, tabs & filters, animal card, animal detail, navigation, badges & labels, toggles & checks, sliders, progress, modals / panels, toasts, empty states, bottom sheet, confirm dialog, quantity stepper, pagination, loading states, notification badge, avatar, scrollbars.


.ds-btn ds-btn--primary       →  rounded green CTA, hover/press/disabled built in
.ds-input    .ds-search       →  text fields with leading-icon slot + placeholder
.ds-tab      .ds-tabs         →  segmented strip with .is-active state
.ds-toggle   .ds-check        →  iOS-style switch + square checkbox (auto-knob via runtime)
.ds-modal    .ds-toast        →  overlays with header / body / actions slots
.ds-icon ds-icon--paw         →  60+ SVG icons, parent-state-driven tints
.mobile .ds-…                 →  one-class layout flip for touch targets
.theme-light                  →  add to .ds-root — every var(--color-*) re-paints, animated

Why this exists

UI Toolkit ships great primitives but no design language. Every project re-invents tokens, button hierarchy, input shells, mobile breakpoints, modal scaffolding, and an icon system — usually inconsistently across screens, usually as a side-project of the actual game/app. This repo is that work, finished, kept evergreen by a real shipping product.

What you get on day one:

  • A dark-themed token palette — primary / secondary / tertiary / warning / danger / surface stack, all referenced via var(--color-...). Swap one token, the whole UI follows. The showcase ships a .theme-light override under Assets/Showcase/Resources/ShowcaseTheme.uss so you can see the cascade animate to a light palette in real time.
  • 24 ready components — buttons (5 variants × 4 states + icon + sizes), inputs (text / textarea / search / dropdown), tabs, toggles, checkboxes, radios, sliders + range, progress, modals, dialogs, drawers, toasts, badges, chips, tags, navigation (side / rail / bottom), avatars, notification dots, pagination, steppers, empty states, skeleton loaders, spinners.
  • 63 SVG icons — paw, shirt, hats, store, cart, plus arrows, chevrons, status glyphs, action icons. White-fill SVGs that tint via -unity-background-image-tint-color so the same artwork serves passive / hover / active / muted states.
  • One .mobile class — add it to your screen root to flip every spacing token, tap target, and dropdown to touch-friendly sizes. Same UXML, same USS, two layouts.
  • A runtime helperDesignSystemRuntime.cs auto-attaches to every UIDocument in a scene, injects toggle knobs (Unity's Toggle doesn't render the iOS-style sliding pill on its own), drives spinner rotation (USS transitions can't loop), and animates skeleton shimmer.
  • Slim themed scrollbars — 8 px-wide pill thumb in var(--color-border-strong) that brightens on hover, scoped to .ds-root so it doesn't leak into editor windows. Auto-themes with the rest of the system.

Requirements

Requirement Notes
Unity 6 (6000.x or newer) Uses Unity 6 USS additions (@import, background-size, -unity-background-image-tint-color, parent-state cascades). Earlier versions partially work but components like the checkbox icon shrink rule rely on Unity 6 background-size.
com.unity.ui (UI Toolkit) Built-in module — already enabled by default in Unity 6.
com.unity.modules.vectorgraphics Built-in module in Unity 6 — already enabled by default. The standalone com.unity.vectorgraphics package is not required; Unity 6's engine ships the SVG ScriptedImporter (fileID: 12408) directly. The repo ships .meta files for every icon preset to svgType: 3 (Texture) so they import correctly on first open.

No other external dependencies. No NuGet, no asmdef requirements, no editor scripts.

Installation

The design system is a single folder you drop into your project's Assets/:

your-unity-project/
└── Assets/
    └── DesignSystem/                  ← drop the whole folder
        ├── Resources/
        │   ├── UI/Styles/DesignSystem/    ← USS + UXML showcase
        │   └── Textures/Icons/            ← 63 SVG icons
        └── Runtime/
            └── DesignSystemRuntime.cs

Option A — copy files:

# From your Unity project root, on Windows or macOS:
git clone https://github.com/sinanata/unity-ui-document-design-system ../design-system-src
cp -r ../design-system-src/Assets/DesignSystem Assets/DesignSystem

Option B — git submodule:

cd your-unity-project
git submodule add https://github.com/sinanata/unity-ui-document-design-system Assets/DesignSystem-src
# Symlink or copy Assets/DesignSystem-src/Assets/DesignSystem → Assets/DesignSystem

After Unity reimports, every screen with a UIDocument can opt into the system by attaching the master stylesheet:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
  <Style src="project://database/Assets/DesignSystem/Resources/UI/Styles/DesignSystem/DesignSystem.uss" />

  <ui:VisualElement class="ds-root">
    <ui:Button text="Get started" class="ds-btn ds-btn--primary" />
  </ui:VisualElement>
</ui:UXML>

That's it. The runtime auto-attaches to every UIDocument; no per-screen wiring needed.

Quick start

<!-- A login form, fully styled, no inline CSS -->
<ui:VisualElement class="ds-root" style="padding: 24px;">

  <ui:Label text="Sign in" class="ds-h2" style="margin-bottom: 16px;" />

  <ui:VisualElement class="ds-search" style="margin-bottom: 8px;">
    <ui:VisualElement class="ds-icon ds-icon--sm ds-icon--user ds-search__icon" />
    <ui:TextField class="ds-search__field" />
  </ui:VisualElement>

  <ui:TextField class="ds-input" style="margin-bottom: 16px;" password="true" />

  <ui:VisualElement class="ds-row" style="justify-content: space-between; margin-bottom: 16px;">
    <ui:Toggle class="ds-check" />
    <ui:Label text="Remember me" class="ds-body-1" />
  </ui:VisualElement>

  <ui:Button text="Sign in" class="ds-btn ds-btn--primary ds-btn--block" />

</ui:VisualElement>

Set searchField.textEdition.placeholder = "Username" from C# and you have a complete, themed, mobile-ready form in 12 lines of UXML.

Mobile

Add the .mobile class to your screen root and the entire stylesheet flips:

if (Screen.width < 768)              // or your own platform check
    root.AddToClassList("mobile");
  • Buttons grow from 36 px to 48 px (touch target minimum).
  • Inputs grow to 48 px height with 15 px font.
  • Tabs spread to 48 px tall.
  • Sliders / range thumbs grow 18 px → 24 px with recomputed centering.
  • Modals widen, side rails compact, bottom-nav bar takes over from side-nav.

All in Mobile.uss — one file, ~350 lines, parallel-class structure to the desktop tokens. Full pattern in docs/MOBILE.md.

Icons

63 white-fill SVGs under Resources/Textures/Icons/. Each has a class in Icons.uss:

<!-- Default tint = text-secondary -->
<ui:VisualElement class="ds-icon ds-icon--paw" />

<!-- Tint variant -->
<ui:VisualElement class="ds-icon ds-icon--lg ds-icon--accent" />

<!-- Inside a button — tint follows the button's hover/active state -->
<ui:Button class="ds-btn ds-btn--icon">
  <ui:VisualElement class="ds-icon ds-icon--search" />
</ui:Button>

Adding a new icon: drop the SVG into Resources/Textures/Icons/, set svgType: 3 (Texture) in the importer, add one line to Icons.uss. SVGs ship as fill="white" so the design system's tint cascade can multiply onto any colour. Black-fill SVGs render black regardless of tint — see docs/ICONS.md for why and how.

Architecture

Assets/
├── DesignSystem/                       ← the drop-in design system
│   ├── Resources/UI/Styles/DesignSystem/
│   │   ├── DesignSystem.uss            ← master, @imports the rest in order
│   │   ├── DesignTokens.uss            ← :root variables (colors, radii, spacing, motion)
│   │   ├── Typography.uss              ← .ds-h1 / .ds-h2 / .ds-h3 / .ds-body-1 / .ds-caption
│   │   ├── Icons.uss                   ← .ds-icon + 63 .ds-icon--<name> + state cascade
│   │   ├── Buttons.uss                 ← .ds-btn + variants + sizes + icon button
│   │   ├── Inputs.uss                  ← .ds-input / .ds-search / .ds-dropdown / .ds-textarea
│   │   ├── TabsAndFilters.uss          ← .ds-tabs / .ds-tab / .ds-view-toggle
│   │   ├── Cards.uss                   ← animal card, info row
│   │   ├── Navigation.uss              ← .ds-side-nav / .ds-side-rail / .ds-bottom-nav / profile
│   │   ├── Badges.uss                  ← .ds-badge / .ds-tag / .ds-chip / .ds-avatar / notif dot
│   │   ├── Controls.uss                ← .ds-toggle / .ds-check / .ds-radio / .ds-slider / .ds-range / scrollbars
│   │   ├── Overlays.uss                ← .ds-modal / .ds-dialog / .ds-toast / .ds-sheet / empty
│   │   ├── Feedback.uss                ← .ds-progress / .ds-spinner / .ds-skeleton / .ds-pagination
│   │   ├── Mobile.uss                  ← every .mobile-prefixed responsive override (loaded LAST)
│   │   └── DesignSystemShowcase.uxml   ← living style guide
│   └── Runtime/DesignSystemRuntime.cs  ← auto-attaches to every UIDocument
│
├── Showcase/                           ← showcase host project (only if cloning the repo)
│   ├── Showcase.unity                  ← minimal scene; bootstrap creates UIDocuments at runtime
│   ├── Resources/
│   │   ├── ShowcaseTheme.uss           ← .theme-light override + universal opacity transition
│   │   ├── UnityDefaultRuntimeTheme.tss
│   │   └── sinanata.jpg                ← avatar texture (Showcase only)
│   └── Runtime/
│       ├── ShowcaseBootstrap.cs        ← spawns docs, wires toggle, promo links
│       └── ShowcaseDocOverlay.cs       ← selector-chain hover overlay
│
├── Editor/BuildCli.cs                  ← Unity batchmode entry for WebGL builds
└── WebGLTemplates/ShowcaseTemplate/    ← custom WebGL template (mobile-friendly)

Tools/Build/
├── Build-Showcase.ps1                  ← Windows orchestrator (-Serve / -Deploy)
├── Deploy-GhPages.ps1                  ← single-commit force-push via git worktree
├── config.example.json                 ← copy to config.local.json (gitignored)
└── README.md                           ← orchestrator docs

Import order is load-bearing — Inputs.uss specialises selectors that Icons.uss generalises; Mobile.uss intentionally loads last so its specificity always wins. Don't reorder unless you read the comments first.

The Assets/Showcase/, Assets/Editor/, Assets/WebGLTemplates/, and Tools/Build/ folders are the host project that runs the live demo. They're not part of the drop-in design system — if you copy Assets/DesignSystem/ into your own project, leave them behind. Use them when you clone this repo to iterate on the design system itself.

Full architectural reasoning in docs/ARCHITECTURE.md. Build pipeline docs in Tools/Build/README.md.

Components reference

One-line summary per component lives in docs/COMPONENTS.md. The showcase UXML is the second source of truth — every class appears there with its expected DOM structure.

What makes this robust

  • Tokens, not hex. Every colour, radius, spacing, motion timing references a var(--…) variable. Theme by editing one file (DesignTokens.uss).
  • Parent-state cascades for icons. A .ds-icon inside .ds-btn:hover retints automatically — you don't write per-component :hover .icon rules.
  • Per-axis radius tokens. Unity 6 USS clamps border-radius per axis to half the element's side. We ship --radius-pill-9 / -16 / -20 / -28 / -36 so a circle stays a circle and a pill stays a pill regardless of element height.
  • Auto-knob injection. Unity's Toggle doesn't render the sliding pill on its own. DesignSystemRuntime injects a .ds-toggle__knob child every 250 ms — covers UXML-authored screens AND C#-cloned templates.
  • No Resources.Load<Texture2D> in C#. Icons resolve via USS resource(...) so they survive Sprite-vs-Texture import differences. The runtime never touches a backgroundImage.
  • MinMaxSlider thumbs cross-centred via top: 50% + margin-top: -<half>px — Unity's stock slider positions thumbs at top: 0 which floats them above the track. Same trick for the single slider.
  • Checkbox tick shrunk via background-size: 12px 12px — the check.svg viewBox runs path-edge to viewBox-edge; default stretch-to-fill made the tick overflow the box's 2 px border. Constraining the rendered size leaves a clean inner margin.
  • Day / night theme via single class. Adding .theme-light to .ds-root redefines every colour token under that scope; the var() cascade re-paints the whole tree. A universal transition-property in ShowcaseTheme.uss animates the swap over 240 ms. Same pattern works for any custom theme — just author the token block.
  • Progress-bar min-height: 0 overrides. Unity's stock .unity-progress-bar ships with min-height: 21px. .ds-progress resets it to 0 across container, background, and progress layers so an 8 px bar reserves exactly 8 px of vertical space (not the 21 px Unity defaults to).
  • Spinner rotation is C#-driven, no USS transition. DesignSystemRuntime.StartSpinners writes style.rotate every 16 ms. We deliberately omit transition-property: rotate from .ds-spinner — a transition would try to ease between consecutive per-frame writes and the spinner visibly jiggles instead of spinning.

Every "why is this ugly?" complaint we hit while shipping the game lives as a comment on the rule that fixed it. Read the USS files — half of them are documentation.

Contributing

Issues and PRs welcome. The whole system is ~1700 lines of USS + 180 lines of C# — readable in an afternoon, hackable in a weekend.

Areas where help is especially useful:

  • Light theme — the token structure supports it (just override :root); a polished LightTokens.uss is on the roadmap.
  • Localisation — RTL flips for nav-item icons / chevrons / arrow buttons, and a doc note on which classes need a mirror modifier.
  • Additional icons — particularly platform glyphs (Steam / Apple / Google), gameplay glyphs (D-pad, button prompts), and currency icons.
  • Editor scripts — a Unity menu item that toggles .mobile on the active UIDocument's root for live preview, like the showcase but for any screen.

See CONTRIBUTING.md for the naming convention, file-load order, and PR checklist.

Credits & support

Made for Leap of Legends — a cross-platform physics-heavy multiplayer game in active development, targeting Steam, iOS, Android, and Mac. If this design system saved you time:

Licence

MIT — see LICENSE. Free for commercial use. No warranty.

The 63 SVG icons under Resources/Textures/Icons/ are released under the same MIT licence — use them in your own projects, ship them in commercial products, modify them freely.


Leap of Legends · physics · multiplayer · cross-platform · in development · the UI you see in every screenshot was built with this system.

About

A drop-in design system for Unity 6 UI Toolkit (UIDocument + UXML + USS). Tokens, components, icons, mobile responsiveness, and a runtime helper — all themed dark, all keyboard-and-touch-ready, all editable from one stylesheet.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors