@dowel-ui/registry 0.5.0 → 0.7.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/dist/build.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as registryIndexSchema, c as hashContent, o as registryItemSchema } from "./schema-ByqIpT47.js";
1
+ import { l as hashContent, o as registryIndexSchema, s as registryItemSchema } from "./schema-BbyNjH6Q.js";
2
2
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -9,7 +9,7 @@ function defineMeta(meta) {
9
9
  }
10
10
  //#endregion
11
11
  //#region ../ui/dist/components/accordion/meta.js
12
- const meta$77 = defineMeta({
12
+ const meta$91 = defineMeta({
13
13
  name: "accordion",
14
14
  title: "Accordion",
15
15
  description: "Vertically stacked sections that expand to reveal their content.",
@@ -22,7 +22,7 @@ const meta$77 = defineMeta({
22
22
  });
23
23
  //#endregion
24
24
  //#region ../ui/dist/components/activity-feed/meta.js
25
- const meta$76 = defineMeta({
25
+ const meta$90 = defineMeta({
26
26
  name: "activity-feed",
27
27
  title: "Activity Feed",
28
28
  description: "A chronological list of events, with a connecting timeline rail.",
@@ -35,7 +35,7 @@ const meta$76 = defineMeta({
35
35
  });
36
36
  //#endregion
37
37
  //#region ../ui/dist/components/ai-action-ledger/meta.js
38
- const meta$75 = defineMeta({
38
+ const meta$89 = defineMeta({
39
39
  name: "ai-action-ledger",
40
40
  title: "AI Action Ledger",
41
41
  description: "What an agent actually did, classified by what can be undone.",
@@ -48,7 +48,7 @@ const meta$75 = defineMeta({
48
48
  });
49
49
  //#endregion
50
50
  //#region ../ui/dist/components/ai-agent-plan/meta.js
51
- const meta$74 = defineMeta({
51
+ const meta$88 = defineMeta({
52
52
  name: "ai-agent-plan",
53
53
  title: "AI Agent Plan",
54
54
  description: "What an agent intends to do — including when it changes its mind mid-run.",
@@ -61,7 +61,7 @@ const meta$74 = defineMeta({
61
61
  });
62
62
  //#endregion
63
63
  //#region ../ui/dist/components/ai-agent-status/meta.js
64
- const meta$73 = defineMeta({
64
+ const meta$87 = defineMeta({
65
65
  name: "ai-agent-status",
66
66
  title: "AI Agent Status",
67
67
  description: "A pill showing what an agent is doing, in words as well as colour.",
@@ -74,7 +74,7 @@ const meta$73 = defineMeta({
74
74
  });
75
75
  //#endregion
76
76
  //#region ../ui/dist/components/ai-approval-request/meta.js
77
- const meta$72 = defineMeta({
77
+ const meta$86 = defineMeta({
78
78
  name: "ai-approval-request",
79
79
  title: "AI Approval Request",
80
80
  description: "Approve a tool call — after correcting the arguments the model got wrong.",
@@ -87,7 +87,7 @@ const meta$72 = defineMeta({
87
87
  });
88
88
  //#endregion
89
89
  //#region ../ui/dist/components/ai-conversation/meta.js
90
- const meta$71 = defineMeta({
90
+ const meta$85 = defineMeta({
91
91
  name: "ai-conversation",
92
92
  title: "AI Conversation",
93
93
  description: "The scrolling transcript container, with follow-on-new-content and a status region.",
@@ -100,7 +100,7 @@ const meta$71 = defineMeta({
100
100
  });
101
101
  //#endregion
102
102
  //#region ../ui/dist/components/ai-disclosure/meta.js
103
- const meta$70 = defineMeta({
103
+ const meta$84 = defineMeta({
104
104
  name: "ai-disclosure",
105
105
  title: "AI Disclosure",
106
106
  description: "Tells a reader they are looking at AI, and what is actually known about it.",
@@ -113,7 +113,7 @@ const meta$70 = defineMeta({
113
113
  });
114
114
  //#endregion
115
115
  //#region ../ui/dist/components/ai-extraction-review/meta.js
116
- const meta$69 = defineMeta({
116
+ const meta$83 = defineMeta({
117
117
  name: "ai-extraction-review",
118
118
  title: "AI Extraction Review",
119
119
  description: "Check extracted fields against the document they came from, and decide each one.",
@@ -126,7 +126,7 @@ const meta$69 = defineMeta({
126
126
  });
127
127
  //#endregion
128
128
  //#region ../ui/dist/components/ai-inline-completion/meta.js
129
- const meta$68 = defineMeta({
129
+ const meta$82 = defineMeta({
130
130
  name: "ai-inline-completion",
131
131
  title: "AI Inline Completion",
132
132
  description: "Ghost-text suggestion inside a real textarea, accepted with Tab.",
@@ -139,7 +139,7 @@ const meta$68 = defineMeta({
139
139
  });
140
140
  //#endregion
141
141
  //#region ../ui/dist/components/ai-message/meta.js
142
- const meta$67 = defineMeta({
142
+ const meta$81 = defineMeta({
143
143
  name: "ai-message",
144
144
  title: "AI Message",
145
145
  description: "One turn in a conversation, with role, avatar, actions and footer slots.",
@@ -152,7 +152,7 @@ const meta$67 = defineMeta({
152
152
  });
153
153
  //#endregion
154
154
  //#region ../ui/dist/components/ai-model-selector/meta.js
155
- const meta$66 = defineMeta({
155
+ const meta$80 = defineMeta({
156
156
  name: "ai-model-selector",
157
157
  title: "AI Model Selector",
158
158
  description: "Picks the model a conversation runs on, with descriptions and availability.",
@@ -165,7 +165,7 @@ const meta$66 = defineMeta({
165
165
  });
166
166
  //#endregion
167
167
  //#region ../ui/dist/components/ai-prompt-input/meta.js
168
- const meta$65 = defineMeta({
168
+ const meta$79 = defineMeta({
169
169
  name: "ai-prompt-input",
170
170
  title: "AI Prompt Input",
171
171
  description: "The composer: auto-growing textarea, send-on-Enter, and a send/stop control.",
@@ -178,7 +178,7 @@ const meta$65 = defineMeta({
178
178
  });
179
179
  //#endregion
180
180
  //#region ../ui/dist/components/ai-reasoning/meta.js
181
- const meta$64 = defineMeta({
181
+ const meta$78 = defineMeta({
182
182
  name: "ai-reasoning",
183
183
  title: "AI Reasoning",
184
184
  description: "A collapsible disclosure for the model's reasoning.",
@@ -191,7 +191,7 @@ const meta$64 = defineMeta({
191
191
  });
192
192
  //#endregion
193
193
  //#region ../ui/dist/components/ai-response/meta.js
194
- const meta$63 = defineMeta({
194
+ const meta$77 = defineMeta({
195
195
  name: "ai-response",
196
196
  title: "AI Response",
197
197
  description: "Assistant response text, with a streaming caret and a thinking indicator.",
@@ -204,7 +204,7 @@ const meta$63 = defineMeta({
204
204
  });
205
205
  //#endregion
206
206
  //#region ../ui/dist/components/ai-sources/meta.js
207
- const meta$62 = defineMeta({
207
+ const meta$76 = defineMeta({
208
208
  name: "ai-sources",
209
209
  title: "AI Sources",
210
210
  description: "Inline citation markers and the source list they refer to.",
@@ -217,7 +217,7 @@ const meta$62 = defineMeta({
217
217
  });
218
218
  //#endregion
219
219
  //#region ../ui/dist/components/ai-structured-output/meta.js
220
- const meta$61 = defineMeta({
220
+ const meta$75 = defineMeta({
221
221
  name: "ai-structured-output",
222
222
  title: "AI Structured Output",
223
223
  description: "An object arriving field by field from the model, without the layout jumping.",
@@ -230,7 +230,7 @@ const meta$61 = defineMeta({
230
230
  });
231
231
  //#endregion
232
232
  //#region ../ui/dist/components/ai-suggested-value/meta.js
233
- const meta$60 = defineMeta({
233
+ const meta$74 = defineMeta({
234
234
  name: "ai-suggested-value",
235
235
  title: "AI Suggested Value",
236
236
  description: "An AI-proposed value for any form control, pending until accepted and marked afterwards.",
@@ -243,7 +243,7 @@ const meta$60 = defineMeta({
243
243
  });
244
244
  //#endregion
245
245
  //#region ../ui/dist/components/ai-token-usage/meta.js
246
- const meta$59 = defineMeta({
246
+ const meta$73 = defineMeta({
247
247
  name: "ai-token-usage",
248
248
  title: "AI Token Usage",
249
249
  description: "A gauge showing how much of the context window a conversation has used.",
@@ -256,7 +256,7 @@ const meta$59 = defineMeta({
256
256
  });
257
257
  //#endregion
258
258
  //#region ../ui/dist/components/ai-tool/meta.js
259
- const meta$58 = defineMeta({
259
+ const meta$72 = defineMeta({
260
260
  name: "ai-tool",
261
261
  title: "AI Tool Call",
262
262
  description: "A collapsible record of a tool the model called, its arguments and its result.",
@@ -269,7 +269,7 @@ const meta$58 = defineMeta({
269
269
  });
270
270
  //#endregion
271
271
  //#region ../ui/dist/components/alert/meta.js
272
- const meta$57 = defineMeta({
272
+ const meta$71 = defineMeta({
273
273
  name: "alert",
274
274
  title: "Alert",
275
275
  description: "A callout that draws attention to an important message.",
@@ -282,7 +282,7 @@ const meta$57 = defineMeta({
282
282
  });
283
283
  //#endregion
284
284
  //#region ../ui/dist/components/avatar/meta.js
285
- const meta$56 = defineMeta({
285
+ const meta$70 = defineMeta({
286
286
  name: "avatar",
287
287
  title: "Avatar",
288
288
  description: "An image representation of a user or entity with a graceful text fallback.",
@@ -295,7 +295,7 @@ const meta$56 = defineMeta({
295
295
  });
296
296
  //#endregion
297
297
  //#region ../ui/dist/components/badge/meta.js
298
- const meta$55 = defineMeta({
298
+ const meta$69 = defineMeta({
299
299
  name: "badge",
300
300
  title: "Badge",
301
301
  description: "A compact marker for status, counts and categories.",
@@ -307,8 +307,21 @@ const meta$55 = defineMeta({
307
307
  a11y: "The badge label must convey the meaning on its own; variant colour is decoration. Use asChild to render an interactive badge as a link or button rather than adding handlers."
308
308
  });
309
309
  //#endregion
310
+ //#region ../ui/dist/components/breadcrumb/meta.js
311
+ const meta$68 = defineMeta({
312
+ name: "breadcrumb",
313
+ title: "Breadcrumb",
314
+ description: "Where the current page sits in the hierarchy, and how to get back up it.",
315
+ category: "navigation",
316
+ status: "stable",
317
+ dependencies: ["radix-ui"],
318
+ registryDependencies: [],
319
+ files: ["breadcrumb.tsx"],
320
+ a11y: "The current page is a span carrying aria-current=\"page\", not a link: a link to the page you are already on does nothing, and in a list of links it is indistinguishable from the ones that go somewhere. Separators are hidden from assistive technology, because the list already conveys the sequence and reading \"slash\" between every item is the design's punctuation leaking into the content. The ellipsis is the exception and is named, because it is content: it says levels have been left out."
321
+ });
322
+ //#endregion
310
323
  //#region ../ui/dist/components/button/meta.js
311
- const meta$54 = defineMeta({
324
+ const meta$67 = defineMeta({
312
325
  name: "button",
313
326
  title: "Button",
314
327
  description: "Triggers an action or event, with variants for every level of emphasis.",
@@ -321,7 +334,7 @@ const meta$54 = defineMeta({
321
334
  });
322
335
  //#endregion
323
336
  //#region ../ui/dist/components/calendar/meta.js
324
- const meta$53 = defineMeta({
337
+ const meta$66 = defineMeta({
325
338
  name: "calendar",
326
339
  title: "Calendar",
327
340
  description: "A date grid for selecting a day, several days or a range.",
@@ -334,7 +347,7 @@ const meta$53 = defineMeta({
334
347
  });
335
348
  //#endregion
336
349
  //#region ../ui/dist/components/card/meta.js
337
- const meta$52 = defineMeta({
350
+ const meta$65 = defineMeta({
338
351
  name: "card",
339
352
  title: "Card",
340
353
  description: "A surface that groups related content and actions into a single block.",
@@ -347,7 +360,7 @@ const meta$52 = defineMeta({
347
360
  });
348
361
  //#endregion
349
362
  //#region ../ui/dist/components/checkbox/meta.js
350
- const meta$51 = defineMeta({
363
+ const meta$64 = defineMeta({
351
364
  name: "checkbox",
352
365
  title: "Checkbox",
353
366
  description: "A control for an on/off choice, with support for an indeterminate state.",
@@ -360,7 +373,7 @@ const meta$51 = defineMeta({
360
373
  });
361
374
  //#endregion
362
375
  //#region ../ui/dist/components/code-block/meta.js
363
- const meta$50 = defineMeta({
376
+ const meta$63 = defineMeta({
364
377
  name: "code-block",
365
378
  title: "Code Block",
366
379
  description: "A block of code with a copy control, ready for any highlighter.",
@@ -372,8 +385,21 @@ const meta$50 = defineMeta({
372
385
  a11y: "The pre is a focusable named region, since code overflows horizontally and an unfocusable scroll box is unreachable by keyboard. Copying is announced through a polite live region as well as shown, and a refused clipboard write reports failure rather than looking like success."
373
386
  });
374
387
  //#endregion
388
+ //#region ../ui/dist/components/collapsible/meta.js
389
+ const meta$62 = defineMeta({
390
+ name: "collapsible",
391
+ title: "Collapsible",
392
+ description: "A single section that opens and closes, without an accordion's set semantics.",
393
+ category: "layout",
394
+ status: "stable",
395
+ dependencies: ["radix-ui"],
396
+ registryDependencies: [],
397
+ files: ["collapsible.tsx"],
398
+ a11y: "The trigger carries aria-expanded and points at the region it controls, both from the primitive. Reach for this rather than an Accordion of one item: a single-item Accordion gives its trigger a heading role and a position in a list of one, neither of which is true."
399
+ });
400
+ //#endregion
375
401
  //#region ../ui/dist/components/combobox/meta.js
376
- const meta$49 = defineMeta({
402
+ const meta$61 = defineMeta({
377
403
  name: "combobox",
378
404
  title: "Combobox",
379
405
  description: "A searchable single-select built on the ARIA combobox pattern.",
@@ -386,7 +412,7 @@ const meta$49 = defineMeta({
386
412
  });
387
413
  //#endregion
388
414
  //#region ../ui/dist/components/command/meta.js
389
- const meta$48 = defineMeta({
415
+ const meta$60 = defineMeta({
390
416
  name: "command",
391
417
  title: "Command",
392
418
  description: "A searchable command palette, with groups and a ⌘K dialog variant.",
@@ -399,7 +425,7 @@ const meta$48 = defineMeta({
399
425
  });
400
426
  //#endregion
401
427
  //#region ../ui/dist/components/confirm-typed/meta.js
402
- const meta$47 = defineMeta({
428
+ const meta$59 = defineMeta({
403
429
  name: "confirm-typed",
404
430
  title: "Confirm Typed",
405
431
  description: "Type the name to confirm — and be told, not ignored, when it does not match.",
@@ -412,7 +438,7 @@ const meta$47 = defineMeta({
412
438
  });
413
439
  //#endregion
414
440
  //#region ../ui/dist/components/cron-editor/meta.js
415
- const meta$46 = defineMeta({
441
+ const meta$58 = defineMeta({
416
442
  name: "cron-editor",
417
443
  title: "Cron Editor",
418
444
  description: "A schedule as a cron expression, with a plain-language reading and the next runs.",
@@ -425,7 +451,7 @@ const meta$46 = defineMeta({
425
451
  });
426
452
  //#endregion
427
453
  //#region ../ui/dist/components/data-table/meta.js
428
- const meta$45 = defineMeta({
454
+ const meta$57 = defineMeta({
429
455
  name: "data-table",
430
456
  title: "Data Table",
431
457
  description: "Presentation for a TanStack Table instance: sorting, column visibility and pagination.",
@@ -443,7 +469,7 @@ const meta$45 = defineMeta({
443
469
  });
444
470
  //#endregion
445
471
  //#region ../ui/dist/components/date-picker/meta.js
446
- const meta$44 = defineMeta({
472
+ const meta$56 = defineMeta({
447
473
  name: "date-picker",
448
474
  title: "Date Picker",
449
475
  description: "A button that opens a calendar to pick a date or a date range.",
@@ -459,8 +485,21 @@ const meta$44 = defineMeta({
459
485
  a11y: "The trigger states the selected date, formatted for the locale, so its accessible name changes with the value. The popover is named because it carries role=\"dialog\". Selecting a single date closes the popover and returns focus to the trigger; a range stays open, since one click is only half an answer. Offer a typed input alongside it for dates the user already knows."
460
486
  });
461
487
  //#endregion
488
+ //#region ../ui/dist/components/direction/meta.js
489
+ const meta$55 = defineMeta({
490
+ name: "direction",
491
+ title: "Direction Provider",
492
+ description: "Tells the component primitives which way the writing runs, so menus and sliders mirror with the rest of the page.",
493
+ category: "foundation",
494
+ status: "stable",
495
+ dependencies: ["radix-ui"],
496
+ registryDependencies: [],
497
+ files: ["direction.tsx"],
498
+ a11y: "Needed only for right-to-left languages, and needed in addition to `dir` on the document rather than instead of it. The styling here is written with logical properties and follows `dir` by itself; the primitives underneath read direction from React context and assume left-to-right without a provider, which mirrors a page correctly except for its menus, selects and sliders — worse than not mirroring at all, because it looks deliberate."
499
+ });
500
+ //#endregion
462
501
  //#region ../ui/dist/components/dialog/meta.js
463
- const meta$43 = defineMeta({
502
+ const meta$54 = defineMeta({
464
503
  name: "dialog",
465
504
  title: "Dialog",
466
505
  description: "A modal window that interrupts the user to gather a response.",
@@ -473,7 +512,7 @@ const meta$43 = defineMeta({
473
512
  });
474
513
  //#endregion
475
514
  //#region ../ui/dist/components/diff-viewer/meta.js
476
- const meta$42 = defineMeta({
515
+ const meta$53 = defineMeta({
477
516
  name: "diff-viewer",
478
517
  title: "Diff Viewer",
479
518
  description: "A diff you can style, and accept or reject hunk by hunk.",
@@ -486,7 +525,7 @@ const meta$42 = defineMeta({
486
525
  });
487
526
  //#endregion
488
527
  //#region ../ui/dist/components/dns-record/meta.js
489
- const meta$41 = defineMeta({
528
+ const meta$52 = defineMeta({
490
529
  name: "dns-record",
491
530
  title: "DNS Record",
492
531
  description: "Add this record at your provider: parts copied separately, checked with what was found.",
@@ -499,7 +538,7 @@ const meta$41 = defineMeta({
499
538
  });
500
539
  //#endregion
501
540
  //#region ../ui/dist/components/drawer/meta.js
502
- const meta$40 = defineMeta({
541
+ const meta$51 = defineMeta({
503
542
  name: "drawer",
504
543
  title: "Drawer",
505
544
  description: "A bottom sheet that can be dismissed by dragging it down.",
@@ -512,7 +551,7 @@ const meta$40 = defineMeta({
512
551
  });
513
552
  //#endregion
514
553
  //#region ../ui/dist/components/dropdown-menu/meta.js
515
- const meta$39 = defineMeta({
554
+ const meta$50 = defineMeta({
516
555
  name: "dropdown-menu",
517
556
  title: "Dropdown Menu",
518
557
  description: "A menu of actions revealed from a trigger, with submenus and selectable items.",
@@ -525,7 +564,7 @@ const meta$39 = defineMeta({
525
564
  });
526
565
  //#endregion
527
566
  //#region ../ui/dist/components/empty-state/meta.js
528
- const meta$38 = defineMeta({
567
+ const meta$49 = defineMeta({
529
568
  name: "empty-state",
530
569
  title: "Empty State",
531
570
  description: "Shown where content would be, explaining why it is empty and what to do next.",
@@ -538,7 +577,7 @@ const meta$38 = defineMeta({
538
577
  });
539
578
  //#endregion
540
579
  //#region ../ui/dist/components/file-upload/meta.js
541
- const meta$37 = defineMeta({
580
+ const meta$48 = defineMeta({
542
581
  name: "file-upload",
543
582
  title: "File Upload",
544
583
  description: "A dropzone over a real file input, plus the upload queue nobody ships.",
@@ -551,7 +590,7 @@ const meta$37 = defineMeta({
551
590
  });
552
591
  //#endregion
553
592
  //#region ../ui/dist/components/form/meta.js
554
- const meta$36 = defineMeta({
593
+ const meta$47 = defineMeta({
555
594
  name: "form",
556
595
  title: "Form",
557
596
  description: "Accessible field wiring that works with any form library, or none.",
@@ -564,7 +603,7 @@ const meta$36 = defineMeta({
564
603
  });
565
604
  //#endregion
566
605
  //#region ../ui/dist/components/input/meta.js
567
- const meta$35 = defineMeta({
606
+ const meta$46 = defineMeta({
568
607
  name: "input",
569
608
  title: "Input",
570
609
  description: "A single-line text field with size variants and native validation styling.",
@@ -577,7 +616,7 @@ const meta$35 = defineMeta({
577
616
  });
578
617
  //#endregion
579
618
  //#region ../ui/dist/components/label/meta.js
580
- const meta$34 = defineMeta({
619
+ const meta$45 = defineMeta({
581
620
  name: "label",
582
621
  title: "Label",
583
622
  description: "An accessible caption that associates text with a form control.",
@@ -590,7 +629,7 @@ const meta$34 = defineMeta({
590
629
  });
591
630
  //#endregion
592
631
  //#region ../ui/dist/components/log-viewer/meta.js
593
- const meta$33 = defineMeta({
632
+ const meta$44 = defineMeta({
594
633
  name: "log-viewer",
595
634
  title: "Log Viewer",
596
635
  description: "A streaming console with filtering, level facets and follow mode.",
@@ -603,7 +642,7 @@ const meta$33 = defineMeta({
603
642
  });
604
643
  //#endregion
605
644
  //#region ../ui/dist/components/meter/meta.js
606
- const meta$32 = defineMeta({
645
+ const meta$43 = defineMeta({
607
646
  name: "meter",
608
647
  title: "Meter",
609
648
  description: "A measurement against a capacity — quota, seats, spend — segmented by category.",
@@ -616,7 +655,7 @@ const meta$32 = defineMeta({
616
655
  });
617
656
  //#endregion
618
657
  //#region ../ui/dist/components/metric-delta/meta.js
619
- const meta$31 = defineMeta({
658
+ const meta$42 = defineMeta({
620
659
  name: "metric-delta",
621
660
  title: "Metric Delta",
622
661
  description: "A headline number with a change indicator that knows which direction is good.",
@@ -629,7 +668,7 @@ const meta$31 = defineMeta({
629
668
  });
630
669
  //#endregion
631
670
  //#region ../ui/dist/components/pagination/meta.js
632
- const meta$30 = defineMeta({
671
+ const meta$41 = defineMeta({
633
672
  name: "pagination",
634
673
  title: "Pagination",
635
674
  description: "Navigation between pages of a list.",
@@ -642,7 +681,7 @@ const meta$30 = defineMeta({
642
681
  });
643
682
  //#endregion
644
683
  //#region ../ui/dist/components/permission-matrix/meta.js
645
- const meta$29 = defineMeta({
684
+ const meta$40 = defineMeta({
646
685
  name: "permission-matrix",
647
686
  title: "Permission Matrix",
648
687
  description: "Roles across, permissions down, with inheritance, locked roles and one tab stop.",
@@ -655,7 +694,7 @@ const meta$29 = defineMeta({
655
694
  });
656
695
  //#endregion
657
696
  //#region ../ui/dist/components/popover/meta.js
658
- const meta$28 = defineMeta({
697
+ const meta$39 = defineMeta({
659
698
  name: "popover",
660
699
  title: "Popover",
661
700
  description: "Rich floating content anchored to a trigger.",
@@ -668,7 +707,7 @@ const meta$28 = defineMeta({
668
707
  });
669
708
  //#endregion
670
709
  //#region ../ui/dist/components/progress/meta.js
671
- const meta$27 = defineMeta({
710
+ const meta$38 = defineMeta({
672
711
  name: "progress",
673
712
  title: "Progress",
674
713
  description: "Shows how far along a task is, or that one is running at all.",
@@ -681,7 +720,7 @@ const meta$27 = defineMeta({
681
720
  });
682
721
  //#endregion
683
722
  //#region ../ui/dist/components/radio-group/meta.js
684
- const meta$26 = defineMeta({
723
+ const meta$37 = defineMeta({
685
724
  name: "radio-group",
686
725
  title: "Radio Group",
687
726
  description: "A set of mutually exclusive options.",
@@ -694,7 +733,7 @@ const meta$26 = defineMeta({
694
733
  });
695
734
  //#endregion
696
735
  //#region ../ui/dist/components/record-diff/meta.js
697
- const meta$25 = defineMeta({
736
+ const meta$36 = defineMeta({
698
737
  name: "record-diff",
699
738
  title: "Record Diff",
700
739
  description: "Field-level before and after, for audit entries, settings history and revisions.",
@@ -707,7 +746,7 @@ const meta$25 = defineMeta({
707
746
  });
708
747
  //#endregion
709
748
  //#region ../ui/dist/components/secret-field/meta.js
710
- const meta$24 = defineMeta({
749
+ const meta$35 = defineMeta({
711
750
  name: "secret-field",
712
751
  title: "Secret Field",
713
752
  description: "An API key in its three states: shown once, hidden but revealable, and gone.",
@@ -720,7 +759,7 @@ const meta$24 = defineMeta({
720
759
  });
721
760
  //#endregion
722
761
  //#region ../ui/dist/components/select/meta.js
723
- const meta$23 = defineMeta({
762
+ const meta$34 = defineMeta({
724
763
  name: "select",
725
764
  title: "Select",
726
765
  description: "Picks one value from a short list of options.",
@@ -733,7 +772,7 @@ const meta$23 = defineMeta({
733
772
  });
734
773
  //#endregion
735
774
  //#region ../ui/dist/components/separator/meta.js
736
- const meta$22 = defineMeta({
775
+ const meta$33 = defineMeta({
737
776
  name: "separator",
738
777
  title: "Separator",
739
778
  description: "A horizontal or vertical rule that divides content.",
@@ -746,7 +785,7 @@ const meta$22 = defineMeta({
746
785
  });
747
786
  //#endregion
748
787
  //#region ../ui/dist/components/session-expiry/meta.js
749
- const meta$21 = defineMeta({
788
+ const meta$32 = defineMeta({
750
789
  name: "session-expiry",
751
790
  title: "Session Expiry",
752
791
  description: "The idle-timeout warning WCAG 2.2.1 asks for: warned, extendable, and not dismissable by accident.",
@@ -758,8 +797,21 @@ const meta$21 = defineMeta({
758
797
  a11y: "An alert dialog, named by its heading and described by the sentence that says how long is left. Escape and the backdrop do nothing, because dismissing a session warning without choosing is choosing nothing; the two buttons are the way out, and focus opens on the safe one. The visible countdown is not live — a number every second for two minutes drowns the question — and a separate status region speaks four times: when the warning opens, at one minute, thirty seconds and ten, still saying a threshold a slow tick skipped over. The clock is read in an effect, so the server renders nothing rather than a countdown from the wrong instant. This satisfies the warn-and-extend half of WCAG 2.2.1 Timing Adjustable; the twenty-second minimum is the default window's business and the application's."
759
798
  });
760
799
  //#endregion
800
+ //#region ../ui/dist/components/sidebar/meta.js
801
+ const meta$31 = defineMeta({
802
+ name: "sidebar",
803
+ title: "Sidebar",
804
+ description: "The application's own navigation: a collapsible rail on a wide screen, an overlay on a narrow one.",
805
+ category: "navigation",
806
+ status: "stable",
807
+ dependencies: ["radix-ui"],
808
+ registryDependencies: ["sheet"],
809
+ files: ["sidebar.tsx"],
810
+ a11y: "The navigation landmark must be named — a page has several, and three regions all called \"navigation\" is a list nobody can choose from. The active entry carries aria-current=\"page\" rather than only a background colour. On a narrow screen it is a Sheet, not a styled div: an overlay needs a focus trap and an Escape key, and without them the page behind stays reachable by Tab while the menu covers it. When the rail collapses, labels are visually hidden rather than removed — removing them leaves controls whose only content is an icon, which is how a collapsed sidebar becomes a column of links all announced as \"link\". The trigger says what pressing it will do, not what the state currently is. The overlay is mounted only on a narrow screen and has its own open state: a modal dialog that CSS hides is still modal, and mounting it always made every wide screen aria-hidden and unclickable whenever the rail was open."
811
+ });
812
+ //#endregion
761
813
  //#region ../ui/dist/components/sheet/meta.js
762
- const meta$20 = defineMeta({
814
+ const meta$30 = defineMeta({
763
815
  name: "sheet",
764
816
  title: "Sheet",
765
817
  description: "A panel that enters from an edge of the viewport for secondary content.",
@@ -772,7 +824,7 @@ const meta$20 = defineMeta({
772
824
  });
773
825
  //#endregion
774
826
  //#region ../ui/dist/components/shortcut-recorder/meta.js
775
- const meta$19 = defineMeta({
827
+ const meta$29 = defineMeta({
776
828
  name: "shortcut-recorder",
777
829
  title: "Shortcut Recorder",
778
830
  description: "Press the keys you want: records a chord, platform-aware, and says when it clashes.",
@@ -785,7 +837,7 @@ const meta$19 = defineMeta({
785
837
  });
786
838
  //#endregion
787
839
  //#region ../ui/dist/components/skeleton/meta.js
788
- const meta$18 = defineMeta({
840
+ const meta$28 = defineMeta({
789
841
  name: "skeleton",
790
842
  title: "Skeleton",
791
843
  description: "A shaped placeholder that holds layout while content loads.",
@@ -798,7 +850,7 @@ const meta$18 = defineMeta({
798
850
  });
799
851
  //#endregion
800
852
  //#region ../ui/dist/components/slider/meta.js
801
- const meta$17 = defineMeta({
853
+ const meta$27 = defineMeta({
802
854
  name: "slider",
803
855
  title: "Slider",
804
856
  description: "Selects a value, or a range, from a continuous span.",
@@ -811,7 +863,7 @@ const meta$17 = defineMeta({
811
863
  });
812
864
  //#endregion
813
865
  //#region ../ui/dist/components/spinner/meta.js
814
- const meta$16 = defineMeta({
866
+ const meta$26 = defineMeta({
815
867
  name: "spinner",
816
868
  title: "Spinner",
817
869
  description: "An indeterminate loading indicator for buttons, panels and inline content.",
@@ -824,7 +876,7 @@ const meta$16 = defineMeta({
824
876
  });
825
877
  //#endregion
826
878
  //#region ../ui/dist/components/switch/meta.js
827
- const meta$15 = defineMeta({
879
+ const meta$25 = defineMeta({
828
880
  name: "switch",
829
881
  title: "Switch",
830
882
  description: "An immediate on/off toggle for settings that apply straight away.",
@@ -837,7 +889,7 @@ const meta$15 = defineMeta({
837
889
  });
838
890
  //#endregion
839
891
  //#region ../ui/dist/components/sync-status/meta.js
840
- const meta$14 = defineMeta({
892
+ const meta$24 = defineMeta({
841
893
  name: "sync-status",
842
894
  title: "Sync Status",
843
895
  description: "Offline, saving, saved or failed — with the count of changes being held.",
@@ -850,7 +902,7 @@ const meta$14 = defineMeta({
850
902
  });
851
903
  //#endregion
852
904
  //#region ../ui/dist/components/table/meta.js
853
- const meta$13 = defineMeta({
905
+ const meta$23 = defineMeta({
854
906
  name: "table",
855
907
  title: "Table",
856
908
  description: "Semantic table primitives for tabular data.",
@@ -863,7 +915,7 @@ const meta$13 = defineMeta({
863
915
  });
864
916
  //#endregion
865
917
  //#region ../ui/dist/components/tabs/meta.js
866
- const meta$12 = defineMeta({
918
+ const meta$22 = defineMeta({
867
919
  name: "tabs",
868
920
  title: "Tabs",
869
921
  description: "Switches between panels of related content.",
@@ -876,7 +928,7 @@ const meta$12 = defineMeta({
876
928
  });
877
929
  //#endregion
878
930
  //#region ../ui/dist/components/tags-input/meta.js
879
- const meta$11 = defineMeta({
931
+ const meta$21 = defineMeta({
880
932
  name: "tags-input",
881
933
  title: "Tags Input",
882
934
  description: "A list of short values, where invalid entries stay visible instead of vanishing.",
@@ -889,7 +941,7 @@ const meta$11 = defineMeta({
889
941
  });
890
942
  //#endregion
891
943
  //#region ../ui/dist/components/time-range-picker/meta.js
892
- const meta$10 = defineMeta({
944
+ const meta$20 = defineMeta({
893
945
  name: "time-range-picker",
894
946
  title: "Time Range Picker",
895
947
  description: "A time range whose value is an expression, so it stays relative across a reload.",
@@ -906,8 +958,21 @@ const meta$10 = defineMeta({
906
958
  a11y: "The trigger is named by the range it holds — \"Last 6 hours\" — and the window that resolves to is read after it, so the relative choice is not replaced by two timestamps. The popover carries role=\"dialog\" and is named. Presets are buttons rather than radios because choosing one both selects and dismisses, with aria-pressed carrying which matches the current expression. The expression field reports why an unparseable entry is invalid through one aria-describedby element that the preview and the error share, so a reader hears the error replace the preview rather than both at once; an invalid expression is never applied, because a chart silently re-scoping itself is worse than one that refuses."
907
959
  });
908
960
  //#endregion
961
+ //#region ../ui/dist/components/textarea/meta.js
962
+ const meta$19 = defineMeta({
963
+ name: "textarea",
964
+ title: "Textarea",
965
+ description: "A multi-line text field, with optional auto-resize and a character count that knows when to stay quiet.",
966
+ category: "form",
967
+ status: "stable",
968
+ dependencies: ["class-variance-authority"],
969
+ registryDependencies: [],
970
+ files: ["textarea.tsx"],
971
+ a11y: "Pair with a Label via htmlFor/id. The error state is driven by aria-invalid, so assistive technology and styling stay in sync. The character count is described by the field rather than announced on every keystroke — a permanently live counter reads the remaining number between every letter typed, which is unusable — so it goes live only once the limit is close, and states the remainder in words rather than as a bare ratio that is read aloud as two unlabelled numbers. Horizontal resizing is off by default, because a field dragged wider than its container is a broken layout."
972
+ });
973
+ //#endregion
909
974
  //#region ../ui/dist/components/toast/meta.js
910
- const meta$9 = defineMeta({
975
+ const meta$18 = defineMeta({
911
976
  name: "toast",
912
977
  title: "Toast",
913
978
  description: "Brief, non-blocking messages with an imperative API callable from anywhere.",
@@ -920,7 +985,7 @@ const meta$9 = defineMeta({
920
985
  });
921
986
  //#endregion
922
987
  //#region ../ui/dist/components/tooltip/meta.js
923
- const meta$8 = defineMeta({
988
+ const meta$17 = defineMeta({
924
989
  name: "tooltip",
925
990
  title: "Tooltip",
926
991
  description: "A short label revealed on hover or keyboard focus.",
@@ -943,6 +1008,31 @@ const meta$8 = defineMeta({
943
1008
  * `meta.test.ts` fails if a block directory exists that is missing from here.
944
1009
  */
945
1010
  const blockMetas = [
1011
+ defineMeta({
1012
+ name: "admin-dashboard",
1013
+ kind: "block",
1014
+ title: "Admin dashboard",
1015
+ description: "An administration console: the shell every admin page shares — navigation, breadcrumb, account menu — and the overview that is its front page, with what needs attention first.",
1016
+ category: "layout",
1017
+ status: "stable",
1018
+ access: "pro",
1019
+ dependencies: [],
1020
+ registryDependencies: [
1021
+ "alert",
1022
+ "avatar",
1023
+ "badge",
1024
+ "breadcrumb",
1025
+ "button",
1026
+ "card",
1027
+ "dropdown-menu",
1028
+ "empty-state",
1029
+ "metric-delta",
1030
+ "sidebar",
1031
+ "table"
1032
+ ],
1033
+ files: ["admin-dashboard.tsx"],
1034
+ a11y: "What needs attention comes first and is the only loud part of the page; it is not a live region, because the list is there on load and re-announcing it on every refresh would make the console unusable. The navigation is a landmark called Admin, the breadcrumb another, so neither is one more thing called 'navigation'. The current page carries aria-current, a count beside a nav item says what it counts, the account menu is named after its owner, and each Open button is named after its account. Every status is a word, with colour agreeing rather than replacing."
1035
+ }),
946
1036
  defineMeta({
947
1037
  name: "admin-users",
948
1038
  kind: "block",
@@ -964,6 +1054,27 @@ const blockMetas = [
964
1054
  files: ["admin-users.tsx"],
965
1055
  a11y: "Filtering changes the results without the user asking, so the matching count is announced politely. The filter has a real label rather than only a placeholder, which disappears the moment anyone types. Each row's action button is named after its row — four identical \"Actions\" buttons say nothing about which row you are on."
966
1056
  }),
1057
+ defineMeta({
1058
+ name: "agent-console",
1059
+ kind: "block",
1060
+ title: "Agent console",
1061
+ description: "One agent run, watched: the plan it is working from, the approval it is blocked on, and the ledger of what it has already done.",
1062
+ category: "ai",
1063
+ status: "stable",
1064
+ dependencies: [],
1065
+ registryDependencies: [
1066
+ "ai-action-ledger",
1067
+ "ai-agent-plan",
1068
+ "ai-agent-status",
1069
+ "ai-approval-request",
1070
+ "ai-token-usage",
1071
+ "button",
1072
+ "card",
1073
+ "empty-state"
1074
+ ],
1075
+ files: ["agent-console.tsx"],
1076
+ a11y: "Whatever the run is blocked on is rendered first rather than below a scrolling plan, because it is the only part of the page waiting on a person. This is the one agent on the page, so its status announces its own transitions — a list of runs each doing that would be noise, which is why the underlying component makes it opt in. Every completed action states whether it can be undone, offset or not taken back at all, in words, since presenting all three behind one Undo is a lie discovered after the click."
1077
+ }),
967
1078
  defineMeta({
968
1079
  name: "ai-chat",
969
1080
  kind: "block",
@@ -988,6 +1099,137 @@ const blockMetas = [
988
1099
  files: ["ai-chat.tsx"],
989
1100
  a11y: "Assembled from the AI components rather than reimplementing them, so their decisions still hold: the transcript is a list and not a live region, state is announced separately through ConversationStatus, and the composer will not send while an IME composition is active. Tool payloads are named per tool, so two open tool calls do not present two regions called \"Result\"."
990
1101
  }),
1102
+ defineMeta({
1103
+ name: "ai-dashboard",
1104
+ kind: "block",
1105
+ title: "AI dashboard",
1106
+ description: "What the AI features cost and whether they worked: tokens, spend, failure rate, a breakdown by model, and the runs still going.",
1107
+ category: "ai",
1108
+ status: "stable",
1109
+ dependencies: [],
1110
+ registryDependencies: [
1111
+ "ai-agent-status",
1112
+ "ai-token-usage",
1113
+ "card",
1114
+ "empty-state",
1115
+ "metric-delta",
1116
+ "table"
1117
+ ],
1118
+ files: ["ai-dashboard.tsx"],
1119
+ a11y: "Spend and failure rate are declared lower-is-better, so a rising bill is not painted green — which is the mistake most usage dashboards make. The totals row is a real table footer rather than a last body row that looks like one, because inside the body it is announced as another model and there is no model called Total. Statuses in the run list do not announce their own changes: several runs each doing that turns a list into a stream of interruptions, and watching one run is the agent console's job."
1120
+ }),
1121
+ defineMeta({
1122
+ name: "ai-workspace",
1123
+ kind: "block",
1124
+ title: "AI workspace",
1125
+ description: "A whole AI application surface: conversations down one side, the active transcript with reasoning, tool calls and sources in the middle, and the context — window usage, attachments and a structured result — on the other.",
1126
+ category: "ai",
1127
+ status: "stable",
1128
+ access: "pro",
1129
+ dependencies: [],
1130
+ registryDependencies: [
1131
+ "ai-conversation",
1132
+ "ai-message",
1133
+ "ai-model-selector",
1134
+ "ai-prompt-input",
1135
+ "ai-reasoning",
1136
+ "ai-response",
1137
+ "ai-sources",
1138
+ "ai-structured-output",
1139
+ "ai-token-usage",
1140
+ "ai-tool",
1141
+ "button",
1142
+ "empty-state",
1143
+ "sidebar"
1144
+ ],
1145
+ files: ["ai-workspace.tsx"],
1146
+ a11y: "Three landmarks, each named: the conversation list is a navigation called Conversations, the transcript is the main content, and the context is a complementary region called Context, so a screen reader user can jump between them and skip the one they do not want. The transcript is a list and never a live region; the response state is announced from a separate status line, so a streaming answer does not read itself aloud token by token. Each attachment's remove button is named after its file. On a narrow screen the conversation list becomes a sheet with a focus trap and an Escape key, not a div slid over content that stays reachable by Tab."
1147
+ }),
1148
+ defineMeta({
1149
+ name: "analytics",
1150
+ kind: "block",
1151
+ title: "Analytics",
1152
+ description: "An analytics page: headline metrics against the previous period, a series over time, and the breakdown that made it up.",
1153
+ category: "data",
1154
+ status: "stable",
1155
+ dependencies: [],
1156
+ registryDependencies: [
1157
+ "button",
1158
+ "card",
1159
+ "metric-delta",
1160
+ "select",
1161
+ "table"
1162
+ ],
1163
+ files: ["analytics.tsx"],
1164
+ a11y: "The bars are declared as a single image with a one-sentence summary — where the series started, where it ended, and where its extremes were — rather than as forty separately labelled elements, which reads as noise instead of a shape. The exact numbers live in a real table that is collapsed for everyone and revealed for everyone from a control on the page, rather than in a visually-hidden copy only screen readers can reach, because the hidden copy is the one that goes stale. The range selector is a select rather than a tab set: tabs promise panels, and a range selector has none — it changes the data behind the whole page, so styled-as-tabs it points every tab at a panel that does not exist."
1165
+ }),
1166
+ defineMeta({
1167
+ name: "billing",
1168
+ kind: "block",
1169
+ title: "Billing",
1170
+ description: "A billing page: the current plan, metered usage against its limits, the payment method and the invoice history.",
1171
+ category: "data",
1172
+ status: "stable",
1173
+ dependencies: [],
1174
+ registryDependencies: [
1175
+ "badge",
1176
+ "button",
1177
+ "card",
1178
+ "empty-state",
1179
+ "progress",
1180
+ "table"
1181
+ ],
1182
+ files: ["billing.tsx"],
1183
+ a11y: "Every usage meter states where it stands in words — \"8 of 10 seats used, 2 left\", or how far over the limit it is — because a bar that turns red says nothing to a screen reader and nothing to anyone who cannot tell the colours apart; the bar itself is hidden from the accessibility tree so the same fact is not announced twice. Each invoice download is named after its invoice rather than being one of ten identical \"Download\" links, which is all a links list would show. A card's last four digits are spoken as digits instead of as a four-figure number. Dates carry a machine-readable time element."
1184
+ }),
1185
+ defineMeta({
1186
+ name: "command-center",
1187
+ kind: "block",
1188
+ title: "Command center",
1189
+ description: "Operations at a glance: service health worst-first, open incidents by severity, capacity meters, a filterable log stream, and a command palette for every action an operator reaches for.",
1190
+ category: "data",
1191
+ status: "stable",
1192
+ access: "pro",
1193
+ dependencies: [],
1194
+ registryDependencies: [
1195
+ "alert",
1196
+ "badge",
1197
+ "button",
1198
+ "card",
1199
+ "command",
1200
+ "empty-state",
1201
+ "log-viewer",
1202
+ "meter"
1203
+ ],
1204
+ files: ["command-center.tsx"],
1205
+ a11y: "The overall status is one sentence computed from the worst service, and it comes first — 'one service is down' rather than a wall of tiles to scan. It is not a live region: the page is refreshed by the application, and a status that re-announces on every poll is one nobody can work beside. Health and severity are words on every row, sorted on, with colour agreeing rather than replacing. ⌘K opens the palette but the Actions button is always visible, so the shortcut is an accelerator and not the only way in. New log lines are not read aloud unless asked."
1206
+ }),
1207
+ defineMeta({
1208
+ name: "crm",
1209
+ kind: "block",
1210
+ title: "CRM",
1211
+ description: "A sales pipeline: open value by stage, the deals in it with filtering and sorting, the win rate and cycle length, and the last few touches.",
1212
+ category: "data",
1213
+ status: "stable",
1214
+ access: "pro",
1215
+ dependencies: ["@tanstack/react-table"],
1216
+ registryDependencies: [
1217
+ "activity-feed",
1218
+ "avatar",
1219
+ "badge",
1220
+ "button",
1221
+ "card",
1222
+ "data-table",
1223
+ "empty-state",
1224
+ "input",
1225
+ "label",
1226
+ "meter",
1227
+ "metric-delta",
1228
+ "select"
1229
+ ],
1230
+ files: ["crm.tsx"],
1231
+ a11y: "The pipeline is one bar split by stage, with the same figures listed beside it as numbers, so nobody reads a proportion off a coloured segment; the meter announces the total and its legend names every stage. Sales cycle is declared lower-is-better, so a slowing pipeline is not painted green. The deal filter has a real label and announces the matching count politely, and each Open button is named after its deal rather than being one of ten identical buttons."
1232
+ }),
991
1233
  defineMeta({
992
1234
  name: "dashboard",
993
1235
  kind: "block",
@@ -1043,6 +1285,23 @@ const blockMetas = [
1043
1285
  files: ["login.tsx"],
1044
1286
  a11y: "Email and password fields carry the right type and autocomplete, so password managers and mobile keyboards behave. Field errors are tied to their inputs through the Form wiring; a server error is an assertive alert, because it arrived after the user acted and explains why nothing happened. The submit button reports its own busy state rather than going quiet."
1045
1287
  }),
1288
+ defineMeta({
1289
+ name: "onboarding",
1290
+ kind: "block",
1291
+ title: "Onboarding",
1292
+ description: "A setup checklist: what is done, which step is current, and what is blocked and why.",
1293
+ category: "feedback",
1294
+ status: "stable",
1295
+ dependencies: [],
1296
+ registryDependencies: [
1297
+ "badge",
1298
+ "button",
1299
+ "card",
1300
+ "progress"
1301
+ ],
1302
+ files: ["onboarding.tsx"],
1303
+ a11y: "Every step states its state in a word — Done, In progress, Not started, Blocked — because a green tick announces nothing and means nothing to a reader who cannot tell the colours apart; the tick and the step number are decoration on top of that. Progress is given as a count rather than only as a bar, and the bar is hidden so the same fact is not announced twice. The current step carries aria-current, so it can be found rather than merely seen. Blocked is a distinct state from not-started and says why. Each step's action is named after its step, so six buttons are not six identical \"Start\" entries in a controls list."
1304
+ }),
1046
1305
  defineMeta({
1047
1306
  name: "pricing",
1048
1307
  kind: "block",
@@ -1118,6 +1377,20 @@ const blockMetas = [
1118
1377
  * words — `switch` cannot be a binding name.
1119
1378
  */
1120
1379
  const componentMetas = [
1380
+ meta$91,
1381
+ meta$90,
1382
+ meta$89,
1383
+ meta$88,
1384
+ meta$87,
1385
+ meta$86,
1386
+ meta$85,
1387
+ meta$84,
1388
+ meta$83,
1389
+ meta$82,
1390
+ meta$81,
1391
+ meta$80,
1392
+ meta$79,
1393
+ meta$78,
1121
1394
  meta$77,
1122
1395
  meta$76,
1123
1396
  meta$75,
@@ -1140,8 +1413,8 @@ const componentMetas = [
1140
1413
  meta$58,
1141
1414
  meta$57,
1142
1415
  meta$56,
1143
- meta$55,
1144
1416
  meta$54,
1417
+ meta$55,
1145
1418
  meta$53,
1146
1419
  meta$52,
1147
1420
  meta$51,
@@ -1164,8 +1437,8 @@ const componentMetas = [
1164
1437
  meta$34,
1165
1438
  meta$33,
1166
1439
  meta$32,
1167
- meta$31,
1168
1440
  meta$30,
1441
+ meta$31,
1169
1442
  meta$29,
1170
1443
  meta$28,
1171
1444
  meta$27,
@@ -1178,16 +1451,7 @@ const componentMetas = [
1178
1451
  meta$20,
1179
1452
  meta$19,
1180
1453
  meta$18,
1181
- meta$17,
1182
- meta$16,
1183
- meta$15,
1184
- meta$14,
1185
- meta$13,
1186
- meta$12,
1187
- meta$11,
1188
- meta$10,
1189
- meta$9,
1190
- meta$8
1454
+ meta$17
1191
1455
  ];
1192
1456
  //#endregion
1193
1457
  //#region src/build.ts
@@ -1237,7 +1501,8 @@ function buildSourceItem(meta) {
1237
1501
  dependencies: meta.dependencies,
1238
1502
  registryDependencies: meta.registryDependencies,
1239
1503
  files,
1240
- a11y: meta.a11y
1504
+ a11y: meta.a11y,
1505
+ access: meta.access ?? "free"
1241
1506
  });
1242
1507
  }
1243
1508
  /**
@@ -1307,6 +1572,14 @@ function buildRegistry() {
1307
1572
  ...blockMetas.map(buildSourceItem)
1308
1573
  ];
1309
1574
  }
1575
+ /** Items whose source anyone may fetch. */
1576
+ function freeItems(items) {
1577
+ return items.filter((item) => item.access !== "pro");
1578
+ }
1579
+ /** Items whose source requires a licence. */
1580
+ function proItems(items) {
1581
+ return items.filter((item) => item.access === "pro");
1582
+ }
1310
1583
  function buildIndex(items) {
1311
1584
  const entries = items.map((item) => ({
1312
1585
  name: item.name,
@@ -1317,6 +1590,7 @@ function buildIndex(items) {
1317
1590
  status: item.status,
1318
1591
  dependencies: item.dependencies,
1319
1592
  registryDependencies: item.registryDependencies,
1593
+ access: item.access,
1320
1594
  fileCount: item.files.length
1321
1595
  }));
1322
1596
  return registryIndexSchema.parse({
@@ -1326,28 +1600,64 @@ function buildIndex(items) {
1326
1600
  items: entries
1327
1601
  });
1328
1602
  }
1603
+ /**
1604
+ * Writes the public registry.
1605
+ *
1606
+ * The index lists everything, including licensed items — that is the catalogue,
1607
+ * and an item nobody can see is an item nobody buys. What it does *not* write is
1608
+ * a licensed item's body: those files never touch the directory a CDN serves,
1609
+ * because a paywall that can be stepped around by fetching the JSON directly is
1610
+ * not a paywall. Their bodies go to `writeLicensedModule` instead, behind a
1611
+ * request the server can refuse.
1612
+ */
1329
1613
  function writeRegistry(outDir) {
1330
1614
  const items = buildRegistry();
1331
1615
  const index = buildIndex(items);
1616
+ const free = freeItems(items);
1332
1617
  rmSync(outDir, {
1333
1618
  recursive: true,
1334
1619
  force: true
1335
1620
  });
1336
1621
  mkdirSync(outDir, { recursive: true });
1337
1622
  writeFileSync(join(outDir, "index.json"), `${JSON.stringify(index, null, 2)}\n`);
1338
- for (const item of items) writeFileSync(join(outDir, `${item.name}.json`), `${JSON.stringify(item, null, 2)}\n`);
1623
+ for (const item of free) writeFileSync(join(outDir, `${item.name}.json`), `${JSON.stringify(item, null, 2)}\n`);
1339
1624
  return {
1340
1625
  items: items.length,
1341
- files: items.reduce((total, item) => total + item.files.length, 0)
1626
+ files: free.reduce((total, item) => total + item.files.length, 0),
1627
+ licensed: items.length - free.length
1342
1628
  };
1343
1629
  }
1630
+ /**
1631
+ * Writes the licensed item bodies as a TypeScript module.
1632
+ *
1633
+ * A module rather than a directory of JSON, because the server that serves
1634
+ * these runs on a platform that traces imports to decide what to deploy. A file
1635
+ * read at runtime from a path the bundler never saw is a file that is not there
1636
+ * in production — and the failure appears only once someone with a valid
1637
+ * licence tries to install something.
1638
+ */
1639
+ function writeLicensedModule(outFile) {
1640
+ const licensed = proItems(buildRegistry());
1641
+ const byName = Object.fromEntries(licensed.map((item) => [item.name, item]));
1642
+ mkdirSync(dirname(outFile), { recursive: true });
1643
+ writeFileSync(outFile, `// Generated by @dowel-ui/registry. Do not edit.
1644
+ //
1645
+ // The bodies of licensed registry items. Imported by the route that serves them
1646
+ // so the platform's dependency tracing includes them in the deployment; they are
1647
+ // deliberately absent from the public registry directory.
1648
+ import type { RegistryItem } from "@dowel-ui/registry";
1649
+
1650
+ export const licensedItems: Record<string, RegistryItem> = ${JSON.stringify(byName, null, 2)};
1651
+ `);
1652
+ return licensed.length;
1653
+ }
1344
1654
  if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL(process.argv[1]).href) {
1345
1655
  const outIndex = process.argv.indexOf("--out");
1346
1656
  const outDir = outIndex === -1 ? join(here, "..", "r") : process.argv[outIndex + 1] ?? join(here, "..", "r");
1347
1657
  const result = writeRegistry(outDir);
1348
- console.log(`Registry written to ${outDir}: ${String(result.items)} items, ${String(result.files)} files.`);
1658
+ console.log(`Registry written to ${outDir}: ${String(result.items)} items, ${String(result.files)} files` + (result.licensed > 0 ? `, ${String(result.licensed)} licensed item(s) withheld.` : "."));
1349
1659
  }
1350
1660
  //#endregion
1351
- export { buildIndex, buildRegistry, writeRegistry };
1661
+ export { buildIndex, buildRegistry, freeItems, proItems, writeLicensedModule, writeRegistry };
1352
1662
 
1353
1663
  //# sourceMappingURL=build.js.map