@tollerud/ui 1.1.5 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +34 -11
- package/CHANGELOG.md +376 -0
- package/COMPONENTS.md +951 -0
- package/GETTING_STARTED.md +159 -0
- package/README.md +51 -43
- package/SKILL.md +55 -21
- package/components.json +18 -0
- package/dist/accordion.d.ts +20 -0
- package/dist/accordion.js +5 -0
- package/dist/accordion.js.map +1 -0
- package/dist/action-diff.d.ts +26 -0
- package/dist/action-diff.js +5 -0
- package/dist/action-diff.js.map +1 -0
- package/dist/action-row.d.ts +36 -0
- package/dist/action-row.js +6 -0
- package/dist/action-row.js.map +1 -0
- package/dist/alert-inbox.d.ts +23 -0
- package/dist/alert-inbox.js +6 -0
- package/dist/alert-inbox.js.map +1 -0
- package/dist/alert.d.ts +33 -0
- package/dist/alert.js +5 -0
- package/dist/alert.js.map +1 -0
- package/dist/approval-card.d.ts +27 -0
- package/dist/approval-card.js +5 -0
- package/dist/approval-card.js.map +1 -0
- package/dist/area-chart.d.ts +10 -0
- package/dist/area-chart.js +5 -0
- package/dist/area-chart.js.map +1 -0
- package/dist/avatar.d.ts +27 -0
- package/dist/avatar.js +5 -0
- package/dist/avatar.js.map +1 -0
- package/dist/backup-status-panel.d.ts +25 -0
- package/dist/backup-status-panel.js +6 -0
- package/dist/backup-status-panel.js.map +1 -0
- package/dist/badge.d.ts +17 -0
- package/dist/badge.js +5 -0
- package/dist/badge.js.map +1 -0
- package/dist/bar-chart.d.ts +15 -0
- package/dist/bar-chart.js +5 -0
- package/dist/bar-chart.js.map +1 -0
- package/dist/bento-dashboard.d.ts +30 -0
- package/dist/bento-dashboard.js +5 -0
- package/dist/bento-dashboard.js.map +1 -0
- package/dist/breadcrumb.d.ts +16 -0
- package/dist/breadcrumb.js +5 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/button.d.ts +29 -0
- package/dist/button.js +5 -0
- package/dist/button.js.map +1 -0
- package/dist/card.d.ts +10 -0
- package/dist/card.js +5 -0
- package/dist/card.js.map +1 -0
- package/dist/checkbox.d.ts +9 -0
- package/dist/checkbox.js +5 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/chunk-2QWKOCWF.js +79 -0
- package/dist/chunk-2QWKOCWF.js.map +1 -0
- package/dist/chunk-3TGMGBKM.js +393 -0
- package/dist/chunk-3TGMGBKM.js.map +1 -0
- package/dist/chunk-3XTZPDNV.js +94 -0
- package/dist/chunk-3XTZPDNV.js.map +1 -0
- package/dist/chunk-435JHF7G.js +65 -0
- package/dist/chunk-435JHF7G.js.map +1 -0
- package/dist/chunk-4PA2ACNF.js +52 -0
- package/dist/chunk-4PA2ACNF.js.map +1 -0
- package/dist/chunk-5GWHUJ5D.js +29 -0
- package/dist/chunk-5GWHUJ5D.js.map +1 -0
- package/dist/chunk-6FUKJD3W.js +123 -0
- package/dist/chunk-6FUKJD3W.js.map +1 -0
- package/dist/chunk-6IS2AYYG.js +106 -0
- package/dist/chunk-6IS2AYYG.js.map +1 -0
- package/dist/chunk-6PZKU6ZL.js +78 -0
- package/dist/chunk-6PZKU6ZL.js.map +1 -0
- package/dist/chunk-6SKTH45H.js +75 -0
- package/dist/chunk-6SKTH45H.js.map +1 -0
- package/dist/chunk-6UXW5YUC.js +77 -0
- package/dist/chunk-6UXW5YUC.js.map +1 -0
- package/dist/chunk-7EP2T3OW.js +52 -0
- package/dist/chunk-7EP2T3OW.js.map +1 -0
- package/dist/chunk-7J5QXUQN.js +38 -0
- package/dist/chunk-7J5QXUQN.js.map +1 -0
- package/dist/chunk-7TOT5ME3.js +53 -0
- package/dist/chunk-7TOT5ME3.js.map +1 -0
- package/dist/chunk-A6L5C3IJ.js +47 -0
- package/dist/chunk-A6L5C3IJ.js.map +1 -0
- package/dist/chunk-ANW6J6PV.js +42 -0
- package/dist/chunk-ANW6J6PV.js.map +1 -0
- package/dist/chunk-APFFKNPS.js +80 -0
- package/dist/chunk-APFFKNPS.js.map +1 -0
- package/dist/chunk-AZADSX4Z.js +85 -0
- package/dist/chunk-AZADSX4Z.js.map +1 -0
- package/dist/chunk-BPCH5LJ3.js +36 -0
- package/dist/chunk-BPCH5LJ3.js.map +1 -0
- package/dist/chunk-CBQ63EBL.js +85 -0
- package/dist/chunk-CBQ63EBL.js.map +1 -0
- package/dist/chunk-CDI7353B.js +40 -0
- package/dist/chunk-CDI7353B.js.map +1 -0
- package/dist/chunk-CKNWXYMA.js +53 -0
- package/dist/chunk-CKNWXYMA.js.map +1 -0
- package/dist/chunk-DFM7UUKB.js +79 -0
- package/dist/chunk-DFM7UUKB.js.map +1 -0
- package/dist/chunk-DGCRHVWW.js +84 -0
- package/dist/chunk-DGCRHVWW.js.map +1 -0
- package/dist/chunk-DNJI65VQ.js +22 -0
- package/dist/chunk-DNJI65VQ.js.map +1 -0
- package/dist/chunk-DOUDJU4P.js +63 -0
- package/dist/chunk-DOUDJU4P.js.map +1 -0
- package/dist/chunk-DRCMGIQ6.js +64 -0
- package/dist/chunk-DRCMGIQ6.js.map +1 -0
- package/dist/chunk-DZOBXK2S.js +28 -0
- package/dist/chunk-DZOBXK2S.js.map +1 -0
- package/dist/chunk-EN4OJCEF.js +54 -0
- package/dist/chunk-EN4OJCEF.js.map +1 -0
- package/dist/chunk-EVHZFYWX.js +33 -0
- package/dist/chunk-EVHZFYWX.js.map +1 -0
- package/dist/chunk-FGXOV2QH.js +23 -0
- package/dist/chunk-FGXOV2QH.js.map +1 -0
- package/dist/chunk-G2VKWNZA.js +53 -0
- package/dist/chunk-G2VKWNZA.js.map +1 -0
- package/dist/chunk-GTM2DE4C.js +156 -0
- package/dist/chunk-GTM2DE4C.js.map +1 -0
- package/dist/chunk-H3ZVGTJM.js +165 -0
- package/dist/chunk-H3ZVGTJM.js.map +1 -0
- package/dist/chunk-HWAWUEHC.js +28 -0
- package/dist/chunk-HWAWUEHC.js.map +1 -0
- package/dist/chunk-HWJVRTWO.js +36 -0
- package/dist/chunk-HWJVRTWO.js.map +1 -0
- package/dist/chunk-HYQGOC2E.js +79 -0
- package/dist/chunk-HYQGOC2E.js.map +1 -0
- package/dist/chunk-ILADNTUB.js +77 -0
- package/dist/chunk-ILADNTUB.js.map +1 -0
- package/dist/chunk-ISHZ6ZPJ.js +31 -0
- package/dist/chunk-ISHZ6ZPJ.js.map +1 -0
- package/dist/chunk-JRFSUVSO.js +66 -0
- package/dist/chunk-JRFSUVSO.js.map +1 -0
- package/dist/chunk-KI6OTVID.js +91 -0
- package/dist/chunk-KI6OTVID.js.map +1 -0
- package/dist/chunk-LUM2YJBH.js +73 -0
- package/dist/chunk-LUM2YJBH.js.map +1 -0
- package/dist/chunk-NHPISZWS.js +71 -0
- package/dist/chunk-NHPISZWS.js.map +1 -0
- package/dist/chunk-NOLWJJHT.js +52 -0
- package/dist/chunk-NOLWJJHT.js.map +1 -0
- package/dist/chunk-NPVINX3Q.js +20 -0
- package/dist/chunk-NPVINX3Q.js.map +1 -0
- package/dist/chunk-NSMU66ZX.js +47 -0
- package/dist/chunk-NSMU66ZX.js.map +1 -0
- package/dist/chunk-O57QMLNI.js +68 -0
- package/dist/chunk-O57QMLNI.js.map +1 -0
- package/dist/chunk-O5SWPHUQ.js +79 -0
- package/dist/chunk-O5SWPHUQ.js.map +1 -0
- package/dist/chunk-OGVSZ7NV.js +53 -0
- package/dist/chunk-OGVSZ7NV.js.map +1 -0
- package/dist/chunk-OONIUDST.js +48 -0
- package/dist/chunk-OONIUDST.js.map +1 -0
- package/dist/chunk-PLF3BBQI.js +139 -0
- package/dist/chunk-PLF3BBQI.js.map +1 -0
- package/dist/chunk-Q74VRQEX.js +26 -0
- package/dist/chunk-Q74VRQEX.js.map +1 -0
- package/dist/chunk-QEHTPQHL.js +35 -0
- package/dist/chunk-QEHTPQHL.js.map +1 -0
- package/dist/chunk-RJTDQOT2.js +73 -0
- package/dist/chunk-RJTDQOT2.js.map +1 -0
- package/dist/chunk-RQ3RXKAZ.js +203 -0
- package/dist/chunk-RQ3RXKAZ.js.map +1 -0
- package/dist/chunk-RWJELAS6.js +46 -0
- package/dist/chunk-RWJELAS6.js.map +1 -0
- package/dist/chunk-RZK2S2OO.js +126 -0
- package/dist/chunk-RZK2S2OO.js.map +1 -0
- package/dist/chunk-SAP7JSSO.js +106 -0
- package/dist/chunk-SAP7JSSO.js.map +1 -0
- package/dist/chunk-T3TQPOVM.js +79 -0
- package/dist/chunk-T3TQPOVM.js.map +1 -0
- package/dist/chunk-T56TTOI6.js +53 -0
- package/dist/chunk-T56TTOI6.js.map +1 -0
- package/dist/chunk-T7EFDE2L.js +36 -0
- package/dist/chunk-T7EFDE2L.js.map +1 -0
- package/dist/chunk-V3P5QLLX.js +154 -0
- package/dist/chunk-V3P5QLLX.js.map +1 -0
- package/dist/chunk-VTRUUT5K.js +31 -0
- package/dist/chunk-VTRUUT5K.js.map +1 -0
- package/dist/chunk-WDANALHD.js +95 -0
- package/dist/chunk-WDANALHD.js.map +1 -0
- package/dist/chunk-WSQNPRGN.js +12 -0
- package/dist/chunk-WSQNPRGN.js.map +1 -0
- package/dist/chunk-XR5QBVEV.js +56 -0
- package/dist/chunk-XR5QBVEV.js.map +1 -0
- package/dist/chunk-YYWODLER.js +111 -0
- package/dist/chunk-YYWODLER.js.map +1 -0
- package/dist/chunk-ZOXO3G3I.js +50 -0
- package/dist/chunk-ZOXO3G3I.js.map +1 -0
- package/dist/code-block.d.ts +14 -0
- package/dist/code-block.js +5 -0
- package/dist/code-block.js.map +1 -0
- package/dist/combobox.d.ts +26 -0
- package/dist/combobox.js +5 -0
- package/dist/combobox.js.map +1 -0
- package/dist/command-menu.d.ts +52 -0
- package/dist/command-menu.js +7 -0
- package/dist/command-menu.js.map +1 -0
- package/dist/container.d.ts +9 -0
- package/dist/container.js +5 -0
- package/dist/container.js.map +1 -0
- package/dist/cta-band.d.ts +12 -0
- package/dist/cta-band.js +5 -0
- package/dist/cta-band.js.map +1 -0
- package/dist/data-table.d.ts +58 -0
- package/dist/data-table.js +12 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +20 -0
- package/dist/date-picker.js +5 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/dialog.d.ts +21 -0
- package/dist/dialog.js +5 -0
- package/dist/dialog.js.map +1 -0
- package/dist/divider.d.ts +12 -0
- package/dist/divider.js +5 -0
- package/dist/divider.js.map +1 -0
- package/dist/docker-stack-card.d.ts +21 -0
- package/dist/docker-stack-card.js +6 -0
- package/dist/docker-stack-card.js.map +1 -0
- package/dist/donut.d.ts +15 -0
- package/dist/donut.js +5 -0
- package/dist/donut.js.map +1 -0
- package/dist/dropdown-menu.d.ts +15 -0
- package/dist/dropdown-menu.js +5 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/empty.d.ts +12 -0
- package/dist/empty.js +5 -0
- package/dist/empty.js.map +1 -0
- package/dist/feature-card.d.ts +11 -0
- package/dist/feature-card.js +6 -0
- package/dist/feature-card.js.map +1 -0
- package/dist/file-upload.d.ts +20 -0
- package/dist/file-upload.js +5 -0
- package/dist/file-upload.js.map +1 -0
- package/dist/footer.d.ts +35 -0
- package/dist/footer.js +5 -0
- package/dist/footer.js.map +1 -0
- package/dist/form-row.d.ts +15 -0
- package/dist/form-row.js +5 -0
- package/dist/form-row.js.map +1 -0
- package/dist/glow-card.d.ts +14 -0
- package/dist/glow-card.js +5 -0
- package/dist/glow-card.js.map +1 -0
- package/dist/hero-block.d.ts +16 -0
- package/dist/hero-block.js +7 -0
- package/dist/hero-block.js.map +1 -0
- package/dist/host-card.d.ts +27 -0
- package/dist/host-card.js +6 -0
- package/dist/host-card.js.map +1 -0
- package/dist/incident-card.d.ts +23 -0
- package/dist/incident-card.js +5 -0
- package/dist/incident-card.js.map +1 -0
- package/dist/index.d.ts +76 -960
- package/dist/index.js +68 -3812
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +10 -0
- package/dist/input.js +5 -0
- package/dist/input.js.map +1 -0
- package/dist/kbd.d.ts +24 -0
- package/dist/kbd.js +5 -0
- package/dist/kbd.js.map +1 -0
- package/dist/log-viewer.d.ts +35 -0
- package/dist/log-viewer.js +5 -0
- package/dist/log-viewer.js.map +1 -0
- package/dist/meter.d.ts +23 -0
- package/dist/meter.js +5 -0
- package/dist/meter.js.map +1 -0
- package/dist/noir-glow-background.d.ts +50 -0
- package/dist/noir-glow-background.js +4 -0
- package/dist/noir-glow-background.js.map +1 -0
- package/dist/pagination.d.ts +16 -0
- package/dist/pagination.js +5 -0
- package/dist/pagination.js.map +1 -0
- package/dist/panel.d.ts +12 -0
- package/dist/panel.js +5 -0
- package/dist/panel.js.map +1 -0
- package/dist/password-input.d.ts +10 -0
- package/dist/password-input.js +5 -0
- package/dist/password-input.js.map +1 -0
- package/dist/pill.d.ts +14 -0
- package/dist/pill.js +5 -0
- package/dist/pill.js.map +1 -0
- package/dist/pricing-card.d.ts +20 -0
- package/dist/pricing-card.js +6 -0
- package/dist/pricing-card.js.map +1 -0
- package/dist/progress.d.ts +6 -0
- package/dist/progress.js +5 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio-group.d.ts +18 -0
- package/dist/radio-group.js +5 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/rollback-plan.d.ts +23 -0
- package/dist/rollback-plan.js +5 -0
- package/dist/rollback-plan.js.map +1 -0
- package/dist/segmented.d.ts +17 -0
- package/dist/segmented.js +5 -0
- package/dist/segmented.js.map +1 -0
- package/dist/select.d.ts +18 -0
- package/dist/select.js +5 -0
- package/dist/select.js.map +1 -0
- package/dist/service-health-card.d.ts +21 -0
- package/dist/service-health-card.js +6 -0
- package/dist/service-health-card.js.map +1 -0
- package/dist/sheet.d.ts +25 -0
- package/dist/sheet.js +5 -0
- package/dist/sheet.js.map +1 -0
- package/dist/skeleton.d.ts +5 -0
- package/dist/skeleton.js +5 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/slider.d.ts +12 -0
- package/dist/slider.js +5 -0
- package/dist/slider.js.map +1 -0
- package/dist/sparkline.d.ts +16 -0
- package/dist/sparkline.js +5 -0
- package/dist/sparkline.js.map +1 -0
- package/dist/stat-card.d.ts +15 -0
- package/dist/stat-card.js +5 -0
- package/dist/stat-card.js.map +1 -0
- package/dist/status-dot.d.ts +13 -0
- package/dist/status-dot.js +5 -0
- package/dist/status-dot.js.map +1 -0
- package/dist/stepper.d.ts +16 -0
- package/dist/stepper.js +5 -0
- package/dist/stepper.js.map +1 -0
- package/dist/switch.d.ts +9 -0
- package/dist/switch.js +5 -0
- package/dist/switch.js.map +1 -0
- package/dist/tabs.d.ts +9 -0
- package/dist/tabs.js +5 -0
- package/dist/tabs.js.map +1 -0
- package/dist/tag-input.d.ts +20 -0
- package/dist/tag-input.js +5 -0
- package/dist/tag-input.js.map +1 -0
- package/dist/textarea.d.ts +10 -0
- package/dist/textarea.js +5 -0
- package/dist/textarea.js.map +1 -0
- package/dist/timeline.d.ts +30 -0
- package/dist/timeline.js +5 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toaster.d.ts +10 -0
- package/dist/toaster.js +4 -0
- package/dist/toaster.js.map +1 -0
- package/dist/tooltip.d.ts +12 -0
- package/dist/tooltip.js +5 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +4 -0
- package/dist/utils.js.map +1 -0
- package/globals-layers.css +935 -0
- package/globals-v3.css +17 -0
- package/globals-v4.css +2 -0
- package/globals.css +12 -939
- package/package.json +82 -16
- package/registry.json +920 -0
- package/tailwind.css +9 -0
- package/dist/index.cjs +0 -3938
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -960
package/COMPONENTS.md
ADDED
|
@@ -0,0 +1,951 @@
|
|
|
1
|
+
# Tollerud Design System — Component Library
|
|
2
|
+
|
|
3
|
+
All components come as CSS classes (in `globals.css` / `tokens.css`) with React `.tsx` examples in `components/`.
|
|
4
|
+
|
|
5
|
+
> **Note:** As of **v1.0.9** the vast majority of components documented here ship in `@tollerud/ui`. Sections for components that are still docs-site-only or roadmap-only are marked with a ⚠️ warning; sections already in the package are marked ✅. **For the authoritative, props-complete reference use [SKILL.md](SKILL.md)** (verified against `components/index.ts`) or [COMPLETENESS_ROADMAP.md](COMPLETENESS_ROADMAP.md).
|
|
6
|
+
|
|
7
|
+
## NoirGlowBackground
|
|
8
|
+
|
|
9
|
+
Tollerud.no-inspired animated WebGL background using `@paper-design/shaders-react`, with CSS fallback classes.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
<section className="relative overflow-hidden bg-black">
|
|
13
|
+
<NoirGlowBackground
|
|
14
|
+
intensity="medium"
|
|
15
|
+
speed="slow"
|
|
16
|
+
grain="soft"
|
|
17
|
+
shape="corners"
|
|
18
|
+
preserveCenter
|
|
19
|
+
/>
|
|
20
|
+
<div className="relative z-10">Content</div>
|
|
21
|
+
</section>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
See `BACKGROUNDS.md` for install, props, usage rules, and fallback HTML.
|
|
25
|
+
|
|
26
|
+
## Button
|
|
27
|
+
|
|
28
|
+
| Variant | Class | React Component | Usage |
|
|
29
|
+
|---------|-------|----------------|-------|
|
|
30
|
+
| Primary | `.tollerud-btn--primary` | `<Button variant="primary">` | Main CTA |
|
|
31
|
+
| Secondary | `.tollerud-btn--secondary` | `<Button variant="secondary">` | Secondary action |
|
|
32
|
+
| Ghost | `.tollerud-btn--ghost` | `<Button variant="ghost">` | Low emphasis |
|
|
33
|
+
| Destructive | `.tollerud-btn--destructive` | `<Button variant="destructive">` | Delete/remove |
|
|
34
|
+
| Terminal | `.tollerud-btn--terminal` | `<Button variant="terminal">` | Dev tools, CLIs |
|
|
35
|
+
|
|
36
|
+
Sizes: `--sm`, `--md`, `--lg`
|
|
37
|
+
|
|
38
|
+
```jsx
|
|
39
|
+
<Button variant="primary" size="md" onClick={handleClick}>
|
|
40
|
+
Deploy
|
|
41
|
+
</Button>
|
|
42
|
+
<Button variant="terminal" size="sm">
|
|
43
|
+
start_building
|
|
44
|
+
</Button>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Card
|
|
48
|
+
|
|
49
|
+
| Class | React | Props |
|
|
50
|
+
|-------|-------|-------|
|
|
51
|
+
| `.tollerud-card` | `<Card>` | — |
|
|
52
|
+
| `.tollerud-card border-tollerud-yellow/25` | `<Card accent>` | accent: boolean |
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
<Card>
|
|
56
|
+
<h3 className="font-semibold mb-1">Title</h3>
|
|
57
|
+
<p className="text-tollerud-text-secondary text-sm">Content</p>
|
|
58
|
+
</Card>
|
|
59
|
+
<Card accent>
|
|
60
|
+
<p>Highlighted card with yellow border</p>
|
|
61
|
+
</Card>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Badge
|
|
65
|
+
|
|
66
|
+
| Variant | Class | React |
|
|
67
|
+
|---------|-------|-------|
|
|
68
|
+
| Default | `.tollerud-badge--default` | `<Badge>` |
|
|
69
|
+
| Accent | `.tollerud-badge--accent` | `<Badge variant="accent">` |
|
|
70
|
+
| Success | `.tollerud-badge--success` | `<Badge variant="success">` |
|
|
71
|
+
| Error | `.tollerud-badge--error` | `<Badge variant="error">` |
|
|
72
|
+
| Info | `.tollerud-badge--info` | `<Badge variant="info">` |
|
|
73
|
+
| Warning | `.tollerud-badge--warning` | `<Badge variant="warning">` |
|
|
74
|
+
|
|
75
|
+
```jsx
|
|
76
|
+
<Badge variant="success">Online</Badge>
|
|
77
|
+
<Badge variant="accent">New</Badge>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## StatusDot
|
|
81
|
+
|
|
82
|
+
| Status | Color | Glow |
|
|
83
|
+
|--------|-------|------|
|
|
84
|
+
| online | `#22C55E` | 6px green glow |
|
|
85
|
+
| offline | `#EF4444` | — |
|
|
86
|
+
| warning | `#E8D500` | 6px yellow glow |
|
|
87
|
+
| idle | `#666666` | — |
|
|
88
|
+
|
|
89
|
+
```jsx
|
|
90
|
+
<StatusDot status="online" label="SSH Connected" />
|
|
91
|
+
<StatusDot status="warning" label="CPU 87%" />
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Input
|
|
95
|
+
|
|
96
|
+
```jsx
|
|
97
|
+
<Input
|
|
98
|
+
label="Server Name"
|
|
99
|
+
placeholder="e.g. emma.tollerud.no"
|
|
100
|
+
error={errors.name}
|
|
101
|
+
/>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Pill Tag
|
|
105
|
+
|
|
106
|
+
> ✅ `Pill` ships in `@tollerud/ui >= 1.0.9`. Import: `import { Pill } from '@tollerud/ui'`
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<span class="tollerud-pill tollerud-pill--outline">new</span>
|
|
111
|
+
<span class="tollerud-pill tollerud-pill--muted">deprecated</span>
|
|
112
|
+
<span class="tollerud-pill tollerud-pill--success">stable</span>
|
|
113
|
+
<span class="tollerud-pill tollerud-pill--error">critical</span>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## StatCard
|
|
117
|
+
|
|
118
|
+
```jsx
|
|
119
|
+
<StatCard
|
|
120
|
+
label="Active Sessions"
|
|
121
|
+
value={42}
|
|
122
|
+
change={{ value: "+12%", direction: "up" }}
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## CodeBlock
|
|
127
|
+
|
|
128
|
+
```jsx
|
|
129
|
+
<CodeBlock>
|
|
130
|
+
{`$ systemctl status tollerud-agent
|
|
131
|
+
● active (running)`}
|
|
132
|
+
</CodeBlock>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Divider
|
|
136
|
+
|
|
137
|
+
> ✅ `Divider` ships in `@tollerud/ui >= 1.0.9`. Import: `import { Divider } from '@tollerud/ui'`
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<hr class="tollerud-divider" />
|
|
142
|
+
<hr class="tollerud-divider--accent" />
|
|
143
|
+
<hr class="tollerud-accent-bar" /> <!-- gradient -->
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Kbd — Keyboard Shortcut Chip
|
|
147
|
+
|
|
148
|
+
Raycast-inspired shortcut badge for displaying key combinations.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<Kbd keys="⌘K" />
|
|
152
|
+
<Kbd keys={["⌘", "⇧", "S"]} size="sm" />
|
|
153
|
+
<Kbd keys="Esc" />
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Props:
|
|
157
|
+
- `keys: string | string[]` — The keys to display. Separate with `+` for chords.
|
|
158
|
+
- `size?: "sm" | "md"` — Small variant for inline use.
|
|
159
|
+
|
|
160
|
+
CSS class: `.tollerud-kbd`, children `.tollerud-kbd__key`.
|
|
161
|
+
|
|
162
|
+
## ActionRow — Command / Action Item
|
|
163
|
+
|
|
164
|
+
A single command/action row used by `CommandMenu` and standalone.
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
<ActionRow
|
|
168
|
+
action={{
|
|
169
|
+
id: 'deploy',
|
|
170
|
+
label: 'Deploy Stack',
|
|
171
|
+
description: 'emma: docker-compose up -d',
|
|
172
|
+
icon: <Rocket />,
|
|
173
|
+
shortcut: '↵',
|
|
174
|
+
onSelect: () => deploy()
|
|
175
|
+
}}
|
|
176
|
+
highlighted={index === 0}
|
|
177
|
+
/>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Used as a controlled row with keyboard navigation via the `highlighted` prop.
|
|
181
|
+
|
|
182
|
+
## CommandMenu — Raycast-style Command Palette
|
|
183
|
+
|
|
184
|
+
The signature keyboard-first component. Full command palette with search, groups, keyboard navigation, and overlay.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
const [open, setOpen] = useState(false)
|
|
188
|
+
const servers = ['Emma', 'Miriam', 'Pia', 'Iris', 'Victoria', 'Embla']
|
|
189
|
+
|
|
190
|
+
<Button onClick={() => setOpen(true)}>Open Menu</Button>
|
|
191
|
+
|
|
192
|
+
<CommandMenu
|
|
193
|
+
open={open}
|
|
194
|
+
onOpenChange={setOpen}
|
|
195
|
+
groups={[
|
|
196
|
+
{
|
|
197
|
+
label: 'Servers',
|
|
198
|
+
items: servers.map((name) => ({
|
|
199
|
+
id: name.toLowerCase(),
|
|
200
|
+
label: `${name}.tollerud.no`,
|
|
201
|
+
description: 'SSH · 4 containers · uptime 14d',
|
|
202
|
+
onSelect: () => ssh(name),
|
|
203
|
+
})),
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
label: 'Actions',
|
|
207
|
+
items: [
|
|
208
|
+
{ id: 'backup', label: 'Run Backup', description: 'rclone to JottaCloud', onSelect: () => runBackup() },
|
|
209
|
+
{ id: 'update', label: 'System Update', description: 'apt update && upgrade', onSelect: () => update() },
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
]}
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Features:
|
|
217
|
+
- Built-in `⌘K` / `Ctrl+K` global listener
|
|
218
|
+
- Arrow key navigation, `Enter` selects, `Esc` closes
|
|
219
|
+
- Search filters across groups, labels, and descriptions
|
|
220
|
+
- Auto-focus on open, body scroll lock
|
|
221
|
+
- Footer keyboard hints
|
|
222
|
+
- Optional `filter` prop for custom search logic
|
|
223
|
+
- `onAction` callback for analytics/tracking
|
|
224
|
+
|
|
225
|
+
Usage: Import as a client component in your page/layout.
|
|
226
|
+
|
|
227
|
+
See `KEYBOARD.md` for full keyboard contract.
|
|
228
|
+
|
|
229
|
+
## Homelab / Infrastructure Components
|
|
230
|
+
|
|
231
|
+
The Tier 2 component set — these make Tia a real infrastructure assistant. All ship from `components/*.tsx` (`@tollerud/ui`) and are showcased on the **Infrastructure** page; `HostCard`, `AlertInbox` and `ApprovalCard` also power the Mission Control dashboard. They share a five-level `SEVERITY` scale (`critical · high · medium · low · info`).
|
|
232
|
+
|
|
233
|
+
### ServiceHealthCard
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
<ServiceHealthCard
|
|
237
|
+
service="emma.tollerud.no"
|
|
238
|
+
status="online"
|
|
239
|
+
uptime="14d 3h"
|
|
240
|
+
responseTime="23ms"
|
|
241
|
+
version="22.04 LTS"
|
|
242
|
+
/>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Props: `service`, `status`, `uptime`, `responseTime`, `version`, `loading`.
|
|
246
|
+
|
|
247
|
+
### HostCard
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
<HostCard
|
|
251
|
+
hostname="emma"
|
|
252
|
+
ip="10.0.10.10"
|
|
253
|
+
status="online"
|
|
254
|
+
cpu="23%"
|
|
255
|
+
memory="6.2/16 GB"
|
|
256
|
+
disk="45%"
|
|
257
|
+
uptime="14d"
|
|
258
|
+
containers={4}
|
|
259
|
+
/>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Props: `hostname`, `ip`, `status`, `cpu`, `memory`, `disk`, `uptime`, `containers`, `loading`.
|
|
263
|
+
|
|
264
|
+
### DockerStackCard
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
<DockerStackCard
|
|
268
|
+
name="monitoring"
|
|
269
|
+
composePath="/hdd/config/prometheus-stack/compose.yml"
|
|
270
|
+
services={[
|
|
271
|
+
{ name: 'prometheus', status: 'online' },
|
|
272
|
+
{ name: 'grafana', status: 'online' },
|
|
273
|
+
{ name: 'alertmanager', status: 'online' },
|
|
274
|
+
]}
|
|
275
|
+
/>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Props: `name`, `services: StackService[]`, `composePath`, `loading`.
|
|
279
|
+
|
|
280
|
+
### IncidentCard
|
|
281
|
+
|
|
282
|
+
```tsx
|
|
283
|
+
<IncidentCard
|
|
284
|
+
title="High CPU on emma"
|
|
285
|
+
severity="high"
|
|
286
|
+
timestamp="2026-05-26 14:32"
|
|
287
|
+
description="CPU sustained at 92% for 5 minutes"
|
|
288
|
+
service="emma"
|
|
289
|
+
acknowledged={false}
|
|
290
|
+
/>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Prop `severity`: `'critical' | 'high' | 'medium' | 'low' | 'info'`. Dot color and border match severity.
|
|
294
|
+
|
|
295
|
+
### ApprovalCard
|
|
296
|
+
|
|
297
|
+
```tsx
|
|
298
|
+
<ApprovalCard
|
|
299
|
+
action="restart_container"
|
|
300
|
+
description="Restart emma:tollerud-hermes container"
|
|
301
|
+
source="emma → /hdd/config/tia/compose.yml"
|
|
302
|
+
state="pending"
|
|
303
|
+
timestamp="2026-05-26 14:35"
|
|
304
|
+
onApprove={() => {}}
|
|
305
|
+
onReject={() => {}}
|
|
306
|
+
/>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
States: `pending` (shows Approve/Reject buttons), `approved`, `rejected`.
|
|
310
|
+
|
|
311
|
+
### ActionDiff
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
<ActionDiff
|
|
315
|
+
label="docker-compose.yml"
|
|
316
|
+
lines={[
|
|
317
|
+
{ text: ' image: hermes:latest', type: 'remove', oldLine: 5 },
|
|
318
|
+
{ text: ' image: hermes:v2.0', type: 'add', newLine: 5 },
|
|
319
|
+
{ text: ' restart: unless-stopped', type: 'context', oldLine: 6, newLine: 6 },
|
|
320
|
+
]}
|
|
321
|
+
/>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Renders a unified diff. `showContext` (default true) toggles context lines off to focus on edits. Line shape: `{ type: 'add' | 'remove' | 'context', text, oldLine?, newLine? }`.
|
|
325
|
+
|
|
326
|
+
### LogViewer
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
<LogViewer
|
|
330
|
+
lines={[
|
|
331
|
+
{ text: 'Starting deployment...', level: 'info', timestamp: '14:32:01', source: 'deploy' },
|
|
332
|
+
{ text: 'Connection refused on port 443', level: 'error', timestamp: '14:32:05', source: 'nginx' },
|
|
333
|
+
{ text: 'Health check passed', level: 'info', timestamp: '14:32:10', source: 'hermes' },
|
|
334
|
+
]}
|
|
335
|
+
follow
|
|
336
|
+
searchable
|
|
337
|
+
showLineNumbers
|
|
338
|
+
height={300}
|
|
339
|
+
/>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
| Prop | Type | Default | Description |
|
|
343
|
+
|------|------|---------|-------------|
|
|
344
|
+
| `lines` | `{ text, level, timestamp?, source? }[]` | `[]` | Log entries. `level` is one of `trace` `debug` `info` `warn` `error`. |
|
|
345
|
+
| `follow` | `boolean` | `false` | Auto-scroll to the newest line whenever `lines` changes. |
|
|
346
|
+
| `searchable` | `boolean` | `false` | Show a filter input (matches `text` + `source`) with a live match count. |
|
|
347
|
+
| `showLineNumbers` | `boolean` | `false` | Prefix each row with a zero-padded line number. |
|
|
348
|
+
| `height` | `number` | `300` | Scroll-area height in px. |
|
|
349
|
+
|
|
350
|
+
Level color coding: `trace` (muted) → `debug` (info blue) → `info` (secondary) → `warn` (yellow) → `error` (red, brightened message). Errors carry a colored left border. For a streaming/level-filter/export toolbar on top of it, see the **Logs & Console** build page.
|
|
351
|
+
|
|
352
|
+
### AlertInbox
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
<AlertInbox
|
|
356
|
+
alerts={[
|
|
357
|
+
{ id: '1', title: 'emma high CPU', severity: 'high', timestamp: '14:32', acknowledged: false },
|
|
358
|
+
{ id: '2', title: 'pia disk 91%', severity: 'critical', timestamp: '13:15', acknowledged: true },
|
|
359
|
+
]}
|
|
360
|
+
onAcknowledge={(id) => {}}
|
|
361
|
+
/>
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Features: severity count badges, hover-to-acknowledge, severity filter, scrollable list. Pass `loading` for a skeleton state; shows “No alerts — everything looks good” when empty.
|
|
365
|
+
|
|
366
|
+
### Timeline
|
|
367
|
+
|
|
368
|
+
```tsx
|
|
369
|
+
<Timeline
|
|
370
|
+
active={true}
|
|
371
|
+
items={[
|
|
372
|
+
{ id: '1', time: '14:32', title: 'Deployed hermes v2.0', description: 'Rolled out to emma', status: 'online',
|
|
373
|
+
meta: ['success', '3s'] },
|
|
374
|
+
{ id: '2', time: '14:31', title: 'Restarted nginx', description: 'Config reloaded', status: 'warning',
|
|
375
|
+
meta: ['warning'] },
|
|
376
|
+
{ id: '3', time: '14:30', title: 'SSH connection failed', description: 'emma refused connection', status: 'offline' },
|
|
377
|
+
]}
|
|
378
|
+
/>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Features: status-colored dots, connecting vertical lines, animated pulse for active items, metadata badges, icon support.
|
|
382
|
+
|
|
383
|
+
### RollbackPlan
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
<RollbackPlan
|
|
387
|
+
name="Rollback hermes v2.0"
|
|
388
|
+
executing={true}
|
|
389
|
+
steps={[
|
|
390
|
+
{ id: '1', label: 'Stop hermes container', status: 'success' },
|
|
391
|
+
{ id: '2', label: 'Restore previous image tag', status: 'running' },
|
|
392
|
+
{ id: '3', label: 'Start container', status: 'pending' },
|
|
393
|
+
{ id: '4', label: 'Run health check', status: 'pending' },
|
|
394
|
+
]}
|
|
395
|
+
/>
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Step statuses: `pending` `running` `success` `failed` `skipped` — each with distinct icon and color.
|
|
399
|
+
|
|
400
|
+
### BackupStatusPanel
|
|
401
|
+
|
|
402
|
+
```tsx
|
|
403
|
+
<BackupStatusPanel
|
|
404
|
+
jobs={[
|
|
405
|
+
{ name: 'emma-config', status: 'online', lastRun: '03:00', size: '4.2 GB', target: 'JottaCloud' },
|
|
406
|
+
{ name: 'iris-config', status: 'online', lastRun: '03:05', size: '1.8 GB', target: 'JottaCloud' },
|
|
407
|
+
{ name: 'miriam-media', status: 'offline', lastRun: '02:45' },
|
|
408
|
+
]}
|
|
409
|
+
totalSize="6.0 GB"
|
|
410
|
+
lastFullBackup="2026-05-25"
|
|
411
|
+
/>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Features: per-job status dots, size/target display, failed job warning footer. Pass `loading` for a skeleton state and `emptyState` (or rely on the default) when no jobs are configured.
|
|
415
|
+
|
|
416
|
+
## Layout & form components
|
|
417
|
+
|
|
418
|
+
### Panel
|
|
419
|
+
|
|
420
|
+
> ✅ `Panel` ships in `@tollerud/ui >= 1.0.9`. Import: `import { Panel } from '@tollerud/ui'`
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
A card with a header bar (title + optional actions) and optional footer — the structural workhorse behind the log viewer, data table, alert inbox and most dashboard surfaces.
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
<Panel title="Compose stack" icon="grid"
|
|
427
|
+
actions={<Button variant="ghost" size="sm">Edit</Button>}
|
|
428
|
+
footer={<span className="ds-mono">compose.yml · 4 services</span>}>
|
|
429
|
+
…content…
|
|
430
|
+
</Panel>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Props: `title`, `icon` (icon-set name), `actions`, `footer`, `noPadding`, `className`, `style`. CSS: `.ds-panel__head` / `.ds-panel__title` / `.ds-panel__foot`.
|
|
434
|
+
|
|
435
|
+
### Meter
|
|
436
|
+
|
|
437
|
+
> ✅ `Meter` ships in `@tollerud/ui >= 1.0.9`. Import: `import { Meter } from '@tollerud/ui'`
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
A labeled progress row that turns red past a hot threshold.
|
|
441
|
+
|
|
442
|
+
```tsx
|
|
443
|
+
<Meter label="CPU" value={23} valueLabel="23%" />
|
|
444
|
+
<Meter label="Containers" value={28} unlimited valueLabel="28 running" />
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
| Prop | Type | Default | Description |
|
|
448
|
+
|------|------|---------|-------------|
|
|
449
|
+
| `label` | `string` | — | Left-hand label. |
|
|
450
|
+
| `value` | `number` | — | Current value. |
|
|
451
|
+
| `max` | `number` | `100` | Denominator for the percentage. |
|
|
452
|
+
| `valueLabel` | `string` | — | Overrides the right-hand readout (else `value / max`). |
|
|
453
|
+
| `hot` | `number` | `85` | Percentage past which the bar turns red. |
|
|
454
|
+
| `unlimited` | `boolean` | `false` | Full dimmed bar; shows `value` alone. |
|
|
455
|
+
|
|
456
|
+
### Stepper
|
|
457
|
+
|
|
458
|
+
> ✅ `Stepper` ships in `@tollerud/ui >= 1.0.9`. Import: `import { Stepper } from '@tollerud/ui'`
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
Horizontal step indicator for wizards. Completed steps fill yellow; the current one carries a ring.
|
|
462
|
+
|
|
463
|
+
```tsx
|
|
464
|
+
<Stepper steps={['Connect host', 'Choose stacks', 'Invite team', 'Finish']} current={1} />
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Props: `steps: string[]`, `current` (0-indexed). CSS: `.ds-wizard__*`.
|
|
468
|
+
|
|
469
|
+
### PasswordInput
|
|
470
|
+
|
|
471
|
+
> ✅ `PasswordInput` ships in `@tollerud/ui >= 1.0.9`. Import: `import { PasswordInput } from '@tollerud/ui'`
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
A password field with a show/hide toggle and an optional label action (e.g. a "Forgot?" link).
|
|
475
|
+
|
|
476
|
+
```tsx
|
|
477
|
+
<PasswordInput label="Password" placeholder="••••••••"
|
|
478
|
+
error={pwError}
|
|
479
|
+
labelAction={<a href="#">Forgot?</a>} />
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Props: `label`, `labelAction`, `error`, `id`, plus all native `<input>` props.
|
|
483
|
+
|
|
484
|
+
### Spinner
|
|
485
|
+
|
|
486
|
+
> ⚠️ **Not yet in the `@tollerud/ui` npm package** — this is a docs-site / roadmap component (see [COMPLETENESS_ROADMAP.md](COMPLETENESS_ROADMAP.md)). Do not import `Spinner` from `@tollerud/ui` — it will not resolve. Check [SKILL.md](SKILL.md) for what's actually shipped.
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
Inline loading spinner; respects reduced-motion.
|
|
490
|
+
|
|
491
|
+
```tsx
|
|
492
|
+
<Button variant="primary"><Spinner size={14} /> Signing in…</Button>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Props: `size` (px, default 16), `style`. CSS: `.ds-spin`.
|
|
496
|
+
|
|
497
|
+
### FormRow
|
|
498
|
+
|
|
499
|
+
> ✅ `FormRow` ships in `@tollerud/ui >= 1.0.9`. Import: `import { FormRow } from '@tollerud/ui'`
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
Label + hint on the left, control on the right. The canonical settings-form layout; stacks vertically under 560px.
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
<FormRow label="Two-factor auth" hint="Require a TOTP code at sign-in.">
|
|
506
|
+
<Switch defaultChecked />
|
|
507
|
+
</FormRow>
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
Props: `label`, `hint`, `children`. CSS: `.ds-formrow`.
|
|
511
|
+
|
|
512
|
+
### PricingCard
|
|
513
|
+
|
|
514
|
+
> ✅ `PricingCard` ships in `@tollerud/ui >= 1.0.9`. Import: `import { PricingCard } from '@tollerud/ui'`
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
A single plan tier with optional ribbon, feature list and CTA. Powers the Billing page and the marketing pricing block.
|
|
518
|
+
|
|
519
|
+
```tsx
|
|
520
|
+
<PricingCard name="Pro" tagline="For a growing fleet"
|
|
521
|
+
price={12} priceNote="billed monthly" recommended
|
|
522
|
+
features={['10 hosts', 'Approvals & rollback', 'Priority support']}
|
|
523
|
+
cta="Upgrade to Pro" />
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
| Prop | Type | Description |
|
|
527
|
+
|------|------|-------------|
|
|
528
|
+
| `name` / `tagline` | `string` | Title + sub-line. |
|
|
529
|
+
| `price` | `number \| string` | `0`, `'Free'`, `'$12'` render as "Free"; numbers get a `$` prefix. |
|
|
530
|
+
| `period` | `string` | Suffix after the price (default `/mo`). |
|
|
531
|
+
| `priceNote` | `string` | Small line under the amount. |
|
|
532
|
+
| `features` | `string[]` | Checklist. |
|
|
533
|
+
| `recommended` | `boolean` | Accent border + ribbon. |
|
|
534
|
+
| `ribbon` | `string` | Ribbon label (default `Recommended`). |
|
|
535
|
+
| `cta` | `string` | Button label. |
|
|
536
|
+
| `ctaVariant` | `string` | Button variant (defaults by recommended/state). |
|
|
537
|
+
| `ctaDisabled` | `boolean` | Disable the CTA (e.g. current plan). |
|
|
538
|
+
| `onCta` | `fn` | CTA click handler. |
|
|
539
|
+
|
|
540
|
+
CSS: `.ds-price` and `.ds-price__*`; grid wrapper `.ds-price-grid`.
|
|
541
|
+
|
|
542
|
+
## Charts
|
|
543
|
+
|
|
544
|
+
Palette-aware SVG charts. Yellow is the highlight series; everything else stays monochrome. Grid/axis use the `--chart-grid` token, so all four are theme-aware.
|
|
545
|
+
|
|
546
|
+
```tsx
|
|
547
|
+
import { BarChart, AreaChart, Donut, Sparkline } from '@tollerud/ui'
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
```tsx
|
|
551
|
+
<BarChart data={[{ label: 'Mon', value: 12 }, { label: 'Tue', value: 18, accent: true }]} height={180} />
|
|
552
|
+
<AreaChart data={[28, 35, 30, 44, 52]} height={150} />
|
|
553
|
+
<Donut segments={[{ label: 'CPU', value: 40, color: '#E8D500' }, { label: 'Idle', value: 60, color: '#444' }]} size={160} />
|
|
554
|
+
<Sparkline data={[12, 18, 14, 22, 19]} w={84} h={26} color="#E8D500" />
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
- **BarChart** — `data: { label, value, accent? }[]`, `height`. `accent: true` paints a bar yellow.
|
|
558
|
+
- **AreaChart** — `data: number[]`, `height`. Gradient fill + point markers.
|
|
559
|
+
- **Donut** — `segments: { label, value, color }[]`, `size`. Renders a legend with percentages.
|
|
560
|
+
- **Sparkline** — `data: number[]`, `w`, `h`, `color`. Inline trend line (used in DataTable cells).
|
|
561
|
+
|
|
562
|
+
## Marketing blocks
|
|
563
|
+
|
|
564
|
+
Full-width page sections used on the Blocks page.
|
|
565
|
+
|
|
566
|
+
```tsx
|
|
567
|
+
import { HeroBlock, FeatureCard, CTABand } from '@tollerud/ui'
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### HeroBlock
|
|
571
|
+
|
|
572
|
+
A landing hero on the noir glow background. Single-column by default; pass `media` for a two-column layout with a right-hand visual.
|
|
573
|
+
|
|
574
|
+
```tsx
|
|
575
|
+
<HeroBlock eyebrow="homelab control plane" title="Run your stack like production."
|
|
576
|
+
description="Deploy, monitor and roll back from one keyboard-first console."
|
|
577
|
+
actions={<><button className="tollerud-btn tollerud-btn--terminal tollerud-btn--md">deploy --free</button></>}
|
|
578
|
+
media={<img src="tia.png" alt="" />} />
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Props: `eyebrow` (pill text), `title`, `description`, `actions`, `media` (optional right column), `minHeight`, `intense`. Pass `intense` to render `NoirGlowBackground` with loud intensity (requires `@paper-design/shaders-react` in the host app).
|
|
582
|
+
|
|
583
|
+
### FeatureCard
|
|
584
|
+
|
|
585
|
+
Icon chip + title + copy. Drop several into a `.ds-grid-3`.
|
|
586
|
+
|
|
587
|
+
```tsx
|
|
588
|
+
<FeatureCard icon="zap" title="Instant deploys"
|
|
589
|
+
description="Push a compose file and watch it roll out with health checks." />
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Props: `icon` (`ReactNode` — pass a Lucide icon or custom element), `title`, `description`.
|
|
593
|
+
|
|
594
|
+
### CTABand
|
|
595
|
+
|
|
596
|
+
A centered closing call-to-action with an optional accent bar.
|
|
597
|
+
|
|
598
|
+
```tsx
|
|
599
|
+
<CTABand title="Ship your homelab like it matters."
|
|
600
|
+
description="Free for one host. No card, no telemetry, no nonsense."
|
|
601
|
+
actions={<><Button variant="primary" size="lg">Get started</Button></>} />
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
Props: `title`, `description`, `actions`, `accentBar` (default true).
|
|
605
|
+
|
|
606
|
+
## Overlays & data
|
|
607
|
+
|
|
608
|
+
### Toast
|
|
609
|
+
|
|
610
|
+
> ⚠️ **Not yet in the `@tollerud/ui` npm package** — this is a docs-site / roadmap component (see [COMPLETENESS_ROADMAP.md](COMPLETENESS_ROADMAP.md)). Do not import `Toast / useToast / ToastProvider` from `@tollerud/ui` — it will not resolve. Check [SKILL.md](SKILL.md) for what's actually shipped.
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
Transient feedback via the `useToast()` hook (provided by `ToastProvider` at the app root). Toasts auto-dismiss and stack bottom-right.
|
|
614
|
+
|
|
615
|
+
```tsx
|
|
616
|
+
const toast = useToast();
|
|
617
|
+
toast({ tone: 'success', title: 'Deployed', message: 'hermes v2.0 is live' });
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
Tones: `success` · `error` · `info` · `accent`. `title` required; `message` optional.
|
|
621
|
+
|
|
622
|
+
### Drawer / Sheet
|
|
623
|
+
|
|
624
|
+
> ⚠️ **`Drawer` is not yet in the npm package** (roadmap only — see [COMPLETENESS_ROADMAP.md](COMPLETENESS_ROADMAP.md)). `Sheet` (with `SheetTrigger`/`SheetContent`/etc.) **is** shipped and is the closest available primitive — see [SKILL.md](SKILL.md) for its API.
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
A side panel for detail views and slide-over forms. Closes on Esc or overlay click.
|
|
628
|
+
|
|
629
|
+
```tsx
|
|
630
|
+
<Drawer open={open} onClose={() => setOpen(false)} side="right" title="Host details"
|
|
631
|
+
description="emma.tollerud.no"
|
|
632
|
+
footer={<Button variant="primary" size="sm">Connect</Button>}>
|
|
633
|
+
…content…
|
|
634
|
+
</Drawer>
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
Props: `open`, `onClose`, `side` (`right` | `left`, default right), `title`, `description`, `children`, `footer`, `width` (default 380).
|
|
638
|
+
|
|
639
|
+
### Combobox
|
|
640
|
+
|
|
641
|
+
> ✅ `Combobox` ships in `@tollerud/ui >= 1.0.9`. Import: `import { Combobox } from '@tollerud/ui'`
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
Searchable single-select with keyboard navigation (↑/↓/Enter/Esc), controlled or uncontrolled.
|
|
645
|
+
|
|
646
|
+
```tsx
|
|
647
|
+
<Combobox label="Host" value={value} onChange={setValue}
|
|
648
|
+
options={[{ value: 'emma', label: 'emma.tollerud.no' }, …]}
|
|
649
|
+
placeholder="Search…" emptyText="No matches" />
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Props: `options: { value, label }[]`, `value`, `onChange`, `label`, `placeholder`, `emptyText`.
|
|
653
|
+
|
|
654
|
+
### AvatarGroup
|
|
655
|
+
|
|
656
|
+
> ✅ `Avatar` and `AvatarGroup` ship in `@tollerud/ui >= 1.0.9`. Import: `import { Avatar, AvatarGroup } from '@tollerud/ui'`
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
Stacked avatars with an overflow count and optional presence dots.
|
|
660
|
+
|
|
661
|
+
```tsx
|
|
662
|
+
<AvatarGroup max={4} size={32} users={[
|
|
663
|
+
{ name: 'Tia', status: 'online' },
|
|
664
|
+
{ name: 'Emma Pung', src: '/emma.jpg', status: 'warning' },
|
|
665
|
+
]} />
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
Props: `users: { name, src?, status? }[]` (`status`: `online` | `offline` | `warning`), `max` (default 4), `size` (default 32).
|
|
669
|
+
|
|
670
|
+
## Elevation & density
|
|
671
|
+
|
|
672
|
+
**Shadow scale** — four theme-aware tiers (deep + low-spread in dark, soft in light): `--shadow-sm` `--shadow-md` `--shadow-lg` `--shadow-xl`, plus `--shadow-glow` for the yellow interaction glow. Drawers use `--shadow-xl`, popovers `--shadow-lg`. Lean on borders first; reach for a shadow only to lift overlays off the page.
|
|
673
|
+
|
|
674
|
+
**Density** — set `data-density="compact"` on any container to tighten cards, table rows, form rows, panel headers and buttons inside it, without changing the components. Default is comfortable.
|
|
675
|
+
|
|
676
|
+
```html
|
|
677
|
+
<div data-density="compact"> … dense tables / forms … </div>
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
## EmptyState
|
|
681
|
+
|
|
682
|
+
> ⚠️ **Not yet in the `@tollerud/ui` npm package** — this is a docs-site / roadmap component (see [COMPLETENESS_ROADMAP.md](COMPLETENESS_ROADMAP.md)). Do not import `EmptyState` from `@tollerud/ui` — it will not resolve. Check [SKILL.md](SKILL.md) for what's actually shipped.
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
For any surface with no data yet, no search results, or an error. Pairs an icon, a one-line headline, a calm explanation and up to two actions. A `compact` variant fits inside cards, tables and panels.
|
|
686
|
+
|
|
687
|
+
```tsx
|
|
688
|
+
<EmptyState
|
|
689
|
+
icon="server"
|
|
690
|
+
title="No hosts connected"
|
|
691
|
+
description="Connect your first machine and Tia will start watching it."
|
|
692
|
+
action={<Button variant="primary" size="sm">Connect a host</Button>}
|
|
693
|
+
/>
|
|
694
|
+
<EmptyState compact accent icon="checkCircle" title="All clear" description="No open alerts." />
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
| Prop | Type | Default | Description |
|
|
698
|
+
|------|------|---------|-------------|
|
|
699
|
+
| `icon` | `string` | `'folder'` | Icon name from the icon set. |
|
|
700
|
+
| `title` | `string` | — | Headline. |
|
|
701
|
+
| `description` | `string` | — | Supporting copy (max ~340px wide). |
|
|
702
|
+
| `action` | `ReactNode` | — | Primary action, usually a `<Button>`. |
|
|
703
|
+
| `secondaryAction` | `ReactNode` | — | Optional second action. |
|
|
704
|
+
| `compact` | `boolean` | `false` | Tighter padding for inline use. |
|
|
705
|
+
| `accent` | `boolean` | `false` | Yellow-tinted surface + border. |
|
|
706
|
+
|
|
707
|
+
CSS class: `.ds-empty` (with `.ds-empty__icon`, `.ds-empty__title`, `.ds-empty__desc`).
|
|
708
|
+
|
|
709
|
+
## DataTable
|
|
710
|
+
|
|
711
|
+
The config-driven table. Pass `rows` + a `columns` spec and opt into search, a filter, selection with bulk actions, per-row menus, pagination and an empty state. It owns all sort / filter / selection / pagination state internally. Powers the **Data Table** build page and the invoice history on **Billing**.
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
<DataTable
|
|
715
|
+
rows={hosts}
|
|
716
|
+
rowKey="id"
|
|
717
|
+
columns={[
|
|
718
|
+
{ key: 'id', header: 'Host', sortable: true, render: (r) => <HostCell {...r} /> },
|
|
719
|
+
{ key: 'status', header: 'Status', sortable: true, render: (r) => <Badge variant={...}>{r.status}</Badge> },
|
|
720
|
+
{ key: 'cpu', header: 'CPU', align: 'right', sortable: true },
|
|
721
|
+
]}
|
|
722
|
+
searchable
|
|
723
|
+
searchKeys={['id', 'ip', 'owner']}
|
|
724
|
+
searchPlaceholder="Search host, ip, owner…"
|
|
725
|
+
filter={{ key: 'region', allLabel: 'All regions' }}
|
|
726
|
+
selectable
|
|
727
|
+
pageSize={5}
|
|
728
|
+
toolbarRight={<Button variant="terminal" size="sm">add_host</Button>}
|
|
729
|
+
bulkActions={[
|
|
730
|
+
{ label: 'Restart', icon: 'refresh', variant: 'ghost', onRun: (ids, clear) => { /* … */ clear(); } },
|
|
731
|
+
{ label: 'Stop', icon: 'trash', variant: 'destructive', onRun: (ids, clear) => clear() },
|
|
732
|
+
]}
|
|
733
|
+
rowMenu={(row) => [
|
|
734
|
+
{ label: 'Connect (SSH)', icon: 'external', onSelect: () => {} },
|
|
735
|
+
{ sep: true },
|
|
736
|
+
{ label: 'Stop host', icon: 'trash', onSelect: () => {} },
|
|
737
|
+
]}
|
|
738
|
+
emptyState={<EmptyState icon="search" title="No hosts found" description="Try clearing your filters." />}
|
|
739
|
+
/>
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
| Prop | Type | Default | Description |
|
|
743
|
+
|------|------|---------|-------------|
|
|
744
|
+
| `rows` | `object[]` | `[]` | Row data. |
|
|
745
|
+
| `rowKey` | `string` | `'id'` | Field used as the unique key + selection id. |
|
|
746
|
+
| `columns` | `Column[]` | `[]` | Column spec — see below. |
|
|
747
|
+
| `searchable` | `boolean` | `false` | Show the search input. |
|
|
748
|
+
| `searchKeys` | `string[]` | all column keys | Which fields the search matches against. |
|
|
749
|
+
| `searchPlaceholder` | `string` | `'Search…'` | Search input placeholder. |
|
|
750
|
+
| `filter` | `{ key, options?, allLabel? }` | — | Segmented filter on one field; `options` defaults to the field's distinct values. |
|
|
751
|
+
| `selectable` | `boolean` | `false` | Row checkboxes + select-all. |
|
|
752
|
+
| `pageSize` | `number` | `8` | Rows per page. |
|
|
753
|
+
| `bulkActions` | `BulkAction[]` | `[]` | Buttons shown when rows are selected; `onRun(ids, clear)`. |
|
|
754
|
+
| `rowMenu` | `(row) => MenuItem[]` | — | Per-row ⋮ dropdown (same item shape as `DropdownMenu`). |
|
|
755
|
+
| `toolbarRight` | `ReactNode` | — | Content pinned to the right of the toolbar (e.g. an add button). |
|
|
756
|
+
| `emptyState` | `ReactNode` | default text | Shown when no rows match. |
|
|
757
|
+
| `loading` | `boolean` | `false` | Render shimmer skeleton rows instead of data. |
|
|
758
|
+
| `skeletonRows` | `number` | `5` | How many skeleton rows while `loading`. |
|
|
759
|
+
|
|
760
|
+
**Column:** `{ key, header, sortable?, align?: 'left' | 'right', width?, render?: (row) => ReactNode }`. Without `render`, the raw `row[key]` is shown in mono.
|
|
761
|
+
|
|
762
|
+
## Skeleton
|
|
763
|
+
|
|
764
|
+
```html
|
|
765
|
+
<div class="tollerud-skeleton h-4 w-48" />
|
|
766
|
+
<div class="tollerud-skeleton h-48 w-full" />
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
## Glass Nav
|
|
770
|
+
|
|
771
|
+
```html
|
|
772
|
+
<nav class="tollerud-glass fixed top-0 left-0 right-0 z-50 h-16 flex items-center px-6">
|
|
773
|
+
...
|
|
774
|
+
</nav>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
## Grid Background
|
|
778
|
+
|
|
779
|
+
```html
|
|
780
|
+
<section class="tollerud-grid-bg">
|
|
781
|
+
...
|
|
782
|
+
</section>
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
## Display Heading
|
|
786
|
+
|
|
787
|
+
```html
|
|
788
|
+
<h1 class="tollerud-display text-[70px]">Dark. Monochrome.</h1>
|
|
789
|
+
<h2 class="tollerud-display--secondary text-[40px]">Yellow where it counts</h2>
|
|
790
|
+
<h3 class="tollerud-display--tertiary text-[28px]">Subtle hierarchy</h3>
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
## Container
|
|
794
|
+
|
|
795
|
+
```jsx
|
|
796
|
+
<Container>
|
|
797
|
+
<p>Content capped at 1100px with 24px padding</p>
|
|
798
|
+
</Container>
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
## Textarea
|
|
802
|
+
|
|
803
|
+
Multiline text input with label and error state.
|
|
804
|
+
|
|
805
|
+
```tsx
|
|
806
|
+
<Textarea
|
|
807
|
+
id="description"
|
|
808
|
+
label="Description"
|
|
809
|
+
placeholder="Enter details..."
|
|
810
|
+
rows={4}
|
|
811
|
+
/>
|
|
812
|
+
<Textarea
|
|
813
|
+
label="Bio"
|
|
814
|
+
value="..."
|
|
815
|
+
error="Max 500 characters"
|
|
816
|
+
onChange={...}
|
|
817
|
+
/>
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
| Prop | Type | Default | Description |
|
|
821
|
+
|------|------|---------|-------------|
|
|
822
|
+
| `label` | `string` | — | Label text |
|
|
823
|
+
| `error` | `string` | — | Error message, shows error styling |
|
|
824
|
+
| All native `<textarea>` props | — | — | rows, cols, placeholder, etc. |
|
|
825
|
+
|
|
826
|
+
## Select
|
|
827
|
+
|
|
828
|
+
Styled native `<select>` dropdown with custom chevron.
|
|
829
|
+
|
|
830
|
+
```tsx
|
|
831
|
+
<Select
|
|
832
|
+
label="Server"
|
|
833
|
+
placeholder="Select a server"
|
|
834
|
+
options={[
|
|
835
|
+
{ value: 'emma', label: 'Emma' },
|
|
836
|
+
{ value: 'miriam', label: 'Miriam' },
|
|
837
|
+
{ value: 'iris', label: 'Iris' },
|
|
838
|
+
]}
|
|
839
|
+
/>
|
|
840
|
+
<Select label="Status" error="Required">
|
|
841
|
+
<option value="running">Running</option>
|
|
842
|
+
<option value="stopped">Stopped</option>
|
|
843
|
+
</Select>
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
| Prop | Type | Default | Description |
|
|
847
|
+
|------|------|---------|-------------|
|
|
848
|
+
| `label` | `string` | — | Label text |
|
|
849
|
+
| `error` | `string` | — | Error message |
|
|
850
|
+
| `placeholder` | `string` | — | Disabled placeholder option |
|
|
851
|
+
| `options` | `{value, label}[]` | — | Option items (alternative to children) |
|
|
852
|
+
| All native `<select>` props | — | — | value, onChange, disabled, etc. |
|
|
853
|
+
|
|
854
|
+
## Checkbox
|
|
855
|
+
|
|
856
|
+
Custom-styled checkbox with checkmark SVG and label.
|
|
857
|
+
|
|
858
|
+
```tsx
|
|
859
|
+
<Checkbox label="Enable backups" checked={...} onChange={...} />
|
|
860
|
+
<Checkbox label="Send alerts" defaultChecked />
|
|
861
|
+
<Checkbox label="Action" disabled />
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
| Prop | Type | Default | Description |
|
|
865
|
+
|------|------|---------|-------------|
|
|
866
|
+
| `label` | `string` | — | Label text (wraps input) |
|
|
867
|
+
| All `<input type="checkbox">` props | — | — | checked, defaultChecked, disabled, onChange |
|
|
868
|
+
|
|
869
|
+
## Switch
|
|
870
|
+
|
|
871
|
+
Toggle switch with `role="switch"` accessibility.
|
|
872
|
+
|
|
873
|
+
```tsx
|
|
874
|
+
<Switch label="Dark mode" checked={...} onChange={...} />
|
|
875
|
+
<Switch label="Notifications" defaultChecked />
|
|
876
|
+
<Switch label="Beta features" disabled />
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
| Prop | Type | Default | Description |
|
|
880
|
+
|------|------|---------|-------------|
|
|
881
|
+
| `label` | `string` | — | Label text |
|
|
882
|
+
| All `<input type="checkbox">` props | — | — | checked, defaultChecked, disabled, onChange |
|
|
883
|
+
|
|
884
|
+
## RadioGroup / Radio
|
|
885
|
+
|
|
886
|
+
Fieldset-based radio group with custom dot indicator.
|
|
887
|
+
|
|
888
|
+
```tsx
|
|
889
|
+
<RadioGroup label="Deployment target" error={error}>
|
|
890
|
+
<Radio value="staging" label="Staging" name="target" />
|
|
891
|
+
<Radio value="production" label="Production" name="target" />
|
|
892
|
+
<Radio value="canary" label="Canary" disabled name="target" />
|
|
893
|
+
</RadioGroup>
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
| RadioGroup Prop | Type | Default | Description |
|
|
897
|
+
|-----------------|------|---------|-------------|
|
|
898
|
+
| `label` | `string` | — | Group label (rendered as `<legend>`) |
|
|
899
|
+
| `error` | `string` | — | Error message |
|
|
900
|
+
|
|
901
|
+
| Radio Prop | Type | Default | Description |
|
|
902
|
+
|------------|------|---------|-------------|
|
|
903
|
+
| `label` | `string` | — | Radio label |
|
|
904
|
+
| All `<input type="radio">` props | — | — | value, checked, name, disabled |
|
|
905
|
+
|
|
906
|
+
## Footer
|
|
907
|
+
|
|
908
|
+
Footer bar with Tollerud monogram and branding link. The component is re-exported from [`@tollerud/footer`](https://www.npmjs.com/package/@tollerud/footer) — install that package directly if you need the footer without the full design system.
|
|
909
|
+
|
|
910
|
+
```tsx
|
|
911
|
+
<Footer />
|
|
912
|
+
<Footer layout="row" />
|
|
913
|
+
<Footer accent />
|
|
914
|
+
<Footer
|
|
915
|
+
labels={{
|
|
916
|
+
tollerudProject: 'A Tollerud Project',
|
|
917
|
+
allRightsReserved: 'All rights reserved.',
|
|
918
|
+
}}
|
|
919
|
+
unstyled
|
|
920
|
+
className="border-t border-tollerud-yellow/20 bg-black"
|
|
921
|
+
/>
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
| Prop | Type | Default | Description |
|
|
925
|
+
|------|------|---------|-------------|
|
|
926
|
+
| `layout` | `'responsive' \| 'row'` | `'responsive'` | responsive = mobile-first stacking, row = horizontal |
|
|
927
|
+
| `accent` | `boolean` | `false` | Yellow-tinted surface |
|
|
928
|
+
| `unstyled` | `boolean` | `false` | Skip all surface styling |
|
|
929
|
+
| `labels` | `Partial<FooterLabels>` | — | tollerudProject, attribution, allRightsReserved |
|
|
930
|
+
| `className` | `string` | — | Footer element |
|
|
931
|
+
| `style` | `CSSProperties` | — | Footer element inline styles |
|
|
932
|
+
| `classNameInner` | `string` | — | Inner wrapper |
|
|
933
|
+
| `classNameLogo` | `string` | — | SVG monogram |
|
|
934
|
+
| `classNameText` | `string` | — | Text paragraph |
|
|
935
|
+
| `classNameLink` | `string` | — | tollerud.no link |
|
|
936
|
+
|
|
937
|
+
## State matrix
|
|
938
|
+
|
|
939
|
+
| Component | Default | Hover | Focus | Active/Check | Disabled | Error | Loading |
|
|
940
|
+
|-----------|---------|-------|-------|-------------|----------|-------|---------|
|
|
941
|
+
| Button | ✅ | ✅ | ✅ | ✅ | ✅ | — | ✅ (disabled) |
|
|
942
|
+
| Input | ✅ | — | ✅ | — | ✅ | ✅ | — |
|
|
943
|
+
| Textarea | ✅ | — | ✅ | — | ✅ | ✅ | — |
|
|
944
|
+
| Select | ✅ | — | ✅ | — | ✅ | ✅ | — |
|
|
945
|
+
| Checkbox | ✅ | ✅ | ✅ | ✅ | ✅ | — | — |
|
|
946
|
+
| Switch | ✅ | ✅ | ✅ | ✅ | ✅ | — | — |
|
|
947
|
+
| Radio | ✅ | ✅ | ✅ | ✅ | ✅ | — | — |
|
|
948
|
+
| Badge | ✅ | — | — | — | — | — | — |
|
|
949
|
+
| Card | ✅ | ✅ | — | — | — | — | — |
|
|
950
|
+
| StatusDot | ✅ | — | — | — | — | — | — |
|
|
951
|
+
| Footer | ✅ | — | — | — | — | — | — |
|