@kerfjs/ui 4.4.1 → 5.0.0-beta.3

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 (158) hide show
  1. package/README.md +231 -5
  2. package/ai/component-catalog.json +4467 -0
  3. package/ai/component-catalog.schema.json +79 -0
  4. package/ai/public-api-signatures-v1.md +619 -0
  5. package/ai/skill.md +64 -11
  6. package/ai/webawesome-jsx-signatures-v1.md +106 -0
  7. package/dist/app-tab.d.ts +12 -2
  8. package/dist/app-tab.js +2 -1
  9. package/dist/browser/app-tab.js +2 -2
  10. package/dist/browser/dialog-header.js +4 -2
  11. package/dist/browser/disclosure-arrow.js +4 -0
  12. package/dist/browser/empty-state.js +3 -3
  13. package/dist/browser/loading-spinner.js +2 -2
  14. package/dist/browser/lucide-icon.js +2 -2
  15. package/dist/browser/menu-action-row.js +3 -0
  16. package/dist/browser/menu-header.js +4 -2
  17. package/dist/browser/menu-item.js +2 -2
  18. package/dist/browser/page-header.js +2 -2
  19. package/dist/browser/resizable-region.js +2 -2
  20. package/dist/browser/segmented-control.js +2 -2
  21. package/dist/browser/select.js +3 -3
  22. package/dist/browser/state-banner.js +2 -2
  23. package/dist/browser/tab-bar.js +2 -2
  24. package/dist/browser/token-search-field.js +4 -0
  25. package/dist/browser/toolbar-control-group.js +2 -2
  26. package/dist/browser/toolbar-text.js +2 -2
  27. package/dist/browser/toolbar.js +2 -2
  28. package/dist/browser/value-table.js +2 -2
  29. package/dist/chunk-56RJXPHG.js +43 -0
  30. package/dist/chunk-56RJXPHG.js.map +1 -0
  31. package/dist/chunk-7BR3DO2A.js +31 -0
  32. package/dist/chunk-7BR3DO2A.js.map +1 -0
  33. package/dist/chunk-7LDCTU7D.js +134 -0
  34. package/dist/chunk-7LDCTU7D.js.map +1 -0
  35. package/dist/{chunk-4HHCYSGT.js → chunk-AQNKJRFH.js} +2 -2
  36. package/dist/{chunk-4HHCYSGT.js.map → chunk-AQNKJRFH.js.map} +1 -1
  37. package/dist/{chunk-NHXX4JI5.js → chunk-CTQKI2XL.js} +3 -3
  38. package/dist/chunk-CTQKI2XL.js.map +1 -0
  39. package/dist/chunk-EGHL5S4P.js +33 -0
  40. package/dist/chunk-EGHL5S4P.js.map +1 -0
  41. package/dist/chunk-H5AGGVU5.js +75 -0
  42. package/dist/chunk-H5AGGVU5.js.map +1 -0
  43. package/dist/chunk-K3G72I6D.js +24 -0
  44. package/dist/chunk-K3G72I6D.js.map +1 -0
  45. package/dist/{chunk-3O7ZEUW2.js → chunk-M5JRI6MN.js} +3 -3
  46. package/dist/chunk-M5JRI6MN.js.map +1 -0
  47. package/dist/chunk-NPPD2A6O.js +40 -0
  48. package/dist/chunk-NPPD2A6O.js.map +1 -0
  49. package/dist/chunk-R6JHHBKQ.js +19 -0
  50. package/dist/chunk-R6JHHBKQ.js.map +1 -0
  51. package/dist/chunk-S3TPM2LP.js +23 -0
  52. package/dist/chunk-S3TPM2LP.js.map +1 -0
  53. package/dist/{chunk-T5XNMVOI.js → chunk-XZXRLY5Q.js} +14 -5
  54. package/dist/chunk-XZXRLY5Q.js.map +1 -0
  55. package/dist/dialog-header.d.ts +3 -2
  56. package/dist/dialog-header.js +3 -1
  57. package/dist/disclosure-arrow.d.ts +14 -0
  58. package/dist/disclosure-arrow.js +4 -0
  59. package/dist/disclosure-arrow.js.map +1 -0
  60. package/dist/index.d.ts +5 -1
  61. package/dist/index.js +16 -11
  62. package/dist/menu-action-row.d.ts +50 -0
  63. package/dist/menu-action-row.js +4 -0
  64. package/dist/menu-action-row.js.map +1 -0
  65. package/dist/menu-header.d.ts +28 -2
  66. package/dist/menu-header.js +4 -1
  67. package/dist/menu-item.d.ts +10 -1
  68. package/dist/menu-item.js +2 -1
  69. package/dist/resizable-region.d.ts +3 -1
  70. package/dist/resizable-region.js +1 -1
  71. package/dist/select.js +1 -1
  72. package/dist/styles/app-tab.css +152 -0
  73. package/dist/styles/dialog-header.css +87 -0
  74. package/dist/styles/disclosure-arrow.css +23 -0
  75. package/dist/styles/empty-state.css +47 -0
  76. package/dist/styles/foundation.css +326 -0
  77. package/dist/styles/layout.css +73 -0
  78. package/dist/styles/loading-spinner.css +21 -0
  79. package/dist/styles/lucide-icon.css +6 -0
  80. package/dist/styles/menu-action-row.css +154 -0
  81. package/dist/styles/menu-header.css +143 -0
  82. package/dist/styles/menu-item.css +118 -0
  83. package/dist/styles/page-header.css +26 -0
  84. package/dist/styles/resizable-region.css +111 -0
  85. package/{src → dist/styles}/segmented-control.css +62 -31
  86. package/dist/styles/select.css +96 -0
  87. package/dist/styles/state-banner.css +173 -0
  88. package/dist/styles/styles.css +22 -0
  89. package/dist/styles/tab-bar.css +45 -0
  90. package/dist/styles/token-search-field.css +281 -0
  91. package/dist/styles/toolbar-control-group.css +161 -0
  92. package/dist/styles/toolbar-text.css +29 -0
  93. package/dist/styles/toolbar.css +52 -0
  94. package/dist/styles/value-table.css +75 -0
  95. package/{src → dist/styles}/webawesome.css +119 -29
  96. package/dist/token-search-field.d.ts +43 -0
  97. package/dist/token-search-field.js +4 -0
  98. package/dist/token-search-field.js.map +1 -0
  99. package/dist/value-table.d.ts +10 -2
  100. package/dist/value-table.js +1 -1
  101. package/dist/webawesome.d.ts +100 -0
  102. package/dist/webawesome.js +3 -0
  103. package/dist/webawesome.js.map +1 -0
  104. package/dist/wire-resizable-regions.js +1 -1
  105. package/dist/wire-token-search-fields.d.ts +11 -0
  106. package/dist/wire-token-search-fields.js +5 -0
  107. package/dist/wire-token-search-fields.js.map +1 -0
  108. package/docs/accessibility.md +60 -3
  109. package/docs/component-contract.md +128 -3
  110. package/docs/component-selection.md +133 -0
  111. package/docs/design-philosophy.md +38 -0
  112. package/docs/examples/command-palette-adapter.tsx +70 -0
  113. package/docs/layout.md +95 -0
  114. package/docs/recipes.md +116 -0
  115. package/docs/ux-demo.md +17 -5
  116. package/docs/webawesome-theme.md +15 -0
  117. package/llms.txt +25 -2
  118. package/package.json +70 -27
  119. package/ux-demo/recipes/app-shell.tsx +32 -0
  120. package/ux-demo/recipes/compact-toolbar.tsx +43 -0
  121. package/ux-demo/recipes/composer-form.tsx +62 -0
  122. package/ux-demo/recipes/list-workspace-states.tsx +26 -0
  123. package/ux-demo/recipes/loaders.ts +27 -0
  124. package/ux-demo/recipes/master-detail-dialog.tsx +45 -0
  125. package/ux-demo/recipes/mount-recipe.ts +38 -0
  126. package/ux-demo/recipes/navigation-sidebar.tsx +26 -0
  127. package/ux-demo/recipes/recipes.css +328 -0
  128. package/ux-demo/recipes/types.ts +11 -0
  129. package/ux-demo/recipes/workspace-header.tsx +12 -0
  130. package/dist/chunk-3O7ZEUW2.js.map +0 -1
  131. package/dist/chunk-723YNJBH.js +0 -17
  132. package/dist/chunk-723YNJBH.js.map +0 -1
  133. package/dist/chunk-NHXX4JI5.js.map +0 -1
  134. package/dist/chunk-OPCJRCYO.js +0 -19
  135. package/dist/chunk-OPCJRCYO.js.map +0 -1
  136. package/dist/chunk-T5XNMVOI.js.map +0 -1
  137. package/dist/chunk-VKH2JLDZ.js +0 -10
  138. package/dist/chunk-VKH2JLDZ.js.map +0 -1
  139. package/dist/chunk-WY4CAEPG.js +0 -14
  140. package/dist/chunk-WY4CAEPG.js.map +0 -1
  141. package/src/app-tab.css +0 -20
  142. package/src/dialog-header.css +0 -9
  143. package/src/empty-state.css +0 -6
  144. package/src/foundation.css +0 -106
  145. package/src/loading-spinner.css +0 -4
  146. package/src/lucide-icon.css +0 -1
  147. package/src/menu-header.css +0 -13
  148. package/src/menu-item.css +0 -12
  149. package/src/page-header.css +0 -3
  150. package/src/resizable-region.css +0 -19
  151. package/src/select.css +0 -18
  152. package/src/state-banner.css +0 -31
  153. package/src/styles.css +0 -18
  154. package/src/tab-bar.css +0 -4
  155. package/src/toolbar-control-group.css +0 -25
  156. package/src/toolbar-text.css +0 -4
  157. package/src/toolbar.css +0 -9
  158. package/src/value-table.css +0 -5
