@kerfjs/ui 5.0.0-beta.46 → 5.0.0-beta.47

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.
@@ -431,6 +431,18 @@
431
431
  "publicTokens": []
432
432
  }
433
433
  },
434
+ "@kerfjs/ui:wa-badge": {
435
+ "_source": "docs/webawesome-theme.md#badge-and-tag-guidance",
436
+ "boundaries": {
437
+ "rootClass": null,
438
+ "publicClasses": [],
439
+ "publicTokens": [
440
+ "--kui-wa-badge-accent-foreground",
441
+ "--kui-wa-badge-filled-background",
442
+ "--kui-wa-badge-filled-foreground"
443
+ ]
444
+ }
445
+ },
434
446
  "@kerfjs/ui:wa-radio-group": {
435
447
  "_source": "docs/webawesome-theme.md#coverage",
436
448
  "children": {
@@ -91,59 +91,6 @@
91
91
  "composition": "generated-permissive-default"
92
92
  }
93
93
  },
94
- {
95
- "key": "@kerfjs/ui:webawesome-theme",
96
- "package": "@kerfjs/ui",
97
- "id": "webawesome-theme",
98
- "name": "Web Awesome theme",
99
- "kind": "composition",
100
- "source": "kerf",
101
- "parents": { "mode": "any", "entries": [] },
102
- "contexts": ["application-ui"],
103
- "zones": [],
104
- "children": { "mode": "any", "concepts": [], "requiredConcepts": [] },
105
- "state": [
106
- {
107
- "id": "individual component registration",
108
- "owner": "application",
109
- "required": false
110
- },
111
- {
112
- "id": "semantic token overrides",
113
- "owner": "application",
114
- "required": false
115
- }
116
- ],
117
- "wiring": { "required": false, "helpers": [], "obligations": [] },
118
- "responsive": { "owner": "not-applicable", "behaviors": [] },
119
- "layout": {
120
- "roles": ["foundation"],
121
- "geometry": { "margin": "child", "border": "child", "padding": "child" }
122
- },
123
- "accessibility": {
124
- "obligations": [
125
- "Preserve Web Awesome semantics and Kerf focus/contrast tokens."
126
- ]
127
- },
128
- "cssValueProps": [],
129
- "boundaries": {
130
- "rootClass": null,
131
- "publicClasses": [],
132
- "publicTokens": [
133
- "--kui-disclosure-icon-scale",
134
- "--kui-wa-carousel-control-size",
135
- "--kui-wa-carousel-dot-hit-size",
136
- "--kui-wa-carousel-dot-size",
137
- "--kui-wa-carousel-icon-size",
138
- "--kui-wa-popover-arrow-size"
139
- ]
140
- },
141
- "diagnostics": [],
142
- "provenance": {
143
- "selection": "ai/component-catalog.json",
144
- "composition": "generated-permissive-default"
145
- }
146
- },
147
94
  {
148
95
  "key": "@kerfjs/ui:foundation",
149
96
  "package": "@kerfjs/ui",
@@ -1318,6 +1265,9 @@
1318
1265
  "children": { "mode": "any", "concepts": [], "requiredConcepts": [] },
1319
1266
  "state": [
1320
1267
  { "id": "semantic variant", "owner": "application", "required": false },
1268
+ { "id": "tone", "owner": "application", "required": false },
1269
+ { "id": "size", "owner": "application", "required": false },
1270
+ { "id": "font", "owner": "application", "required": false },
1321
1271
  { "id": "copy", "owner": "application", "required": false },
1322
1272
  {
1323
1273
  "id": "document heading hierarchy",
@@ -1341,14 +1291,21 @@
1341
1291
  "accessibility": {
1342
1292
  "obligations": [
1343
1293
  "Text renders a native paragraph by default; choose an h1 through h6 variant by document outline rather than appearance.",
1344
- "Ordinary global, data, and ARIA attributes pass through to the native element."
1294
+ "Ordinary global, data, and ARIA attributes pass through to the native element.",
1295
+ "Choose tone, size, and font independently of the heading level so appearance does not distort the document outline."
1345
1296
  ]
1346
1297
  },
1347
1298
  "cssValueProps": [],
1348
1299
  "boundaries": {
1349
1300
  "rootClass": "kui-text",
1350
1301
  "publicClasses": ["kui-text"],
1351
- "publicTokens": ["--kui-layout-item-padding"]
1302
+ "publicTokens": [
1303
+ "--kui-color-danger-text",
1304
+ "--kui-color-text-quiet",
1305
+ "--kui-font-mono",
1306
+ "--kui-font-xs",
1307
+ "--kui-layout-item-padding"
1308
+ ]
1352
1309
  },
1353
1310
  "diagnostics": [],
1354
1311
  "provenance": {
@@ -3664,7 +3621,12 @@
3664
3621
  "boundaries": {
3665
3622
  "rootClass": null,
3666
3623
  "publicClasses": [],
3667
- "publicTokens": []
3624
+ "publicTokens": [
3625
+ "--kui-wa-surface-margin",
3626
+ "--kui-wa-surface-inset",
3627
+ "--kui-wa-sunken-background",
3628
+ "--kui-wa-sunken-radius"
3629
+ ]
3668
3630
  },
3669
3631
  "diagnostics": [],
3670
3632
  "provenance": {
@@ -3726,7 +3688,12 @@
3726
3688
  "boundaries": {
3727
3689
  "rootClass": null,
3728
3690
  "publicClasses": [],
3729
- "publicTokens": []
3691
+ "publicTokens": [
3692
+ "--kui-wa-surface-margin",
3693
+ "--kui-wa-surface-inset",
3694
+ "--kui-wa-sunken-background",
3695
+ "--kui-wa-sunken-radius"
3696
+ ]
3730
3697
  },
3731
3698
  "diagnostics": [],
3732
3699
  "provenance": {
@@ -3757,7 +3724,12 @@
3757
3724
  "boundaries": {
3758
3725
  "rootClass": null,
3759
3726
  "publicClasses": [],
3760
- "publicTokens": ["--kui-wa-surface-margin", "--kui-wa-surface-inset"]
3727
+ "publicTokens": [
3728
+ "--kui-wa-surface-margin",
3729
+ "--kui-wa-surface-inset",
3730
+ "--kui-wa-sunken-background",
3731
+ "--kui-wa-sunken-radius"
3732
+ ]
3761
3733
  },
3762
3734
  "diagnostics": [],
3763
3735
  "provenance": {
@@ -4253,12 +4225,16 @@
4253
4225
  "boundaries": {
4254
4226
  "rootClass": null,
4255
4227
  "publicClasses": [],
4256
- "publicTokens": []
4228
+ "publicTokens": [
4229
+ "--kui-wa-badge-accent-foreground",
4230
+ "--kui-wa-badge-filled-background",
4231
+ "--kui-wa-badge-filled-foreground"
4232
+ ]
4257
4233
  },
4258
4234
  "diagnostics": [],
4259
4235
  "provenance": {
4260
4236
  "selection": "ai/component-catalog.json",
4261
- "composition": "generated-permissive-default"
4237
+ "composition": "docs/webawesome-theme.md#badge-and-tag-guidance"
4262
4238
  }
4263
4239
  },
4264
4240
  {
@@ -121,133 +121,6 @@
121
121
  "recipe": "docs/component-selection.md#problem-to-component-matrix"
122
122
  }
123
123
  },
124
- {
125
- "id": "webawesome-theme",
126
- "name": "Web Awesome theme",
127
- "category": "Foundation",
128
- "kind": "composition",
129
- "source": "kerf",
130
- "description": "Kerf palettes, typography, geometry, and focus styling across free Web Awesome component families.",
131
- "uses": [
132
- "wa-button",
133
- "wa-button-group",
134
- "wa-copy-button",
135
- "wa-dropdown",
136
- "wa-dropdown-item",
137
- "wa-checkbox",
138
- "wa-checkbox-group",
139
- "wa-color-picker",
140
- "wa-input",
141
- "wa-known-date",
142
- "wa-number-input",
143
- "wa-option",
144
- "wa-otp-input",
145
- "wa-radio",
146
- "wa-radio-group",
147
- "wa-rating",
148
- "wa-select",
149
- "wa-slider",
150
- "wa-switch",
151
- "wa-textarea",
152
- "wa-time-input",
153
- "wa-accordion",
154
- "wa-accordion-item",
155
- "wa-card",
156
- "wa-details",
157
- "wa-dialog",
158
- "wa-divider",
159
- "wa-drawer",
160
- "wa-page",
161
- "wa-scroller",
162
- "wa-split-panel",
163
- "wa-breadcrumb",
164
- "wa-breadcrumb-item",
165
- "wa-pagination",
166
- "wa-tab",
167
- "wa-tab-group",
168
- "wa-tab-panel",
169
- "wa-tree",
170
- "wa-tree-item",
171
- "wa-badge",
172
- "wa-callout",
173
- "wa-progress-bar",
174
- "wa-progress-ring",
175
- "wa-skeleton",
176
- "wa-spinner",
177
- "wa-tag",
178
- "wa-toast",
179
- "wa-toast-item",
180
- "wa-tooltip",
181
- "wa-animated-image",
182
- "wa-avatar",
183
- "wa-carousel",
184
- "wa-carousel-item",
185
- "wa-comparison",
186
- "wa-icon",
187
- "wa-markdown",
188
- "wa-qr-code",
189
- "wa-zoomable-frame",
190
- "wa-animation",
191
- "wa-format-bytes",
192
- "wa-format-date",
193
- "wa-format-number",
194
- "wa-include",
195
- "wa-intersection-observer",
196
- "wa-mutation-observer",
197
- "wa-popover",
198
- "wa-popup",
199
- "wa-random-content",
200
- "wa-relative-time",
201
- "wa-resize-observer"
202
- ],
203
- "purpose": "Kerf palettes, typography, geometry, and focus styling across free Web Awesome component families.",
204
- "publicExports": [],
205
- "useWhen": [
206
- "Theme individually registered free Web Awesome components to match Kerf UI."
207
- ],
208
- "avoidWhen": [
209
- "Do not treat theme coverage as a recommendation or import the full registration bundle."
210
- ],
211
- "alternatives": [],
212
- "appOwns": [
213
- "individual component registration",
214
- "semantic token overrides"
215
- ],
216
- "variants": [
217
- "light",
218
- "dark",
219
- "invert"
220
- ],
221
- "accessibility": [
222
- "Preserve Web Awesome semantics and Kerf focus/contrast tokens."
223
- ],
224
- "geometry": {
225
- "margin": "child",
226
- "border": "child",
227
- "padding": "child"
228
- },
229
- "delivery": {
230
- "manualCssImport": "@kerfjs/ui/webawesome.css",
231
- "sideEffects": [
232
- "css"
233
- ]
234
- },
235
- "wiring": [],
236
- "publicClasses": [],
237
- "publicTokens": [
238
- "--kui-disclosure-icon-scale",
239
- "--kui-wa-carousel-control-size",
240
- "--kui-wa-carousel-dot-hit-size",
241
- "--kui-wa-carousel-dot-size",
242
- "--kui-wa-carousel-icon-size",
243
- "--kui-wa-popover-arrow-size"
244
- ],
245
- "links": {
246
- "catalogRoute": "?component=webawesome-theme",
247
- "documentation": "docs/component-selection.md",
248
- "recipe": "docs/webawesome-theme.md#component-selection-guidance"
249
- }
250
- },
251
124
  {
252
125
  "id": "foundation",
253
126
  "name": "Foundation tokens",
@@ -1514,9 +1387,9 @@
1514
1387
  "category": "Structure",
1515
1388
  "kind": "component",
1516
1389
  "source": "kerf",
1517
- "description": "Semantic native paragraph text by default, with heading variants and standard padded content geometry.",
1390
+ "description": "Semantic native paragraph text by default, with heading variants, composable semantic presentation roles, and standard padded content geometry.",
1518
1391
  "uses": [],
1519
- "purpose": "Render paragraph semantics by default or h1 through h6 when selected, while consistently supplying the standard transparent border and content padding.",
1392
+ "purpose": "Render paragraph semantics by default or h1 through h6 when selected, while independently configuring quiet or danger tone, compact size, or monospace font and consistently supplying standard geometry.",
1520
1393
  "publicExports": ["Text"],
1521
1394
  "useWhen": [
1522
1395
  "Render ordinary application headings or paragraphs that should use native document semantics and the standard text-box inset."
@@ -1535,11 +1408,24 @@
1535
1408
  "relationship": "list-geometry-specific"
1536
1409
  }
1537
1410
  ],
1538
- "appOwns": ["semantic variant", "copy", "document heading hierarchy"],
1539
- "variants": ["h1", "h2", "h3", "h4", "h5", "h6", "p"],
1411
+ "appOwns": [
1412
+ "semantic variant",
1413
+ "tone",
1414
+ "size",
1415
+ "font",
1416
+ "copy",
1417
+ "document heading hierarchy"
1418
+ ],
1419
+ "variants": [
1420
+ "p or h1 through h6 semantic variant",
1421
+ "default, quiet, or danger tone",
1422
+ "default or compact size",
1423
+ "default or monospace font"
1424
+ ],
1540
1425
  "accessibility": [
1541
1426
  "Text renders a native paragraph by default; choose an h1 through h6 variant by document outline rather than appearance.",
1542
- "Ordinary global, data, and ARIA attributes pass through to the native element."
1427
+ "Ordinary global, data, and ARIA attributes pass through to the native element.",
1428
+ "Choose tone, size, and font independently of the heading level so appearance does not distort the document outline."
1543
1429
  ],
1544
1430
  "geometry": {
1545
1431
  "margin": "none",
@@ -1556,7 +1442,13 @@
1556
1442
  },
1557
1443
  "wiring": [],
1558
1444
  "publicClasses": ["kui-text"],
1559
- "publicTokens": ["--kui-layout-item-padding"],
1445
+ "publicTokens": [
1446
+ "--kui-color-danger-text",
1447
+ "--kui-color-text-quiet",
1448
+ "--kui-font-mono",
1449
+ "--kui-font-xs",
1450
+ "--kui-layout-item-padding"
1451
+ ],
1560
1452
  "links": {
1561
1453
  "catalogRoute": "?component=text",
1562
1454
  "documentation": "docs/component-selection.md",
@@ -4458,6 +4350,15 @@
4458
4350
  ],
4459
4351
  "recommendation": "supported",
4460
4352
  "alternatives": [],
4353
+ "variants": [
4354
+ "sunken appearance"
4355
+ ],
4356
+ "publicTokens": [
4357
+ "--kui-wa-surface-margin",
4358
+ "--kui-wa-surface-inset",
4359
+ "--kui-wa-sunken-background",
4360
+ "--kui-wa-sunken-radius"
4361
+ ],
4461
4362
  "geometry": {
4462
4363
  "margin": "self",
4463
4364
  "border": "self",
@@ -4532,6 +4433,15 @@
4532
4433
  ],
4533
4434
  "recommendation": "supported",
4534
4435
  "alternatives": [],
4436
+ "variants": [
4437
+ "sunken appearance"
4438
+ ],
4439
+ "publicTokens": [
4440
+ "--kui-wa-surface-margin",
4441
+ "--kui-wa-surface-inset",
4442
+ "--kui-wa-sunken-background",
4443
+ "--kui-wa-sunken-radius"
4444
+ ],
4535
4445
  "geometry": {
4536
4446
  "margin": "self",
4537
4447
  "border": "self",
@@ -4570,9 +4480,14 @@
4570
4480
  ],
4571
4481
  "recommendation": "supported",
4572
4482
  "alternatives": [],
4483
+ "variants": [
4484
+ "sunken appearance"
4485
+ ],
4573
4486
  "publicTokens": [
4574
4487
  "--kui-wa-surface-margin",
4575
- "--kui-wa-surface-inset"
4488
+ "--kui-wa-surface-inset",
4489
+ "--kui-wa-sunken-background",
4490
+ "--kui-wa-sunken-radius"
4576
4491
  ],
4577
4492
  "geometry": {
4578
4493
  "margin": "self",
@@ -5172,6 +5087,11 @@
5172
5087
  "border": "self",
5173
5088
  "padding": "self"
5174
5089
  },
5090
+ "publicTokens": [
5091
+ "--kui-wa-badge-accent-foreground",
5092
+ "--kui-wa-badge-filled-background",
5093
+ "--kui-wa-badge-filled-foreground"
5094
+ ],
5175
5095
  "delivery": {
5176
5096
  "registrationImport": "@awesome.me/webawesome/dist/components/badge/badge.js",
5177
5097
  "themeCssImport": "@kerfjs/ui/webawesome.css",
@@ -1,6 +1,6 @@
1
1
  # Public API signatures for the UI authoring corpus
2
2
 
3
- Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.46` and `kerfjs@5.0.0-beta.46`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.47` and `kerfjs@5.0.0-beta.47`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
4
4
 
5
5
  ## `@kerfjs/ui/css-values`
6
6
 
@@ -2013,10 +2013,19 @@ import { KerfBaseAttrs } from 'kerfjs/jsx-runtime';
2013
2013
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2014
2014
 
2015
2015
  type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';
2016
+ type TextTone = 'default' | 'quiet' | 'danger';
2017
+ type TextSize = 'default' | 'compact';
2018
+ type TextFont = 'default' | 'monospace';
2016
2019
  type TextContent = KerfUiContent | string | number | readonly TextContent[];
2017
2020
  type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
2018
2021
  /** Native heading or paragraph element to render. Defaults to `p`. */
2019
2022
  variant?: TextVariant;
2023
+ /** Semantic foreground treatment. Defaults to the inherited foreground. */
2024
+ tone?: TextTone;
2025
+ /** Text sizing independent of the native semantic element. */
2026
+ size?: TextSize;
2027
+ /** Font family independent of the native semantic element. */
2028
+ font?: TextFont;
2020
2029
  children: TextContent;
2021
2030
  class?: string;
2022
2031
  className?: string;
@@ -2025,9 +2034,9 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
2025
2034
  * Semantic heading or paragraph text with the standard content-item padding.
2026
2035
  * All ordinary native heading/paragraph attributes pass through to the element.
2027
2036
  */
2028
- declare function Text({ variant: Variant, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
2037
+ declare function Text({ variant: Variant, tone, size, font, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
2029
2038
 
2030
- export { Text, type TextContent, type TextProps, type TextVariant };
2039
+ export { Text, type TextContent, type TextFont, type TextProps, type TextSize, type TextTone, type TextVariant };
2031
2040
  ```
2032
2041
 
2033
2042
  ## `@kerfjs/ui/row`
package/ai/skill.md CHANGED
@@ -126,10 +126,10 @@ Hard rules:
126
126
  10. Compose `AppTab` inside controlled `TabBar`; call `wireTabBars()` once and retain its disposer. It owns same-bar drag mechanics, including proximity-based horizontal edge autoscroll, while the app applies `onReorder` and owns order, selection, panels, close policy, routing, and persistence. Arrow/Home/End select on move by default and restore focus by bar/tab identity when controlled activation replaces the strip; pass `activation: 'manual'` (or `TabBar activation="manual"` per strip) so arrow keys move focus only and the user selects with Enter/Space/click — use it when selecting a tab is a heavy action. Use runtime-filtered `rootAttributes` for domain metadata and keep an optional `closeIcon` decorative and noninteractive.
127
127
  11. Use token-controlled `TokenSearchField` when free text and removable structured filters share one editor. Editable text stays DOM-owned between token changes. The leading icon, first text line, clear action, and trailing slot share one fixed row when content wraps. The app owns parsing and suggestions; call `readTokenSearchField()` on input, empty `textContent` on clear, use `placeTokenSearchCaret()` after explicit controlled focus changes, and call `wireTokenSearchFields()` once so Enter submits without inserting a line break and keyboard chip deletion restores focus plus the text-relative caret after controlled replacement. Enable `collapsible` for an animated iconic closed state, standalone or inside `ToolbarControlGroup`; the field keeps text or tokens expanded, and `wireTokenSearchFields()` manages the transient expand/collapse/focus by default (activate to reveal + focus, Escape or empty blur to collapse). Bind the field's `expanded` to the returned handle's `expanded(id)` signal or adopt your own via `collapsible.signals`; opt a behavior out only when the app must own it. Do not hand-roll the open handler, the focusout collapse, a clear-button mousedown guard, or reopening after controlled clear or Select All deletion — the helper keeps the replacement editor open and focused. Clear and deletion restoration finish at the replacement mutation checkpoint before the next input task, so shortcut-letter typing cannot escape to the page and delayed animation frames cannot overwrite a later selection. Persist both query and tokens returned by the DOM read. For real-app adoption it also provides a focusout keep-open exception (`data-token-search-keep-open` regions or `collapsible.keepOpenOn(target)`, so a sibling suggestions/date/help surface does not collapse an empty field), opt-in atomic-chip keyboard (`keyboard`: Backspace/Delete remove the adjacent chip via `onRemoveToken`, ArrowRight moves the caret past a trailing chip), and an `onEdit({id, editor, event})` input callback (the `InputEvent` lets you gate on `inputType`/`data`) — reach for these instead of re-adding hand-rolled keydown/input handlers around the field.
128
128
  12. Demo work uses public production component subpaths and their browser-selected CSS. Give every public visual component its own category-grouped catalog route; list themed third-party components under a clearly labeled collapsible ecosystem section, with a focused route for each. For the complete focused/composition decision, `CatalogExample` / `CatalogExampleStack` row/group nesting, exact specimen selection, geometry-overlay legend and exclusions, skip-marker behavior, and metadata ownership, follow the single [Catalog demo authoring contract](../docs/catalog.md#catalog-demo-authoring-contract), discovered machine-readably through [`catalog-authoring.json`](./catalog-authoring.json). Never infer structure from private `kui-catalog-*` classes. Project each component's deterministic repository-relative demo source and existing documentation path so the detail can expose `View demo source` and `Read guidance` links without a runtime export; also derive first-party component implementation paths from their canonical browser imports, and label Web Awesome documentation as Kerf integration guidance. Declare direct `uses` relationships so `Used by` stays derivable, and theme shell chrome through the same semantic tokens as the stage instead of drawing a substitute. Enable `wireCatalog({ revealSelection: true })` for long desktop sidebars so controlled selections remain visible without moving focus; keep its default compact media guard unless compact scrolling is an explicit product behavior, and use `revealCatalogEntry` for an initial deep link.
129
- 13. The Web Awesome theme makes Tooltip and Popover arrowless by default. Keep that default unless a pointer materially clarifies the anchor; opt back in with `--wa-tooltip-arrow-size`, `--kui-wa-popover-arrow-size`, or a popover's public `--arrow-size`, and use `without-arrow` when local no-arrow intent should survive theme changes. Its non-field chrome uses `--kui-wa-control-inset` (8px controls/items), `--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside Accordion, Card, Details, Callout, and Include), and `--kui-wa-container-inset` (16px Tab Panel content); Dialog maps its body to the 8px surface tier and its footer to the 16px container tier independently of `--spacing`. Override those tiers instead of restyling individual parts. When a dialog provides another dismissal affordance, put `hide-actions` on the `wa-dialog` host to hide its directly exported `header-actions` part; never chain `::part()` selectors through internal parts. Checkbox and Radio Group option regions, the Color Picker trigger, and Slider's complete interactive region receive the shared 8px logical inline outer inset because those controls have no bordered field shell. Known Date field captions and bordered text-like field hints align with values at the 9px border-plus-padding inset. OTP Input's label uses the same uppercase xs/650 treatment as other field labels, and both its label and hint use that 9px inset.
129
+ 13. The Web Awesome theme makes Tooltip and Popover arrowless by default. Keep that default unless a pointer materially clarifies the anchor; opt back in with `--wa-tooltip-arrow-size`, `--kui-wa-popover-arrow-size`, or a popover's public `--arrow-size`, and use `without-arrow` when local no-arrow intent should survive theme changes. Its non-field chrome uses `--kui-wa-control-inset` (8px controls/items), `--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside Accordion, Card, Details, Callout, and Include), and `--kui-wa-container-inset` (16px Tab Panel content); Dialog maps its body to the 8px surface tier and its footer to the 16px container tier independently of `--spacing`. Override those tiers instead of restyling individual parts. Filled badges use each variant's quiet fill with normal text so their compact copy stays WCAG-AA readable; override the pair with `--kui-wa-badge-filled-background` / `--kui-wa-badge-filled-foreground`, not host selectors. When a dialog provides another dismissal affordance, put `hide-actions` on the `wa-dialog` host to hide its directly exported `header-actions` part; never chain `::part()` selectors through internal parts. Checkbox and Radio Group option regions, the Color Picker trigger, and Slider's complete interactive region receive the shared 8px logical inline outer inset because those controls have no bordered field shell. Known Date field captions and bordered text-like field hints align with values at the 9px border-plus-padding inset. OTP Input's label uses the same uppercase xs/650 treatment as other field labels, and both its label and hint use that 9px inset.
130
130
  14. Treat the complete Web Awesome catalog as support coverage, not a recommendation list. Its UX sidebar marks superseded and exceptional entries `Discouraged`. Consider Popup when it replaces custom anchored positioning. Prefer Kerf `Select` over direct Dropdown/Dropdown Item/Select/Option composition, `SegmentedControl` over Button Group, `TabBar` or `SegmentedControl` over Web Awesome Tabs, `LucideIcon` over Web Awesome Icon, and `ResizableRegion` over Split Panel. Use Tree/Tree Item, Animated Image, and Comparison only for a specific required behavior; avoid Zoomable Frame.
131
131
  15. Build sidebars, main areas, inspectors, and dialogs from `@kerfjs/ui/layout.css`: an unpadded `.kui-pane`, optional `.kui-pane__toolbar`, one scrolling `.kui-pane__content`, and optional `.kui-pane__footer`. Use `Row` instead of a hand-written flex-row wrapper and `List` instead of a hand-written flex-column wrapper when children need shared physical-axis alignment and typed spacing. `Row` defaults to left/full with an `xs` gap and no wrapping; `List` retains full/top and zero-gap defaults. Use `List` when rows or sections also need flex growth, one vertical scroll owner, or physical-edge dividers. `dividerSides`, `textInsets`, and `controlInsets` use canonical physical `t`/`r`/`b`/`l` order; text geometry wins where text and control selections overlap. `ListInsetText` and `ListInsetControl` inset all four sides by default and accept the same `sides` grammar for selective edges. A dialog body is generally a `List`: set `DialogSurface bodyInset="none"` when its list children own geometry, and wrap bare dialog prose in `ListInsetText` so it aligns with bordered siblings without a second inset. Add `.kui-content` for 24px major vertical separation and `.kui-content-item` for a child-owned 8px inline margin, 1px transparent-or-visible border, 8px padding, and 12px radius. Use the pill modifier for 22px. Do not pad pane shells, duplicate item geometry in wrappers, or create nested scroll owners.
132
- 15a. Use `Text` from `@kerfjs/ui/text` for ordinary headings and paragraphs outside toolbar title zones. Omit `variant` for the default `p`, or pass `h1`–`h6` according to the document outline; ordinary native attributes pass through. Text owns a transparent 1px border and the standard item padding. Keep toolbar identity/title content on `ToolbarText` and list-aligned bare prose on `ListInsetText`.
132
+ 15a. Use `Text` from `@kerfjs/ui/text` for ordinary headings and paragraphs outside toolbar title zones. Omit `variant` for the default `p`, or pass `h1`–`h6` according to the document outline; ordinary native attributes pass through. Express supporting, error, compact, or code text with the independent finite `tone="quiet|danger"`, `size="compact"`, and `font="monospace"` props instead of global utility classes or appearance-only heading choices. Text owns a transparent 1px border and the standard item padding. Keep toolbar identity/title content on `ToolbarText` and list-aligned bare prose on `ListInsetText`.
133
133
  16. Keep a visible collapsible pane's collapse control in its own toolbar. When hidden, move its restore control into the adjacent main toolbar on the corresponding logical edge: leading for an inline-start sidebar and trailing for an inline-end inspector. Collapse the pane completely; do not preserve an empty icon-only rail.
134
134
  17. The only direct children of a `Toolbar` zone (`leading`/`center`/`trailing`) are `ToolbarText` (identity/title text) and `ToolbarControlGroup`; never drop bare buttons, inputs, links, or arbitrary markup straight into a zone. Put identity/title text directly in the zone as `ToolbarText`; wrap interactive controls and icon tiles in `ToolbarControlGroup`. `SegmentedControl`, `Select`, a collapsible `TokenSearchField`, and Web Awesome controls all live inside a group. For an ordinary icon/action control inside a group, use a plain `<button>` (the group styles `> button` fully) — that is the default; reach for `wa-button` only when you need a Web Awesome feature, chiefly a `wa-dropdown` popup trigger. A popup menu in a toolbar is a `single` group wrapping a `wa-dropdown` whose `slot="trigger"` `wa-button` is the toolbar button and whose `wa-dropdown-item`s are the menu, with the dropdown kept under `data-morph-skip-children`. For a compact mixed group, keep the standard item padding and raised selected chrome; the selected item paints over the outer border without an internal separator. For an avatar control, set `content="avatar"` and `avatarImage` on the group instead of inserting an `img`: a lone control paints the contained image on the outer group and a multi-button group paints it only on the pressed selection highlight. Compose panel/dialog/page headings with a direct extra-large `ToolbarText`, optional grouped icon, grouped trailing controls, and app-owned supporting copy below. A group remains 44px outside (`calc(2px + remify(42px))`) when its border/background are transparent; use 8px between groups and inside items. Split dormant and interactive regions: `ListHeader` fills the available inline width by default; set `inline` only when it should shrink-wrap in surrounding content without outer margin, border, or padding. It keeps its label and mutually exclusive semantic count or non-count `badge` together, with an independent logical-end action unless disclosure mode makes the title cluster the button. Its action visual defaults to 18px through `--kui-list-header-action-icon-size`; never shrink the target to match it. Pass every non-negative safe-integer section quantity through `count` with a localized full spoken `countLabel`; never concatenate it into `label` or put a number in `badge`. `ListItem.trailing` is dormant; use `ListActionRow` when primary and trailing actions need sibling native buttons. Its `label`, `icon`, and `trailingActionIcon` slots are also dormant and cannot contain controls. Let panes relocate at narrow widths instead of shrinking targets.
135
135
  18. When a recurring concept has no matching export or production recipe, keep its semantics in a thin application adapter while reusing the public layout vocabulary. The composer recipe uses one visible form surface, toolbar title/supporting-copy ids, shared 8px field/action gutters, 24px major rhythm, and a conditional StateBanner as its only nested semantic surface; do not turn every section into a card or double-inset intrinsically bordered controls. The application-local `../docs/examples/command-palette-adapter.tsx` is reference source for one such missing concept, not an `@kerfjs/ui` runtime export or catalog recipe. The application owns its registration, ranking, history, permissions, availability, shortcut policy, focus policy, dispatch, and copy. If a missing concept recurs across products, open an upstream component or recipe request.
@@ -1,6 +1,6 @@
1
1
  # Web Awesome JSX signatures for the UI authoring corpus
2
2
 
3
- Generated from the emitted `@kerfjs/ui@5.0.0-beta.46` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
3
+ Generated from the emitted `@kerfjs/ui@5.0.0-beta.47` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
4
4
 
5
5
  ```ts
6
6
  import { KerfCustomElement } from 'kerfjs/jsx-runtime';
package/dist/catalog.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ToolbarControlGroup } from './chunk-B6JYRX3P.js';
2
2
  import { Toolbar } from './chunk-VXFGMDA7.js';
3
3
  import { Pane } from './chunk-I4V3UDSA.js';
4
- import { ListHeader } from './chunk-SE7MQMW7.js';
5
- import { Text } from './chunk-QM4GQ7W3.js';
4
+ import { ListHeader } from './chunk-GYGM363P.js';
5
+ import { Text } from './chunk-XKFRMGMW.js';
6
6
  import { ListItem } from './chunk-I45QO2IZ.js';
7
7
  import { List } from './chunk-WVLMZ5SG.js';
8
8
 
@@ -1,4 +1,4 @@
1
- import { Text } from './chunk-QM4GQ7W3.js';
1
+ import { Text } from './chunk-XKFRMGMW.js';
2
2
  import { filterDataAttributes, filterControlAttributes } from './chunk-SRSJO5QE.js';
3
3
  import { Skeleton } from './chunk-T7DOWS6T.js';
4
4
  import { em } from './chunk-OL4TC3U2.js';
@@ -138,4 +138,4 @@ function ListHeader({
138
138
 
139
139
  export { ListHeader };
140
140
 
141
- //# sourceMappingURL=chunk-SE7MQMW7.js.map
141
+ //# sourceMappingURL=chunk-GYGM363P.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/list-header.tsx"],"names":[],"mappings":"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","file":"chunk-SE7MQMW7.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { em } from './css-values.js';\nimport { DisclosureArrow } from './disclosure-arrow.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\nimport { Text } from './text.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-has-badge',\n 'data-has-count',\n 'data-density',\n 'data-divider',\n 'data-inline',\n 'data-indicator-tone',\n 'data-toggle',\n]);\nconst PROTECTED_TRIGGER_DATA_ATTRIBUTES = new Set(['data-action']);\n\ntype ListHeaderRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-has-badge'?: never;\n 'data-has-count'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-inline'?: never;\n 'data-indicator-tone'?: never;\n 'data-toggle'?: never;\n }\n>;\n\ntype ListHeaderTriggerAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-action'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\ninterface ListHeaderBaseProps {\n label: string;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Shrink-wrap the header without its default outer margin, border, or padding. */\n inline?: boolean;\n indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';\n /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */\n placeholder?: boolean;\n rootAttributes?: ListHeaderRootAttributes;\n triggerAttributes?: ListHeaderTriggerAttributes;\n}\n\ntype ListHeaderModeProps =\n | {\n /** Render the title as a controlled disclosure trigger. */\n toggle: true;\n action: string;\n expanded: boolean;\n actionIcon?: SafeHtml;\n actionLabel?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a separately named trailing action. */\n toggle?: false;\n action: string;\n actionLabel: string;\n actionIcon: SafeHtml;\n expanded?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a passive section heading. */\n toggle?: false;\n action?: never;\n actionLabel?: never;\n actionIcon?: never;\n expanded?: never;\n actionDisabled?: never;\n disabledReason?: never;\n };\n\ntype ListHeaderIndicatorProps =\n | { count: number; countLabel: string; badge?: never; status?: never }\n | { count?: never; countLabel?: never; badge: SafeHtml; status?: never }\n | { count?: never; countLabel?: never; badge?: never; status?: SafeHtml };\n\nexport type ListHeaderProps = ListHeaderBaseProps &\n ListHeaderIndicatorProps &\n ListHeaderModeProps;\n\nexport function ListHeader({\n label,\n count,\n countLabel,\n badge,\n status,\n density = 'standard',\n divider = 'none',\n inline = false,\n indicatorTone = 'neutral',\n action,\n actionLabel,\n actionIcon,\n actionDisabled = false,\n disabledReason,\n expanded,\n toggle = false,\n placeholder = false,\n rootAttributes = {},\n triggerAttributes = {},\n}: ListHeaderProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTriggerAttributes = filterControlAttributes(\n triggerAttributes,\n PROTECTED_TRIGGER_DATA_ATTRIBUTES,\n );\n const normalizedCount =\n typeof count === 'number' && Number.isSafeInteger(count) && count >= 0\n ? count\n : undefined;\n const normalizedCountLabel =\n normalizedCount === undefined\n ? undefined\n : typeof countLabel === 'string' && countLabel.trim()\n ? countLabel\n : String(normalizedCount);\n const renderedBadge =\n normalizedCount === undefined ? (status ?? badge) : undefined;\n const renderedActionIcon =\n actionIcon ??\n (toggle ? <DisclosureArrow open={Boolean(expanded)} /> : undefined);\n const accessibleLabel =\n normalizedCount === undefined\n ? undefined\n : `${label}, ${normalizedCountLabel}`;\n const indicator = placeholder ? (\n (normalizedCount !== undefined || renderedBadge) && (\n <span class=\"kui-list-header__badge\">\n <Skeleton width={em(1.75)} />\n </span>\n )\n ) : normalizedCount === undefined ? (\n renderedBadge && <span class=\"kui-list-header__badge\">{renderedBadge}</span>\n ) : (\n <span class=\"kui-list-header__count\" aria-hidden=\"true\">\n {normalizedCount}\n </span>\n );\n const busy = placeholder ? ('true' as const) : undefined;\n if (toggle) {\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-indicator-tone={indicatorTone}\n data-toggle=\"true\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n >\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__title kui-list-header__toggle\"\n data-action={placeholder ? undefined : action}\n title={actionDisabled ? disabledReason : undefined}\n disabled={actionDisabled || placeholder || undefined}\n aria-label={accessibleLabel}\n aria-expanded={String(Boolean(expanded))}\n >\n <span class=\"kui-list-header__label\">{label}</span>\n {indicator}\n {renderedActionIcon && (\n <span class=\"kui-list-header__action-layer\">\n {renderedActionIcon}\n </span>\n )}\n </button>\n </header>\n );\n }\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-indicator-tone={indicatorTone}\n data-toggle=\"false\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n >\n <div class=\"kui-list-header__title\">\n <Text\n variant=\"h2\"\n class=\"kui-list-header__label\"\n aria-label={accessibleLabel}\n >\n {label}\n </Text>\n {indicator}\n </div>\n {action && (\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__action\"\n data-action={placeholder ? undefined : action}\n aria-label={actionLabel}\n title={actionDisabled ? disabledReason : actionLabel}\n disabled={actionDisabled || placeholder || undefined}\n >\n {renderedActionIcon}\n </button>\n )}\n </header>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/list-header.tsx"],"names":[],"mappings":"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","file":"chunk-GYGM363P.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { em } from './css-values.js';\nimport { DisclosureArrow } from './disclosure-arrow.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\nimport { Text } from './text.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-has-badge',\n 'data-has-count',\n 'data-density',\n 'data-divider',\n 'data-inline',\n 'data-indicator-tone',\n 'data-toggle',\n]);\nconst PROTECTED_TRIGGER_DATA_ATTRIBUTES = new Set(['data-action']);\n\ntype ListHeaderRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-has-badge'?: never;\n 'data-has-count'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-inline'?: never;\n 'data-indicator-tone'?: never;\n 'data-toggle'?: never;\n }\n>;\n\ntype ListHeaderTriggerAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-action'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\ninterface ListHeaderBaseProps {\n label: string;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Shrink-wrap the header without its default outer margin, border, or padding. */\n inline?: boolean;\n indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';\n /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */\n placeholder?: boolean;\n rootAttributes?: ListHeaderRootAttributes;\n triggerAttributes?: ListHeaderTriggerAttributes;\n}\n\ntype ListHeaderModeProps =\n | {\n /** Render the title as a controlled disclosure trigger. */\n toggle: true;\n action: string;\n expanded: boolean;\n actionIcon?: SafeHtml;\n actionLabel?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a separately named trailing action. */\n toggle?: false;\n action: string;\n actionLabel: string;\n actionIcon: SafeHtml;\n expanded?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a passive section heading. */\n toggle?: false;\n action?: never;\n actionLabel?: never;\n actionIcon?: never;\n expanded?: never;\n actionDisabled?: never;\n disabledReason?: never;\n };\n\ntype ListHeaderIndicatorProps =\n | { count: number; countLabel: string; badge?: never; status?: never }\n | { count?: never; countLabel?: never; badge: SafeHtml; status?: never }\n | { count?: never; countLabel?: never; badge?: never; status?: SafeHtml };\n\nexport type ListHeaderProps = ListHeaderBaseProps &\n ListHeaderIndicatorProps &\n ListHeaderModeProps;\n\nexport function ListHeader({\n label,\n count,\n countLabel,\n badge,\n status,\n density = 'standard',\n divider = 'none',\n inline = false,\n indicatorTone = 'neutral',\n action,\n actionLabel,\n actionIcon,\n actionDisabled = false,\n disabledReason,\n expanded,\n toggle = false,\n placeholder = false,\n rootAttributes = {},\n triggerAttributes = {},\n}: ListHeaderProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTriggerAttributes = filterControlAttributes(\n triggerAttributes,\n PROTECTED_TRIGGER_DATA_ATTRIBUTES,\n );\n const normalizedCount =\n typeof count === 'number' && Number.isSafeInteger(count) && count >= 0\n ? count\n : undefined;\n const normalizedCountLabel =\n normalizedCount === undefined\n ? undefined\n : typeof countLabel === 'string' && countLabel.trim()\n ? countLabel\n : String(normalizedCount);\n const renderedBadge =\n normalizedCount === undefined ? (status ?? badge) : undefined;\n const renderedActionIcon =\n actionIcon ??\n (toggle ? <DisclosureArrow open={Boolean(expanded)} /> : undefined);\n const accessibleLabel =\n normalizedCount === undefined\n ? undefined\n : `${label}, ${normalizedCountLabel}`;\n const indicator = placeholder ? (\n (normalizedCount !== undefined || renderedBadge) && (\n <span class=\"kui-list-header__badge\">\n <Skeleton width={em(1.75)} />\n </span>\n )\n ) : normalizedCount === undefined ? (\n renderedBadge && <span class=\"kui-list-header__badge\">{renderedBadge}</span>\n ) : (\n <span class=\"kui-list-header__count\" aria-hidden=\"true\">\n {normalizedCount}\n </span>\n );\n const busy = placeholder ? ('true' as const) : undefined;\n if (toggle) {\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-indicator-tone={indicatorTone}\n data-toggle=\"true\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n >\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__title kui-list-header__toggle\"\n data-action={placeholder ? undefined : action}\n title={actionDisabled ? disabledReason : undefined}\n disabled={actionDisabled || placeholder || undefined}\n aria-label={accessibleLabel}\n aria-expanded={String(Boolean(expanded))}\n >\n <span class=\"kui-list-header__label\">{label}</span>\n {indicator}\n {renderedActionIcon && (\n <span class=\"kui-list-header__action-layer\">\n {renderedActionIcon}\n </span>\n )}\n </button>\n </header>\n );\n }\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-indicator-tone={indicatorTone}\n data-toggle=\"false\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n >\n <div class=\"kui-list-header__title\">\n <Text\n variant=\"h2\"\n class=\"kui-list-header__label\"\n aria-label={accessibleLabel}\n >\n {label}\n </Text>\n {indicator}\n </div>\n {action && (\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__action\"\n data-action={placeholder ? undefined : action}\n aria-label={actionLabel}\n title={actionDisabled ? disabledReason : actionLabel}\n disabled={actionDisabled || placeholder || undefined}\n >\n {renderedActionIcon}\n </button>\n )}\n </header>\n );\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import { jsx } from 'kerfjs/jsx-runtime';
2
+
3
+ // src/text.tsx
4
+ function Text({
5
+ variant: Variant = "p",
6
+ tone = "default",
7
+ size = "default",
8
+ font = "default",
9
+ children,
10
+ class: classValue = "",
11
+ className = "",
12
+ ...attributes
13
+ }) {
14
+ const classes = `kui-text ${classValue} ${className}`.trim();
15
+ return /* @__PURE__ */ jsx(
16
+ Variant,
17
+ {
18
+ ...attributes,
19
+ class: classes,
20
+ "data-component": "text",
21
+ "data-tone": tone,
22
+ "data-size": size,
23
+ "data-font": font,
24
+ children
25
+ }
26
+ );
27
+ }
28
+
29
+ export { Text };
30
+
31
+ //# sourceMappingURL=chunk-XKFRMGMW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/text.tsx"],"names":[],"mappings":";;;AAiCO,SAAS,IAAA,CAAK;AAAA,EACnB,SAAS,OAAA,GAAU,GAAA;AAAA,EACnB,IAAA,GAAO,SAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,QAAA;AAAA,EACA,OAAO,UAAA,GAAa,EAAA;AAAA,EACpB,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,EAAc;AACZ,EAAA,MAAM,UAAU,CAAA,SAAA,EAAY,UAAU,CAAA,CAAA,EAAI,SAAS,GAAG,IAAA,EAAK;AAC3D,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA;AAAA,MACJ,KAAA,EAAO,OAAA;AAAA,MACP,gBAAA,EAAe,MAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,IAAA;AAAA,MAEV;AAAA;AAAA,GACH;AAEJ","file":"chunk-XKFRMGMW.js","sourcesContent":["import type { KerfBaseAttrs } from 'kerfjs/jsx-runtime';\n\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';\nexport type TextTone = 'default' | 'quiet' | 'danger';\nexport type TextSize = 'default' | 'compact';\nexport type TextFont = 'default' | 'monospace';\n\nexport type TextContent =\n KerfUiContent | string | number | readonly TextContent[];\n\nexport type TextProps = Omit<\n KerfBaseAttrs,\n 'children' | 'class' | 'className'\n> & {\n /** Native heading or paragraph element to render. Defaults to `p`. */\n variant?: TextVariant;\n /** Semantic foreground treatment. Defaults to the inherited foreground. */\n tone?: TextTone;\n /** Text sizing independent of the native semantic element. */\n size?: TextSize;\n /** Font family independent of the native semantic element. */\n font?: TextFont;\n children: TextContent;\n class?: string;\n className?: string;\n};\n\n/**\n * Semantic heading or paragraph text with the standard content-item padding.\n * All ordinary native heading/paragraph attributes pass through to the element.\n */\nexport function Text({\n variant: Variant = 'p',\n tone = 'default',\n size = 'default',\n font = 'default',\n children,\n class: classValue = '',\n className = '',\n ...attributes\n}: TextProps) {\n const classes = `kui-text ${classValue} ${className}`.trim();\n return (\n <Variant\n {...attributes}\n class={classes}\n data-component=\"text\"\n data-tone={tone}\n data-size={size}\n data-font={font}\n >\n {children}\n </Variant>\n );\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -23,7 +23,7 @@ export { StateBanner, StateBannerProps, StateBannerTone, StateBannerUrgency } fr
23
23
  export { SunkenPanel, SunkenPanelProps, SunkenPanelShape } from './sunken-panel.js';
24
24
  export { DialogSurface, DialogSurfacePresentation, DialogSurfaceProps, DialogSurfaceSize, PopupSurface, PopupSurfaceInset, PopupSurfaceProps, SurfaceInset } from './surface-scaffold.js';
25
25
  export { TabActivation, TabBar, TabBarAllocation, TabBarPresentation, TabBarProps, TabBarTrailingPlacement } from './tab-bar.js';
26
- export { Text, TextContent, TextProps, TextVariant } from './text.js';
26
+ export { Text, TextContent, TextFont, TextProps, TextSize, TextTone, TextVariant } from './text.js';
27
27
  export { TokenSearchEditorAttributes, TokenSearchField, TokenSearchFieldProps, TokenSearchFieldValue, TokenSearchToken, placeTokenSearchCaret, readTokenSearchField } from './token-search-field.js';
28
28
  export { Toolbar, ToolbarProps } from './toolbar.js';
29
29
  export { ToolbarControlGroup, ToolbarControlGroupAppearance, ToolbarControlGroupButtonAppearance, ToolbarControlGroupContent, ToolbarControlGroupDensity, ToolbarControlGroupProps, ToolbarControlGroupSelectedChrome, ToolbarControlGroupSelectedTone, ToolbarControlGroupShape, ToolbarControlGroupSize, ToolbarControlGroupTone } from './toolbar-control-group.js';