@you-agent-factory/components 0.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.
Files changed (92) hide show
  1. package/README.md +223 -0
  2. package/docs/README.md +83 -0
  3. package/docs/button.md +119 -0
  4. package/docs/charts.md +325 -0
  5. package/docs/data-display-code-panel.md +120 -0
  6. package/docs/feedback-alert-panel.md +117 -0
  7. package/docs/feedback-skeleton.md +54 -0
  8. package/docs/forms-form-field.md +490 -0
  9. package/docs/forms-input-primitives.md +311 -0
  10. package/docs/forms-select-primitives.md +362 -0
  11. package/docs/graphs.md +250 -0
  12. package/docs/layout-display-primitives.md +211 -0
  13. package/docs/overlays.md +414 -0
  14. package/docs/table-data-table.md +331 -0
  15. package/docs/typography-roles.md +182 -0
  16. package/docs/widget-frame-recipes.md +273 -0
  17. package/package.json +161 -0
  18. package/src/category-paths.ts +20 -0
  19. package/src/charts/chart-state-panel.tsx +103 -0
  20. package/src/charts/chart.tsx +287 -0
  21. package/src/charts/index.ts +21 -0
  22. package/src/data-display/code-panel.tsx +67 -0
  23. package/src/data-display/data-table.tsx +180 -0
  24. package/src/data-display/description-list.tsx +24 -0
  25. package/src/data-display/index.ts +34 -0
  26. package/src/data-display/table-layout.ts +12 -0
  27. package/src/data-display/table.tsx +131 -0
  28. package/src/feedback/alert-panel-semantics.ts +75 -0
  29. package/src/feedback/alert-panel.tsx +187 -0
  30. package/src/feedback/index.ts +21 -0
  31. package/src/feedback/skeleton.tsx +16 -0
  32. package/src/forms/index.ts +73 -0
  33. package/src/forms/package-checkbox.tsx +50 -0
  34. package/src/forms/package-enum-select.tsx +185 -0
  35. package/src/forms/package-file-input.tsx +25 -0
  36. package/src/forms/package-form-field.tsx +202 -0
  37. package/src/forms/package-input.tsx +25 -0
  38. package/src/forms/package-native-select.tsx +25 -0
  39. package/src/forms/package-select.tsx +209 -0
  40. package/src/forms/package-textarea.tsx +35 -0
  41. package/src/forms/select-icons.tsx +35 -0
  42. package/src/graphs/graph-edge-path.ts +241 -0
  43. package/src/graphs/graph-edge.tsx +130 -0
  44. package/src/graphs/graph-interactive-example.tsx +187 -0
  45. package/src/graphs/graph-node-button.tsx +51 -0
  46. package/src/graphs/graph-node-handle-badge.tsx +108 -0
  47. package/src/graphs/graph-node-handle.ts +28 -0
  48. package/src/graphs/graph-node-shell.tsx +111 -0
  49. package/src/graphs/graph-node-state-indicator.tsx +47 -0
  50. package/src/graphs/graph-node-state.ts +111 -0
  51. package/src/graphs/graph-viewport-surface.tsx +27 -0
  52. package/src/graphs/index.ts +41 -0
  53. package/src/icons/index.ts +4 -0
  54. package/src/index.ts +209 -0
  55. package/src/layout/action-row.tsx +53 -0
  56. package/src/layout/index.ts +9 -0
  57. package/src/layout/surface-panel.tsx +91 -0
  58. package/src/navigation/index.ts +4 -0
  59. package/src/overlays/collapsible.tsx +22 -0
  60. package/src/overlays/dialog.tsx +148 -0
  61. package/src/overlays/index.ts +31 -0
  62. package/src/overlays/overlay-layout.ts +9 -0
  63. package/src/overlays/popover.tsx +29 -0
  64. package/src/overlays/scroll-area.tsx +78 -0
  65. package/src/primitives/button-link.tsx +22 -0
  66. package/src/primitives/button.tsx +258 -0
  67. package/src/primitives/icon-button-shell.tsx +49 -0
  68. package/src/primitives/index.ts +31 -0
  69. package/src/primitives/package-text.tsx +29 -0
  70. package/src/primitives/typography-roles.ts +12 -0
  71. package/src/primitives/typography.tsx +165 -0
  72. package/src/recipes/index.ts +61 -0
  73. package/src/recipes/widget-frame-content.tsx +114 -0
  74. package/src/recipes/widget-frame-disclosure.tsx +161 -0
  75. package/src/recipes/widget-frame-layout.ts +40 -0
  76. package/src/recipes/widget-frame-skeleton.tsx +16 -0
  77. package/src/recipes/widget-frame-states.tsx +99 -0
  78. package/src/recipes/widget-frame-typography.ts +19 -0
  79. package/src/recipes/widget-frame.tsx +84 -0
  80. package/src/styles/color-palette-presets.css +167 -0
  81. package/src/styles/color-role-tokens.css +163 -0
  82. package/src/styles/layout-role-tokens.css +27 -0
  83. package/src/styles/text-color-role-tokens.css +29 -0
  84. package/src/styles/typography-role-tokens.css +72 -0
  85. package/src/styles/typography-role-utilities.css +73 -0
  86. package/src/styles/typography-roles.css +53 -0
  87. package/src/styles.css +32 -0
  88. package/src/testing/index.ts +13 -0
  89. package/src/testing/render.tsx +16 -0
  90. package/src/tokens/index.ts +4 -0
  91. package/src/utilities/cn.ts +5 -0
  92. package/src/utilities/index.ts +6 -0
