Introduction
thl-ui is a framework‑agnostic design system with its own CSS (no Bootstrap, no jQuery) that ships native components for React, Vue and Angular.
Architecture
┌────────────────────────── @thl-ui/core ──────────────────────────┐
│ createThl() → config store · i18n · applyToDocument() │
│ headless: tabs · table · select · toast · upload · calendar … │
│ utils: bem() · cx() · focusTrap · scrollLock · clickOutside │
└───────────────▲──────────────────▲──────────────────▲────────────┘
│ │ │
@thl-ui/tokens ──► @thl-ui/styles (CSS vars, .thl-* BEM, 12 skins, dark)
│ │ │
@thl-ui/react @thl-ui/vue @thl-ui/angular
ThlProvider + hooks plugin + composables provideThlUI + signals| Package | Purpose |
|---|---|
@thl-ui/tokens | Design tokens (palette, spacing, radius, skins) → CSS custom properties |
@thl-ui/styles | Framework‑free CSS (thl-ui.css, per‑component CSS, SCSS sources) |
@thl-ui/locales | Messages for en, ja, vi, zh + types |
@thl-ui/core | Config, i18n, headless state machines, utilities |
@thl-ui/icons | Icon registry (lucide subset, extendable with font icons) |
@thl-ui/charts | Dependency‑free SVG chart geometry |
@thl-ui/react · @thl-ui/vue · @thl-ui/angular | Native adapters |
Same API, three frameworks
Every adapter renders identical markup (built with the shared bem() helper) and exposes the same prop names, so a component looks and behaves the same everywhere:
vue
<ThlButton variant="primary" icon="download" rounded>Download</ThlButton>tsx
<Button variant="primary" icon="download" rounded>Download</Button>html
<button thl-button variant="primary" icon="download" rounded>Download</button>Differences follow each framework's idioms only:
| Concept | Vue | React | Angular |
|---|---|---|---|
| Install | app.use(ThlUI, config) | <ThlProvider config> | provideThlUI(config) |
| Two‑way binding | v-model | value + onChange | [(value)], formControlName, ngModel |
| Translate | useI18n().t / $t | useT() | ThlI18nService.t / | thlT |
| Config | useThlConfig() | useThlConfig() | ThlConfigService |
| Toast | useToast() | useToast() | ThlToastService |
| Confirm | confirm() | confirm() | ThlModalService.confirm() |
| Component names | ThlButton | Button | ThlButtonComponent / thl-* selectors |
Next steps
- Installation → Tutorial: build your first admin page
- Framework setup: React · Vue · Angular
- Global config · i18n · Theming
- FAQ & troubleshooting