annotate design_system/README.md @ 254:2b6e732087ff

[ui] Add complete native component catalog Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Tue, 04 Aug 2026 15:12:09 -0700
parents 7a7581f040e8
children 30c2196d03d4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 # Zenbu UI design system
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 Zenbu UI is a dependency-free set of light-DOM Web Components and CSS tokens.
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 It stays close to ordinary HTML: components wrap native controls and sectioning
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 elements instead of replacing their semantics.
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6
254
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
7 The catalog includes native Zenbu implementations of all 65 concepts currently
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
8 listed by shadcn/ui. These are original Web Components using Zenbu tokens, not
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
9 ports of shadcn's React, Radix, or third-party runtime. See
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
10 [`COMPONENTS.md`](COMPONENTS.md) for the complete mapping and HTML contracts.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
11
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 ## Catalog
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 Run the Seobeo-backed component catalog:
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 ```bash
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 bazel run //design_system:dev
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 ```
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 Open `http://127.0.0.1:6980`. Override the port with
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 `DESIGN_SYSTEM_PORT`.
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 The catalog is intentionally Storybook-like without depending on Storybook. Its
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 stories are declared as HTML templates:
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 ```html
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 <zen-story name="Primary button">
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 <template>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 <zen-button>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 <button type="button">Save</button>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 </zen-button>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 </template>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 </zen-story>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 ```
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 The story component renders the example and its source side by side.
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 ## Reuse
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 Reusable assets are public Bazel targets:
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 ```text
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43 //design_system:components
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 //design_system:styles
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 //design_system:web_assets
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 ```
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 Applications should copy the assets while preserving `components/` and
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 `styles/`, then load:
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 ```html
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 <link rel="stylesheet" href="/design-system/styles/tokens.css">
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 <link rel="stylesheet" href="/design-system/styles/components.css">
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 <script type="module" src="/design-system/components/index.js"></script>
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 ```
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 Every visual token is a `--zen-*` custom property and can be overridden by the
254
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
58 application. See [`COLORS.md`](COLORS.md) for the complete warm color ramps,
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
59 material aliases, semantic roles, dark-theme behavior, and data palette.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
60
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
61 Use [`zen-icon`](ICONS.md) for all interface iconography. Design-system source
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
62 does not use emoji, ad hoc SVG, icon fonts, or third-party icon packages.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
63
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
64 All exported JavaScript APIs use Google-style JSDoc. The policy target checks
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
65 the documentation contract along with token-only colors and first-party icons.
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
66
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
67 The catalog navigation is searchable with `/`, and every route is exercised at
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
68 desktop and mobile widths. Form controls reset browser chrome; date selection
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
69 uses Zenbu's first-party keyboard calendar.
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 ## Native HTML contract
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72
254
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
73 | Component family | Native content | Attributes | Events |
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 | --- | --- | --- | --- |
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 | `zen-button` | direct `button` or `a` | `variant`, `loading`, `disabled` | native click/form events |
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 | `zen-card` | direct `article` or `section` | `interactive` | native descendant events |
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 | `zen-alert` | message HTML | `tone`, `dismissible` | `zen-dismiss` |
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 | `zen-field` | direct `label`, form control, help text | native control attributes | native input/change/invalid |
252
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
79 | `zen-notifications` | descendant event producers | `aria-label`, `dismiss-label` | `zen-notification-action`, `zen-notification-removed` |
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 | `zen-stack` | any HTML | `direction`, `gap` | native descendant events |
254
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
81 | Disclosure and tabs | `details`, `summary`, buttons, sections | `multiple`, `activation` | `zen-change` |
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
82 | Dialogs and menus | native `dialog`, buttons, links | `placement`, native attributes | native click/close |
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
83 | Form controls | native input, select, textarea, fieldset | native control attributes | native form events |
2b6e732087ff [ui] Add complete native component catalog
MrJuneJune <me@mrjunejune.com>
parents: 252
diff changeset
84 | Collections | table, article, section, scroll containers | component-specific data hooks | `zen-change`, `zen-sort`, `zen-resize` |
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 Do not put business state into the design-system components. They provide
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 presentation, small accessibility wiring, and interaction affordances while
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 applications retain data and workflow ownership.
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89
252
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
90 ### Notifications
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
91
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
92 See [`NOTIFICATIONS.md`](NOTIFICATIONS.md) for the complete event contract,
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
93 queue semantics, actions, timing, and accessibility behavior.
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
94
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
95 Place one scope around the part of the application that owns notifications:
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
96
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
97 ```html
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
98 <zen-notifications aria-label="Notifications">
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
99 <main id="application"></main>
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
100 </zen-notifications>
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
101 ```
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
102
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
103 Any descendant can dispatch a non-composed bubbling event:
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
104
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
105 ```js
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
106 source.dispatchEvent(new CustomEvent("zen-notify", {
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
107 bubbles: true,
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
108 composed: false,
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
109 detail: {
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
110 version: 1,
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
111 id: "deployment-complete",
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
112 tone: "success",
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
113 message: "Deployment complete",
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
114 announcement: "polite",
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
115 durationMs: 5000,
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
116 },
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
117 }));
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
118 ```
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
119
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
120 Use `zen-dismiss-notification` with `{ version: 1, id }` to dismiss by ID.
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
121 Actions contain only an opaque token and label; clicking dispatches
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
122 `zen-notification-action`. Tokens are held in private component state and never
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
123 written to DOM attributes. The component renders three records and retains up
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
124 to 20 additional queued records.
7a7581f040e8 [ui] Add scoped notification component
MrJuneJune <me@mrjunejune.com>
parents: 251
diff changeset
125
251
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 ## Tests
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 ```bash
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 bazel test //design_system/test:storybook_test
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 bazel build //design_system:design_system_server_bundle
117c4d53c9a4 [ui] Add HTML-first Web Component system
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 ```