@@ -0,0 +1,331 @@
1
+ # Table primitives and DataTable
2
+
3
+ Domain-free semantic table primitives and a generic `DataTable` for rendering
4
+ arbitrary row objects through host-provided column definitions and render
5
+ callbacks. Use these components when you need accessible tabular data display
6
+ without importing dashboard routes, API clients, generated OpenAPI types, or app
7
+ localization providers.
8
+
9
+ ## Required setup
10
+
11
+ Import package styles once in your host application before rendering tables:
12
+
13
+ ```css
14
+ @import "@you-agent-factory/components/styles.css";
15
+ ```
16
+
17
+ Table components depend on package role tokens (`--color-outline`,
18
+ `--color-on-surface`, `--color-af-overlay`, typography roles) and Tailwind
19
+ utility classes compiled from those tokens. They do not require dashboard
20
+ `styles.css`, dashboard providers, React Query, Zustand, or app i18n context.
21
+
22
+ ## Import paths
23
+
24
+ Prefer the data-display category entrypoint:
25
+
26
+ ```ts
27
+ import {
28
+ DataTable,
29
+ type DataTableColumn,
30
+ type DataTableProps,
31
+ type DataTableState,
32
+ Table,
33
+ TableBody,
34
+ TableCaption,
35
+ TableCell,
36
+ TableHead,
37
+ TableHeader,
38
+ TableRow,
39
+ type TableSize,
40
+ tableCellTruncateClassName,
41
+ tableCellWrapClassName,
42
+ tableMinWidthWideClassName,
43
+ tableNarrowContainerClassName,
44
+ } from "@you-agent-factory/components/data-display";
45
+ ```
46
+
47
+ The same exports are also available from the package root:
48
+
49
+ ```ts
50
+ import { DataTable } from "@you-agent-factory/components";
51
+ ```
52
+
53
+ ## Host ownership
54
+
55
+ The package owns presentation markup, semantic table structure, state-region
56
+ semantics, density variants, and scroll containment helpers. Host applications
57
+ own everything domain-specific:
58
+
59
+ | Concern | Owner |
60
+ | --- | --- |
61
+ | User-visible copy (headers, empty/loading/error messages, cell labels) | Host |
62
+ | Row data, domain models, and stable row identity | Host |
63
+ | Data fetching, caching, retries, and error mapping | Host |
64
+ | Formatting, translations, and business display rules | Host |
65
+ | Sorting policy, pagination, selection, and row actions | Host |
66
+ | Which `state` value to render (`loading`, `empty`, `error`, `success`) | Host |
67
+
68
+ Pass data, copy, and callbacks into `DataTable` as props. Do not expect the
69
+ package to read from your routers, stores, API layers, or i18n providers.
70
+
71
+ ## Generic row contract
72
+
73
+ `DataTable` is generic over `Row`. The host defines the row shape and supplies:
74
+
75
+ 1. **`data`** — array of row objects for the success state.
76
+ 2. **`columns`** — column definitions with stable `id`, visible `header`, and a
77
+ `cell` render callback.
78
+ 3. **`getRowKey`** — returns a stable string key per row for React list identity.
79
+
80
+ ```tsx
81
+ interface ProductRow {
82
+ id: string;
83
+ name: string;
84
+ status: "active" | "draft";
85
+ }
86
+
87
+ const columns: DataTableColumn<ProductRow>[] = [
88
+ {
89
+ id: "name",
90
+ header: "Product",
91
+ cell: (row) => <span className="font-medium">{row.name}</span>,
92
+ },
93
+ {
94
+ id: "status",
95
+ header: "Status",
96
+ cell: (row) => (row.status === "active" ? "Active" : "Draft"),
97
+ },
98
+ ];
99
+
100
+ <DataTable<ProductRow>
101
+ ariaLabel="Product catalog"
102
+ columns={columns}
103
+ data={products}
104
+ emptyMessage="No products match the current filters"
105
+ getRowKey={(row) => row.id}
106
+ state="success"
107
+ />
108
+ ```
109
+
110
+ ### Column definitions
111
+
112
+ | Field | Purpose |
113
+ | --- | --- |
114
+ | `id` | Stable column identifier used for React keys. |
115
+ | `header` | Visible column heading (`ReactNode`). Host supplies copy and formatting. |
116
+ | `cell` | `(row: Row) => ReactNode` callback that renders one cell per row. |
117
+ | `headerClassName` | Optional class names for the `<th>` element. |
118
+ | `cellClassName` | Optional class names for the `<td>` element (use layout helpers for long cells). |
119
+
120
+ ### Row keys
121
+
122
+ `getRowKey` must return a stable, unique string for each row in the current
123
+ dataset. Use domain identifiers (for example record IDs), not array indexes,
124
+ when rows can be reordered, filtered, or updated.
125
+
126
+ ## Explicit data states
127
+
128
+ `DataTable` does not fetch data or read application context. The host sets
129
+ `state` explicitly:
130
+
131
+ | `state` | When to use | Host copy props |
132
+ | --- | --- | --- |
133
+ | `loading` | Data is in flight | `loadingMessage` |
134
+ | `empty` | Fetch succeeded with zero rows, or filters exclude all rows | `emptyMessage` |
135
+ | `error` | Fetch or mapping failed | `errorMessage` |
136
+ | `success` | Rows are ready to render | none required; uses `data` and `columns` |
137
+
138
+ ```tsx
139
+ <DataTable
140
+ ariaLabel="Product catalog"
141
+ columns={columns}
142
+ data={[]}
143
+ emptyMessage="No products match the current filters"
144
+ errorMessage="Unable to load product catalog data"
145
+ getRowKey={(row) => row.id}
146
+ loadingMessage="Loading product catalog"
147
+ state={isLoading ? "loading" : hasError ? "error" : rows.length === 0 ? "empty" : "success"}
148
+ />
149
+ ```
150
+
151
+ Behavior notes:
152
+
153
+ - Headers remain visible for `loading`, `empty`, and `error` so the layout stays
154
+ table-compatible.
155
+ - `state="success"` with an empty `data` array still renders `emptyMessage` for
156
+ backward compatibility.
157
+ - `state="empty"` ignores row data even when `data` is non-empty.
158
+
159
+ ## Table primitives
160
+
161
+ Use low-level primitives when you need custom body composition beyond
162
+ `DataTable`:
163
+
164
+ ```tsx
165
+ import {
166
+ Table,
167
+ TableBody,
168
+ TableCaption,
169
+ TableCell,
170
+ TableHead,
171
+ TableHeader,
172
+ TableRow,
173
+ } from "@you-agent-factory/components/data-display";
174
+
175
+ <Table aria-label="Custom table" size="dense">
176
+ <TableCaption>Host-provided caption</TableCaption>
177
+ <TableHeader>
178
+ <TableRow>
179
+ <TableHead scope="col">Name</TableHead>
180
+ </TableRow>
181
+ </TableHeader>
182
+ <TableBody>
183
+ <TableRow>
184
+ <TableCell>Host-provided cell</TableCell>
185
+ </TableRow>
186
+ </TableBody>
187
+ </Table>
188
+ ```
189
+
190
+ `Table` wraps the native `<table>` in a scroll container with
191
+ `overflow-x-auto`, rounded border, and optional `size` (`default` | `dense`).
192
+
193
+ ## Density, long cells, and narrow viewports
194
+
195
+ ### Dense mode
196
+
197
+ Set `size="dense"` on `DataTable` or `Table` for compact header and cell
198
+ padding. Dense spacing uses `data-size="dense"` on the scroll container and
199
+ `group-data-[size=dense]/table:` utility classes on header and cell elements.
200
+
201
+ ### Long cell content
202
+
203
+ Export layout helpers from the data-display entrypoint:
204
+
205
+ | Helper | Purpose |
206
+ | --- | --- |
207
+ | `tableCellWrapClassName` | Wrap long values with `overflow-wrap: anywhere` inside the table scroller. |
208
+ | `tableCellTruncateClassName` | Truncate overflowing values with ellipsis. |
209
+ | `tableMinWidthWideClassName` | Minimum table width (`min-w-2xl`) for wide datasets. |
210
+ | `tableNarrowContainerClassName` | Scroll container classes (`min-w-0 overscroll-x-contain`) for narrow parents. |
211
+
212
+ Apply helpers through `column.cellClassName` or `column.headerClassName`:
213
+
214
+ ```tsx
215
+ const columns = [
216
+ {
217
+ id: "traceId",
218
+ header: "Trace ID",
219
+ cellClassName: tableCellTruncateClassName,
220
+ cell: (row) => row.traceId,
221
+ },
222
+ {
223
+ id: "notes",
224
+ header: "Notes",
225
+ cellClassName: tableCellWrapClassName,
226
+ cell: (row) => row.notes,
227
+ },
228
+ ];
229
+ ```
230
+
231
+ ### Narrow viewports
232
+
233
+ Pair `tableNarrowContainerClassName` on the table container with
234
+ `tableMinWidthWideClassName` on the table element so wide datasets scroll
235
+ horizontally inside the table region instead of forcing page-level overflow.
236
+
237
+ ## Key props
238
+
239
+ ### `DataTable`
240
+
241
+ | Prop | Purpose |
242
+ | --- | --- |
243
+ | `columns` | Required column definitions with headers and cell callbacks. |
244
+ | `data` | Row array for the success state. |
245
+ | `getRowKey` | Stable row identity callback. |
246
+ | `state` | `loading` \| `empty` \| `error` \| `success` (default `success`). |
247
+ | `loadingMessage` / `emptyMessage` / `errorMessage` | Host-provided copy for non-success states. |
248
+ | `ariaLabel` | Accessible name when no visible caption names the table. |
249
+ | `caption` | Optional `<caption>` content below the table. |
250
+ | `size` | `default` or `dense` table spacing. |
251
+ | `rowClassName` | Optional per-row class callback. |
252
+ | `tableClassName` | Class names on the `<table>` element. |
253
+ | `containerClassName` / `containerProps` | Scroll container overrides (for narrow layouts). |
254
+
255
+ ### `Table` primitives
256
+
257
+ | Prop | Purpose |
258
+ | --- | --- |
259
+ | `size` | `default` or `dense` spacing variant. |
260
+ | `containerClassName` / `containerProps` | Scroll container overrides. |
261
+
262
+ ## Accessibility expectations
263
+
264
+ - Success state renders semantic `<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th
265
+ scope="col">`, and `<td>` structure.
266
+ - Provide `ariaLabel` when the table has no visible caption or external heading
267
+ that names it.
268
+ - `loading` renders `role="status"` with `aria-busy="true"` and non-interactive
269
+ placeholder bars (`aria-hidden`) so loading does not masquerade as row data.
270
+ - `empty` renders `role="status"` with polite live-region semantics.
271
+ - `error` renders `role="alert"` with assertive live-region semantics.
272
+ - Interactive controls inside cells (buttons, links) must include accessible
273
+ names from the host (`aria-label` or visible text).
274
+ - Dense mode preserves readable focus indicators on interactive controls inside
275
+ cells.
276
+
277
+ ## Storybook visual reference
278
+
279
+ Package Storybook lives under `Data Display/DataTable`. Stories use package
280
+ imports and package token decorators only — no dashboard providers.
281
+
282
+ | Story | Storybook id | Demonstrates |
283
+ | --- | --- | --- |
284
+ | Success | `data-display-datatable--success` | Callback-driven generic rows |
285
+ | Loading | `data-display-datatable--loading` | Loading status region + placeholders |
286
+ | Empty | `data-display-datatable--empty` | Host-provided empty copy |
287
+ | Error | `data-display-datatable--error-state` | Host-provided error alert |
288
+ | Dense | `data-display-datatable--dense` | Compact row spacing with operable controls |
289
+ | Long cell | `data-display-datatable--long-cell` | Wrap and truncate containment |
290
+ | Narrow viewport | `data-display-datatable--narrow-viewport` | Horizontal scroll on small widths |
291
+
292
+ Run package Storybook locally:
293
+
294
+ ```bash
295
+ cd ui/packages/components
296
+ bun run storybook
297
+ ```
298
+
299
+ Browser verification for documented stories:
300
+
301
+ ```bash
302
+ cd ui/packages/components
303
+ bun run verify:storybook-browser
304
+ ```
305
+
306
+ ## Allowed dependencies
307
+
308
+ Table source may import:
309
+
310
+ - Package utilities (`cn` from `@you-agent-factory/components/utilities`)
311
+ - Package token CSS via the host `styles.css` import
312
+ - React and `react-dom` peer dependencies
313
+
314
+ Table source must **not** import:
315
+
316
+ - Dashboard feature modules, routes, or providers
317
+ - Generated OpenAPI clients or dashboard API adapters
318
+ - React Query, Zustand, Monaco, Sonner, or dashboard i18n/session providers
319
+ - Factory, work, session, provider, or other domain row types
320
+
321
+ `check:package-boundary` enforces these rules in CI.
322
+
323
+ ## Dashboard integration note
324
+
325
+ The dashboard keeps data fetching, translations, and business formatting in
326
+ feature code. Dashboard tables import primitives and `DataTable` from
327
+ `@you-agent-factory/components/data-display` (or through thin dashboard
328
+ re-exports) and pass host copy, row data, and render callbacks as props.
329
+
330
+ When adopting tables outside the dashboard, compose `DataTable` directly and
331
+ supply your own messages, row keys, column callbacks, and `state` transitions.
@@ -0,0 +1,182 @@
1
+ # Typography roles
2
+
3
+ Domain-free typography primitives for headings, body copy, labels, and inline
4
+ code. Use these components when you need consistent text hierarchy, dense
5
+ metadata rows, and predictable truncation or wrapping without dashboard routes,
6
+ providers, API clients, or generated OpenAPI types.
7
+
8
+ The package ships four primitives:
9
+
10
+ | Component | Role |
11
+ | --- | --- |
12
+ | `Heading` | Page and section titles with semantic heading levels. |
13
+ | `Text` | Body, supporting, muted, caption, and dense copy variants. |
14
+ | `Label` | Uppercase field labels and description-list term labels. |
15
+ | `Code` | Inline monospace identifiers at body or supporting sizes. |
16
+
17
+ These components are **presentation typography**. They apply token-backed role
18
+ classes and optional overflow behavior. They do not fetch data, localize strings,
19
+ or own application state.
20
+
21
+ ## Required setup
22
+
23
+ Import package styles once in your host application before rendering typography:
24
+
25
+ ```css
26
+ @import "@you-agent-factory/components/styles.css";
27
+ ```
28
+
29
+ Typography roles depend on package font tokens (`--font-display`, `--font-sans`,
30
+ `--font-mono`) and semantic color roles such as `text-on-surface` and
31
+ `text-on-surface-subtle`. They do not require dashboard `styles.css`, dashboard
32
+ providers, generated OpenAPI types, React Query, or Zustand.
33
+
34
+ ## Import paths
35
+
36
+ Prefer the primitives category entrypoint for explicit category boundaries:
37
+
38
+ ```ts
39
+ import {
40
+ Code,
41
+ Heading,
42
+ Label,
43
+ Text,
44
+ type CodeProps,
45
+ type HeadingProps,
46
+ type LabelProps,
47
+ type TextProps,
48
+ type TextVariant,
49
+ } from "@you-agent-factory/components/primitives";
50
+ ```
51
+
52
+ The same exports are also available from the package root:
53
+
54
+ ```ts
55
+ import { Code, Heading, Label, Text } from "@you-agent-factory/components";
56
+ ```
57
+
58
+ ## Typography role hierarchy
59
+
60
+ Each primitive maps to a domain-free `af-*` role class defined in package CSS.
61
+ Prefer the React components over applying raw `af-*` classes in host markup so
62
+ overflow props and semantic element defaults stay consistent.
63
+
64
+ ### Headings
65
+
66
+ | `level` | Default element | Role class | When to use |
67
+ | --- | --- | --- | --- |
68
+ | `page` | `h1` | `af-page-heading` | Top-level page titles. |
69
+ | `section` | `h3` | `af-section-heading` | Section titles inside panels or forms. |
70
+
71
+ Override the rendered element with `as` when the visual role and document
72
+ outline need different semantics:
73
+
74
+ ```tsx
75
+ import { Heading } from "@you-agent-factory/components";
76
+
77
+ <Heading level="section" as="h2">
78
+ Section title supplied by the host
79
+ </Heading>
80
+ ```
81
+
82
+ ### Text variants
83
+
84
+ | `variant` | Role class | When to use |
85
+ | --- | --- | --- |
86
+ | `body` (default) | `af-body-text` | Primary readable copy. |
87
+ | `supporting` | `af-supporting-text` | Secondary metadata below primary content. |
88
+ | `muted` | `af-muted-text` | De-emphasized supporting copy. |
89
+ | `caption` | `af-caption-text` | Compact captions and footnotes. |
90
+ | `dense` | `af-dense-body-text` | Tight metadata rows in tables or description lists. |
91
+
92
+ ```tsx
93
+ import { Text } from "@you-agent-factory/components";
94
+
95
+ <Text>Primary body copy supplied by the host</Text>
96
+ <Text variant="muted">Muted secondary metadata</Text>
97
+ <Text variant="dense">Dense row value</Text>
98
+ ```
99
+
100
+ ### Labels and code
101
+
102
+ - `Label` applies `af-supporting-label` for uppercase field and term labels.
103
+ Use `as="dt"` inside description lists.
104
+ - `Code` applies `af-body-code` or `af-supporting-code` for inline identifiers.
105
+ Use `size="supporting"` for compact metadata.
106
+
107
+ ```tsx
108
+ import { Code, Label } from "@you-agent-factory/components";
109
+
110
+ <Label htmlFor="resource-name">Resource name</Label>
111
+ <Code size="supporting">example-resource-id</Code>
112
+ ```
113
+
114
+ ## Dense text
115
+
116
+ Use `Text variant="dense"` when scan-friendly metadata needs tighter line height
117
+ without switching to caption sizing. Dense rows pair well with `DescriptionList`
118
+ and compact panel layouts.
119
+
120
+ The dense role uses `text-body-small` with `leading-tight` and
121
+ `text-on-surface-variant`. It is intended for host-supplied values such as
122
+ timestamps, revision numbers, and status summaries—not for long paragraphs.
123
+
124
+ ## Truncation and long content
125
+
126
+ `Text`, `Heading`, and `Label` accept `truncate` and `wrap` props for overflow
127
+ behavior. Do not mix both on the same element.
128
+
129
+ | Prop | Role class | Behavior |
130
+ | --- | --- | --- |
131
+ | `truncate` | `af-text-truncate` | Single-line ellipsis inside a width-constrained parent. |
132
+ | `wrap` | `af-text-wrap` | Multi-line wrapping with `min-w-0` and `overflow-wrap: anywhere`. |
133
+
134
+ Truncation requires a bounded-width ancestor. Wrap long values inside narrow
135
+ containers to avoid horizontal page overflow:
136
+
137
+ ```tsx
138
+ import { Label, Text } from "@you-agent-factory/components";
139
+
140
+ <div className="max-w-xs">
141
+ <Label truncate>{longHostLabel}</Label>
142
+ <Text wrap>{longHostValue}</Text>
143
+ </div>
144
+ ```
145
+
146
+ Choose `truncate` for toolbar labels, table headers, and single-line metadata.
147
+ Choose `wrap` for multi-line descriptions, identifiers, and messages that must
148
+ remain fully readable.
149
+
150
+ ## Host application responsibilities
151
+
152
+ The component package owns presentation: role classes, semantic defaults, and
153
+ overflow utilities backed by package tokens.
154
+
155
+ Host applications own:
156
+
157
+ | Concern | Owner |
158
+ | --- | --- |
159
+ | Visible headings, labels, body copy, and code content | Host |
160
+ | When to use muted, caption, or dense variants in product context | Host |
161
+ | `htmlFor`, `id`, and accessible naming for labels | Host |
162
+ | `dateTime` on time elements and heading level in the document outline | Host |
163
+ | Truncation versus wrapping for specific data values | Host |
164
+ | Loading, empty, error, and success copy around typography | Host |
165
+ | Localization and string formatting | Host |
166
+
167
+ Pass copy and accessibility attributes into typography primitives as props. Do
168
+ not expect the package to read from your routers, stores, or API layers.
169
+
170
+ ## Storybook examples
171
+
172
+ Package Storybook stories demonstrate role hierarchy and overflow behavior with
173
+ package imports only:
174
+
175
+ - `Primitives/Typography` — body, supporting, muted, caption, dense, heading,
176
+ label, code, truncated, and wrapped examples.
177
+ - `Primitives/Typography/Mobile typography roles` and
178
+ `Primitives/Typography/Desktop typography roles` — responsive readability
179
+ checks at narrow and wide viewport sizes.
180
+
181
+ Run `bun run storybook` from `ui/packages/components` or inspect the static
182
+ build with `bun run build-storybook`.