@@ -0,0 +1,4467 @@
1
+ {
2
+ "$schema": "./component-catalog.schema.json",
3
+ "schemaVersion": 1,
4
+ "package": "@kerfjs/ui",
5
+ "description": "Machine-readable selection, composition, delivery, ownership, and accessibility metadata for Kerf UI and its supported Web Awesome set.",
6
+ "entries": [
7
+ {
8
+ "id": "lucide-icon",
9
+ "name": "LucideIcon",
10
+ "category": "Foundation",
11
+ "kind": "component",
12
+ "source": "kerf",
13
+ "description": "Decorative and meaningfully labeled Lucide-compatible icons.",
14
+ "uses": [],
15
+ "purpose": "Decorative and meaningfully labeled Lucide-compatible icons.",
16
+ "publicExports": [
17
+ "LucideIcon"
18
+ ],
19
+ "useWhen": [
20
+ "Render a decorative or explicitly labeled Lucide-compatible icon in Kerf application UI."
21
+ ],
22
+ "avoidWhen": [
23
+ "Do not use an icon as the only name of an unfamiliar action."
24
+ ],
25
+ "alternatives": [
26
+ {
27
+ "id": "wa-icon",
28
+ "relationship": "prefer-over"
29
+ }
30
+ ],
31
+ "appOwns": [
32
+ "icon choice",
33
+ "meaningful label"
34
+ ],
35
+ "variants": [
36
+ "decorative",
37
+ "labeled"
38
+ ],
39
+ "accessibility": [
40
+ "Decorative icons are aria-hidden; meaningful icons require a label."
41
+ ],
42
+ "delivery": {
43
+ "browserImport": "@kerfjs/ui/lucide-icon",
44
+ "manualCssImport": "@kerfjs/ui/lucide-icon.css",
45
+ "sideEffects": [
46
+ "browser-condition-css"
47
+ ]
48
+ },
49
+ "wiring": [],
50
+ "publicClasses": [],
51
+ "publicTokens": [],
52
+ "links": {
53
+ "catalogRoute": "?component=lucide-icon",
54
+ "documentation": "docs/component-selection.md",
55
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
56
+ }
57
+ },
58
+ {
59
+ "id": "disclosure-arrow",
60
+ "name": "DisclosureArrow",
61
+ "category": "Foundation",
62
+ "kind": "component",
63
+ "source": "kerf",
64
+ "description": "Root-scaled 18px animated open and closed disclosure indicator with configurable directions, shortest-path rotation, and right-oriented replacement icon content.",
65
+ "uses": [
66
+ "lucide-icon"
67
+ ],
68
+ "purpose": "Indicate whether a disclosure control is open with an overridable 18px root-scaled visual and shortest-path rotation behavior.",
69
+ "publicExports": [
70
+ "DisclosureArrow"
71
+ ],
72
+ "useWhen": [
73
+ "Add a shortest-path rotating indicator to a control that owns open and closed state; author replacement icon content facing right before direction transforms are applied."
74
+ ],
75
+ "avoidWhen": [
76
+ "Do not use the arrow as the interactive control or accessible name by itself."
77
+ ],
78
+ "alternatives": [],
79
+ "appOwns": [
80
+ "open state",
81
+ "interaction",
82
+ "accessible control label"
83
+ ],
84
+ "variants": [
85
+ "open",
86
+ "closed",
87
+ "custom directions",
88
+ "replacement icon"
89
+ ],
90
+ "accessibility": [
91
+ "The arrow is decorative; expose expanded state through aria-expanded on its owning control and keep that control's accessible name stable."
92
+ ],
93
+ "delivery": {
94
+ "browserImport": "@kerfjs/ui/disclosure-arrow",
95
+ "manualCssImport": "@kerfjs/ui/disclosure-arrow.css",
96
+ "sideEffects": [
97
+ "browser-condition-css"
98
+ ]
99
+ },
100
+ "wiring": [],
101
+ "publicClasses": [
102
+ "kui-disclosure-arrow"
103
+ ],
104
+ "publicTokens": [
105
+ "--kui-disclosure-arrow-duration",
106
+ "--kui-disclosure-arrow-size"
107
+ ],
108
+ "links": {
109
+ "catalogRoute": "?component=disclosure-arrow",
110
+ "documentation": "docs/component-selection.md",
111
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
112
+ }
113
+ },
114
+ {
115
+ "id": "webawesome-theme",
116
+ "name": "Web Awesome theme",
117
+ "category": "Foundation",
118
+ "kind": "composition",
119
+ "source": "kerf",
120
+ "description": "Kerf palettes, typography, geometry, and focus styling across free Web Awesome component families.",
121
+ "uses": [
122
+ "wa-button",
123
+ "wa-button-group",
124
+ "wa-copy-button",
125
+ "wa-dropdown",
126
+ "wa-dropdown-item",
127
+ "wa-checkbox",
128
+ "wa-checkbox-group",
129
+ "wa-color-picker",
130
+ "wa-input",
131
+ "wa-known-date",
132
+ "wa-number-input",
133
+ "wa-option",
134
+ "wa-otp-input",
135
+ "wa-radio",
136
+ "wa-radio-group",
137
+ "wa-rating",
138
+ "wa-select",
139
+ "wa-slider",
140
+ "wa-switch",
141
+ "wa-textarea",
142
+ "wa-time-input",
143
+ "wa-accordion",
144
+ "wa-accordion-item",
145
+ "wa-card",
146
+ "wa-details",
147
+ "wa-dialog",
148
+ "wa-divider",
149
+ "wa-drawer",
150
+ "wa-page",
151
+ "wa-scroller",
152
+ "wa-split-panel",
153
+ "wa-breadcrumb",
154
+ "wa-breadcrumb-item",
155
+ "wa-pagination",
156
+ "wa-tab",
157
+ "wa-tab-group",
158
+ "wa-tab-panel",
159
+ "wa-tree",
160
+ "wa-tree-item",
161
+ "wa-badge",
162
+ "wa-callout",
163
+ "wa-progress-bar",
164
+ "wa-progress-ring",
165
+ "wa-skeleton",
166
+ "wa-spinner",
167
+ "wa-tag",
168
+ "wa-toast",
169
+ "wa-toast-item",
170
+ "wa-tooltip",
171
+ "wa-animated-image",
172
+ "wa-avatar",
173
+ "wa-carousel",
174
+ "wa-carousel-item",
175
+ "wa-comparison",
176
+ "wa-icon",
177
+ "wa-markdown",
178
+ "wa-qr-code",
179
+ "wa-zoomable-frame",
180
+ "wa-animation",
181
+ "wa-format-bytes",
182
+ "wa-format-date",
183
+ "wa-format-number",
184
+ "wa-include",
185
+ "wa-intersection-observer",
186
+ "wa-mutation-observer",
187
+ "wa-popover",
188
+ "wa-popup",
189
+ "wa-random-content",
190
+ "wa-relative-time",
191
+ "wa-resize-observer"
192
+ ],
193
+ "purpose": "Kerf palettes, typography, geometry, and focus styling across free Web Awesome component families.",
194
+ "publicExports": [],
195
+ "useWhen": [
196
+ "Theme individually registered free Web Awesome components to match Kerf UI."
197
+ ],
198
+ "avoidWhen": [
199
+ "Do not treat theme coverage as a recommendation or import the full registration bundle."
200
+ ],
201
+ "alternatives": [],
202
+ "appOwns": [
203
+ "individual component registration",
204
+ "semantic token overrides"
205
+ ],
206
+ "variants": [
207
+ "light",
208
+ "dark",
209
+ "invert"
210
+ ],
211
+ "accessibility": [
212
+ "Preserve Web Awesome semantics and Kerf focus/contrast tokens."
213
+ ],
214
+ "delivery": {
215
+ "manualCssImport": "@kerfjs/ui/webawesome.css",
216
+ "sideEffects": [
217
+ "css"
218
+ ]
219
+ },
220
+ "wiring": [],
221
+ "publicClasses": [],
222
+ "publicTokens": [
223
+ "--kui-disclosure-icon-scale",
224
+ "--kui-wa-carousel-control-size",
225
+ "--kui-wa-carousel-dot-hit-size",
226
+ "--kui-wa-carousel-dot-size",
227
+ "--kui-wa-carousel-icon-size",
228
+ "--kui-wa-popover-arrow-size"
229
+ ],
230
+ "links": {
231
+ "catalogRoute": "?component=webawesome-theme",
232
+ "documentation": "docs/component-selection.md",
233
+ "recipe": "docs/webawesome-theme.md#component-selection-guidance"
234
+ }
235
+ },
236
+ {
237
+ "id": "layout",
238
+ "name": "Application layout",
239
+ "category": "Foundation",
240
+ "kind": "composition",
241
+ "source": "kerf",
242
+ "description": "Unpadded panes, 24px content stacks, and self-contained 8/1/8 content items for application layout boundaries.",
243
+ "uses": [],
244
+ "purpose": "Provide one reusable pane, toolbar, content stack, and content-item geometry across sidebars, main areas, and dialogs.",
245
+ "publicExports": [],
246
+ "useWhen": [
247
+ "Build sidebars, main areas, or dialogs from an unpadded pane with optional toolbar/footer and one content stack."
248
+ ],
249
+ "avoidWhen": [
250
+ "Do not pad the pane itself or add wrapper insets around children that already own content-item geometry."
251
+ ],
252
+ "alternatives": [],
253
+ "appOwns": [
254
+ "layout hierarchy",
255
+ "reading width",
256
+ "responsive relocation"
257
+ ],
258
+ "variants": [
259
+ "toolbar + content",
260
+ "toolbar + content + footer",
261
+ "rounded content item",
262
+ "pill content item"
263
+ ],
264
+ "accessibility": [
265
+ "Keep reading and focus order coherent when controls wrap or panes relocate, and preserve one scroll owner per pane."
266
+ ],
267
+ "delivery": {
268
+ "manualCssImport": "@kerfjs/ui/layout.css",
269
+ "sideEffects": [
270
+ "css"
271
+ ]
272
+ },
273
+ "wiring": [],
274
+ "publicClasses": [
275
+ "kui-content",
276
+ "kui-content-item",
277
+ "kui-content-item--pill",
278
+ "kui-control-cluster",
279
+ "kui-inline-metadata",
280
+ "kui-pane",
281
+ "kui-pane__content",
282
+ "kui-pane__footer",
283
+ "kui-pane__toolbar",
284
+ "kui-scroll-owner"
285
+ ],
286
+ "publicTokens": [
287
+ "--kui-layout-control-gap",
288
+ "--kui-layout-content-gap",
289
+ "--kui-layout-inline-margin",
290
+ "--kui-layout-item-border-width",
291
+ "--kui-layout-item-padding",
292
+ "--kui-layout-metadata-gap",
293
+ "--kui-layout-pill-radius",
294
+ "--kui-layout-rounded-radius"
295
+ ],
296
+ "links": {
297
+ "catalogRoute": "?component=layout",
298
+ "documentation": "docs/component-selection.md",
299
+ "recipe": "docs/layout.md#public-roles-and-tokens"
300
+ }
301
+ },
302
+ {
303
+ "id": "toolbar",
304
+ "name": "Toolbar",
305
+ "category": "Structure",
306
+ "kind": "component",
307
+ "source": "kerf",
308
+ "description": "Leading, centered, and trailing toolbar composition.",
309
+ "uses": [
310
+ "toolbar-text",
311
+ "toolbar-control-group"
312
+ ],
313
+ "purpose": "Leading, centered, and trailing toolbar composition.",
314
+ "publicExports": [
315
+ "Toolbar"
316
+ ],
317
+ "useWhen": [
318
+ "Compose persistent application chrome with leading, center, and trailing regions."
319
+ ],
320
+ "avoidWhen": [
321
+ "Do not use for a page title or dialog heading."
322
+ ],
323
+ "alternatives": [
324
+ {
325
+ "id": "page-header",
326
+ "relationship": "nearest"
327
+ },
328
+ {
329
+ "id": "dialog-header",
330
+ "relationship": "nearest"
331
+ }
332
+ ],
333
+ "appOwns": [
334
+ "actions",
335
+ "command availability",
336
+ "responsive relocation"
337
+ ],
338
+ "variants": [
339
+ "divider",
340
+ "no divider",
341
+ "centered content"
342
+ ],
343
+ "accessibility": [
344
+ "Supply a label when the toolbar needs an accessible name."
345
+ ],
346
+ "delivery": {
347
+ "browserImport": "@kerfjs/ui/toolbar",
348
+ "manualCssImport": "@kerfjs/ui/toolbar.css",
349
+ "sideEffects": [
350
+ "browser-condition-css"
351
+ ]
352
+ },
353
+ "wiring": [],
354
+ "publicClasses": [
355
+ "kui-toolbar",
356
+ "kui-toolbar__center",
357
+ "kui-toolbar__leading",
358
+ "kui-toolbar__trailing"
359
+ ],
360
+ "publicTokens": [
361
+ "--kui-color-border",
362
+ "--kui-font-sans"
363
+ ],
364
+ "links": {
365
+ "catalogRoute": "?component=toolbar",
366
+ "documentation": "docs/component-selection.md",
367
+ "recipe": "docs/component-selection.md#ambiguous-choices"
368
+ }
369
+ },
370
+ {
371
+ "id": "toolbar-control-group",
372
+ "name": "ToolbarControlGroup",
373
+ "category": "Structure",
374
+ "kind": "component",
375
+ "source": "kerf",
376
+ "description": "Contained, borderless, pressed, and single-control toolbar groups.",
377
+ "uses": [
378
+ "lucide-icon",
379
+ "segmented-control"
380
+ ],
381
+ "purpose": "Contained, borderless, pressed, and single-control toolbar groups.",
382
+ "publicExports": [
383
+ "ToolbarControlGroup"
384
+ ],
385
+ "useWhen": [
386
+ "Group related controls inside a toolbar with a supported visual treatment."
387
+ ],
388
+ "avoidWhen": [
389
+ "Do not use merely to align unrelated buttons or to imitate an exclusive choice."
390
+ ],
391
+ "alternatives": [
392
+ {
393
+ "id": "segmented-control",
394
+ "relationship": "nearest"
395
+ },
396
+ {
397
+ "id": "wa-button-group",
398
+ "relationship": "prefer-over"
399
+ }
400
+ ],
401
+ "appOwns": [
402
+ "actions",
403
+ "pressed state",
404
+ "expanded state"
405
+ ],
406
+ "variants": [
407
+ "contained",
408
+ "borderless",
409
+ "pressed",
410
+ "single"
411
+ ],
412
+ "accessibility": [
413
+ "Name the group when its relationship is not evident from context."
414
+ ],
415
+ "delivery": {
416
+ "browserImport": "@kerfjs/ui/toolbar-control-group",
417
+ "manualCssImport": "@kerfjs/ui/toolbar-control-group.css",
418
+ "sideEffects": [
419
+ "browser-condition-css"
420
+ ]
421
+ },
422
+ "wiring": [],
423
+ "publicClasses": [
424
+ "kui-toolbar-control-group"
425
+ ],
426
+ "publicTokens": [
427
+ "--kui-color-brand-on-quiet",
428
+ "--kui-color-neutral-border-loud",
429
+ "--kui-color-neutral-border-normal",
430
+ "--kui-color-neutral-fill-loud",
431
+ "--kui-color-neutral-fill-normal",
432
+ "--kui-color-neutral-on-loud",
433
+ "--kui-color-neutral-on-quiet",
434
+ "--kui-color-surface",
435
+ "--kui-focus-ring",
436
+ "--kui-shadow-s",
437
+ "--kui-toolbar-control-background",
438
+ "--kui-toolbar-control-border",
439
+ "--kui-toolbar-control-color",
440
+ "--kui-toolbar-control-dark-border",
441
+ "--kui-toolbar-control-hover-background",
442
+ "--kui-toolbar-control-pressed-background",
443
+ "--kui-toolbar-control-pressed-border",
444
+ "--kui-toolbar-control-pressed-color",
445
+ "--kui-toolbar-control-selected-background",
446
+ "--kui-toolbar-control-selected-color",
447
+ "--kui-toolbar-control-selected-shadow"
448
+ ],
449
+ "links": {
450
+ "catalogRoute": "?component=toolbar-control-group",
451
+ "documentation": "docs/component-selection.md",
452
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
453
+ }
454
+ },
455
+ {
456
+ "id": "toolbar-text",
457
+ "name": "ToolbarText",
458
+ "category": "Structure",
459
+ "kind": "component",
460
+ "source": "kerf",
461
+ "description": "Large, default, and compact toolbar identity text.",
462
+ "uses": [],
463
+ "purpose": "Large, default, and compact toolbar identity text.",
464
+ "publicExports": [
465
+ "ToolbarText"
466
+ ],
467
+ "useWhen": [
468
+ "Render toolbar identity text at a supported hierarchy size."
469
+ ],
470
+ "avoidWhen": [
471
+ "Do not substitute it for document heading semantics."
472
+ ],
473
+ "alternatives": [
474
+ {
475
+ "id": "page-header",
476
+ "relationship": "nearest"
477
+ }
478
+ ],
479
+ "appOwns": [
480
+ "text",
481
+ "responsive priority"
482
+ ],
483
+ "variants": [
484
+ "large",
485
+ "default",
486
+ "small"
487
+ ],
488
+ "accessibility": [],
489
+ "delivery": {
490
+ "browserImport": "@kerfjs/ui/toolbar-text",
491
+ "manualCssImport": "@kerfjs/ui/toolbar-text.css",
492
+ "sideEffects": [
493
+ "browser-condition-css"
494
+ ]
495
+ },
496
+ "wiring": [],
497
+ "publicClasses": [
498
+ "kui-toolbar-text"
499
+ ],
500
+ "publicTokens": [
501
+ "--kui-color-neutral-on-quiet",
502
+ "--kui-font-m",
503
+ "--kui-font-mono",
504
+ "--kui-font-s",
505
+ "--kui-font-xs"
506
+ ],
507
+ "links": {
508
+ "catalogRoute": "?component=toolbar-text",
509
+ "documentation": "docs/component-selection.md",
510
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
511
+ }
512
+ },
513
+ {
514
+ "id": "headers",
515
+ "name": "Header composition",
516
+ "category": "Structure",
517
+ "kind": "composition",
518
+ "source": "kerf",
519
+ "description": "Page, dialog, and definition-list hierarchy.",
520
+ "uses": [
521
+ "page-header",
522
+ "dialog-header",
523
+ "value-table"
524
+ ],
525
+ "purpose": "Page, dialog, and definition-list hierarchy.",
526
+ "publicExports": [],
527
+ "useWhen": [
528
+ "Compose page, dialog, and definition-list hierarchy from their distinct primitives."
529
+ ],
530
+ "avoidWhen": [
531
+ "Do not reuse one header primitive only because its typography looks similar."
532
+ ],
533
+ "alternatives": [
534
+ {
535
+ "id": "toolbar",
536
+ "relationship": "nearest"
537
+ },
538
+ {
539
+ "id": "page-header",
540
+ "relationship": "nearest"
541
+ },
542
+ {
543
+ "id": "dialog-header",
544
+ "relationship": "nearest"
545
+ }
546
+ ],
547
+ "appOwns": [
548
+ "scope hierarchy",
549
+ "copy",
550
+ "actions"
551
+ ],
552
+ "variants": [
553
+ "page",
554
+ "dialog",
555
+ "key/value"
556
+ ],
557
+ "accessibility": [
558
+ "Preserve heading and description relationships for the containing surface."
559
+ ],
560
+ "delivery": {
561
+ "sideEffects": [
562
+ "css"
563
+ ]
564
+ },
565
+ "wiring": [],
566
+ "publicClasses": [],
567
+ "publicTokens": [],
568
+ "links": {
569
+ "catalogRoute": "?component=headers",
570
+ "documentation": "docs/component-selection.md",
571
+ "recipe": "docs/component-selection.md#ambiguous-choices"
572
+ }
573
+ },
574
+ {
575
+ "id": "page-header",
576
+ "name": "PageHeader",
577
+ "category": "Structure",
578
+ "kind": "component",
579
+ "source": "kerf",
580
+ "description": "Page identity with an optional trailing action.",
581
+ "uses": [],
582
+ "purpose": "Page identity with an optional trailing action.",
583
+ "publicExports": [
584
+ "PageHeader"
585
+ ],
586
+ "useWhen": [
587
+ "Identify a page with its primary heading and optional trailing action."
588
+ ],
589
+ "avoidWhen": [
590
+ "Do not use for persistent app chrome or a modal task."
591
+ ],
592
+ "alternatives": [
593
+ {
594
+ "id": "toolbar",
595
+ "relationship": "nearest"
596
+ },
597
+ {
598
+ "id": "dialog-header",
599
+ "relationship": "nearest"
600
+ }
601
+ ],
602
+ "appOwns": [
603
+ "title",
604
+ "action",
605
+ "responsive placement"
606
+ ],
607
+ "variants": [
608
+ "title",
609
+ "title with action"
610
+ ],
611
+ "accessibility": [
612
+ "Use once for the page primary heading."
613
+ ],
614
+ "delivery": {
615
+ "browserImport": "@kerfjs/ui/page-header",
616
+ "manualCssImport": "@kerfjs/ui/page-header.css",
617
+ "sideEffects": [
618
+ "browser-condition-css"
619
+ ]
620
+ },
621
+ "wiring": [],
622
+ "publicClasses": [
623
+ "kui-page-header",
624
+ "kui-page-header__action"
625
+ ],
626
+ "publicTokens": [
627
+ "--kui-color-text",
628
+ "--kui-font-2xl",
629
+ "--kui-font-l",
630
+ "--kui-page-header-background",
631
+ "--kui-page-header-border",
632
+ "--kui-page-header-foreground"
633
+ ],
634
+ "links": {
635
+ "catalogRoute": "?component=page-header",
636
+ "documentation": "docs/component-selection.md",
637
+ "recipe": "docs/component-selection.md#ambiguous-choices"
638
+ }
639
+ },
640
+ {
641
+ "id": "dialog-header",
642
+ "name": "DialogHeader",
643
+ "category": "Structure",
644
+ "kind": "component",
645
+ "source": "kerf",
646
+ "description": "Dialog toolbar with aligned icon, title, grouped actions, and a subtitle row.",
647
+ "uses": [
648
+ "lucide-icon",
649
+ "toolbar",
650
+ "toolbar-control-group"
651
+ ],
652
+ "purpose": "Dialog toolbar with aligned icon, title, grouped actions, and a subtitle row.",
653
+ "publicExports": [
654
+ "DialogHeader"
655
+ ],
656
+ "useWhen": [
657
+ "Label a focused dialog task with a toolbar-aligned title, icon, actions, and subtitle."
658
+ ],
659
+ "avoidWhen": [
660
+ "Do not use as the page heading or as a replacement for modal behavior."
661
+ ],
662
+ "alternatives": [
663
+ {
664
+ "id": "page-header",
665
+ "relationship": "nearest"
666
+ },
667
+ {
668
+ "id": "wa-dialog",
669
+ "relationship": "prefer-over"
670
+ }
671
+ ],
672
+ "appOwns": [
673
+ "open state",
674
+ "focus lifecycle",
675
+ "dismissal",
676
+ "copy",
677
+ "localized action-group label"
678
+ ],
679
+ "variants": [
680
+ "title",
681
+ "optional summary",
682
+ "icon",
683
+ "actions",
684
+ "actionsLabel"
685
+ ],
686
+ "accessibility": [
687
+ "Connect the title id and any provided summary id to the dialog host.",
688
+ "Pass a localized actionsLabel when the automatic action group needs an accessible name."
689
+ ],
690
+ "delivery": {
691
+ "browserImport": "@kerfjs/ui/dialog-header",
692
+ "manualCssImport": "@kerfjs/ui/dialog-header.css",
693
+ "sideEffects": [
694
+ "browser-condition-css"
695
+ ]
696
+ },
697
+ "wiring": [],
698
+ "publicClasses": [
699
+ "kui-dialog-header",
700
+ "kui-dialog-header__actions",
701
+ "kui-dialog-header__copy",
702
+ "kui-dialog-header__icon",
703
+ "kui-dialog-header__identity",
704
+ "kui-dialog-header__summary",
705
+ "kui-dialog-header__toolbar"
706
+ ],
707
+ "publicTokens": [
708
+ "--kui-color-brand-fill-quiet",
709
+ "--kui-color-brand-on-quiet",
710
+ "--kui-color-text",
711
+ "--kui-color-text-quiet",
712
+ "--kui-dialog-header-border",
713
+ "--kui-dialog-header-icon-background",
714
+ "--kui-dialog-header-icon-foreground",
715
+ "--kui-font-l",
716
+ "--kui-radius-circle"
717
+ ],
718
+ "links": {
719
+ "catalogRoute": "?component=dialog-header",
720
+ "documentation": "docs/component-selection.md",
721
+ "recipe": "docs/component-selection.md#ambiguous-choices"
722
+ }
723
+ },
724
+ {
725
+ "id": "value-table",
726
+ "name": "ValueTable",
727
+ "category": "Structure",
728
+ "kind": "component",
729
+ "source": "kerf",
730
+ "description": "Key/value rows with optional icons.",
731
+ "uses": [
732
+ "lucide-icon"
733
+ ],
734
+ "purpose": "Key/value rows with optional icons and aligned separators.",
735
+ "publicExports": [
736
+ "ValueTable",
737
+ "ValueTableRow"
738
+ ],
739
+ "useWhen": [
740
+ "Present read-only label/value facts as a semantic definition list, optionally with a 24px leading icon."
741
+ ],
742
+ "avoidWhen": [
743
+ "Do not use for editable fields or row/column tabular data."
744
+ ],
745
+ "alternatives": [],
746
+ "appOwns": [
747
+ "values",
748
+ "formatting",
749
+ "empty policy"
750
+ ],
751
+ "variants": [
752
+ "icon rows",
753
+ "iconless rows"
754
+ ],
755
+ "accessibility": [
756
+ "Name ValueTable with its label; ValueTableRow supplies dt/dd semantics, and row icons stay decorative unless meaning requires an accessible label."
757
+ ],
758
+ "delivery": {
759
+ "browserImport": "@kerfjs/ui/value-table",
760
+ "manualCssImport": "@kerfjs/ui/value-table.css",
761
+ "sideEffects": [
762
+ "browser-condition-css"
763
+ ]
764
+ },
765
+ "wiring": [],
766
+ "publicClasses": [
767
+ "kui-value-table",
768
+ "kui-value-table__row",
769
+ "kui-value-table__icon",
770
+ "kui-value-table__label"
771
+ ],
772
+ "publicTokens": [
773
+ "--kui-color-border",
774
+ "--kui-color-surface-lowered",
775
+ "--kui-color-text",
776
+ "--kui-color-text-quiet",
777
+ "--kui-font-weight-semibold",
778
+ "--kui-layout-inline-margin",
779
+ "--kui-layout-item-gap",
780
+ "--kui-layout-item-padding",
781
+ "--kui-space-2xs",
782
+ "--kui-value-table-background",
783
+ "--kui-value-table-border",
784
+ "--kui-value-table-icon-size"
785
+ ],
786
+ "links": {
787
+ "catalogRoute": "?component=value-table",
788
+ "documentation": "docs/component-selection.md",
789
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
790
+ }
791
+ },
792
+ {
793
+ "id": "menu",
794
+ "name": "Menu composition",
795
+ "category": "Navigation",
796
+ "kind": "composition",
797
+ "source": "kerf",
798
+ "description": "Navigation rows and section headers composed as ordinary content items inside a pane.",
799
+ "uses": [
800
+ "menu-header",
801
+ "menu-action-row",
802
+ "menu-item"
803
+ ],
804
+ "purpose": "Compose navigation with the same pane, content stack, item, and toolbar geometry used throughout the application, including a controlled MenuHeader disclosure only when it reveals real content.",
805
+ "publicExports": [],
806
+ "useWhen": [
807
+ "Compose navigation sections in a .kui-content stack, using MenuHeader, MenuItem, and MenuActionRow children plus optional .kui-content-item surfaces."
808
+ ],
809
+ "avoidWhen": [
810
+ "Do not add sidebar-specific wrapper padding or use the pattern for unrelated inline controls.",
811
+ "Do not place a disclosure chevron on navigation that does not expand content."
812
+ ],
813
+ "alternatives": [],
814
+ "appOwns": [
815
+ "information architecture",
816
+ "routing",
817
+ "responsive shell behavior"
818
+ ],
819
+ "variants": [
820
+ "section",
821
+ "icon rows",
822
+ "iconless rows",
823
+ "content item",
824
+ "pane toolbar or footer"
825
+ ],
826
+ "accessibility": [
827
+ "Use native links for link navigation, retain MenuItem button semantics for actions, and keep standalone header and toolbar actions at least 44px square.",
828
+ "A MenuHeader disclosure controls real content, keeps a stable accessible name and aria-expanded state, and uses the production DisclosureArrow visual."
829
+ ],
830
+ "delivery": {
831
+ "manualCssImport": "@kerfjs/ui/layout.css",
832
+ "sideEffects": [
833
+ "css"
834
+ ]
835
+ },
836
+ "wiring": [],
837
+ "publicClasses": [
838
+ "kui-content",
839
+ "kui-content-item",
840
+ "kui-pane"
841
+ ],
842
+ "publicTokens": [
843
+ "--kui-layout-content-gap",
844
+ "--kui-layout-inline-margin",
845
+ "--kui-layout-item-padding",
846
+ "--kui-layout-rounded-radius"
847
+ ],
848
+ "links": {
849
+ "catalogRoute": "?component=menu",
850
+ "documentation": "docs/component-selection.md",
851
+ "recipe": "docs/component-selection.md#correct-composition-and-duplicated-markup-trap"
852
+ }
853
+ },
854
+ {
855
+ "id": "menu-header",
856
+ "name": "MenuHeader",
857
+ "category": "Navigation",
858
+ "kind": "component",
859
+ "source": "kerf",
860
+ "description": "Full-width section headings with a semantic neutral count pill or non-count badge, a logical-end action, disclosure states, and protected native-popover trigger metadata.",
861
+ "uses": [
862
+ "lucide-icon",
863
+ "disclosure-arrow"
864
+ ],
865
+ "purpose": "Fill the available section width while splitting a dormant title and mutually exclusive semantic count or legacy badge from an optional logical-end 44px action with an 18px visual, or render that title cluster as a disclosure button with a default production DisclosureArrow.",
866
+ "publicExports": [
867
+ "MenuHeader"
868
+ ],
869
+ "useWhen": [
870
+ "Label a navigation section with an optional semantic count, non-count badge, action, or disclosure state; toggle mode supplies an 18px DisclosureArrow unless actionIcon replaces it."
871
+ ],
872
+ "avoidWhen": [
873
+ "Do not concatenate a section count into label or pass numeric content through badge; use count with its required localized countLabel.",
874
+ "Do not use as a page or dialog title."
875
+ ],
876
+ "alternatives": [
877
+ {
878
+ "id": "page-header",
879
+ "relationship": "nearest"
880
+ },
881
+ {
882
+ "id": "dialog-header",
883
+ "relationship": "nearest"
884
+ }
885
+ ],
886
+ "appOwns": [
887
+ "section organization",
888
+ "valid count and localized count label",
889
+ "non-count badge content",
890
+ "expanded state",
891
+ "action policy",
892
+ "domain data attributes",
893
+ "popover target behavior"
894
+ ],
895
+ "variants": [
896
+ "heading",
897
+ "count",
898
+ "badge",
899
+ "action",
900
+ "toggle"
901
+ ],
902
+ "accessibility": [
903
+ "A valid count is hidden as duplicate visual text and its required localized countLabel joins the owned heading or disclosure-button accessible name; zero remains visible.",
904
+ "The application controls and updates disclosure state and the revealed content; the default DisclosureArrow mirrors expanded while the button name stays stable. triggerAttributes can describe the controlled relationship but cannot replace the owned accessible name or expanded state."
905
+ ],
906
+ "delivery": {
907
+ "browserImport": "@kerfjs/ui/menu-header",
908
+ "manualCssImport": "@kerfjs/ui/menu-header.css",
909
+ "sideEffects": [
910
+ "browser-condition-css"
911
+ ]
912
+ },
913
+ "wiring": [],
914
+ "publicClasses": [
915
+ "kui-menu-header",
916
+ "kui-menu-header__action",
917
+ "kui-menu-header__action-layer",
918
+ "kui-menu-header__badge",
919
+ "kui-menu-header__count",
920
+ "kui-menu-header__label",
921
+ "kui-menu-header__title",
922
+ "kui-menu-header__toggle"
923
+ ],
924
+ "publicTokens": [
925
+ "--kui-color-neutral-border-quiet",
926
+ "--kui-color-neutral-fill-quiet",
927
+ "--kui-color-neutral-on-quiet",
928
+ "--kui-focus-ring",
929
+ "--kui-font-xs",
930
+ "--kui-menu-header-action-icon-size",
931
+ "--kui-menu-header-color",
932
+ "--kui-layout-inline-margin",
933
+ "--kui-layout-item-gap",
934
+ "--kui-layout-item-padding",
935
+ "--kui-layout-pill-radius",
936
+ "--kui-menu-header-count-font-size",
937
+ "--kui-menu-header-hover-background"
938
+ ],
939
+ "links": {
940
+ "catalogRoute": "?component=menu-header",
941
+ "documentation": "docs/component-selection.md",
942
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
943
+ }
944
+ },
945
+ {
946
+ "id": "menu-action-row",
947
+ "name": "MenuActionRow",
948
+ "category": "Navigation",
949
+ "kind": "component",
950
+ "source": "kerf",
951
+ "description": "Full-width navigation rows with sibling primary and trailing native-button actions.",
952
+ "uses": [
953
+ "lucide-icon"
954
+ ],
955
+ "purpose": "Keep a selectable primary row action and an independently named trailing action as sibling native controls inside one noninteractive visual row.",
956
+ "publicExports": [
957
+ "MenuActionRow"
958
+ ],
959
+ "useWhen": [
960
+ "A navigation or item row needs both a primary selectable action and an independently focusable trailing action."
961
+ ],
962
+ "avoidWhen": [
963
+ "Use MenuItem when trailing content is dormant metadata; use AppTab only for tablist semantics and ToolbarControlGroup only for toolbar controls."
964
+ ],
965
+ "alternatives": [
966
+ {
967
+ "id": "menu-item",
968
+ "relationship": "nearest",
969
+ "when": "Trailing content is noninteractive."
970
+ },
971
+ {
972
+ "id": "tabs",
973
+ "relationship": "semantic alternative",
974
+ "when": "The primary control selects a tabpanel inside TabBar."
975
+ }
976
+ ],
977
+ "appOwns": [
978
+ "routing",
979
+ "selection",
980
+ "action handling",
981
+ "domain data attributes",
982
+ "popover or context-menu policy"
983
+ ],
984
+ "variants": [
985
+ "selected",
986
+ "pressed",
987
+ "disabled primary",
988
+ "disabled trailing action",
989
+ "multiline"
990
+ ],
991
+ "accessibility": [
992
+ "The noninteractive root contains two sibling native buttons in primary-then-trailing focus order; each button has its own action, item identity, accessible name, and disabled state.",
993
+ "Selection semantics are exposed only by the primary button; label, icon, and trailingActionIcon are dormant SafeHtml and must not contain interactive descendants; never place an interactive descendant in MenuItem.trailing."
994
+ ],
995
+ "delivery": {
996
+ "browserImport": "@kerfjs/ui/menu-action-row",
997
+ "manualCssImport": "@kerfjs/ui/menu-action-row.css",
998
+ "sideEffects": [
999
+ "browser-condition-css"
1000
+ ]
1001
+ },
1002
+ "wiring": [],
1003
+ "publicClasses": [
1004
+ "kui-menu-action-row",
1005
+ "kui-menu-action-row__icon",
1006
+ "kui-menu-action-row__label",
1007
+ "kui-menu-action-row__primary",
1008
+ "kui-menu-action-row__trailing-action"
1009
+ ],
1010
+ "publicTokens": [
1011
+ "--kui-color-brand-border-quiet",
1012
+ "--kui-color-brand-fill-normal",
1013
+ "--kui-color-brand-on-quiet",
1014
+ "--kui-color-neutral-border-normal",
1015
+ "--kui-color-neutral-fill-normal",
1016
+ "--kui-color-neutral-fill-quiet",
1017
+ "--kui-color-neutral-on-normal",
1018
+ "--kui-focus-ring",
1019
+ "--kui-layout-inline-margin",
1020
+ "--kui-layout-item-gap",
1021
+ "--kui-layout-item-padding",
1022
+ "--kui-layout-rounded-radius",
1023
+ "--kui-radius-pill",
1024
+ "--kui-menu-action-row-background",
1025
+ "--kui-menu-action-row-border",
1026
+ "--kui-menu-action-row-color",
1027
+ "--kui-menu-action-row-hover-background",
1028
+ "--kui-menu-action-row-hover-border",
1029
+ "--kui-menu-action-row-selected-background",
1030
+ "--kui-menu-action-row-selected-border",
1031
+ "--kui-menu-action-row-selected-color",
1032
+ "--kui-menu-action-row-trailing-hover-background"
1033
+ ],
1034
+ "links": {
1035
+ "catalogRoute": "?component=menu-action-row",
1036
+ "documentation": "docs/component-selection.md",
1037
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
1038
+ }
1039
+ },
1040
+ {
1041
+ "id": "menu-item",
1042
+ "name": "MenuItem",
1043
+ "category": "Navigation",
1044
+ "kind": "component",
1045
+ "source": "kerf",
1046
+ "description": "Selectable, disabled, trailing, and multiline native-button navigation rows with protected domain metadata hooks.",
1047
+ "uses": [
1048
+ "lucide-icon"
1049
+ ],
1050
+ "purpose": "Selectable, disabled, trailing, and multiline navigation rows.",
1051
+ "publicExports": [
1052
+ "MenuItem"
1053
+ ],
1054
+ "useWhen": [
1055
+ "Render a selectable, disabled, trailing, or multiline sidebar/navigation action row."
1056
+ ],
1057
+ "avoidWhen": [
1058
+ "Do not use for an ordinary inline link, form button, isolated ARIA menuitem, or an interactive trailing action; use MenuActionRow for sibling row actions."
1059
+ ],
1060
+ "alternatives": [
1061
+ {
1062
+ "id": "menu-action-row",
1063
+ "relationship": "nearest",
1064
+ "when": "The trailing region must be independently interactive."
1065
+ }
1066
+ ],
1067
+ "appOwns": [
1068
+ "routing",
1069
+ "selection",
1070
+ "permissions",
1071
+ "action handling",
1072
+ "domain data attributes"
1073
+ ],
1074
+ "variants": [
1075
+ "selected",
1076
+ "pressed",
1077
+ "disabled",
1078
+ "trailing",
1079
+ "multiline"
1080
+ ],
1081
+ "accessibility": [
1082
+ "Uses native button activation; selected maps to aria-current and pressed to aria-pressed; rootAttributes cannot add role=menuitem or replace owned ARIA; trailing is dormant content and must not contain controls."
1083
+ ],
1084
+ "delivery": {
1085
+ "browserImport": "@kerfjs/ui/menu-item",
1086
+ "manualCssImport": "@kerfjs/ui/menu-item.css",
1087
+ "sideEffects": [
1088
+ "browser-condition-css"
1089
+ ]
1090
+ },
1091
+ "wiring": [],
1092
+ "publicClasses": [
1093
+ "kui-menu-item",
1094
+ "kui-menu-item__icon",
1095
+ "kui-menu-item__label",
1096
+ "kui-menu-item__trailing"
1097
+ ],
1098
+ "publicTokens": [
1099
+ "--kui-color-brand-fill-normal",
1100
+ "--kui-color-brand-on-quiet",
1101
+ "--kui-color-neutral-fill-quiet",
1102
+ "--kui-color-neutral-on-normal",
1103
+ "--kui-color-neutral-on-quiet",
1104
+ "--kui-focus-ring",
1105
+ "--kui-menu-item-color",
1106
+ "--kui-menu-item-hover-background",
1107
+ "--kui-menu-item-selected-background",
1108
+ "--kui-menu-item-selected-color",
1109
+ "--kui-layout-inline-margin",
1110
+ "--kui-layout-item-gap",
1111
+ "--kui-layout-item-padding",
1112
+ "--kui-layout-rounded-radius"
1113
+ ],
1114
+ "links": {
1115
+ "catalogRoute": "?component=menu-item",
1116
+ "documentation": "docs/component-selection.md",
1117
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
1118
+ }
1119
+ },
1120
+ {
1121
+ "id": "tabs",
1122
+ "name": "AppTab",
1123
+ "category": "Navigation",
1124
+ "kind": "component",
1125
+ "source": "kerf",
1126
+ "description": "Roving-tabindex-ready tabs with protected application metadata and customizable close affordances.",
1127
+ "uses": [
1128
+ "lucide-icon"
1129
+ ],
1130
+ "purpose": "Roving-tabindex-ready tabs with protected application metadata and customizable close affordances.",
1131
+ "publicExports": [
1132
+ "AppTab"
1133
+ ],
1134
+ "useWhen": [
1135
+ "Render one controlled application tab inside TabBar."
1136
+ ],
1137
+ "avoidWhen": [
1138
+ "Do not render alone or use for a compact settings choice."
1139
+ ],
1140
+ "alternatives": [
1141
+ {
1142
+ "id": "segmented-control",
1143
+ "relationship": "nearest"
1144
+ }
1145
+ ],
1146
+ "appOwns": [
1147
+ "tab identity",
1148
+ "selection",
1149
+ "close policy",
1150
+ "content",
1151
+ "application data attribute values"
1152
+ ],
1153
+ "variants": [
1154
+ "selected",
1155
+ "closable",
1156
+ "draggable",
1157
+ "leading",
1158
+ "trailing",
1159
+ "custom close icon",
1160
+ "root metadata"
1161
+ ],
1162
+ "accessibility": [
1163
+ "Compose in a tablist and pair with an application-owned tabpanel.",
1164
+ "Keep closeIcon decorative and free of interactive descendants; the owning close button supplies its accessible name and interaction.",
1165
+ "Use rootAttributes only for application data-* metadata; component-owned identity, state, action, and role semantics are protected at runtime."
1166
+ ],
1167
+ "delivery": {
1168
+ "browserImport": "@kerfjs/ui/app-tab",
1169
+ "manualCssImport": "@kerfjs/ui/app-tab.css",
1170
+ "sideEffects": [
1171
+ "browser-condition-css"
1172
+ ]
1173
+ },
1174
+ "wiring": [],
1175
+ "publicClasses": [
1176
+ "kui-app-tab",
1177
+ "kui-app-tab__close",
1178
+ "kui-app-tab__close-icon",
1179
+ "kui-app-tab__name",
1180
+ "kui-app-tab__select",
1181
+ "kui-app-tab__trailing"
1182
+ ],
1183
+ "publicTokens": [
1184
+ "--kui-app-tab-color",
1185
+ "--kui-app-tab-drop-indicator",
1186
+ "--kui-app-tab-hover-background",
1187
+ "--kui-app-tab-selected-background",
1188
+ "--kui-app-tab-selected-border",
1189
+ "--kui-app-tab-selected-color",
1190
+ "--kui-color-brand-border-normal",
1191
+ "--kui-color-brand-on-quiet",
1192
+ "--kui-color-neutral-border-normal",
1193
+ "--kui-color-neutral-on-quiet",
1194
+ "--kui-color-surface",
1195
+ "--kui-color-text",
1196
+ "--kui-focus-ring",
1197
+ "--kui-font-xs",
1198
+ "--kui-radius-pill",
1199
+ "--kui-shadow-s",
1200
+ "--kui-space-2xs",
1201
+ "--kui-space-xs"
1202
+ ],
1203
+ "links": {
1204
+ "catalogRoute": "?component=tabs",
1205
+ "documentation": "docs/component-selection.md",
1206
+ "recipe": "docs/accessibility.md#tabs"
1207
+ }
1208
+ },
1209
+ {
1210
+ "id": "tab-bar",
1211
+ "name": "TabBar",
1212
+ "category": "Navigation",
1213
+ "kind": "component",
1214
+ "source": "kerf",
1215
+ "description": "Controlled, reorderable tab strips with horizontal overflow.",
1216
+ "uses": [
1217
+ "tabs",
1218
+ "toolbar-control-group"
1219
+ ],
1220
+ "purpose": "Controlled, reorderable tab strips with horizontal overflow.",
1221
+ "publicExports": [
1222
+ "TabBar",
1223
+ "wireTabBars",
1224
+ "reorderTabs"
1225
+ ],
1226
+ "useWhen": [
1227
+ "Switch application tabpanels with optional overflow, closing, and reordering."
1228
+ ],
1229
+ "avoidWhen": [
1230
+ "Do not use for a compact local toggle or a long value list."
1231
+ ],
1232
+ "alternatives": [
1233
+ {
1234
+ "id": "segmented-control",
1235
+ "relationship": "nearest"
1236
+ },
1237
+ {
1238
+ "id": "select",
1239
+ "relationship": "nearest"
1240
+ },
1241
+ {
1242
+ "id": "wa-tab-group",
1243
+ "relationship": "prefer-over"
1244
+ }
1245
+ ],
1246
+ "appOwns": [
1247
+ "ordered tabs",
1248
+ "selection",
1249
+ "panels",
1250
+ "routing",
1251
+ "persistence"
1252
+ ],
1253
+ "variants": [
1254
+ "leading",
1255
+ "trailing",
1256
+ "overflow",
1257
+ "reorderable"
1258
+ ],
1259
+ "accessibility": [
1260
+ "Keep exactly one selected tab at tabindex 0 and preserve the wiring keyboard model."
1261
+ ],
1262
+ "delivery": {
1263
+ "browserImport": "@kerfjs/ui/tab-bar",
1264
+ "manualCssImport": "@kerfjs/ui/tab-bar.css",
1265
+ "sideEffects": [
1266
+ "browser-condition-css"
1267
+ ]
1268
+ },
1269
+ "wiring": [
1270
+ {
1271
+ "export": "wireTabBars",
1272
+ "import": "@kerfjs/ui/wire-tab-bars",
1273
+ "required": true
1274
+ },
1275
+ {
1276
+ "export": "reorderTabs",
1277
+ "import": "@kerfjs/ui/wire-tab-bars",
1278
+ "required": false
1279
+ }
1280
+ ],
1281
+ "publicClasses": [
1282
+ "kui-tab-bar",
1283
+ "kui-tab-bar__leading",
1284
+ "kui-tab-bar__tabs",
1285
+ "kui-tab-bar__trailing"
1286
+ ],
1287
+ "publicTokens": [
1288
+ "--kui-tab-bar-background",
1289
+ "--kui-tab-bar-border"
1290
+ ],
1291
+ "links": {
1292
+ "catalogRoute": "?component=tab-bar",
1293
+ "documentation": "docs/component-selection.md",
1294
+ "recipe": "docs/accessibility.md#tabs"
1295
+ }
1296
+ },
1297
+ {
1298
+ "id": "segmented-control",
1299
+ "name": "SegmentedControl",
1300
+ "category": "Controls",
1301
+ "kind": "component",
1302
+ "source": "kerf",
1303
+ "description": "Controlled exclusive choices in toolbar, rounded-rectangle, and pill presentations.",
1304
+ "uses": [
1305
+ "lucide-icon"
1306
+ ],
1307
+ "purpose": "Controlled exclusive choices in toolbar, rounded-rectangle, and pill presentations.",
1308
+ "publicExports": [
1309
+ "SegmentedControl"
1310
+ ],
1311
+ "useWhen": [
1312
+ "Expose a small controlled exclusive choice set."
1313
+ ],
1314
+ "avoidWhen": [
1315
+ "Do not use for tabpanel semantics or many choices."
1316
+ ],
1317
+ "alternatives": [
1318
+ {
1319
+ "id": "tab-bar",
1320
+ "relationship": "nearest"
1321
+ },
1322
+ {
1323
+ "id": "select",
1324
+ "relationship": "nearest"
1325
+ },
1326
+ {
1327
+ "id": "wa-button-group",
1328
+ "relationship": "prefer-over"
1329
+ }
1330
+ ],
1331
+ "appOwns": [
1332
+ "value",
1333
+ "labels",
1334
+ "action",
1335
+ "persistence"
1336
+ ],
1337
+ "variants": [
1338
+ "filled",
1339
+ "outlined",
1340
+ "toolbar",
1341
+ "rounded",
1342
+ "pill",
1343
+ "equal width",
1344
+ "small"
1345
+ ],
1346
+ "accessibility": [
1347
+ "Keep choice labels meaningful and every enabled native button in sequential Tab order."
1348
+ ],
1349
+ "delivery": {
1350
+ "browserImport": "@kerfjs/ui/segmented-control",
1351
+ "manualCssImport": "@kerfjs/ui/segmented-control.css",
1352
+ "sideEffects": [
1353
+ "browser-condition-css"
1354
+ ]
1355
+ },
1356
+ "wiring": [],
1357
+ "publicClasses": [
1358
+ "kui-segmented-control",
1359
+ "kui-segmented-control__item"
1360
+ ],
1361
+ "publicTokens": [
1362
+ "--kui-color-brand-on-quiet",
1363
+ "--kui-color-neutral-border-normal",
1364
+ "--kui-color-neutral-fill-normal",
1365
+ "--kui-color-neutral-on-quiet",
1366
+ "--kui-color-surface",
1367
+ "--kui-focus-ring",
1368
+ "--kui-font-2xs",
1369
+ "--kui-font-weight-semibold",
1370
+ "--kui-font-xs",
1371
+ "--kui-segmented-background",
1372
+ "--kui-segmented-border",
1373
+ "--kui-segmented-foreground",
1374
+ "--kui-segmented-hover-background",
1375
+ "--kui-segmented-item-radius",
1376
+ "--kui-segmented-radius",
1377
+ "--kui-segmented-selected-background",
1378
+ "--kui-segmented-selected-border",
1379
+ "--kui-segmented-selected-foreground",
1380
+ "--kui-segmented-selected-shadow",
1381
+ "--kui-shadow-s",
1382
+ "--kui-toolbar-control-color",
1383
+ "--kui-toolbar-control-hover-background",
1384
+ "--kui-toolbar-control-selected-background",
1385
+ "--kui-toolbar-control-selected-color",
1386
+ "--kui-toolbar-control-selected-shadow"
1387
+ ],
1388
+ "links": {
1389
+ "catalogRoute": "?component=segmented-control",
1390
+ "documentation": "docs/component-selection.md",
1391
+ "recipe": "docs/accessibility.md#segmentedcontrol"
1392
+ }
1393
+ },
1394
+ {
1395
+ "id": "token-search-field",
1396
+ "name": "TokenSearchField",
1397
+ "category": "Controls",
1398
+ "kind": "component",
1399
+ "source": "kerf",
1400
+ "description": "Token-controlled, optionally collapsible search editor with ordered, editable, removable filter chips.",
1401
+ "uses": [
1402
+ "lucide-icon"
1403
+ ],
1404
+ "purpose": "Token-controlled, optionally collapsible search editor with ordered, editable, removable filter chips.",
1405
+ "publicExports": [
1406
+ "TokenSearchField",
1407
+ "readTokenSearchField",
1408
+ "placeTokenSearchCaret",
1409
+ "wireTokenSearchFields"
1410
+ ],
1411
+ "useWhen": [
1412
+ "Combine DOM-owned free text with ordered editable/removable filter tokens in one searchbox.",
1413
+ "Enable collapsible mode when an empty, unfocused search should reduce to one iconic action, standalone or inside a toolbar group."
1414
+ ],
1415
+ "avoidWhen": [
1416
+ "Do not use for ordinary text input or separately labeled filter controls."
1417
+ ],
1418
+ "alternatives": [
1419
+ {
1420
+ "id": "wa-input",
1421
+ "relationship": "prefer-over"
1422
+ }
1423
+ ],
1424
+ "appOwns": [
1425
+ "parsing",
1426
+ "suggestions",
1427
+ "tokens",
1428
+ "query execution",
1429
+ "results",
1430
+ "transient focused/open state and focus transfer"
1431
+ ],
1432
+ "variants": [
1433
+ "tokens",
1434
+ "free text",
1435
+ "disabled",
1436
+ "collapsible standalone or toolbar composition"
1437
+ ],
1438
+ "accessibility": [
1439
+ "Announce result changes when useful and keep tokens atomic during editing.",
1440
+ "Keep leading and trailing controls aligned to the first text line while content wraps.",
1441
+ "Wire Enter to submit without inserting a contenteditable line break and preserve focus plus the text-relative caret across controlled keyboard chip deletion; visual wrapping remains available.",
1442
+ "In collapsible mode, transfer focus from the named trigger into the revealed searchbox and clear expanded only after focus leaves the component."
1443
+ ],
1444
+ "delivery": {
1445
+ "browserImport": "@kerfjs/ui/token-search-field",
1446
+ "manualCssImport": "@kerfjs/ui/token-search-field.css",
1447
+ "sideEffects": [
1448
+ "browser-condition-css"
1449
+ ]
1450
+ },
1451
+ "wiring": [
1452
+ {
1453
+ "export": "readTokenSearchField",
1454
+ "import": "@kerfjs/ui/token-search-field",
1455
+ "required": true
1456
+ },
1457
+ {
1458
+ "export": "placeTokenSearchCaret",
1459
+ "import": "@kerfjs/ui/token-search-field",
1460
+ "required": false
1461
+ },
1462
+ {
1463
+ "export": "wireTokenSearchFields",
1464
+ "import": "@kerfjs/ui/wire-token-search-fields",
1465
+ "required": true
1466
+ }
1467
+ ],
1468
+ "publicClasses": [
1469
+ "kui-token-search",
1470
+ "kui-token-search__clear",
1471
+ "kui-token-search__editor",
1472
+ "kui-token-search__expand",
1473
+ "kui-token-search__leading",
1474
+ "kui-token-search__token",
1475
+ "kui-token-search__token-edit",
1476
+ "kui-token-search__token-remove",
1477
+ "kui-token-search__trailing"
1478
+ ],
1479
+ "publicTokens": [
1480
+ "--kui-color-accent",
1481
+ "--kui-color-accent-text",
1482
+ "--kui-color-border",
1483
+ "--kui-color-text-link",
1484
+ "--kui-color-surface",
1485
+ "--kui-color-text",
1486
+ "--kui-color-text-quiet",
1487
+ "--kui-focus-ring",
1488
+ "--kui-font-s",
1489
+ "--kui-font-xs",
1490
+ "--kui-radius-pill",
1491
+ "--kui-token-search-background",
1492
+ "--kui-token-search-border",
1493
+ "--kui-token-search-line-size",
1494
+ "--kui-token-search-token-background",
1495
+ "--kui-token-search-token-foreground",
1496
+ "--kui-token-search-expanded-width"
1497
+ ],
1498
+ "links": {
1499
+ "catalogRoute": "?component=token-search-field",
1500
+ "documentation": "docs/component-selection.md",
1501
+ "recipe": "docs/accessibility.md#tokensearchfield"
1502
+ }
1503
+ },
1504
+ {
1505
+ "id": "resize",
1506
+ "name": "ResizableRegion",
1507
+ "category": "Controls",
1508
+ "kind": "component",
1509
+ "source": "kerf",
1510
+ "description": "Pointer and keyboard-operable split region with a customizable handle icon.",
1511
+ "uses": [
1512
+ "lucide-icon"
1513
+ ],
1514
+ "purpose": "Pointer and keyboard-operable split region with a customizable handle icon.",
1515
+ "publicExports": [
1516
+ "ResizableRegion",
1517
+ "clampRegionSize",
1518
+ "resizeRegionFromPointer",
1519
+ "wireResizableRegions"
1520
+ ],
1521
+ "useWhen": [
1522
+ "Provide a controlled user-resizable application pane."
1523
+ ],
1524
+ "avoidWhen": [
1525
+ "Do not use for static columns; use CSS grid."
1526
+ ],
1527
+ "alternatives": [
1528
+ {
1529
+ "id": "layout",
1530
+ "relationship": "nearest"
1531
+ },
1532
+ {
1533
+ "id": "wa-split-panel",
1534
+ "relationship": "prefer-over"
1535
+ }
1536
+ ],
1537
+ "appOwns": [
1538
+ "size",
1539
+ "min/max policy",
1540
+ "collapse policy",
1541
+ "persistence"
1542
+ ],
1543
+ "variants": [
1544
+ "horizontal",
1545
+ "vertical",
1546
+ "start edge",
1547
+ "end edge",
1548
+ "collapsed",
1549
+ "custom handle icon"
1550
+ ],
1551
+ "accessibility": [
1552
+ "Preserve separator naming, value ARIA, and keyboard behavior.",
1553
+ "Keep handleIcon decorative and free of interactive descendants; the separator owns focus, naming, and pointer/keyboard interaction."
1554
+ ],
1555
+ "delivery": {
1556
+ "browserImport": "@kerfjs/ui/resizable-region",
1557
+ "manualCssImport": "@kerfjs/ui/resizable-region.css",
1558
+ "sideEffects": [
1559
+ "browser-condition-css"
1560
+ ]
1561
+ },
1562
+ "wiring": [
1563
+ {
1564
+ "export": "wireResizableRegions",
1565
+ "import": "@kerfjs/ui/wire-resizable-regions",
1566
+ "required": true
1567
+ },
1568
+ {
1569
+ "export": "clampRegionSize",
1570
+ "import": "@kerfjs/ui/resizable-region",
1571
+ "required": false
1572
+ },
1573
+ {
1574
+ "export": "resizeRegionFromPointer",
1575
+ "import": "@kerfjs/ui/resizable-region",
1576
+ "required": false
1577
+ }
1578
+ ],
1579
+ "publicClasses": [
1580
+ "kui-resizable-region",
1581
+ "kui-resizable-region__content",
1582
+ "kui-resizable-region__handle",
1583
+ "kui-resizable-region__handle-icon"
1584
+ ],
1585
+ "publicTokens": [
1586
+ "--kui-color-border",
1587
+ "--kui-color-neutral-on-quiet",
1588
+ "--kui-color-text-link",
1589
+ "--kui-focus-ring",
1590
+ "--kui-radius-s",
1591
+ "--kui-resizable-region-handle-active-color",
1592
+ "--kui-resizable-region-handle-color",
1593
+ "--kui-resizable-region-separator-color",
1594
+ "--kui-resizable-region-size"
1595
+ ],
1596
+ "links": {
1597
+ "catalogRoute": "?component=resize",
1598
+ "documentation": "docs/component-selection.md",
1599
+ "recipe": "docs/accessibility.md#resizableregion"
1600
+ }
1601
+ },
1602
+ {
1603
+ "id": "select",
1604
+ "name": "Select",
1605
+ "category": "Controls",
1606
+ "kind": "component",
1607
+ "source": "kerf",
1608
+ "description": "Controlled Web Awesome select with grouped choices and rerender-stable icon slots.",
1609
+ "uses": [
1610
+ "lucide-icon",
1611
+ "wa-select",
1612
+ "wa-option"
1613
+ ],
1614
+ "purpose": "Controlled Web Awesome select with grouped choices and rerender-stable icon slots.",
1615
+ "publicExports": [
1616
+ "Select"
1617
+ ],
1618
+ "useWhen": [
1619
+ "Choose a controlled value from a moderate or long list, including grouped and icon-bearing choices."
1620
+ ],
1621
+ "avoidWhen": [
1622
+ "Do not use for commands or a small choice set that should stay visible."
1623
+ ],
1624
+ "alternatives": [
1625
+ {
1626
+ "id": "segmented-control",
1627
+ "relationship": "nearest"
1628
+ },
1629
+ {
1630
+ "id": "wa-select",
1631
+ "relationship": "prefer-over"
1632
+ },
1633
+ {
1634
+ "id": "wa-dropdown",
1635
+ "relationship": "prefer-over"
1636
+ }
1637
+ ],
1638
+ "appOwns": [
1639
+ "value",
1640
+ "validation",
1641
+ "choices",
1642
+ "domain mapping"
1643
+ ],
1644
+ "variants": [
1645
+ "placeholder",
1646
+ "disabled",
1647
+ "fit menu",
1648
+ "grouped",
1649
+ "custom selected content"
1650
+ ],
1651
+ "accessibility": [
1652
+ "Verify the live value, standard events, focus, and rendered output."
1653
+ ],
1654
+ "delivery": {
1655
+ "browserImport": "@kerfjs/ui/select",
1656
+ "manualCssImport": "@kerfjs/ui/select.css",
1657
+ "registrationImport": "@kerfjs/ui/select/register",
1658
+ "sideEffects": [
1659
+ "custom-element-registration"
1660
+ ]
1661
+ },
1662
+ "wiring": [],
1663
+ "publicClasses": [
1664
+ "kui-select",
1665
+ "kui-select--custom-selected",
1666
+ "kui-select--fit-menu",
1667
+ "kui-select__custom-selected",
1668
+ "kui-select__group",
1669
+ "kui-select__group--separated",
1670
+ "kui-select__group-title",
1671
+ "kui-select__icon"
1672
+ ],
1673
+ "publicTokens": [
1674
+ "--kui-color-brand-fill-normal",
1675
+ "--kui-color-brand-on-quiet",
1676
+ "--kui-color-neutral-border-quiet",
1677
+ "--kui-color-neutral-on-quiet",
1678
+ "--kui-disclosure-icon-scale",
1679
+ "--kui-font-2xs"
1680
+ ],
1681
+ "links": {
1682
+ "catalogRoute": "?component=select",
1683
+ "documentation": "docs/component-selection.md",
1684
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
1685
+ }
1686
+ },
1687
+ {
1688
+ "id": "feedback",
1689
+ "name": "Feedback composition",
1690
+ "category": "Feedback",
1691
+ "kind": "composition",
1692
+ "source": "kerf",
1693
+ "description": "Banners, empty states, and labeled progress.",
1694
+ "uses": [
1695
+ "state-banner",
1696
+ "empty-state",
1697
+ "loading-spinner"
1698
+ ],
1699
+ "purpose": "Banners, empty states, and labeled progress.",
1700
+ "publicExports": [],
1701
+ "useWhen": [
1702
+ "Compose persistent status, empty/busy content, and compact loading feedback."
1703
+ ],
1704
+ "avoidWhen": [
1705
+ "Do not collapse different message lifetimes or urgency into one visual treatment."
1706
+ ],
1707
+ "alternatives": [
1708
+ {
1709
+ "id": "state-banner",
1710
+ "relationship": "nearest"
1711
+ },
1712
+ {
1713
+ "id": "empty-state",
1714
+ "relationship": "nearest"
1715
+ },
1716
+ {
1717
+ "id": "wa-callout",
1718
+ "relationship": "prefer-over"
1719
+ },
1720
+ {
1721
+ "id": "wa-toast",
1722
+ "relationship": "prefer-over"
1723
+ }
1724
+ ],
1725
+ "appOwns": [
1726
+ "state mapping",
1727
+ "message lifetime",
1728
+ "recovery policy"
1729
+ ],
1730
+ "variants": [
1731
+ "banner",
1732
+ "empty",
1733
+ "busy",
1734
+ "spinner"
1735
+ ],
1736
+ "accessibility": [
1737
+ "Choose polite status versus assertive alert deliberately."
1738
+ ],
1739
+ "delivery": {
1740
+ "sideEffects": [
1741
+ "css"
1742
+ ]
1743
+ },
1744
+ "wiring": [],
1745
+ "publicClasses": [],
1746
+ "publicTokens": [],
1747
+ "links": {
1748
+ "catalogRoute": "?component=feedback",
1749
+ "documentation": "docs/component-selection.md",
1750
+ "recipe": "docs/component-selection.md#ambiguous-choices"
1751
+ }
1752
+ },
1753
+ {
1754
+ "id": "state-banner",
1755
+ "name": "StateBanner",
1756
+ "category": "Feedback",
1757
+ "kind": "component",
1758
+ "source": "kerf",
1759
+ "description": "Polite status and assertive alert feedback with semantic tones.",
1760
+ "uses": [
1761
+ "lucide-icon"
1762
+ ],
1763
+ "purpose": "Polite status and assertive alert feedback with semantic tones.",
1764
+ "publicExports": [
1765
+ "StateBanner"
1766
+ ],
1767
+ "useWhen": [
1768
+ "Place persistent inline semantic status beside affected work."
1769
+ ],
1770
+ "avoidWhen": [
1771
+ "Do not use for an absent-content screen or transient confirmation."
1772
+ ],
1773
+ "alternatives": [
1774
+ {
1775
+ "id": "empty-state",
1776
+ "relationship": "nearest"
1777
+ },
1778
+ {
1779
+ "id": "wa-callout",
1780
+ "relationship": "prefer-over"
1781
+ },
1782
+ {
1783
+ "id": "wa-toast",
1784
+ "relationship": "prefer-over"
1785
+ }
1786
+ ],
1787
+ "appOwns": [
1788
+ "state mapping",
1789
+ "message lifetime",
1790
+ "retry behavior",
1791
+ "copy"
1792
+ ],
1793
+ "variants": [
1794
+ "neutral",
1795
+ "info",
1796
+ "success",
1797
+ "warning",
1798
+ "danger",
1799
+ "status",
1800
+ "alert"
1801
+ ],
1802
+ "accessibility": [
1803
+ "Use alert urgency only for an attention-requiring failure."
1804
+ ],
1805
+ "delivery": {
1806
+ "browserImport": "@kerfjs/ui/state-banner",
1807
+ "manualCssImport": "@kerfjs/ui/state-banner.css",
1808
+ "sideEffects": [
1809
+ "browser-condition-css"
1810
+ ]
1811
+ },
1812
+ "wiring": [],
1813
+ "publicClasses": [
1814
+ "kui-state-banner",
1815
+ "kui-state-banner__action",
1816
+ "kui-state-banner__copy",
1817
+ "kui-state-banner__icon"
1818
+ ],
1819
+ "publicTokens": [
1820
+ "--kui-color-brand-border-quiet",
1821
+ "--kui-color-brand-fill-quiet",
1822
+ "--kui-color-brand-on-quiet",
1823
+ "--kui-color-danger-border-quiet",
1824
+ "--kui-color-danger-fill-quiet",
1825
+ "--kui-color-danger-on-quiet",
1826
+ "--kui-color-neutral-border-normal",
1827
+ "--kui-color-neutral-fill-quiet",
1828
+ "--kui-color-neutral-on-normal",
1829
+ "--kui-color-success-border-normal",
1830
+ "--kui-color-success-fill-quiet",
1831
+ "--kui-color-success-on-quiet",
1832
+ "--kui-color-surface",
1833
+ "--kui-color-text-link",
1834
+ "--kui-color-warning-border-normal",
1835
+ "--kui-color-warning-fill-quiet",
1836
+ "--kui-color-warning-on-quiet",
1837
+ "--kui-font-2xs",
1838
+ "--kui-font-xs",
1839
+ "--kui-radius-pill",
1840
+ "--kui-state-banner-action-background",
1841
+ "--kui-state-banner-action-hover-background",
1842
+ "--kui-state-banner-background",
1843
+ "--kui-state-banner-border",
1844
+ "--kui-state-banner-danger-background",
1845
+ "--kui-state-banner-danger-border",
1846
+ "--kui-state-banner-danger-foreground",
1847
+ "--kui-state-banner-detail",
1848
+ "--kui-state-banner-foreground",
1849
+ "--kui-state-banner-info-background",
1850
+ "--kui-state-banner-info-border",
1851
+ "--kui-state-banner-info-foreground",
1852
+ "--kui-state-banner-neutral-background",
1853
+ "--kui-state-banner-neutral-border",
1854
+ "--kui-state-banner-neutral-foreground",
1855
+ "--kui-state-banner-success-background",
1856
+ "--kui-state-banner-success-border",
1857
+ "--kui-state-banner-success-foreground",
1858
+ "--kui-state-banner-warning-background",
1859
+ "--kui-state-banner-warning-border",
1860
+ "--kui-state-banner-warning-foreground"
1861
+ ],
1862
+ "links": {
1863
+ "catalogRoute": "?component=state-banner",
1864
+ "documentation": "docs/component-selection.md",
1865
+ "recipe": "docs/component-selection.md#ambiguous-choices"
1866
+ }
1867
+ },
1868
+ {
1869
+ "id": "empty-state",
1870
+ "name": "EmptyState",
1871
+ "category": "Feedback",
1872
+ "kind": "component",
1873
+ "source": "kerf",
1874
+ "description": "Actionable empty and busy content states.",
1875
+ "uses": [
1876
+ "lucide-icon",
1877
+ "loading-spinner"
1878
+ ],
1879
+ "purpose": "Actionable empty and busy content states.",
1880
+ "publicExports": [
1881
+ "EmptyState"
1882
+ ],
1883
+ "useWhen": [
1884
+ "Explain absent or busy content and offer an optional recovery action."
1885
+ ],
1886
+ "avoidWhen": [
1887
+ "Do not use for an inline update or transient success."
1888
+ ],
1889
+ "alternatives": [
1890
+ {
1891
+ "id": "state-banner",
1892
+ "relationship": "nearest"
1893
+ },
1894
+ {
1895
+ "id": "wa-toast",
1896
+ "relationship": "prefer-over"
1897
+ }
1898
+ ],
1899
+ "appOwns": [
1900
+ "empty/busy policy",
1901
+ "recovery action",
1902
+ "copy"
1903
+ ],
1904
+ "variants": [
1905
+ "actionable",
1906
+ "busy",
1907
+ "illustrated"
1908
+ ],
1909
+ "accessibility": [
1910
+ "Busy state uses aria-busy; the illustration never supplies the only label."
1911
+ ],
1912
+ "delivery": {
1913
+ "browserImport": "@kerfjs/ui/empty-state",
1914
+ "manualCssImport": "@kerfjs/ui/empty-state.css",
1915
+ "sideEffects": [
1916
+ "browser-condition-css"
1917
+ ]
1918
+ },
1919
+ "wiring": [],
1920
+ "publicClasses": [
1921
+ "kui-empty-state",
1922
+ "kui-empty-state__action",
1923
+ "kui-empty-state__icon"
1924
+ ],
1925
+ "publicTokens": [
1926
+ "--kui-color-neutral-on-quiet",
1927
+ "--kui-color-text",
1928
+ "--kui-empty-state-foreground",
1929
+ "--kui-empty-state-title",
1930
+ "--kui-font-l",
1931
+ "--kui-font-s",
1932
+ "--kui-space-xl",
1933
+ "--kui-space-xs"
1934
+ ],
1935
+ "links": {
1936
+ "catalogRoute": "?component=empty-state",
1937
+ "documentation": "docs/component-selection.md",
1938
+ "recipe": "docs/component-selection.md#ambiguous-choices"
1939
+ }
1940
+ },
1941
+ {
1942
+ "id": "loading-spinner",
1943
+ "name": "LoadingSpinner",
1944
+ "category": "Feedback",
1945
+ "kind": "component",
1946
+ "source": "kerf",
1947
+ "description": "Meaningfully labeled or decorative progress.",
1948
+ "uses": [],
1949
+ "purpose": "Meaningfully labeled or decorative progress.",
1950
+ "publicExports": [
1951
+ "LoadingSpinner"
1952
+ ],
1953
+ "useWhen": [
1954
+ "Show compact labeled or decorative indeterminate activity in Kerf UI."
1955
+ ],
1956
+ "avoidWhen": [
1957
+ "Do not use for known progress."
1958
+ ],
1959
+ "alternatives": [
1960
+ {
1961
+ "id": "wa-spinner",
1962
+ "relationship": "prefer-over"
1963
+ },
1964
+ {
1965
+ "id": "wa-progress-bar",
1966
+ "relationship": "prefer-over"
1967
+ },
1968
+ {
1969
+ "id": "wa-progress-ring",
1970
+ "relationship": "prefer-over"
1971
+ }
1972
+ ],
1973
+ "appOwns": [
1974
+ "loading lifecycle",
1975
+ "adjacent status copy"
1976
+ ],
1977
+ "variants": [
1978
+ "labeled",
1979
+ "decorative"
1980
+ ],
1981
+ "accessibility": [
1982
+ "Labeled spinners use role img; decorative spinners are hidden and stop for reduced motion."
1983
+ ],
1984
+ "delivery": {
1985
+ "browserImport": "@kerfjs/ui/loading-spinner",
1986
+ "manualCssImport": "@kerfjs/ui/loading-spinner.css",
1987
+ "sideEffects": [
1988
+ "browser-condition-css"
1989
+ ]
1990
+ },
1991
+ "wiring": [],
1992
+ "publicClasses": [
1993
+ "kui-loading-spinner"
1994
+ ],
1995
+ "publicTokens": [],
1996
+ "links": {
1997
+ "catalogRoute": "?component=loading-spinner",
1998
+ "documentation": "docs/component-selection.md",
1999
+ "recipe": "docs/component-selection.md#problem-to-component-matrix"
2000
+ }
2001
+ },
2002
+ {
2003
+ "id": "wa-button",
2004
+ "name": "Button",
2005
+ "category": "Actions",
2006
+ "kind": "component",
2007
+ "source": "webawesome",
2008
+ "description": "Action control with semantic variants, appearances, loading, and icon support.",
2009
+ "uses": [
2010
+ "wa-icon",
2011
+ "wa-spinner"
2012
+ ],
2013
+ "purpose": "Action control with semantic variants, appearances, loading, and icon support.",
2014
+ "customElement": "wa-button",
2015
+ "useWhen": [
2016
+ "Action control with semantic variants, appearances, loading, and icon support."
2017
+ ],
2018
+ "avoidWhen": [
2019
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2020
+ ],
2021
+ "recommendation": "supported",
2022
+ "alternatives": [],
2023
+ "delivery": {
2024
+ "registrationImport": "@awesome.me/webawesome/dist/components/button/button.js",
2025
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2026
+ "sideEffects": [
2027
+ "custom-element-registration"
2028
+ ]
2029
+ },
2030
+ "links": {
2031
+ "catalogRoute": "?component=wa-button",
2032
+ "documentation": "docs/webawesome-theme.md#coverage",
2033
+ "recipe": "docs/webawesome-theme.md#coverage"
2034
+ }
2035
+ },
2036
+ {
2037
+ "id": "wa-button-group",
2038
+ "name": "Button Group",
2039
+ "category": "Actions",
2040
+ "kind": "component",
2041
+ "source": "webawesome",
2042
+ "description": "Exceptional grouped actions; prefer Kerf SegmentedControl for exclusive choices.",
2043
+ "uses": [
2044
+ "wa-button"
2045
+ ],
2046
+ "purpose": "Exceptional grouped actions; prefer Kerf SegmentedControl for exclusive choices.",
2047
+ "customElement": "wa-button-group",
2048
+ "useWhen": [
2049
+ "Exceptional grouped actions; prefer Kerf SegmentedControl for exclusive choices."
2050
+ ],
2051
+ "avoidWhen": [
2052
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2053
+ ],
2054
+ "recommendation": "conditional",
2055
+ "alternatives": [
2056
+ {
2057
+ "id": "segmented-control",
2058
+ "relationship": "prefer-kerf"
2059
+ }
2060
+ ],
2061
+ "delivery": {
2062
+ "registrationImport": "@awesome.me/webawesome/dist/components/button-group/button-group.js",
2063
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2064
+ "sideEffects": [
2065
+ "custom-element-registration"
2066
+ ]
2067
+ },
2068
+ "links": {
2069
+ "catalogRoute": "?component=wa-button-group",
2070
+ "documentation": "docs/webawesome-theme.md#coverage",
2071
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
2072
+ }
2073
+ },
2074
+ {
2075
+ "id": "wa-copy-button",
2076
+ "name": "Copy Button",
2077
+ "category": "Actions",
2078
+ "kind": "component",
2079
+ "source": "webawesome",
2080
+ "description": "Copies a supplied value and announces success or failure.",
2081
+ "uses": [
2082
+ "wa-icon",
2083
+ "wa-tooltip"
2084
+ ],
2085
+ "purpose": "Copies a supplied value and announces success or failure.",
2086
+ "customElement": "wa-copy-button",
2087
+ "useWhen": [
2088
+ "Copies a supplied value and announces success or failure."
2089
+ ],
2090
+ "avoidWhen": [
2091
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2092
+ ],
2093
+ "recommendation": "supported",
2094
+ "alternatives": [],
2095
+ "delivery": {
2096
+ "registrationImport": "@awesome.me/webawesome/dist/components/copy-button/copy-button.js",
2097
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2098
+ "sideEffects": [
2099
+ "custom-element-registration"
2100
+ ]
2101
+ },
2102
+ "links": {
2103
+ "catalogRoute": "?component=wa-copy-button",
2104
+ "documentation": "docs/webawesome-theme.md#coverage",
2105
+ "recipe": "docs/webawesome-theme.md#coverage"
2106
+ }
2107
+ },
2108
+ {
2109
+ "id": "wa-dropdown",
2110
+ "name": "Dropdown",
2111
+ "category": "Actions",
2112
+ "kind": "component",
2113
+ "source": "webawesome",
2114
+ "description": "Action-menu primitive; prefer Kerf Select when choosing a value.",
2115
+ "uses": [
2116
+ "wa-dropdown-item",
2117
+ "wa-popup"
2118
+ ],
2119
+ "purpose": "Action-menu primitive; prefer Kerf Select when choosing a value.",
2120
+ "customElement": "wa-dropdown",
2121
+ "useWhen": [
2122
+ "Action-menu primitive; prefer Kerf Select when choosing a value."
2123
+ ],
2124
+ "avoidWhen": [
2125
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2126
+ ],
2127
+ "recommendation": "conditional",
2128
+ "alternatives": [
2129
+ {
2130
+ "id": "select",
2131
+ "relationship": "prefer-kerf"
2132
+ }
2133
+ ],
2134
+ "delivery": {
2135
+ "registrationImport": "@awesome.me/webawesome/dist/components/dropdown/dropdown.js",
2136
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2137
+ "sideEffects": [
2138
+ "custom-element-registration"
2139
+ ]
2140
+ },
2141
+ "links": {
2142
+ "catalogRoute": "?component=wa-dropdown",
2143
+ "documentation": "docs/webawesome-theme.md#coverage",
2144
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
2145
+ }
2146
+ },
2147
+ {
2148
+ "id": "wa-dropdown-item",
2149
+ "name": "Dropdown Item",
2150
+ "category": "Actions",
2151
+ "kind": "component",
2152
+ "source": "webawesome",
2153
+ "description": "Action-menu row; prefer Kerf Select options for value selection.",
2154
+ "uses": [
2155
+ "wa-icon"
2156
+ ],
2157
+ "purpose": "Action-menu row; prefer Kerf Select options for value selection.",
2158
+ "customElement": "wa-dropdown-item",
2159
+ "useWhen": [
2160
+ "Action-menu row; prefer Kerf Select options for value selection."
2161
+ ],
2162
+ "avoidWhen": [
2163
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2164
+ ],
2165
+ "recommendation": "conditional",
2166
+ "alternatives": [
2167
+ {
2168
+ "id": "select",
2169
+ "relationship": "prefer-kerf"
2170
+ }
2171
+ ],
2172
+ "delivery": {
2173
+ "registrationImport": "@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js",
2174
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2175
+ "sideEffects": [
2176
+ "custom-element-registration"
2177
+ ]
2178
+ },
2179
+ "links": {
2180
+ "catalogRoute": "?component=wa-dropdown-item",
2181
+ "documentation": "docs/webawesome-theme.md#coverage",
2182
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
2183
+ }
2184
+ },
2185
+ {
2186
+ "id": "wa-checkbox",
2187
+ "name": "Checkbox",
2188
+ "category": "Forms",
2189
+ "kind": "component",
2190
+ "source": "webawesome",
2191
+ "description": "Binary form control with checked, indeterminate, and disabled states.",
2192
+ "uses": [
2193
+ "wa-icon"
2194
+ ],
2195
+ "purpose": "Binary form control with checked, indeterminate, and disabled states.",
2196
+ "customElement": "wa-checkbox",
2197
+ "useWhen": [
2198
+ "Binary form control with checked, indeterminate, and disabled states."
2199
+ ],
2200
+ "avoidWhen": [
2201
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2202
+ ],
2203
+ "recommendation": "supported",
2204
+ "alternatives": [],
2205
+ "delivery": {
2206
+ "registrationImport": "@awesome.me/webawesome/dist/components/checkbox/checkbox.js",
2207
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2208
+ "sideEffects": [
2209
+ "custom-element-registration"
2210
+ ]
2211
+ },
2212
+ "links": {
2213
+ "catalogRoute": "?component=wa-checkbox",
2214
+ "documentation": "docs/webawesome-theme.md#coverage",
2215
+ "recipe": "docs/webawesome-theme.md#coverage"
2216
+ }
2217
+ },
2218
+ {
2219
+ "id": "wa-checkbox-group",
2220
+ "name": "Checkbox Group",
2221
+ "category": "Forms",
2222
+ "kind": "component",
2223
+ "source": "webawesome",
2224
+ "description": "Labels and validates a related set of checkboxes.",
2225
+ "uses": [
2226
+ "wa-checkbox"
2227
+ ],
2228
+ "purpose": "Labels and validates a related set of checkboxes.",
2229
+ "customElement": "wa-checkbox-group",
2230
+ "useWhen": [
2231
+ "Labels and validates a related set of checkboxes."
2232
+ ],
2233
+ "avoidWhen": [
2234
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2235
+ ],
2236
+ "recommendation": "supported",
2237
+ "alternatives": [],
2238
+ "delivery": {
2239
+ "registrationImport": "@awesome.me/webawesome/dist/components/checkbox-group/checkbox-group.js",
2240
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2241
+ "sideEffects": [
2242
+ "custom-element-registration"
2243
+ ]
2244
+ },
2245
+ "links": {
2246
+ "catalogRoute": "?component=wa-checkbox-group",
2247
+ "documentation": "docs/webawesome-theme.md#coverage",
2248
+ "recipe": "docs/webawesome-theme.md#coverage"
2249
+ }
2250
+ },
2251
+ {
2252
+ "id": "wa-color-picker",
2253
+ "name": "Color Picker",
2254
+ "category": "Forms",
2255
+ "kind": "component",
2256
+ "source": "webawesome",
2257
+ "description": "Color input with swatches, formats, opacity, and eyedropper support.",
2258
+ "uses": [
2259
+ "wa-button",
2260
+ "wa-button-group",
2261
+ "wa-input",
2262
+ "wa-popup"
2263
+ ],
2264
+ "purpose": "Color input with swatches, formats, opacity, and eyedropper support.",
2265
+ "customElement": "wa-color-picker",
2266
+ "useWhen": [
2267
+ "Color input with swatches, formats, opacity, and eyedropper support."
2268
+ ],
2269
+ "avoidWhen": [
2270
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2271
+ ],
2272
+ "recommendation": "supported",
2273
+ "alternatives": [],
2274
+ "delivery": {
2275
+ "registrationImport": "@awesome.me/webawesome/dist/components/color-picker/color-picker.js",
2276
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2277
+ "sideEffects": [
2278
+ "custom-element-registration"
2279
+ ]
2280
+ },
2281
+ "links": {
2282
+ "catalogRoute": "?component=wa-color-picker",
2283
+ "documentation": "docs/webawesome-theme.md#coverage",
2284
+ "recipe": "docs/webawesome-theme.md#coverage"
2285
+ }
2286
+ },
2287
+ {
2288
+ "id": "wa-input",
2289
+ "name": "Input",
2290
+ "category": "Forms",
2291
+ "kind": "component",
2292
+ "source": "webawesome",
2293
+ "description": "Text input with labels, hints, clear controls, and semantic appearances.",
2294
+ "uses": [
2295
+ "wa-icon"
2296
+ ],
2297
+ "purpose": "Text input with labels, hints, clear controls, and semantic appearances.",
2298
+ "customElement": "wa-input",
2299
+ "useWhen": [
2300
+ "Text input with labels, hints, clear controls, and semantic appearances."
2301
+ ],
2302
+ "avoidWhen": [
2303
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2304
+ ],
2305
+ "recommendation": "supported",
2306
+ "alternatives": [
2307
+ {
2308
+ "id": "token-search-field",
2309
+ "relationship": "prefer-kerf"
2310
+ }
2311
+ ],
2312
+ "delivery": {
2313
+ "registrationImport": "@awesome.me/webawesome/dist/components/input/input.js",
2314
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2315
+ "sideEffects": [
2316
+ "custom-element-registration"
2317
+ ]
2318
+ },
2319
+ "links": {
2320
+ "catalogRoute": "?component=wa-input",
2321
+ "documentation": "docs/webawesome-theme.md#coverage",
2322
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
2323
+ }
2324
+ },
2325
+ {
2326
+ "id": "wa-known-date",
2327
+ "name": "Known Date",
2328
+ "category": "Forms",
2329
+ "kind": "component",
2330
+ "source": "webawesome",
2331
+ "description": "Experimental segmented field for partially or fully known dates.",
2332
+ "uses": [],
2333
+ "purpose": "Experimental segmented field for partially or fully known dates.",
2334
+ "customElement": "wa-known-date",
2335
+ "useWhen": [
2336
+ "Experimental segmented field for partially or fully known dates."
2337
+ ],
2338
+ "avoidWhen": [
2339
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2340
+ ],
2341
+ "recommendation": "supported",
2342
+ "alternatives": [],
2343
+ "delivery": {
2344
+ "registrationImport": "@awesome.me/webawesome/dist/components/known-date/known-date.js",
2345
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2346
+ "sideEffects": [
2347
+ "custom-element-registration"
2348
+ ]
2349
+ },
2350
+ "links": {
2351
+ "catalogRoute": "?component=wa-known-date",
2352
+ "documentation": "docs/webawesome-theme.md#coverage",
2353
+ "recipe": "docs/webawesome-theme.md#coverage"
2354
+ }
2355
+ },
2356
+ {
2357
+ "id": "wa-number-input",
2358
+ "name": "Number Input",
2359
+ "category": "Forms",
2360
+ "kind": "component",
2361
+ "source": "webawesome",
2362
+ "description": "Numeric input with keyboard and stepper controls.",
2363
+ "uses": [
2364
+ "wa-icon"
2365
+ ],
2366
+ "purpose": "Numeric input with keyboard and stepper controls.",
2367
+ "customElement": "wa-number-input",
2368
+ "useWhen": [
2369
+ "Numeric input with keyboard and stepper controls."
2370
+ ],
2371
+ "avoidWhen": [
2372
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2373
+ ],
2374
+ "recommendation": "supported",
2375
+ "alternatives": [],
2376
+ "delivery": {
2377
+ "registrationImport": "@awesome.me/webawesome/dist/components/number-input/number-input.js",
2378
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2379
+ "sideEffects": [
2380
+ "custom-element-registration"
2381
+ ]
2382
+ },
2383
+ "links": {
2384
+ "catalogRoute": "?component=wa-number-input",
2385
+ "documentation": "docs/webawesome-theme.md#coverage",
2386
+ "recipe": "docs/webawesome-theme.md#coverage"
2387
+ }
2388
+ },
2389
+ {
2390
+ "id": "wa-option",
2391
+ "name": "Option",
2392
+ "category": "Forms",
2393
+ "kind": "component",
2394
+ "source": "webawesome",
2395
+ "description": "Underlying ecosystem option; prefer choices passed to Kerf Select.",
2396
+ "uses": [
2397
+ "wa-icon"
2398
+ ],
2399
+ "purpose": "Underlying ecosystem option; prefer choices passed to Kerf Select.",
2400
+ "customElement": "wa-option",
2401
+ "useWhen": [
2402
+ "Underlying ecosystem option; prefer choices passed to Kerf Select."
2403
+ ],
2404
+ "avoidWhen": [
2405
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2406
+ ],
2407
+ "recommendation": "underlying",
2408
+ "alternatives": [
2409
+ {
2410
+ "id": "select",
2411
+ "relationship": "prefer-kerf"
2412
+ }
2413
+ ],
2414
+ "delivery": {
2415
+ "registrationImport": "@awesome.me/webawesome/dist/components/option/option.js",
2416
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2417
+ "sideEffects": [
2418
+ "custom-element-registration"
2419
+ ]
2420
+ },
2421
+ "links": {
2422
+ "catalogRoute": "?component=wa-option",
2423
+ "documentation": "docs/webawesome-theme.md#coverage",
2424
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
2425
+ }
2426
+ },
2427
+ {
2428
+ "id": "wa-otp-input",
2429
+ "name": "OTP Input",
2430
+ "category": "Forms",
2431
+ "kind": "component",
2432
+ "source": "webawesome",
2433
+ "description": "Experimental segmented one-time-password input.",
2434
+ "uses": [],
2435
+ "purpose": "Experimental segmented one-time-password input.",
2436
+ "customElement": "wa-otp-input",
2437
+ "useWhen": [
2438
+ "Experimental segmented one-time-password input."
2439
+ ],
2440
+ "avoidWhen": [
2441
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2442
+ ],
2443
+ "recommendation": "supported",
2444
+ "alternatives": [],
2445
+ "delivery": {
2446
+ "registrationImport": "@awesome.me/webawesome/dist/components/otp-input/otp-input.js",
2447
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2448
+ "sideEffects": [
2449
+ "custom-element-registration"
2450
+ ]
2451
+ },
2452
+ "links": {
2453
+ "catalogRoute": "?component=wa-otp-input",
2454
+ "documentation": "docs/webawesome-theme.md#coverage",
2455
+ "recipe": "docs/webawesome-theme.md#coverage"
2456
+ }
2457
+ },
2458
+ {
2459
+ "id": "wa-radio",
2460
+ "name": "Radio",
2461
+ "category": "Forms",
2462
+ "kind": "component",
2463
+ "source": "webawesome",
2464
+ "description": "Single-choice control used inside a radio group.",
2465
+ "uses": [
2466
+ "wa-icon"
2467
+ ],
2468
+ "purpose": "Single-choice control used inside a radio group.",
2469
+ "customElement": "wa-radio",
2470
+ "useWhen": [
2471
+ "Single-choice control used inside a radio group."
2472
+ ],
2473
+ "avoidWhen": [
2474
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2475
+ ],
2476
+ "recommendation": "supported",
2477
+ "alternatives": [],
2478
+ "delivery": {
2479
+ "registrationImport": "@awesome.me/webawesome/dist/components/radio/radio.js",
2480
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2481
+ "sideEffects": [
2482
+ "custom-element-registration"
2483
+ ]
2484
+ },
2485
+ "links": {
2486
+ "catalogRoute": "?component=wa-radio",
2487
+ "documentation": "docs/webawesome-theme.md#coverage",
2488
+ "recipe": "docs/webawesome-theme.md#coverage"
2489
+ }
2490
+ },
2491
+ {
2492
+ "id": "wa-radio-group",
2493
+ "name": "Radio Group",
2494
+ "category": "Forms",
2495
+ "kind": "component",
2496
+ "source": "webawesome",
2497
+ "description": "Labels and manages a mutually exclusive set of radios.",
2498
+ "uses": [
2499
+ "wa-radio"
2500
+ ],
2501
+ "purpose": "Labels and manages a mutually exclusive set of radios.",
2502
+ "customElement": "wa-radio-group",
2503
+ "useWhen": [
2504
+ "Labels and manages a mutually exclusive set of radios."
2505
+ ],
2506
+ "avoidWhen": [
2507
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2508
+ ],
2509
+ "recommendation": "supported",
2510
+ "alternatives": [],
2511
+ "delivery": {
2512
+ "registrationImport": "@awesome.me/webawesome/dist/components/radio-group/radio-group.js",
2513
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2514
+ "sideEffects": [
2515
+ "custom-element-registration"
2516
+ ]
2517
+ },
2518
+ "links": {
2519
+ "catalogRoute": "?component=wa-radio-group",
2520
+ "documentation": "docs/webawesome-theme.md#coverage",
2521
+ "recipe": "docs/webawesome-theme.md#coverage"
2522
+ }
2523
+ },
2524
+ {
2525
+ "id": "wa-rating",
2526
+ "name": "Rating",
2527
+ "category": "Forms",
2528
+ "kind": "component",
2529
+ "source": "webawesome",
2530
+ "description": "Interactive rating control with accessible labeling.",
2531
+ "uses": [
2532
+ "wa-icon"
2533
+ ],
2534
+ "purpose": "Interactive rating control with accessible labeling.",
2535
+ "customElement": "wa-rating",
2536
+ "useWhen": [
2537
+ "Interactive rating control with accessible labeling."
2538
+ ],
2539
+ "avoidWhen": [
2540
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2541
+ ],
2542
+ "recommendation": "supported",
2543
+ "alternatives": [],
2544
+ "delivery": {
2545
+ "registrationImport": "@awesome.me/webawesome/dist/components/rating/rating.js",
2546
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2547
+ "sideEffects": [
2548
+ "custom-element-registration"
2549
+ ]
2550
+ },
2551
+ "links": {
2552
+ "catalogRoute": "?component=wa-rating",
2553
+ "documentation": "docs/webawesome-theme.md#coverage",
2554
+ "recipe": "docs/webawesome-theme.md#coverage"
2555
+ }
2556
+ },
2557
+ {
2558
+ "id": "wa-select",
2559
+ "name": "Select",
2560
+ "category": "Forms",
2561
+ "kind": "component",
2562
+ "source": "webawesome",
2563
+ "description": "Underlying ecosystem field; prefer Kerf Select for app UI.",
2564
+ "uses": [
2565
+ "wa-icon",
2566
+ "wa-popup",
2567
+ "wa-tag",
2568
+ "wa-option"
2569
+ ],
2570
+ "purpose": "Underlying ecosystem field; prefer Kerf Select for app UI.",
2571
+ "customElement": "wa-select",
2572
+ "useWhen": [
2573
+ "Underlying ecosystem field; prefer Kerf Select for app UI."
2574
+ ],
2575
+ "avoidWhen": [
2576
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2577
+ ],
2578
+ "recommendation": "underlying",
2579
+ "alternatives": [
2580
+ {
2581
+ "id": "select",
2582
+ "relationship": "prefer-kerf"
2583
+ }
2584
+ ],
2585
+ "delivery": {
2586
+ "registrationImport": "@awesome.me/webawesome/dist/components/select/select.js",
2587
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2588
+ "sideEffects": [
2589
+ "custom-element-registration"
2590
+ ]
2591
+ },
2592
+ "links": {
2593
+ "catalogRoute": "?component=wa-select",
2594
+ "documentation": "docs/webawesome-theme.md#coverage",
2595
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
2596
+ }
2597
+ },
2598
+ {
2599
+ "id": "wa-slider",
2600
+ "name": "Slider",
2601
+ "category": "Forms",
2602
+ "kind": "component",
2603
+ "source": "webawesome",
2604
+ "description": "Range input with markers and value tooltip support.",
2605
+ "uses": [
2606
+ "wa-tooltip"
2607
+ ],
2608
+ "purpose": "Range input with markers and value tooltip support.",
2609
+ "customElement": "wa-slider",
2610
+ "useWhen": [
2611
+ "Range input with markers and value tooltip support."
2612
+ ],
2613
+ "avoidWhen": [
2614
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2615
+ ],
2616
+ "recommendation": "supported",
2617
+ "alternatives": [],
2618
+ "delivery": {
2619
+ "registrationImport": "@awesome.me/webawesome/dist/components/slider/slider.js",
2620
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2621
+ "sideEffects": [
2622
+ "custom-element-registration"
2623
+ ]
2624
+ },
2625
+ "links": {
2626
+ "catalogRoute": "?component=wa-slider",
2627
+ "documentation": "docs/webawesome-theme.md#coverage",
2628
+ "recipe": "docs/webawesome-theme.md#coverage"
2629
+ }
2630
+ },
2631
+ {
2632
+ "id": "wa-switch",
2633
+ "name": "Switch",
2634
+ "category": "Forms",
2635
+ "kind": "component",
2636
+ "source": "webawesome",
2637
+ "description": "Immediate on/off setting control.",
2638
+ "uses": [],
2639
+ "purpose": "Immediate on/off setting control.",
2640
+ "customElement": "wa-switch",
2641
+ "useWhen": [
2642
+ "Immediate on/off setting control."
2643
+ ],
2644
+ "avoidWhen": [
2645
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2646
+ ],
2647
+ "recommendation": "supported",
2648
+ "alternatives": [],
2649
+ "delivery": {
2650
+ "registrationImport": "@awesome.me/webawesome/dist/components/switch/switch.js",
2651
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2652
+ "sideEffects": [
2653
+ "custom-element-registration"
2654
+ ]
2655
+ },
2656
+ "links": {
2657
+ "catalogRoute": "?component=wa-switch",
2658
+ "documentation": "docs/webawesome-theme.md#coverage",
2659
+ "recipe": "docs/webawesome-theme.md#coverage"
2660
+ }
2661
+ },
2662
+ {
2663
+ "id": "wa-textarea",
2664
+ "name": "Textarea",
2665
+ "category": "Forms",
2666
+ "kind": "component",
2667
+ "source": "webawesome",
2668
+ "description": "Multiline text field with labels, hints, and resize behavior.",
2669
+ "uses": [],
2670
+ "purpose": "Multiline text field with labels, hints, and resize behavior.",
2671
+ "customElement": "wa-textarea",
2672
+ "useWhen": [
2673
+ "Multiline text field with labels, hints, and resize behavior."
2674
+ ],
2675
+ "avoidWhen": [
2676
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2677
+ ],
2678
+ "recommendation": "supported",
2679
+ "alternatives": [],
2680
+ "delivery": {
2681
+ "registrationImport": "@awesome.me/webawesome/dist/components/textarea/textarea.js",
2682
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2683
+ "sideEffects": [
2684
+ "custom-element-registration"
2685
+ ]
2686
+ },
2687
+ "links": {
2688
+ "catalogRoute": "?component=wa-textarea",
2689
+ "documentation": "docs/webawesome-theme.md#coverage",
2690
+ "recipe": "docs/webawesome-theme.md#coverage"
2691
+ }
2692
+ },
2693
+ {
2694
+ "id": "wa-time-input",
2695
+ "name": "Time Input",
2696
+ "category": "Forms",
2697
+ "kind": "component",
2698
+ "source": "webawesome",
2699
+ "description": "Experimental segmented time field with an optional picker.",
2700
+ "uses": [
2701
+ "wa-icon",
2702
+ "wa-popup"
2703
+ ],
2704
+ "purpose": "Experimental segmented time field with an optional picker.",
2705
+ "customElement": "wa-time-input",
2706
+ "useWhen": [
2707
+ "Experimental segmented time field with an optional picker."
2708
+ ],
2709
+ "avoidWhen": [
2710
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2711
+ ],
2712
+ "recommendation": "supported",
2713
+ "alternatives": [],
2714
+ "delivery": {
2715
+ "registrationImport": "@awesome.me/webawesome/dist/components/time-input/time-input.js",
2716
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2717
+ "sideEffects": [
2718
+ "custom-element-registration"
2719
+ ]
2720
+ },
2721
+ "links": {
2722
+ "catalogRoute": "?component=wa-time-input",
2723
+ "documentation": "docs/webawesome-theme.md#coverage",
2724
+ "recipe": "docs/webawesome-theme.md#coverage"
2725
+ }
2726
+ },
2727
+ {
2728
+ "id": "wa-accordion",
2729
+ "name": "Accordion",
2730
+ "category": "Layout",
2731
+ "kind": "component",
2732
+ "source": "webawesome",
2733
+ "description": "Coordinates one or more collapsible content sections.",
2734
+ "uses": [
2735
+ "wa-accordion-item"
2736
+ ],
2737
+ "purpose": "Coordinates one or more collapsible content sections.",
2738
+ "customElement": "wa-accordion",
2739
+ "useWhen": [
2740
+ "Coordinates one or more collapsible content sections."
2741
+ ],
2742
+ "avoidWhen": [
2743
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2744
+ ],
2745
+ "recommendation": "supported",
2746
+ "alternatives": [],
2747
+ "delivery": {
2748
+ "registrationImport": "@awesome.me/webawesome/dist/components/accordion/accordion.js",
2749
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2750
+ "sideEffects": [
2751
+ "custom-element-registration"
2752
+ ]
2753
+ },
2754
+ "links": {
2755
+ "catalogRoute": "?component=wa-accordion",
2756
+ "documentation": "docs/webawesome-theme.md#coverage",
2757
+ "recipe": "docs/webawesome-theme.md#coverage"
2758
+ }
2759
+ },
2760
+ {
2761
+ "id": "wa-accordion-item",
2762
+ "name": "Accordion Item",
2763
+ "category": "Layout",
2764
+ "kind": "component",
2765
+ "source": "webawesome",
2766
+ "description": "Experimental labeled disclosure section used by an accordion.",
2767
+ "uses": [
2768
+ "wa-icon"
2769
+ ],
2770
+ "purpose": "Experimental labeled disclosure section used by an accordion.",
2771
+ "customElement": "wa-accordion-item",
2772
+ "useWhen": [
2773
+ "Experimental labeled disclosure section used by an accordion."
2774
+ ],
2775
+ "avoidWhen": [
2776
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2777
+ ],
2778
+ "recommendation": "supported",
2779
+ "alternatives": [],
2780
+ "delivery": {
2781
+ "registrationImport": "@awesome.me/webawesome/dist/components/accordion-item/accordion-item.js",
2782
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2783
+ "sideEffects": [
2784
+ "custom-element-registration"
2785
+ ]
2786
+ },
2787
+ "links": {
2788
+ "catalogRoute": "?component=wa-accordion-item",
2789
+ "documentation": "docs/webawesome-theme.md#coverage",
2790
+ "recipe": "docs/webawesome-theme.md#coverage"
2791
+ }
2792
+ },
2793
+ {
2794
+ "id": "wa-card",
2795
+ "name": "Card",
2796
+ "category": "Layout",
2797
+ "kind": "component",
2798
+ "source": "webawesome",
2799
+ "description": "Groups related content and optional header, media, and footer slots.",
2800
+ "uses": [],
2801
+ "purpose": "Groups related content and optional header, media, and footer slots.",
2802
+ "customElement": "wa-card",
2803
+ "useWhen": [
2804
+ "Groups related content and optional header, media, and footer slots."
2805
+ ],
2806
+ "avoidWhen": [
2807
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2808
+ ],
2809
+ "recommendation": "supported",
2810
+ "alternatives": [],
2811
+ "delivery": {
2812
+ "registrationImport": "@awesome.me/webawesome/dist/components/card/card.js",
2813
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2814
+ "sideEffects": [
2815
+ "custom-element-registration"
2816
+ ]
2817
+ },
2818
+ "links": {
2819
+ "catalogRoute": "?component=wa-card",
2820
+ "documentation": "docs/webawesome-theme.md#coverage",
2821
+ "recipe": "docs/webawesome-theme.md#coverage"
2822
+ }
2823
+ },
2824
+ {
2825
+ "id": "wa-details",
2826
+ "name": "Details",
2827
+ "category": "Layout",
2828
+ "kind": "component",
2829
+ "source": "webawesome",
2830
+ "description": "Single disclosure panel for secondary information.",
2831
+ "uses": [
2832
+ "wa-icon"
2833
+ ],
2834
+ "purpose": "Single disclosure panel for secondary information.",
2835
+ "customElement": "wa-details",
2836
+ "useWhen": [
2837
+ "Single disclosure panel for secondary information."
2838
+ ],
2839
+ "avoidWhen": [
2840
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2841
+ ],
2842
+ "recommendation": "supported",
2843
+ "alternatives": [],
2844
+ "delivery": {
2845
+ "registrationImport": "@awesome.me/webawesome/dist/components/details/details.js",
2846
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2847
+ "sideEffects": [
2848
+ "custom-element-registration"
2849
+ ]
2850
+ },
2851
+ "links": {
2852
+ "catalogRoute": "?component=wa-details",
2853
+ "documentation": "docs/webawesome-theme.md#coverage",
2854
+ "recipe": "docs/webawesome-theme.md#coverage"
2855
+ }
2856
+ },
2857
+ {
2858
+ "id": "wa-dialog",
2859
+ "name": "Dialog",
2860
+ "category": "Layout",
2861
+ "kind": "component",
2862
+ "source": "webawesome",
2863
+ "description": "Modal surface for focused tasks and confirmations.",
2864
+ "uses": [
2865
+ "wa-button"
2866
+ ],
2867
+ "purpose": "Modal surface for focused tasks and confirmations.",
2868
+ "customElement": "wa-dialog",
2869
+ "useWhen": [
2870
+ "Modal surface for focused tasks and confirmations."
2871
+ ],
2872
+ "avoidWhen": [
2873
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2874
+ ],
2875
+ "recommendation": "supported",
2876
+ "alternatives": [],
2877
+ "delivery": {
2878
+ "registrationImport": "@awesome.me/webawesome/dist/components/dialog/dialog.js",
2879
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2880
+ "sideEffects": [
2881
+ "custom-element-registration"
2882
+ ]
2883
+ },
2884
+ "links": {
2885
+ "catalogRoute": "?component=wa-dialog",
2886
+ "documentation": "docs/webawesome-theme.md#coverage",
2887
+ "recipe": "docs/webawesome-theme.md#coverage"
2888
+ }
2889
+ },
2890
+ {
2891
+ "id": "wa-divider",
2892
+ "name": "Divider",
2893
+ "category": "Layout",
2894
+ "kind": "component",
2895
+ "source": "webawesome",
2896
+ "description": "Visual separator for related groups of content.",
2897
+ "uses": [],
2898
+ "purpose": "Visual separator for related groups of content.",
2899
+ "customElement": "wa-divider",
2900
+ "useWhen": [
2901
+ "Visual separator for related groups of content."
2902
+ ],
2903
+ "avoidWhen": [
2904
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2905
+ ],
2906
+ "recommendation": "supported",
2907
+ "alternatives": [],
2908
+ "delivery": {
2909
+ "registrationImport": "@awesome.me/webawesome/dist/components/divider/divider.js",
2910
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2911
+ "sideEffects": [
2912
+ "custom-element-registration"
2913
+ ]
2914
+ },
2915
+ "links": {
2916
+ "catalogRoute": "?component=wa-divider",
2917
+ "documentation": "docs/webawesome-theme.md#coverage",
2918
+ "recipe": "docs/webawesome-theme.md#coverage"
2919
+ }
2920
+ },
2921
+ {
2922
+ "id": "wa-drawer",
2923
+ "name": "Drawer",
2924
+ "category": "Layout",
2925
+ "kind": "component",
2926
+ "source": "webawesome",
2927
+ "description": "Edge-anchored modal surface for navigation or secondary tasks.",
2928
+ "uses": [
2929
+ "wa-button"
2930
+ ],
2931
+ "purpose": "Edge-anchored modal surface for navigation or secondary tasks.",
2932
+ "customElement": "wa-drawer",
2933
+ "useWhen": [
2934
+ "Edge-anchored modal surface for navigation or secondary tasks."
2935
+ ],
2936
+ "avoidWhen": [
2937
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2938
+ ],
2939
+ "recommendation": "supported",
2940
+ "alternatives": [],
2941
+ "delivery": {
2942
+ "registrationImport": "@awesome.me/webawesome/dist/components/drawer/drawer.js",
2943
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2944
+ "sideEffects": [
2945
+ "custom-element-registration"
2946
+ ]
2947
+ },
2948
+ "links": {
2949
+ "catalogRoute": "?component=wa-drawer",
2950
+ "documentation": "docs/webawesome-theme.md#coverage",
2951
+ "recipe": "docs/webawesome-theme.md#coverage"
2952
+ }
2953
+ },
2954
+ {
2955
+ "id": "wa-page",
2956
+ "name": "Page",
2957
+ "category": "Layout",
2958
+ "kind": "component",
2959
+ "source": "webawesome",
2960
+ "description": "Responsive application shell with navigation, banner, and main slots.",
2961
+ "uses": [],
2962
+ "purpose": "Responsive application shell with navigation, banner, and main slots.",
2963
+ "customElement": "wa-page",
2964
+ "useWhen": [
2965
+ "Responsive application shell with navigation, banner, and main slots."
2966
+ ],
2967
+ "avoidWhen": [
2968
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
2969
+ ],
2970
+ "recommendation": "supported",
2971
+ "alternatives": [],
2972
+ "delivery": {
2973
+ "registrationImport": "@awesome.me/webawesome/dist/components/page/page.js",
2974
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
2975
+ "sideEffects": [
2976
+ "custom-element-registration"
2977
+ ]
2978
+ },
2979
+ "links": {
2980
+ "catalogRoute": "?component=wa-page",
2981
+ "documentation": "docs/webawesome-theme.md#coverage",
2982
+ "recipe": "docs/webawesome-theme.md#coverage"
2983
+ }
2984
+ },
2985
+ {
2986
+ "id": "wa-scroller",
2987
+ "name": "Scroller",
2988
+ "category": "Layout",
2989
+ "kind": "component",
2990
+ "source": "webawesome",
2991
+ "description": "Overflow container with accessible scrolling affordances.",
2992
+ "uses": [],
2993
+ "purpose": "Overflow container with accessible scrolling affordances.",
2994
+ "customElement": "wa-scroller",
2995
+ "useWhen": [
2996
+ "Overflow container with accessible scrolling affordances."
2997
+ ],
2998
+ "avoidWhen": [
2999
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3000
+ ],
3001
+ "recommendation": "supported",
3002
+ "alternatives": [],
3003
+ "delivery": {
3004
+ "registrationImport": "@awesome.me/webawesome/dist/components/scroller/scroller.js",
3005
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3006
+ "sideEffects": [
3007
+ "custom-element-registration"
3008
+ ]
3009
+ },
3010
+ "links": {
3011
+ "catalogRoute": "?component=wa-scroller",
3012
+ "documentation": "docs/webawesome-theme.md#coverage",
3013
+ "recipe": "docs/webawesome-theme.md#coverage"
3014
+ }
3015
+ },
3016
+ {
3017
+ "id": "wa-split-panel",
3018
+ "name": "Split Panel",
3019
+ "category": "Layout",
3020
+ "kind": "component",
3021
+ "source": "webawesome",
3022
+ "description": "Alternative split API; prefer Kerf ResizableRegion for application panes.",
3023
+ "uses": [],
3024
+ "purpose": "Alternative split API; prefer Kerf ResizableRegion for application panes.",
3025
+ "customElement": "wa-split-panel",
3026
+ "useWhen": [
3027
+ "Alternative split API; prefer Kerf ResizableRegion for application panes."
3028
+ ],
3029
+ "avoidWhen": [
3030
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3031
+ ],
3032
+ "recommendation": "conditional",
3033
+ "alternatives": [
3034
+ {
3035
+ "id": "resize",
3036
+ "relationship": "prefer-kerf"
3037
+ }
3038
+ ],
3039
+ "delivery": {
3040
+ "registrationImport": "@awesome.me/webawesome/dist/components/split-panel/split-panel.js",
3041
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3042
+ "sideEffects": [
3043
+ "custom-element-registration"
3044
+ ]
3045
+ },
3046
+ "links": {
3047
+ "catalogRoute": "?component=wa-split-panel",
3048
+ "documentation": "docs/webawesome-theme.md#coverage",
3049
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3050
+ }
3051
+ },
3052
+ {
3053
+ "id": "wa-breadcrumb",
3054
+ "name": "Breadcrumb",
3055
+ "category": "Navigation",
3056
+ "kind": "component",
3057
+ "source": "webawesome",
3058
+ "description": "Ordered navigation trail for the current location.",
3059
+ "uses": [
3060
+ "wa-icon",
3061
+ "wa-breadcrumb-item"
3062
+ ],
3063
+ "purpose": "Ordered navigation trail for the current location.",
3064
+ "customElement": "wa-breadcrumb",
3065
+ "useWhen": [
3066
+ "Ordered navigation trail for the current location."
3067
+ ],
3068
+ "avoidWhen": [
3069
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3070
+ ],
3071
+ "recommendation": "supported",
3072
+ "alternatives": [],
3073
+ "delivery": {
3074
+ "registrationImport": "@awesome.me/webawesome/dist/components/breadcrumb/breadcrumb.js",
3075
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3076
+ "sideEffects": [
3077
+ "custom-element-registration"
3078
+ ]
3079
+ },
3080
+ "links": {
3081
+ "catalogRoute": "?component=wa-breadcrumb",
3082
+ "documentation": "docs/webawesome-theme.md#coverage",
3083
+ "recipe": "docs/webawesome-theme.md#coverage"
3084
+ }
3085
+ },
3086
+ {
3087
+ "id": "wa-breadcrumb-item",
3088
+ "name": "Breadcrumb Item",
3089
+ "category": "Navigation",
3090
+ "kind": "component",
3091
+ "source": "webawesome",
3092
+ "description": "One link or current-location item in a breadcrumb.",
3093
+ "uses": [],
3094
+ "purpose": "One link or current-location item in a breadcrumb.",
3095
+ "customElement": "wa-breadcrumb-item",
3096
+ "useWhen": [
3097
+ "One link or current-location item in a breadcrumb."
3098
+ ],
3099
+ "avoidWhen": [
3100
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3101
+ ],
3102
+ "recommendation": "supported",
3103
+ "alternatives": [],
3104
+ "delivery": {
3105
+ "registrationImport": "@awesome.me/webawesome/dist/components/breadcrumb-item/breadcrumb-item.js",
3106
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3107
+ "sideEffects": [
3108
+ "custom-element-registration"
3109
+ ]
3110
+ },
3111
+ "links": {
3112
+ "catalogRoute": "?component=wa-breadcrumb-item",
3113
+ "documentation": "docs/webawesome-theme.md#coverage",
3114
+ "recipe": "docs/webawesome-theme.md#coverage"
3115
+ }
3116
+ },
3117
+ {
3118
+ "id": "wa-pagination",
3119
+ "name": "Pagination",
3120
+ "category": "Navigation",
3121
+ "kind": "component",
3122
+ "source": "webawesome",
3123
+ "description": "Experimental page navigation for a bounded result set.",
3124
+ "uses": [
3125
+ "wa-icon"
3126
+ ],
3127
+ "purpose": "Experimental page navigation for a bounded result set.",
3128
+ "customElement": "wa-pagination",
3129
+ "useWhen": [
3130
+ "Experimental page navigation for a bounded result set."
3131
+ ],
3132
+ "avoidWhen": [
3133
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3134
+ ],
3135
+ "recommendation": "supported",
3136
+ "alternatives": [],
3137
+ "delivery": {
3138
+ "registrationImport": "@awesome.me/webawesome/dist/components/pagination/pagination.js",
3139
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3140
+ "sideEffects": [
3141
+ "custom-element-registration"
3142
+ ]
3143
+ },
3144
+ "links": {
3145
+ "catalogRoute": "?component=wa-pagination",
3146
+ "documentation": "docs/webawesome-theme.md#coverage",
3147
+ "recipe": "docs/webawesome-theme.md#coverage"
3148
+ }
3149
+ },
3150
+ {
3151
+ "id": "wa-tab",
3152
+ "name": "Tab",
3153
+ "category": "Navigation",
3154
+ "kind": "component",
3155
+ "source": "webawesome",
3156
+ "description": "Ecosystem tab label; prefer Kerf TabBar or SegmentedControl.",
3157
+ "uses": [],
3158
+ "purpose": "Ecosystem tab label; prefer Kerf TabBar or SegmentedControl.",
3159
+ "customElement": "wa-tab",
3160
+ "useWhen": [
3161
+ "Ecosystem tab label; prefer Kerf TabBar or SegmentedControl."
3162
+ ],
3163
+ "avoidWhen": [
3164
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3165
+ ],
3166
+ "recommendation": "conditional",
3167
+ "alternatives": [
3168
+ {
3169
+ "id": "tab-bar",
3170
+ "relationship": "prefer-kerf"
3171
+ },
3172
+ {
3173
+ "id": "segmented-control",
3174
+ "relationship": "prefer-kerf"
3175
+ }
3176
+ ],
3177
+ "delivery": {
3178
+ "registrationImport": "@awesome.me/webawesome/dist/components/tab/tab.js",
3179
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3180
+ "sideEffects": [
3181
+ "custom-element-registration"
3182
+ ]
3183
+ },
3184
+ "links": {
3185
+ "catalogRoute": "?component=wa-tab",
3186
+ "documentation": "docs/webawesome-theme.md#coverage",
3187
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3188
+ }
3189
+ },
3190
+ {
3191
+ "id": "wa-tab-group",
3192
+ "name": "Tab Group",
3193
+ "category": "Navigation",
3194
+ "kind": "component",
3195
+ "source": "webawesome",
3196
+ "description": "Ecosystem tabs; prefer Kerf TabBar or SegmentedControl.",
3197
+ "uses": [
3198
+ "wa-button",
3199
+ "wa-tab",
3200
+ "wa-tab-panel"
3201
+ ],
3202
+ "purpose": "Ecosystem tabs; prefer Kerf TabBar or SegmentedControl.",
3203
+ "customElement": "wa-tab-group",
3204
+ "useWhen": [
3205
+ "Ecosystem tabs; prefer Kerf TabBar or SegmentedControl."
3206
+ ],
3207
+ "avoidWhen": [
3208
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3209
+ ],
3210
+ "recommendation": "conditional",
3211
+ "alternatives": [
3212
+ {
3213
+ "id": "tab-bar",
3214
+ "relationship": "prefer-kerf"
3215
+ },
3216
+ {
3217
+ "id": "segmented-control",
3218
+ "relationship": "prefer-kerf"
3219
+ }
3220
+ ],
3221
+ "delivery": {
3222
+ "registrationImport": "@awesome.me/webawesome/dist/components/tab-group/tab-group.js",
3223
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3224
+ "sideEffects": [
3225
+ "custom-element-registration"
3226
+ ]
3227
+ },
3228
+ "links": {
3229
+ "catalogRoute": "?component=wa-tab-group",
3230
+ "documentation": "docs/webawesome-theme.md#coverage",
3231
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3232
+ }
3233
+ },
3234
+ {
3235
+ "id": "wa-tab-panel",
3236
+ "name": "Tab Panel",
3237
+ "category": "Navigation",
3238
+ "kind": "component",
3239
+ "source": "webawesome",
3240
+ "description": "Ecosystem tab panel; prefer app-owned panels with Kerf navigation.",
3241
+ "uses": [],
3242
+ "purpose": "Ecosystem tab panel; prefer app-owned panels with Kerf navigation.",
3243
+ "customElement": "wa-tab-panel",
3244
+ "useWhen": [
3245
+ "Ecosystem tab panel; prefer app-owned panels with Kerf navigation."
3246
+ ],
3247
+ "avoidWhen": [
3248
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3249
+ ],
3250
+ "recommendation": "conditional",
3251
+ "alternatives": [
3252
+ {
3253
+ "id": "tab-bar",
3254
+ "relationship": "prefer-kerf"
3255
+ }
3256
+ ],
3257
+ "delivery": {
3258
+ "registrationImport": "@awesome.me/webawesome/dist/components/tab-panel/tab-panel.js",
3259
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3260
+ "sideEffects": [
3261
+ "custom-element-registration"
3262
+ ]
3263
+ },
3264
+ "links": {
3265
+ "catalogRoute": "?component=wa-tab-panel",
3266
+ "documentation": "docs/webawesome-theme.md#coverage",
3267
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3268
+ }
3269
+ },
3270
+ {
3271
+ "id": "wa-tree",
3272
+ "name": "Tree",
3273
+ "category": "Navigation",
3274
+ "kind": "component",
3275
+ "source": "webawesome",
3276
+ "description": "Specialized hierarchy; use only when the product requires tree behavior.",
3277
+ "uses": [
3278
+ "wa-tree-item"
3279
+ ],
3280
+ "purpose": "Specialized hierarchy; use only when the product requires tree behavior.",
3281
+ "customElement": "wa-tree",
3282
+ "useWhen": [
3283
+ "Specialized hierarchy; use only when the product requires tree behavior."
3284
+ ],
3285
+ "avoidWhen": [
3286
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3287
+ ],
3288
+ "recommendation": "exceptional",
3289
+ "alternatives": [],
3290
+ "delivery": {
3291
+ "registrationImport": "@awesome.me/webawesome/dist/components/tree/tree.js",
3292
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3293
+ "sideEffects": [
3294
+ "custom-element-registration"
3295
+ ]
3296
+ },
3297
+ "links": {
3298
+ "catalogRoute": "?component=wa-tree",
3299
+ "documentation": "docs/webawesome-theme.md#coverage",
3300
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3301
+ }
3302
+ },
3303
+ {
3304
+ "id": "wa-tree-item",
3305
+ "name": "Tree Item",
3306
+ "category": "Navigation",
3307
+ "kind": "component",
3308
+ "source": "webawesome",
3309
+ "description": "Specialized tree row; use only as part of a required tree.",
3310
+ "uses": [
3311
+ "wa-checkbox",
3312
+ "wa-icon",
3313
+ "wa-spinner"
3314
+ ],
3315
+ "purpose": "Specialized tree row; use only as part of a required tree.",
3316
+ "customElement": "wa-tree-item",
3317
+ "useWhen": [
3318
+ "Specialized tree row; use only as part of a required tree."
3319
+ ],
3320
+ "avoidWhen": [
3321
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3322
+ ],
3323
+ "recommendation": "exceptional",
3324
+ "alternatives": [],
3325
+ "delivery": {
3326
+ "registrationImport": "@awesome.me/webawesome/dist/components/tree-item/tree-item.js",
3327
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3328
+ "sideEffects": [
3329
+ "custom-element-registration"
3330
+ ]
3331
+ },
3332
+ "links": {
3333
+ "catalogRoute": "?component=wa-tree-item",
3334
+ "documentation": "docs/webawesome-theme.md#coverage",
3335
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3336
+ }
3337
+ },
3338
+ {
3339
+ "id": "wa-badge",
3340
+ "name": "Badge",
3341
+ "category": "Feedback",
3342
+ "kind": "component",
3343
+ "source": "webawesome",
3344
+ "description": "Compact status or count label with semantic variants.",
3345
+ "uses": [],
3346
+ "purpose": "Compact status or count label with semantic variants.",
3347
+ "customElement": "wa-badge",
3348
+ "useWhen": [
3349
+ "Compact status or count label with semantic variants."
3350
+ ],
3351
+ "avoidWhen": [
3352
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3353
+ ],
3354
+ "recommendation": "supported",
3355
+ "alternatives": [],
3356
+ "delivery": {
3357
+ "registrationImport": "@awesome.me/webawesome/dist/components/badge/badge.js",
3358
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3359
+ "sideEffects": [
3360
+ "custom-element-registration"
3361
+ ]
3362
+ },
3363
+ "links": {
3364
+ "catalogRoute": "?component=wa-badge",
3365
+ "documentation": "docs/webawesome-theme.md#coverage",
3366
+ "recipe": "docs/webawesome-theme.md#coverage"
3367
+ }
3368
+ },
3369
+ {
3370
+ "id": "wa-callout",
3371
+ "name": "Callout",
3372
+ "category": "Feedback",
3373
+ "kind": "component",
3374
+ "source": "webawesome",
3375
+ "description": "Prominent contextual message with semantic variants.",
3376
+ "uses": [],
3377
+ "purpose": "Prominent contextual message with semantic variants.",
3378
+ "customElement": "wa-callout",
3379
+ "useWhen": [
3380
+ "Prominent contextual message with semantic variants."
3381
+ ],
3382
+ "avoidWhen": [
3383
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3384
+ ],
3385
+ "recommendation": "supported",
3386
+ "alternatives": [
3387
+ {
3388
+ "id": "state-banner",
3389
+ "relationship": "prefer-kerf"
3390
+ }
3391
+ ],
3392
+ "delivery": {
3393
+ "registrationImport": "@awesome.me/webawesome/dist/components/callout/callout.js",
3394
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3395
+ "sideEffects": [
3396
+ "custom-element-registration"
3397
+ ]
3398
+ },
3399
+ "links": {
3400
+ "catalogRoute": "?component=wa-callout",
3401
+ "documentation": "docs/webawesome-theme.md#coverage",
3402
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3403
+ }
3404
+ },
3405
+ {
3406
+ "id": "wa-progress-bar",
3407
+ "name": "Progress Bar",
3408
+ "category": "Feedback",
3409
+ "kind": "component",
3410
+ "source": "webawesome",
3411
+ "description": "Linear indicator for determinate or indeterminate progress.",
3412
+ "uses": [],
3413
+ "purpose": "Linear indicator for determinate or indeterminate progress.",
3414
+ "customElement": "wa-progress-bar",
3415
+ "useWhen": [
3416
+ "Linear indicator for determinate or indeterminate progress."
3417
+ ],
3418
+ "avoidWhen": [
3419
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3420
+ ],
3421
+ "recommendation": "supported",
3422
+ "alternatives": [],
3423
+ "delivery": {
3424
+ "registrationImport": "@awesome.me/webawesome/dist/components/progress-bar/progress-bar.js",
3425
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3426
+ "sideEffects": [
3427
+ "custom-element-registration"
3428
+ ]
3429
+ },
3430
+ "links": {
3431
+ "catalogRoute": "?component=wa-progress-bar",
3432
+ "documentation": "docs/webawesome-theme.md#coverage",
3433
+ "recipe": "docs/webawesome-theme.md#coverage"
3434
+ }
3435
+ },
3436
+ {
3437
+ "id": "wa-progress-ring",
3438
+ "name": "Progress Ring",
3439
+ "category": "Feedback",
3440
+ "kind": "component",
3441
+ "source": "webawesome",
3442
+ "description": "Circular indicator for determinate or indeterminate progress.",
3443
+ "uses": [],
3444
+ "purpose": "Circular indicator for determinate or indeterminate progress.",
3445
+ "customElement": "wa-progress-ring",
3446
+ "useWhen": [
3447
+ "Circular indicator for determinate or indeterminate progress."
3448
+ ],
3449
+ "avoidWhen": [
3450
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3451
+ ],
3452
+ "recommendation": "supported",
3453
+ "alternatives": [],
3454
+ "delivery": {
3455
+ "registrationImport": "@awesome.me/webawesome/dist/components/progress-ring/progress-ring.js",
3456
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3457
+ "sideEffects": [
3458
+ "custom-element-registration"
3459
+ ]
3460
+ },
3461
+ "links": {
3462
+ "catalogRoute": "?component=wa-progress-ring",
3463
+ "documentation": "docs/webawesome-theme.md#coverage",
3464
+ "recipe": "docs/webawesome-theme.md#coverage"
3465
+ }
3466
+ },
3467
+ {
3468
+ "id": "wa-skeleton",
3469
+ "name": "Skeleton",
3470
+ "category": "Feedback",
3471
+ "kind": "component",
3472
+ "source": "webawesome",
3473
+ "description": "Placeholder shape for content that is still loading.",
3474
+ "uses": [],
3475
+ "purpose": "Placeholder shape for content that is still loading.",
3476
+ "customElement": "wa-skeleton",
3477
+ "useWhen": [
3478
+ "Placeholder shape for content that is still loading."
3479
+ ],
3480
+ "avoidWhen": [
3481
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3482
+ ],
3483
+ "recommendation": "supported",
3484
+ "alternatives": [],
3485
+ "delivery": {
3486
+ "registrationImport": "@awesome.me/webawesome/dist/components/skeleton/skeleton.js",
3487
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3488
+ "sideEffects": [
3489
+ "custom-element-registration"
3490
+ ]
3491
+ },
3492
+ "links": {
3493
+ "catalogRoute": "?component=wa-skeleton",
3494
+ "documentation": "docs/webawesome-theme.md#coverage",
3495
+ "recipe": "docs/webawesome-theme.md#coverage"
3496
+ }
3497
+ },
3498
+ {
3499
+ "id": "wa-spinner",
3500
+ "name": "Spinner",
3501
+ "category": "Feedback",
3502
+ "kind": "component",
3503
+ "source": "webawesome",
3504
+ "description": "Compact indeterminate activity indicator.",
3505
+ "uses": [],
3506
+ "purpose": "Compact indeterminate activity indicator.",
3507
+ "customElement": "wa-spinner",
3508
+ "useWhen": [
3509
+ "Compact indeterminate activity indicator."
3510
+ ],
3511
+ "avoidWhen": [
3512
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3513
+ ],
3514
+ "recommendation": "supported",
3515
+ "alternatives": [
3516
+ {
3517
+ "id": "loading-spinner",
3518
+ "relationship": "prefer-kerf"
3519
+ }
3520
+ ],
3521
+ "delivery": {
3522
+ "registrationImport": "@awesome.me/webawesome/dist/components/spinner/spinner.js",
3523
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3524
+ "sideEffects": [
3525
+ "custom-element-registration"
3526
+ ]
3527
+ },
3528
+ "links": {
3529
+ "catalogRoute": "?component=wa-spinner",
3530
+ "documentation": "docs/webawesome-theme.md#coverage",
3531
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3532
+ }
3533
+ },
3534
+ {
3535
+ "id": "wa-tag",
3536
+ "name": "Tag",
3537
+ "category": "Feedback",
3538
+ "kind": "component",
3539
+ "source": "webawesome",
3540
+ "description": "Compact categorization label with optional removal action.",
3541
+ "uses": [
3542
+ "wa-button"
3543
+ ],
3544
+ "purpose": "Compact categorization label with optional removal action.",
3545
+ "customElement": "wa-tag",
3546
+ "useWhen": [
3547
+ "Compact categorization label with optional removal action."
3548
+ ],
3549
+ "avoidWhen": [
3550
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3551
+ ],
3552
+ "recommendation": "supported",
3553
+ "alternatives": [
3554
+ {
3555
+ "id": "token-search-field",
3556
+ "relationship": "prefer-kerf"
3557
+ }
3558
+ ],
3559
+ "delivery": {
3560
+ "registrationImport": "@awesome.me/webawesome/dist/components/tag/tag.js",
3561
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3562
+ "sideEffects": [
3563
+ "custom-element-registration"
3564
+ ]
3565
+ },
3566
+ "links": {
3567
+ "catalogRoute": "?component=wa-tag",
3568
+ "documentation": "docs/webawesome-theme.md#coverage",
3569
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3570
+ }
3571
+ },
3572
+ {
3573
+ "id": "wa-toast",
3574
+ "name": "Toast",
3575
+ "category": "Feedback",
3576
+ "kind": "component",
3577
+ "source": "webawesome",
3578
+ "description": "Placement-aware stack of transient notifications.",
3579
+ "uses": [
3580
+ "wa-toast-item"
3581
+ ],
3582
+ "purpose": "Placement-aware stack of transient notifications.",
3583
+ "customElement": "wa-toast",
3584
+ "useWhen": [
3585
+ "Placement-aware stack of transient notifications."
3586
+ ],
3587
+ "avoidWhen": [
3588
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3589
+ ],
3590
+ "recommendation": "supported",
3591
+ "alternatives": [
3592
+ {
3593
+ "id": "state-banner",
3594
+ "relationship": "prefer-kerf"
3595
+ },
3596
+ {
3597
+ "id": "empty-state",
3598
+ "relationship": "prefer-kerf"
3599
+ }
3600
+ ],
3601
+ "delivery": {
3602
+ "registrationImport": "@awesome.me/webawesome/dist/components/toast/toast.js",
3603
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3604
+ "sideEffects": [
3605
+ "custom-element-registration"
3606
+ ]
3607
+ },
3608
+ "links": {
3609
+ "catalogRoute": "?component=wa-toast",
3610
+ "documentation": "docs/webawesome-theme.md#coverage",
3611
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3612
+ }
3613
+ },
3614
+ {
3615
+ "id": "wa-toast-item",
3616
+ "name": "Toast Item",
3617
+ "category": "Feedback",
3618
+ "kind": "component",
3619
+ "source": "webawesome",
3620
+ "description": "One dismissible notification inside a toast stack.",
3621
+ "uses": [
3622
+ "wa-icon",
3623
+ "wa-progress-ring"
3624
+ ],
3625
+ "purpose": "One dismissible notification inside a toast stack.",
3626
+ "customElement": "wa-toast-item",
3627
+ "useWhen": [
3628
+ "One dismissible notification inside a toast stack."
3629
+ ],
3630
+ "avoidWhen": [
3631
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3632
+ ],
3633
+ "recommendation": "supported",
3634
+ "alternatives": [
3635
+ {
3636
+ "id": "state-banner",
3637
+ "relationship": "prefer-kerf"
3638
+ },
3639
+ {
3640
+ "id": "empty-state",
3641
+ "relationship": "prefer-kerf"
3642
+ }
3643
+ ],
3644
+ "delivery": {
3645
+ "registrationImport": "@awesome.me/webawesome/dist/components/toast-item/toast-item.js",
3646
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3647
+ "sideEffects": [
3648
+ "custom-element-registration"
3649
+ ]
3650
+ },
3651
+ "links": {
3652
+ "catalogRoute": "?component=wa-toast-item",
3653
+ "documentation": "docs/webawesome-theme.md#coverage",
3654
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3655
+ }
3656
+ },
3657
+ {
3658
+ "id": "wa-tooltip",
3659
+ "name": "Tooltip",
3660
+ "category": "Feedback",
3661
+ "kind": "component",
3662
+ "source": "webawesome",
3663
+ "description": "Brief contextual label anchored to a control.",
3664
+ "uses": [
3665
+ "wa-popup"
3666
+ ],
3667
+ "purpose": "Brief contextual label anchored to a control.",
3668
+ "customElement": "wa-tooltip",
3669
+ "useWhen": [
3670
+ "Brief contextual label anchored to a control."
3671
+ ],
3672
+ "avoidWhen": [
3673
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3674
+ ],
3675
+ "recommendation": "supported",
3676
+ "alternatives": [],
3677
+ "delivery": {
3678
+ "registrationImport": "@awesome.me/webawesome/dist/components/tooltip/tooltip.js",
3679
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3680
+ "sideEffects": [
3681
+ "custom-element-registration"
3682
+ ]
3683
+ },
3684
+ "links": {
3685
+ "catalogRoute": "?component=wa-tooltip",
3686
+ "documentation": "docs/webawesome-theme.md#coverage",
3687
+ "recipe": "docs/webawesome-theme.md#coverage"
3688
+ }
3689
+ },
3690
+ {
3691
+ "id": "wa-animated-image",
3692
+ "name": "Animated Image",
3693
+ "category": "Media",
3694
+ "kind": "component",
3695
+ "source": "webawesome",
3696
+ "description": "Specialized animated media; use only for a concrete product requirement.",
3697
+ "uses": [
3698
+ "wa-icon"
3699
+ ],
3700
+ "purpose": "Specialized animated media; use only for a concrete product requirement.",
3701
+ "customElement": "wa-animated-image",
3702
+ "useWhen": [
3703
+ "Specialized animated media; use only for a concrete product requirement."
3704
+ ],
3705
+ "avoidWhen": [
3706
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3707
+ ],
3708
+ "recommendation": "exceptional",
3709
+ "alternatives": [],
3710
+ "delivery": {
3711
+ "registrationImport": "@awesome.me/webawesome/dist/components/animated-image/animated-image.js",
3712
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3713
+ "sideEffects": [
3714
+ "custom-element-registration"
3715
+ ]
3716
+ },
3717
+ "links": {
3718
+ "catalogRoute": "?component=wa-animated-image",
3719
+ "documentation": "docs/webawesome-theme.md#coverage",
3720
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3721
+ }
3722
+ },
3723
+ {
3724
+ "id": "wa-avatar",
3725
+ "name": "Avatar",
3726
+ "category": "Media",
3727
+ "kind": "component",
3728
+ "source": "webawesome",
3729
+ "description": "Person or entity image with initials fallback.",
3730
+ "uses": [
3731
+ "wa-icon"
3732
+ ],
3733
+ "purpose": "Person or entity image with initials fallback.",
3734
+ "customElement": "wa-avatar",
3735
+ "useWhen": [
3736
+ "Person or entity image with initials fallback."
3737
+ ],
3738
+ "avoidWhen": [
3739
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3740
+ ],
3741
+ "recommendation": "supported",
3742
+ "alternatives": [],
3743
+ "delivery": {
3744
+ "registrationImport": "@awesome.me/webawesome/dist/components/avatar/avatar.js",
3745
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3746
+ "sideEffects": [
3747
+ "custom-element-registration"
3748
+ ]
3749
+ },
3750
+ "links": {
3751
+ "catalogRoute": "?component=wa-avatar",
3752
+ "documentation": "docs/webawesome-theme.md#coverage",
3753
+ "recipe": "docs/webawesome-theme.md#coverage"
3754
+ }
3755
+ },
3756
+ {
3757
+ "id": "wa-carousel",
3758
+ "name": "Carousel",
3759
+ "category": "Media",
3760
+ "kind": "component",
3761
+ "source": "webawesome",
3762
+ "description": "Navigable horizontal or vertical collection of slides.",
3763
+ "uses": [
3764
+ "wa-icon",
3765
+ "wa-carousel-item"
3766
+ ],
3767
+ "purpose": "Navigable horizontal or vertical collection of slides.",
3768
+ "customElement": "wa-carousel",
3769
+ "useWhen": [
3770
+ "Navigable horizontal or vertical collection of slides."
3771
+ ],
3772
+ "avoidWhen": [
3773
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3774
+ ],
3775
+ "recommendation": "supported",
3776
+ "alternatives": [],
3777
+ "delivery": {
3778
+ "registrationImport": "@awesome.me/webawesome/dist/components/carousel/carousel.js",
3779
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3780
+ "sideEffects": [
3781
+ "custom-element-registration"
3782
+ ]
3783
+ },
3784
+ "links": {
3785
+ "catalogRoute": "?component=wa-carousel",
3786
+ "documentation": "docs/webawesome-theme.md#coverage",
3787
+ "recipe": "docs/webawesome-theme.md#coverage"
3788
+ }
3789
+ },
3790
+ {
3791
+ "id": "wa-carousel-item",
3792
+ "name": "Carousel Item",
3793
+ "category": "Media",
3794
+ "kind": "component",
3795
+ "source": "webawesome",
3796
+ "description": "One content slide inside a carousel.",
3797
+ "uses": [],
3798
+ "purpose": "One content slide inside a carousel.",
3799
+ "customElement": "wa-carousel-item",
3800
+ "useWhen": [
3801
+ "One content slide inside a carousel."
3802
+ ],
3803
+ "avoidWhen": [
3804
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3805
+ ],
3806
+ "recommendation": "supported",
3807
+ "alternatives": [],
3808
+ "delivery": {
3809
+ "registrationImport": "@awesome.me/webawesome/dist/components/carousel-item/carousel-item.js",
3810
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3811
+ "sideEffects": [
3812
+ "custom-element-registration"
3813
+ ]
3814
+ },
3815
+ "links": {
3816
+ "catalogRoute": "?component=wa-carousel-item",
3817
+ "documentation": "docs/webawesome-theme.md#coverage",
3818
+ "recipe": "docs/webawesome-theme.md#coverage"
3819
+ }
3820
+ },
3821
+ {
3822
+ "id": "wa-comparison",
3823
+ "name": "Comparison",
3824
+ "category": "Media",
3825
+ "kind": "component",
3826
+ "source": "webawesome",
3827
+ "description": "Specialized before-and-after media; use only when specifically required.",
3828
+ "uses": [
3829
+ "wa-icon"
3830
+ ],
3831
+ "purpose": "Specialized before-and-after media; use only when specifically required.",
3832
+ "customElement": "wa-comparison",
3833
+ "useWhen": [
3834
+ "Specialized before-and-after media; use only when specifically required."
3835
+ ],
3836
+ "avoidWhen": [
3837
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3838
+ ],
3839
+ "recommendation": "exceptional",
3840
+ "alternatives": [],
3841
+ "delivery": {
3842
+ "registrationImport": "@awesome.me/webawesome/dist/components/comparison/comparison.js",
3843
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3844
+ "sideEffects": [
3845
+ "custom-element-registration"
3846
+ ]
3847
+ },
3848
+ "links": {
3849
+ "catalogRoute": "?component=wa-comparison",
3850
+ "documentation": "docs/webawesome-theme.md#coverage",
3851
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3852
+ }
3853
+ },
3854
+ {
3855
+ "id": "wa-icon",
3856
+ "name": "Icon",
3857
+ "category": "Media",
3858
+ "kind": "component",
3859
+ "source": "webawesome",
3860
+ "description": "Ecosystem icon renderer; use Kerf LucideIcon in application UI.",
3861
+ "uses": [],
3862
+ "purpose": "Ecosystem icon renderer; use Kerf LucideIcon in application UI.",
3863
+ "customElement": "wa-icon",
3864
+ "useWhen": [
3865
+ "Ecosystem icon renderer; use Kerf LucideIcon in application UI."
3866
+ ],
3867
+ "avoidWhen": [
3868
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3869
+ ],
3870
+ "recommendation": "avoid",
3871
+ "alternatives": [
3872
+ {
3873
+ "id": "lucide-icon",
3874
+ "relationship": "prefer-kerf"
3875
+ }
3876
+ ],
3877
+ "delivery": {
3878
+ "registrationImport": "@awesome.me/webawesome/dist/components/icon/icon.js",
3879
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3880
+ "sideEffects": [
3881
+ "custom-element-registration"
3882
+ ]
3883
+ },
3884
+ "links": {
3885
+ "catalogRoute": "?component=wa-icon",
3886
+ "documentation": "docs/webawesome-theme.md#coverage",
3887
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3888
+ }
3889
+ },
3890
+ {
3891
+ "id": "wa-markdown",
3892
+ "name": "Markdown",
3893
+ "category": "Media",
3894
+ "kind": "component",
3895
+ "source": "webawesome",
3896
+ "description": "Experimental renderer for trusted Markdown content.",
3897
+ "uses": [],
3898
+ "purpose": "Experimental renderer for trusted Markdown content.",
3899
+ "customElement": "wa-markdown",
3900
+ "useWhen": [
3901
+ "Experimental renderer for trusted Markdown content."
3902
+ ],
3903
+ "avoidWhen": [
3904
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3905
+ ],
3906
+ "recommendation": "supported",
3907
+ "alternatives": [],
3908
+ "delivery": {
3909
+ "registrationImport": "@awesome.me/webawesome/dist/components/markdown/markdown.js",
3910
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3911
+ "sideEffects": [
3912
+ "custom-element-registration"
3913
+ ]
3914
+ },
3915
+ "links": {
3916
+ "catalogRoute": "?component=wa-markdown",
3917
+ "documentation": "docs/webawesome-theme.md#coverage",
3918
+ "recipe": "docs/webawesome-theme.md#coverage"
3919
+ }
3920
+ },
3921
+ {
3922
+ "id": "wa-qr-code",
3923
+ "name": "QR Code",
3924
+ "category": "Media",
3925
+ "kind": "component",
3926
+ "source": "webawesome",
3927
+ "description": "Scannable QR representation of a supplied value.",
3928
+ "uses": [],
3929
+ "purpose": "Scannable QR representation of a supplied value.",
3930
+ "customElement": "wa-qr-code",
3931
+ "useWhen": [
3932
+ "Scannable QR representation of a supplied value."
3933
+ ],
3934
+ "avoidWhen": [
3935
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3936
+ ],
3937
+ "recommendation": "supported",
3938
+ "alternatives": [],
3939
+ "delivery": {
3940
+ "registrationImport": "@awesome.me/webawesome/dist/components/qr-code/qr-code.js",
3941
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3942
+ "sideEffects": [
3943
+ "custom-element-registration"
3944
+ ]
3945
+ },
3946
+ "links": {
3947
+ "catalogRoute": "?component=wa-qr-code",
3948
+ "documentation": "docs/webawesome-theme.md#coverage",
3949
+ "recipe": "docs/webawesome-theme.md#coverage"
3950
+ }
3951
+ },
3952
+ {
3953
+ "id": "wa-zoomable-frame",
3954
+ "name": "Zoomable Frame",
3955
+ "category": "Media",
3956
+ "kind": "component",
3957
+ "source": "webawesome",
3958
+ "description": "Avoid for application UI; keep embedded-media behavior application-owned.",
3959
+ "uses": [
3960
+ "wa-icon"
3961
+ ],
3962
+ "purpose": "Avoid for application UI; keep embedded-media behavior application-owned.",
3963
+ "customElement": "wa-zoomable-frame",
3964
+ "useWhen": [
3965
+ "Avoid for application UI; keep embedded-media behavior application-owned."
3966
+ ],
3967
+ "avoidWhen": [
3968
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
3969
+ ],
3970
+ "recommendation": "avoid",
3971
+ "alternatives": [],
3972
+ "delivery": {
3973
+ "registrationImport": "@awesome.me/webawesome/dist/components/zoomable-frame/zoomable-frame.js",
3974
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
3975
+ "sideEffects": [
3976
+ "custom-element-registration"
3977
+ ]
3978
+ },
3979
+ "links": {
3980
+ "catalogRoute": "?component=wa-zoomable-frame",
3981
+ "documentation": "docs/webawesome-theme.md#coverage",
3982
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
3983
+ }
3984
+ },
3985
+ {
3986
+ "id": "wa-animation",
3987
+ "name": "Animation",
3988
+ "category": "Helpers",
3989
+ "kind": "component",
3990
+ "source": "webawesome",
3991
+ "description": "Declarative Web Animations API wrapper with preset effects.",
3992
+ "uses": [
3993
+ "select"
3994
+ ],
3995
+ "purpose": "Declarative Web Animations API wrapper with preset effects.",
3996
+ "customElement": "wa-animation",
3997
+ "useWhen": [
3998
+ "Declarative Web Animations API wrapper with preset effects."
3999
+ ],
4000
+ "avoidWhen": [
4001
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4002
+ ],
4003
+ "recommendation": "supported",
4004
+ "alternatives": [],
4005
+ "delivery": {
4006
+ "registrationImport": "@awesome.me/webawesome/dist/components/animation/animation.js",
4007
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4008
+ "sideEffects": [
4009
+ "custom-element-registration"
4010
+ ]
4011
+ },
4012
+ "links": {
4013
+ "catalogRoute": "?component=wa-animation",
4014
+ "documentation": "docs/webawesome-theme.md#coverage",
4015
+ "recipe": "docs/webawesome-theme.md#coverage"
4016
+ }
4017
+ },
4018
+ {
4019
+ "id": "wa-format-bytes",
4020
+ "name": "Format Bytes",
4021
+ "category": "Helpers",
4022
+ "kind": "component",
4023
+ "source": "webawesome",
4024
+ "description": "Locale-aware byte and bit value formatter.",
4025
+ "uses": [],
4026
+ "purpose": "Locale-aware byte and bit value formatter.",
4027
+ "customElement": "wa-format-bytes",
4028
+ "useWhen": [
4029
+ "Locale-aware byte and bit value formatter."
4030
+ ],
4031
+ "avoidWhen": [
4032
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4033
+ ],
4034
+ "recommendation": "supported",
4035
+ "alternatives": [],
4036
+ "delivery": {
4037
+ "registrationImport": "@awesome.me/webawesome/dist/components/format-bytes/format-bytes.js",
4038
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4039
+ "sideEffects": [
4040
+ "custom-element-registration"
4041
+ ]
4042
+ },
4043
+ "links": {
4044
+ "catalogRoute": "?component=wa-format-bytes",
4045
+ "documentation": "docs/webawesome-theme.md#coverage",
4046
+ "recipe": "docs/webawesome-theme.md#coverage"
4047
+ }
4048
+ },
4049
+ {
4050
+ "id": "wa-format-date",
4051
+ "name": "Format Date",
4052
+ "category": "Helpers",
4053
+ "kind": "component",
4054
+ "source": "webawesome",
4055
+ "description": "Locale-aware date and time formatter.",
4056
+ "uses": [],
4057
+ "purpose": "Locale-aware date and time formatter.",
4058
+ "customElement": "wa-format-date",
4059
+ "useWhen": [
4060
+ "Locale-aware date and time formatter."
4061
+ ],
4062
+ "avoidWhen": [
4063
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4064
+ ],
4065
+ "recommendation": "supported",
4066
+ "alternatives": [],
4067
+ "delivery": {
4068
+ "registrationImport": "@awesome.me/webawesome/dist/components/format-date/format-date.js",
4069
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4070
+ "sideEffects": [
4071
+ "custom-element-registration"
4072
+ ]
4073
+ },
4074
+ "links": {
4075
+ "catalogRoute": "?component=wa-format-date",
4076
+ "documentation": "docs/webawesome-theme.md#coverage",
4077
+ "recipe": "docs/webawesome-theme.md#coverage"
4078
+ }
4079
+ },
4080
+ {
4081
+ "id": "wa-format-number",
4082
+ "name": "Format Number",
4083
+ "category": "Helpers",
4084
+ "kind": "component",
4085
+ "source": "webawesome",
4086
+ "description": "Locale-aware number, currency, unit, and percentage formatter.",
4087
+ "uses": [],
4088
+ "purpose": "Locale-aware number, currency, unit, and percentage formatter.",
4089
+ "customElement": "wa-format-number",
4090
+ "useWhen": [
4091
+ "Locale-aware number, currency, unit, and percentage formatter."
4092
+ ],
4093
+ "avoidWhen": [
4094
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4095
+ ],
4096
+ "recommendation": "supported",
4097
+ "alternatives": [],
4098
+ "delivery": {
4099
+ "registrationImport": "@awesome.me/webawesome/dist/components/format-number/format-number.js",
4100
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4101
+ "sideEffects": [
4102
+ "custom-element-registration"
4103
+ ]
4104
+ },
4105
+ "links": {
4106
+ "catalogRoute": "?component=wa-format-number",
4107
+ "documentation": "docs/webawesome-theme.md#coverage",
4108
+ "recipe": "docs/webawesome-theme.md#coverage"
4109
+ }
4110
+ },
4111
+ {
4112
+ "id": "wa-include",
4113
+ "name": "Include",
4114
+ "category": "Helpers",
4115
+ "kind": "component",
4116
+ "source": "webawesome",
4117
+ "description": "Loads and injects an external HTML fragment.",
4118
+ "uses": [],
4119
+ "purpose": "Loads and injects an external HTML fragment.",
4120
+ "customElement": "wa-include",
4121
+ "useWhen": [
4122
+ "Loads and injects an external HTML fragment."
4123
+ ],
4124
+ "avoidWhen": [
4125
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4126
+ ],
4127
+ "recommendation": "supported",
4128
+ "alternatives": [],
4129
+ "delivery": {
4130
+ "registrationImport": "@awesome.me/webawesome/dist/components/include/include.js",
4131
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4132
+ "sideEffects": [
4133
+ "custom-element-registration"
4134
+ ]
4135
+ },
4136
+ "links": {
4137
+ "catalogRoute": "?component=wa-include",
4138
+ "documentation": "docs/webawesome-theme.md#coverage",
4139
+ "recipe": "docs/webawesome-theme.md#coverage"
4140
+ }
4141
+ },
4142
+ {
4143
+ "id": "wa-intersection-observer",
4144
+ "name": "Intersection Observer",
4145
+ "category": "Helpers",
4146
+ "kind": "component",
4147
+ "source": "webawesome",
4148
+ "description": "Declaratively emits visibility changes for slotted content.",
4149
+ "uses": [],
4150
+ "purpose": "Declaratively emits visibility changes for slotted content.",
4151
+ "customElement": "wa-intersection-observer",
4152
+ "useWhen": [
4153
+ "Declaratively emits visibility changes for slotted content."
4154
+ ],
4155
+ "avoidWhen": [
4156
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4157
+ ],
4158
+ "recommendation": "supported",
4159
+ "alternatives": [],
4160
+ "delivery": {
4161
+ "registrationImport": "@awesome.me/webawesome/dist/components/intersection-observer/intersection-observer.js",
4162
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4163
+ "sideEffects": [
4164
+ "custom-element-registration"
4165
+ ]
4166
+ },
4167
+ "links": {
4168
+ "catalogRoute": "?component=wa-intersection-observer",
4169
+ "documentation": "docs/webawesome-theme.md#coverage",
4170
+ "recipe": "docs/webawesome-theme.md#coverage"
4171
+ }
4172
+ },
4173
+ {
4174
+ "id": "wa-mutation-observer",
4175
+ "name": "Mutation Observer",
4176
+ "category": "Helpers",
4177
+ "kind": "component",
4178
+ "source": "webawesome",
4179
+ "description": "Declaratively emits DOM mutation records for slotted content.",
4180
+ "uses": [],
4181
+ "purpose": "Declaratively emits DOM mutation records for slotted content.",
4182
+ "customElement": "wa-mutation-observer",
4183
+ "useWhen": [
4184
+ "Declaratively emits DOM mutation records for slotted content."
4185
+ ],
4186
+ "avoidWhen": [
4187
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4188
+ ],
4189
+ "recommendation": "supported",
4190
+ "alternatives": [],
4191
+ "delivery": {
4192
+ "registrationImport": "@awesome.me/webawesome/dist/components/mutation-observer/mutation-observer.js",
4193
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4194
+ "sideEffects": [
4195
+ "custom-element-registration"
4196
+ ]
4197
+ },
4198
+ "links": {
4199
+ "catalogRoute": "?component=wa-mutation-observer",
4200
+ "documentation": "docs/webawesome-theme.md#coverage",
4201
+ "recipe": "docs/webawesome-theme.md#coverage"
4202
+ }
4203
+ },
4204
+ {
4205
+ "id": "wa-popover",
4206
+ "name": "Popover",
4207
+ "category": "Helpers",
4208
+ "kind": "component",
4209
+ "source": "webawesome",
4210
+ "description": "Anchored non-modal surface built on popup positioning.",
4211
+ "uses": [
4212
+ "wa-popup"
4213
+ ],
4214
+ "purpose": "Anchored non-modal surface built on popup positioning.",
4215
+ "customElement": "wa-popover",
4216
+ "useWhen": [
4217
+ "Anchored non-modal surface built on popup positioning."
4218
+ ],
4219
+ "avoidWhen": [
4220
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4221
+ ],
4222
+ "recommendation": "supported",
4223
+ "alternatives": [],
4224
+ "delivery": {
4225
+ "registrationImport": "@awesome.me/webawesome/dist/components/popover/popover.js",
4226
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4227
+ "sideEffects": [
4228
+ "custom-element-registration"
4229
+ ]
4230
+ },
4231
+ "links": {
4232
+ "catalogRoute": "?component=wa-popover",
4233
+ "documentation": "docs/webawesome-theme.md#coverage",
4234
+ "recipe": "docs/webawesome-theme.md#coverage"
4235
+ }
4236
+ },
4237
+ {
4238
+ "id": "wa-popup",
4239
+ "name": "Popup",
4240
+ "category": "Helpers",
4241
+ "kind": "component",
4242
+ "source": "webawesome",
4243
+ "description": "Preferred low-level anchored positioning when Tooltip or Popover do not fit.",
4244
+ "uses": [],
4245
+ "purpose": "Preferred low-level anchored positioning when Tooltip or Popover do not fit.",
4246
+ "customElement": "wa-popup",
4247
+ "useWhen": [
4248
+ "Preferred low-level anchored positioning when Tooltip or Popover do not fit."
4249
+ ],
4250
+ "avoidWhen": [
4251
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4252
+ ],
4253
+ "recommendation": "conditional",
4254
+ "alternatives": [],
4255
+ "delivery": {
4256
+ "registrationImport": "@awesome.me/webawesome/dist/components/popup/popup.js",
4257
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4258
+ "sideEffects": [
4259
+ "custom-element-registration"
4260
+ ]
4261
+ },
4262
+ "links": {
4263
+ "catalogRoute": "?component=wa-popup",
4264
+ "documentation": "docs/webawesome-theme.md#coverage",
4265
+ "recipe": "docs/component-selection.md#web-awesome-overlap-policy"
4266
+ }
4267
+ },
4268
+ {
4269
+ "id": "wa-random-content",
4270
+ "name": "Random Content",
4271
+ "category": "Helpers",
4272
+ "kind": "component",
4273
+ "source": "webawesome",
4274
+ "description": "Experimental helper that selects one slotted item at random.",
4275
+ "uses": [],
4276
+ "purpose": "Experimental helper that selects one slotted item at random.",
4277
+ "customElement": "wa-random-content",
4278
+ "useWhen": [
4279
+ "Experimental helper that selects one slotted item at random."
4280
+ ],
4281
+ "avoidWhen": [
4282
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4283
+ ],
4284
+ "recommendation": "supported",
4285
+ "alternatives": [],
4286
+ "delivery": {
4287
+ "registrationImport": "@awesome.me/webawesome/dist/components/random-content/random-content.js",
4288
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4289
+ "sideEffects": [
4290
+ "custom-element-registration"
4291
+ ]
4292
+ },
4293
+ "links": {
4294
+ "catalogRoute": "?component=wa-random-content",
4295
+ "documentation": "docs/webawesome-theme.md#coverage",
4296
+ "recipe": "docs/webawesome-theme.md#coverage"
4297
+ }
4298
+ },
4299
+ {
4300
+ "id": "wa-relative-time",
4301
+ "name": "Relative Time",
4302
+ "category": "Helpers",
4303
+ "kind": "component",
4304
+ "source": "webawesome",
4305
+ "description": "Locale-aware human description of a date relative to now.",
4306
+ "uses": [],
4307
+ "purpose": "Locale-aware human description of a date relative to now.",
4308
+ "customElement": "wa-relative-time",
4309
+ "useWhen": [
4310
+ "Locale-aware human description of a date relative to now."
4311
+ ],
4312
+ "avoidWhen": [
4313
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4314
+ ],
4315
+ "recommendation": "supported",
4316
+ "alternatives": [],
4317
+ "delivery": {
4318
+ "registrationImport": "@awesome.me/webawesome/dist/components/relative-time/relative-time.js",
4319
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4320
+ "sideEffects": [
4321
+ "custom-element-registration"
4322
+ ]
4323
+ },
4324
+ "links": {
4325
+ "catalogRoute": "?component=wa-relative-time",
4326
+ "documentation": "docs/webawesome-theme.md#coverage",
4327
+ "recipe": "docs/webawesome-theme.md#coverage"
4328
+ }
4329
+ },
4330
+ {
4331
+ "id": "wa-resize-observer",
4332
+ "name": "Resize Observer",
4333
+ "category": "Helpers",
4334
+ "kind": "component",
4335
+ "source": "webawesome",
4336
+ "description": "Declaratively emits size changes for slotted content.",
4337
+ "uses": [],
4338
+ "purpose": "Declaratively emits size changes for slotted content.",
4339
+ "customElement": "wa-resize-observer",
4340
+ "useWhen": [
4341
+ "Declaratively emits size changes for slotted content."
4342
+ ],
4343
+ "avoidWhen": [
4344
+ "Do not choose it from catalog presence alone; confirm that its semantic and interaction contract matches the product need."
4345
+ ],
4346
+ "recommendation": "supported",
4347
+ "alternatives": [],
4348
+ "delivery": {
4349
+ "registrationImport": "@awesome.me/webawesome/dist/components/resize-observer/resize-observer.js",
4350
+ "themeCssImport": "@kerfjs/ui/webawesome.css",
4351
+ "sideEffects": [
4352
+ "custom-element-registration"
4353
+ ]
4354
+ },
4355
+ "links": {
4356
+ "catalogRoute": "?component=wa-resize-observer",
4357
+ "documentation": "docs/webawesome-theme.md#coverage",
4358
+ "recipe": "docs/webawesome-theme.md#coverage"
4359
+ }
4360
+ },
4361
+ {
4362
+ "id": "recipe-app-shell",
4363
+ "name": "Desktop application shell",
4364
+ "category": "Recipes",
4365
+ "kind": "recipe",
4366
+ "source": "kerf",
4367
+ "purpose": "Toolbar, navigation, content, and inspector shell with controlled resizing and explicit pane scroll owners.",
4368
+ "uses": ["toolbar", "toolbar-text", "toolbar-control-group", "menu-header", "menu-item", "page-header", "resize", "value-table", "layout"],
4369
+ "useWhen": ["A desktop workspace needs persistent chrome and user-adjustable navigation or inspector panes."],
4370
+ "avoidWhen": ["Use ordinary CSS grid when panes are static or the product does not need a user-operable separator."],
4371
+ "appOwns": ["routing", "pane visibility", "pane sizes and persistence", "workspace data"],
4372
+ "accessibility": ["Each pane has one scroll owner and each resize handle keeps its separator keyboard contract."],
4373
+ "delivery": { "sideEffects": ["lazy-recipe-css"] },
4374
+ "links": { "catalogRoute": "?component=recipe-app-shell", "documentation": "docs/recipes.md#desktop-application-shell", "recipe": "docs/recipes.md#desktop-application-shell" }
4375
+ },
4376
+ {
4377
+ "id": "recipe-navigation-sidebar",
4378
+ "name": "Navigation sidebar",
4379
+ "category": "Recipes",
4380
+ "kind": "recipe",
4381
+ "source": "kerf",
4382
+ "purpose": "Navigation sections with icon and iconless rows, a content-item surface, disclosure, and pane footer actions.",
4383
+ "uses": ["menu-header", "menu-item", "toolbar", "toolbar-control-group"],
4384
+ "useWhen": ["A workspace sidebar needs the shared toolbar/content/footer pane model, 24px major section rhythm, and 44px row and utility-action targets."],
4385
+ "avoidWhen": ["Use ordinary links when menu selection, section, and sidebar anatomy do not apply."],
4386
+ "appOwns": ["information architecture", "routing", "permissions", "disclosure state"],
4387
+ "accessibility": ["Native buttons retain names, current state, sequential focus, and disclosure state; rows and standalone footer actions remain at least 44px tall."],
4388
+ "delivery": { "sideEffects": ["lazy-recipe-css"] },
4389
+ "links": { "catalogRoute": "?component=recipe-navigation-sidebar", "documentation": "docs/recipes.md#navigation-sidebar", "recipe": "docs/recipes.md#navigation-sidebar" }
4390
+ },
4391
+ {
4392
+ "id": "recipe-workspace-header",
4393
+ "name": "Workspace header",
4394
+ "category": "Recipes",
4395
+ "kind": "recipe",
4396
+ "source": "kerf",
4397
+ "purpose": "Page identity with primary, secondary, and overflow actions that relocate at narrow widths.",
4398
+ "uses": ["page-header", "state-banner", "layout"],
4399
+ "useWhen": ["A workspace page needs one primary heading and a small prioritized action set."],
4400
+ "avoidWhen": ["Use Toolbar for persistent application chrome or DialogHeader for a focused modal task."],
4401
+ "appOwns": ["authorization", "command behavior", "breadcrumbs", "product copy"],
4402
+ "accessibility": ["Heading order and action focus order remain stable when controls wrap."],
4403
+ "delivery": { "sideEffects": ["lazy-recipe-css"] },
4404
+ "links": { "catalogRoute": "?component=recipe-workspace-header", "documentation": "docs/recipes.md#workspace-header", "recipe": "docs/recipes.md#workspace-header" }
4405
+ },
4406
+ {
4407
+ "id": "recipe-master-detail-dialog",
4408
+ "name": "Master-detail dialog",
4409
+ "category": "Recipes",
4410
+ "kind": "recipe",
4411
+ "source": "kerf",
4412
+ "purpose": "Production modal containing a DialogHeader, navigable record master list, and ValueTable detail.",
4413
+ "uses": ["dialog-header", "menu-header", "menu-item", "value-table", "wa-dialog", "wa-button"],
4414
+ "useWhen": ["A focused task compares several records without leaving the current workspace."],
4415
+ "avoidWhen": ["Use a page when the task needs a durable route or substantially more working space."],
4416
+ "appOwns": ["open state", "selected record", "dismiss policy", "record actions"],
4417
+ "accessibility": ["Web Awesome owns modal focus and Escape; the application adapter restores the invoking control after hide, and DialogHeader supplies the visible hierarchy."],
4418
+ "delivery": { "sideEffects": ["lazy-recipe-css", "individual-custom-element-registration"] },
4419
+ "links": { "catalogRoute": "?component=recipe-master-detail-dialog", "documentation": "docs/recipes.md#master-detail-dialog", "recipe": "docs/recipes.md#master-detail-dialog" }
4420
+ },
4421
+ {
4422
+ "id": "recipe-composer-form",
4423
+ "name": "Composer form",
4424
+ "category": "Recipes",
4425
+ "kind": "recipe",
4426
+ "source": "kerf",
4427
+ "purpose": "One visible publishing-form surface with exactly three transparent 8/1/8 content sections, 24px major rhythm, and a conditional StateBanner as its only nested semantic surface.",
4428
+ "uses": ["select", "state-banner", "wa-input", "wa-textarea", "wa-button", "layout"],
4429
+ "useWhen": ["A short form needs one coherent surface, consistent field/action rhythm, and persistent validation feedback."],
4430
+ "avoidWhen": ["Do not turn each form section into another visible card or use the recipe as a generic form engine or transport abstraction."],
4431
+ "appOwns": ["validation rules", "draft persistence", "permissions", "transport"],
4432
+ "accessibility": ["Production fields own labels and help; invalid submission creates an assertive persistent StateBanner while successful submission creates a polite persistent banner."],
4433
+ "delivery": { "sideEffects": ["lazy-recipe-css", "individual-custom-element-registration"] },
4434
+ "links": { "catalogRoute": "?component=recipe-composer-form", "documentation": "docs/recipes.md#composer-form", "recipe": "docs/recipes.md#composer-form" }
4435
+ },
4436
+ {
4437
+ "id": "recipe-list-workspace-states",
4438
+ "name": "List workspace states",
4439
+ "category": "Recipes",
4440
+ "kind": "recipe",
4441
+ "source": "kerf",
4442
+ "purpose": "Deterministic loading, empty, populated, stale refresh, and error states around one stable list workspace.",
4443
+ "uses": ["page-header", "state-banner", "empty-state", "loading-spinner", "layout"],
4444
+ "useWhen": ["A list surface must communicate initial load, absence, background refresh, failure, and recovery."],
4445
+ "avoidWhen": ["Do not replace domain rows with a generic component or use transient toasts as the only error record."],
4446
+ "appOwns": ["fetching", "cache age", "retry policy", "domain rows"],
4447
+ "accessibility": ["Busy, polite, and assertive states use the appropriate production feedback semantics."],
4448
+ "delivery": { "sideEffects": ["lazy-recipe-css"] },
4449
+ "links": { "catalogRoute": "?component=recipe-list-workspace-states", "documentation": "docs/recipes.md#list-workspace-states", "recipe": "docs/recipes.md#list-workspace-states" }
4450
+ },
4451
+ {
4452
+ "id": "recipe-compact-toolbar",
4453
+ "name": "Compact toolbar choices and actions",
4454
+ "category": "Recipes",
4455
+ "kind": "recipe",
4456
+ "source": "kerf",
4457
+ "purpose": "A compact toolbar that distinguishes grouped commands, a visible exclusive choice, a longer Select, and one ordinary action.",
4458
+ "uses": ["toolbar", "toolbar-text", "toolbar-control-group", "segmented-control", "select", "lucide-icon"],
4459
+ "useWhen": ["A dense workspace toolbar mixes a few distinct control semantics."],
4460
+ "avoidWhen": ["Do not group unrelated actions or use buttons to imitate selection controls."],
4461
+ "appOwns": ["controlled values", "actions", "persistence", "responsive priority"],
4462
+ "accessibility": ["Each control retains its own native name, pressed/value state, and keyboard contract."],
4463
+ "delivery": { "sideEffects": ["lazy-recipe-css", "individual-custom-element-registration"] },
4464
+ "links": { "catalogRoute": "?component=recipe-compact-toolbar", "documentation": "docs/recipes.md#compact-toolbar-choices-and-actions", "recipe": "docs/recipes.md#compact-toolbar-choices-and-actions" }
4465
+ }
4466
+ ]
4467
+ }