@kerfjs/ui 5.0.0-beta.6 → 5.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/ai/component-catalog.json +84 -11
- package/ai/public-api-signatures-v1.md +74 -11
- package/ai/skill.md +1 -0
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/app-tab.d.ts +3 -1
- package/dist/app-tab.js +2 -1
- package/dist/browser/app-tab.js +1 -0
- package/dist/browser/menu-action-row.js +1 -0
- package/dist/browser/menu-header.js +1 -0
- package/dist/browser/menu-item.js +1 -0
- package/dist/browser/panel-header.js +1 -0
- package/dist/browser/segmented-control.js +1 -0
- package/dist/browser/select.js +1 -0
- package/dist/browser/skeleton.js +3 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/browser/toolbar-text.js +1 -0
- package/dist/browser/value-table.js +1 -0
- package/dist/{chunk-XZXRLY5Q.js → chunk-2Z5TWHKQ.js} +7 -6
- package/dist/chunk-2Z5TWHKQ.js.map +1 -0
- package/dist/{chunk-EGHL5S4P.js → chunk-3YD6ZNRA.js} +8 -7
- package/dist/chunk-3YD6ZNRA.js.map +1 -0
- package/dist/chunk-B24C4A6T.js +22 -0
- package/dist/chunk-B24C4A6T.js.map +1 -0
- package/dist/{chunk-RBTVBGRD.js → chunk-BLK3UEEI.js} +2 -2
- package/dist/{chunk-RBTVBGRD.js.map → chunk-BLK3UEEI.js.map} +1 -1
- package/dist/{chunk-KZKSBUKC.js → chunk-BNQ2YDV4.js} +8 -7
- package/dist/chunk-BNQ2YDV4.js.map +1 -0
- package/dist/{chunk-NPPD2A6O.js → chunk-H6URQGJI.js} +8 -6
- package/dist/chunk-H6URQGJI.js.map +1 -0
- package/dist/chunk-I7INRJO4.js +17 -0
- package/dist/chunk-I7INRJO4.js.map +1 -0
- package/dist/{chunk-CTQKI2XL.js → chunk-LC3YSAZC.js} +14 -3
- package/dist/chunk-LC3YSAZC.js.map +1 -0
- package/dist/{chunk-R6JHHBKQ.js → chunk-PONXLV5U.js} +5 -5
- package/dist/chunk-PONXLV5U.js.map +1 -0
- package/dist/chunk-RUNWEPR4.js +10 -0
- package/dist/chunk-RUNWEPR4.js.map +1 -0
- package/dist/{chunk-TRNBHPNW.js → chunk-YGN7OMLT.js} +11 -8
- package/dist/chunk-YGN7OMLT.js.map +1 -0
- package/dist/chunk-YKUUZPED.js +24 -0
- package/dist/chunk-YKUUZPED.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +12 -11
- package/dist/menu-action-row.d.ts +3 -1
- package/dist/menu-action-row.js +2 -1
- package/dist/menu-header.d.ts +3 -1
- package/dist/menu-header.js +2 -1
- package/dist/menu-item.d.ts +3 -1
- package/dist/menu-item.js +2 -1
- package/dist/nav-stack.js +2 -1
- package/dist/panel-header.d.ts +11 -1
- package/dist/panel-header.js +2 -1
- package/dist/segmented-control.d.ts +3 -1
- package/dist/segmented-control.js +2 -1
- package/dist/select.d.ts +5 -2
- package/dist/select.js +2 -1
- package/dist/skeleton.d.ts +24 -0
- package/dist/skeleton.js +3 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/split-view.js +2 -1
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +3 -1
- package/dist/state-banner.js +2 -1
- package/dist/styles/panel-header.css +5 -0
- package/dist/styles/select.css +42 -0
- package/dist/styles/skeleton.css +31 -0
- package/dist/styles/styles.css +1 -0
- package/dist/toolbar-text.d.ts +12 -2
- package/dist/toolbar-text.js +2 -1
- package/dist/value-table.d.ts +3 -1
- package/dist/value-table.js +2 -1
- package/docs/accessibility.md +10 -5
- package/docs/component-contract.md +12 -0
- package/docs/component-selection.md +3 -2
- package/llms.txt +10 -1
- package/package.json +7 -1
- package/dist/chunk-24Z2XE6C.js +0 -10
- package/dist/chunk-24Z2XE6C.js.map +0 -1
- package/dist/chunk-CTQKI2XL.js.map +0 -1
- package/dist/chunk-EGHL5S4P.js.map +0 -1
- package/dist/chunk-KZKSBUKC.js.map +0 -1
- package/dist/chunk-NPPD2A6O.js.map +0 -1
- package/dist/chunk-R6JHHBKQ.js.map +0 -1
- package/dist/chunk-S3TPM2LP.js +0 -23
- package/dist/chunk-S3TPM2LP.js.map +0 -1
- package/dist/chunk-TRNBHPNW.js.map +0 -1
- package/dist/chunk-VHW5YNIB.js +0 -17
- package/dist/chunk-VHW5YNIB.js.map +0 -1
- package/dist/chunk-XZXRLY5Q.js.map +0 -1
package/README.md
CHANGED
|
@@ -109,6 +109,7 @@ as a `New` marker.
|
|
|
109
109
|
| `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
|
|
110
110
|
| `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
|
|
111
111
|
| `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
|
|
112
|
+
| `Skeleton` | `@kerfjs/ui/skeleton` | `@kerfjs/ui/skeleton.css` |
|
|
112
113
|
| `Select` | `@kerfjs/ui/select` | `@kerfjs/ui/select.css` |
|
|
113
114
|
| `SegmentedControl` | `@kerfjs/ui/segmented-control` | `@kerfjs/ui/segmented-control.css` |
|
|
114
115
|
| `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret` | `@kerfjs/ui/token-search-field` | `@kerfjs/ui/token-search-field.css` |
|
|
@@ -485,9 +485,12 @@
|
|
|
485
485
|
"variants": [
|
|
486
486
|
"large",
|
|
487
487
|
"default",
|
|
488
|
-
"small"
|
|
488
|
+
"small",
|
|
489
|
+
"placeholder (loading)"
|
|
490
|
+
],
|
|
491
|
+
"accessibility": [
|
|
492
|
+
"Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title."
|
|
489
493
|
],
|
|
490
|
-
"accessibility": [],
|
|
491
494
|
"delivery": {
|
|
492
495
|
"browserImport": "@kerfjs/ui/toolbar-text",
|
|
493
496
|
"manualCssImport": "@kerfjs/ui/toolbar-text.css",
|
|
@@ -612,11 +615,14 @@
|
|
|
612
615
|
"title",
|
|
613
616
|
"optional summary",
|
|
614
617
|
"icon",
|
|
615
|
-
"actions"
|
|
618
|
+
"actions",
|
|
619
|
+
"placeholder (loading)",
|
|
620
|
+
"page heading (headingLevel)"
|
|
616
621
|
],
|
|
617
622
|
"accessibility": [
|
|
618
623
|
"Connect the title id and any provided summary id to the dialog or panel host.",
|
|
619
|
-
"Pass the trailing actions as a labeled ToolbarControlGroup when the group needs an accessible name."
|
|
624
|
+
"Pass the trailing actions as a labeled ToolbarControlGroup when the group needs an accessible name.",
|
|
625
|
+
"For a page/view title pass headingLevel (usually 1) so the title exposes role=heading + aria-level as a heading landmark; omit it for a dialog title, which is referenced via aria-labelledby to titleId."
|
|
620
626
|
],
|
|
621
627
|
"delivery": {
|
|
622
628
|
"browserImport": "@kerfjs/ui/panel-header",
|
|
@@ -674,7 +680,8 @@
|
|
|
674
680
|
],
|
|
675
681
|
"variants": [
|
|
676
682
|
"icon rows",
|
|
677
|
-
"iconless rows"
|
|
683
|
+
"iconless rows",
|
|
684
|
+
"placeholder (loading)"
|
|
678
685
|
],
|
|
679
686
|
"accessibility": [
|
|
680
687
|
"Name ValueTable with its label; ValueTableRow supplies dt/dd semantics, and row icons stay decorative unless meaning requires an accessible label."
|
|
@@ -817,7 +824,8 @@
|
|
|
817
824
|
"count",
|
|
818
825
|
"badge",
|
|
819
826
|
"action",
|
|
820
|
-
"toggle"
|
|
827
|
+
"toggle",
|
|
828
|
+
"placeholder (loading)"
|
|
821
829
|
],
|
|
822
830
|
"accessibility": [
|
|
823
831
|
"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.",
|
|
@@ -906,7 +914,8 @@
|
|
|
906
914
|
"pressed",
|
|
907
915
|
"disabled primary",
|
|
908
916
|
"disabled trailing action",
|
|
909
|
-
"multiline"
|
|
917
|
+
"multiline",
|
|
918
|
+
"placeholder (loading)"
|
|
910
919
|
],
|
|
911
920
|
"accessibility": [
|
|
912
921
|
"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.",
|
|
@@ -996,7 +1005,8 @@
|
|
|
996
1005
|
"pressed",
|
|
997
1006
|
"disabled",
|
|
998
1007
|
"trailing",
|
|
999
|
-
"multiline"
|
|
1008
|
+
"multiline",
|
|
1009
|
+
"placeholder (loading)"
|
|
1000
1010
|
],
|
|
1001
1011
|
"accessibility": [
|
|
1002
1012
|
"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."
|
|
@@ -1261,7 +1271,8 @@
|
|
|
1261
1271
|
"rounded",
|
|
1262
1272
|
"pill",
|
|
1263
1273
|
"equal width",
|
|
1264
|
-
"small"
|
|
1274
|
+
"small",
|
|
1275
|
+
"placeholder (loading)"
|
|
1265
1276
|
],
|
|
1266
1277
|
"accessibility": [
|
|
1267
1278
|
"Keep choice labels meaningful and every enabled native button in sequential Tab order."
|
|
@@ -1566,7 +1577,8 @@
|
|
|
1566
1577
|
"disabled",
|
|
1567
1578
|
"fit menu",
|
|
1568
1579
|
"grouped",
|
|
1569
|
-
"custom selected content"
|
|
1580
|
+
"custom selected content",
|
|
1581
|
+
"placeholder (loading)"
|
|
1570
1582
|
],
|
|
1571
1583
|
"accessibility": [
|
|
1572
1584
|
"Verify the live value, standard events, focus, and rendered output."
|
|
@@ -1717,7 +1729,8 @@
|
|
|
1717
1729
|
"warning",
|
|
1718
1730
|
"danger",
|
|
1719
1731
|
"status",
|
|
1720
|
-
"alert"
|
|
1732
|
+
"alert",
|
|
1733
|
+
"placeholder (loading)"
|
|
1721
1734
|
],
|
|
1722
1735
|
"accessibility": [
|
|
1723
1736
|
"Use alert urgency only for an attention-requiring failure."
|
|
@@ -1919,6 +1932,66 @@
|
|
|
1919
1932
|
"recipe": "docs/component-selection.md#problem-to-component-matrix"
|
|
1920
1933
|
}
|
|
1921
1934
|
},
|
|
1935
|
+
{
|
|
1936
|
+
"id": "skeleton",
|
|
1937
|
+
"name": "Skeleton",
|
|
1938
|
+
"category": "Feedback",
|
|
1939
|
+
"kind": "component",
|
|
1940
|
+
"source": "kerf",
|
|
1941
|
+
"description": "A subtle, unanimated loading placeholder block for a not-yet-known value slot.",
|
|
1942
|
+
"uses": [],
|
|
1943
|
+
"purpose": "A subtle, unanimated loading placeholder block for a not-yet-known value slot.",
|
|
1944
|
+
"publicExports": [
|
|
1945
|
+
"Skeleton"
|
|
1946
|
+
],
|
|
1947
|
+
"useWhen": [
|
|
1948
|
+
"Stand in for a value that is still loading, on its own or via a component's placeholder prop, keeping the surrounding layout stable.",
|
|
1949
|
+
"Placeholder a custom or free-text slot with the same visual the components' placeholder mode uses."
|
|
1950
|
+
],
|
|
1951
|
+
"avoidWhen": [
|
|
1952
|
+
"Do not use for known progress or a busy spinner; use LoadingSpinner.",
|
|
1953
|
+
"Do not animate it or use it as decorative filler."
|
|
1954
|
+
],
|
|
1955
|
+
"alternatives": [
|
|
1956
|
+
{
|
|
1957
|
+
"id": "wa-skeleton",
|
|
1958
|
+
"relationship": "prefer-over"
|
|
1959
|
+
}
|
|
1960
|
+
],
|
|
1961
|
+
"appOwns": [
|
|
1962
|
+
"loading lifecycle",
|
|
1963
|
+
"which slots are unknown",
|
|
1964
|
+
"announcing the loading region"
|
|
1965
|
+
],
|
|
1966
|
+
"variants": [
|
|
1967
|
+
"block",
|
|
1968
|
+
"lines",
|
|
1969
|
+
"labeled"
|
|
1970
|
+
],
|
|
1971
|
+
"accessibility": [
|
|
1972
|
+
"Decorative by default (aria-hidden); pass label to announce it as an image. A component in placeholder mode marks itself aria-busy and disables its own controls."
|
|
1973
|
+
],
|
|
1974
|
+
"delivery": {
|
|
1975
|
+
"browserImport": "@kerfjs/ui/skeleton",
|
|
1976
|
+
"manualCssImport": "@kerfjs/ui/skeleton.css",
|
|
1977
|
+
"sideEffects": [
|
|
1978
|
+
"browser-condition-css"
|
|
1979
|
+
]
|
|
1980
|
+
},
|
|
1981
|
+
"wiring": [],
|
|
1982
|
+
"publicClasses": [
|
|
1983
|
+
"kui-skeleton",
|
|
1984
|
+
"kui-skeleton-lines"
|
|
1985
|
+
],
|
|
1986
|
+
"publicTokens": [
|
|
1987
|
+
"--kui-skeleton-radius"
|
|
1988
|
+
],
|
|
1989
|
+
"links": {
|
|
1990
|
+
"catalogRoute": "?component=skeleton",
|
|
1991
|
+
"documentation": "docs/component-selection.md",
|
|
1992
|
+
"recipe": "docs/component-selection.md#problem-to-component-matrix"
|
|
1993
|
+
}
|
|
1994
|
+
},
|
|
1922
1995
|
{
|
|
1923
1996
|
"id": "wa-button",
|
|
1924
1997
|
"name": "Button",
|
|
@@ -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.
|
|
3
|
+
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.8` and `kerfjs@5.0.0-beta.8`. 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/disclosure-arrow`
|
|
6
6
|
|
|
@@ -45,16 +45,26 @@ export { Toolbar, type ToolbarProps };
|
|
|
45
45
|
import * as kerfjs from 'kerfjs';
|
|
46
46
|
|
|
47
47
|
type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';
|
|
48
|
+
/** ARIA heading level for a title exposed as a heading landmark. */
|
|
49
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
48
50
|
interface ToolbarTextProps {
|
|
49
51
|
text: string;
|
|
50
52
|
size?: ToolbarTextSize;
|
|
51
53
|
className?: string;
|
|
52
54
|
/** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */
|
|
53
55
|
id?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Expose heading semantics (`role="heading"` + `aria-level`) so the text acts as
|
|
58
|
+
* a heading landmark — e.g. a page's primary title. Omit to keep the plain span
|
|
59
|
+
* (the default), which suits a dialog title referenced via `aria-labelledby`.
|
|
60
|
+
*/
|
|
61
|
+
headingLevel?: HeadingLevel;
|
|
62
|
+
/** Render the text as an unanimated loading skeleton instead of its value. */
|
|
63
|
+
placeholder?: boolean;
|
|
54
64
|
}
|
|
55
|
-
declare function ToolbarText({ text, size, className, id }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
65
|
+
declare function ToolbarText({ text, size, className, id, headingLevel, placeholder }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
56
66
|
|
|
57
|
-
export { ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
67
|
+
export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
58
68
|
```
|
|
59
69
|
|
|
60
70
|
## `@kerfjs/ui/toolbar-control-group`
|
|
@@ -105,6 +115,8 @@ interface MenuHeaderBaseProps {
|
|
|
105
115
|
disabledReason?: string;
|
|
106
116
|
expanded?: boolean;
|
|
107
117
|
toggle?: boolean;
|
|
118
|
+
/** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */
|
|
119
|
+
placeholder?: boolean;
|
|
108
120
|
rootAttributes?: MenuHeaderRootAttributes;
|
|
109
121
|
triggerAttributes?: MenuHeaderTriggerAttributes;
|
|
110
122
|
}
|
|
@@ -118,7 +130,7 @@ type MenuHeaderIndicatorProps = {
|
|
|
118
130
|
badge?: SafeHtml;
|
|
119
131
|
};
|
|
120
132
|
type MenuHeaderProps = MenuHeaderBaseProps & MenuHeaderIndicatorProps;
|
|
121
|
-
declare function MenuHeader({ label, count, countLabel, badge, action, actionLabel, actionIcon, actionDisabled, disabledReason, expanded, toggle, rootAttributes, triggerAttributes }: MenuHeaderProps): SafeHtml;
|
|
133
|
+
declare function MenuHeader({ label, count, countLabel, badge, action, actionLabel, actionIcon, actionDisabled, disabledReason, expanded, toggle, placeholder, rootAttributes, triggerAttributes }: MenuHeaderProps): SafeHtml;
|
|
122
134
|
|
|
123
135
|
export { MenuHeader, type MenuHeaderProps };
|
|
124
136
|
```
|
|
@@ -162,6 +174,8 @@ interface MenuActionRowProps {
|
|
|
162
174
|
state?: string;
|
|
163
175
|
disabled?: boolean;
|
|
164
176
|
tabIndex?: number;
|
|
177
|
+
/** Render as an unanimated loading skeleton, disabling both actions. */
|
|
178
|
+
placeholder?: boolean;
|
|
165
179
|
trailingAction: string;
|
|
166
180
|
trailingActionLabel: string;
|
|
167
181
|
/** Decorative dormant content for the trailing button. Must not contain interactive descendants. */
|
|
@@ -173,7 +187,7 @@ interface MenuActionRowProps {
|
|
|
173
187
|
rootAttributes?: MenuActionRowRootAttributes;
|
|
174
188
|
trailingActionAttributes?: MenuActionRowTrailingAttributes;
|
|
175
189
|
}
|
|
176
|
-
declare function MenuActionRow({ label, icon, action, itemId, selected, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled, trailingActionTitle, className, style, rootAttributes, trailingActionAttributes }: MenuActionRowProps): SafeHtml;
|
|
190
|
+
declare function MenuActionRow({ label, icon, action, itemId, selected, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled, trailingActionTitle, className, style, rootAttributes, trailingActionAttributes }: MenuActionRowProps): SafeHtml;
|
|
177
191
|
|
|
178
192
|
export { MenuActionRow, type MenuActionRowProps };
|
|
179
193
|
```
|
|
@@ -207,9 +221,11 @@ interface MenuItemProps {
|
|
|
207
221
|
state?: string;
|
|
208
222
|
disabled?: boolean;
|
|
209
223
|
tabIndex?: number;
|
|
224
|
+
/** Render the row as an unanimated loading skeleton, disabling its action. */
|
|
225
|
+
placeholder?: boolean;
|
|
210
226
|
rootAttributes?: MenuItemRootAttributes;
|
|
211
227
|
}
|
|
212
|
-
declare function MenuItem({ label, icon, trailing, selected, action, itemId, className, style, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, rootAttributes }: MenuItemProps): SafeHtml;
|
|
228
|
+
declare function MenuItem({ label, icon, trailing, selected, action, itemId, className, style, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, rootAttributes }: MenuItemProps): SafeHtml;
|
|
213
229
|
|
|
214
230
|
export { MenuItem, type MenuItemProps };
|
|
215
231
|
```
|
|
@@ -218,6 +234,7 @@ export { MenuItem, type MenuItemProps };
|
|
|
218
234
|
|
|
219
235
|
```ts
|
|
220
236
|
import { SafeHtml } from 'kerfjs';
|
|
237
|
+
import { HeadingLevel } from './toolbar-text.js';
|
|
221
238
|
|
|
222
239
|
interface PanelHeaderProps {
|
|
223
240
|
title: string;
|
|
@@ -227,6 +244,15 @@ interface PanelHeaderProps {
|
|
|
227
244
|
icon?: SafeHtml;
|
|
228
245
|
iconClassName?: string;
|
|
229
246
|
actions?: SafeHtml;
|
|
247
|
+
/**
|
|
248
|
+
* Expose the title as a heading landmark (`role="heading"` + `aria-level`). Set it
|
|
249
|
+
* for a PAGE or view heading so screen-reader heading navigation works and the view
|
|
250
|
+
* has a primary heading; omit it (the default) for a dialog title, which is instead
|
|
251
|
+
* referenced via `aria-labelledby={titleId}` and needs no heading landmark.
|
|
252
|
+
*/
|
|
253
|
+
headingLevel?: HeadingLevel;
|
|
254
|
+
/** Render the title and summary as unanimated loading skeletons, keeping the icon and actions. */
|
|
255
|
+
placeholder?: boolean;
|
|
230
256
|
}
|
|
231
257
|
/**
|
|
232
258
|
* The heading of a panel, dialog, or page: a plain `Toolbar` whose leading zone
|
|
@@ -240,7 +266,7 @@ interface PanelHeaderProps {
|
|
|
240
266
|
* is passed straight into the toolbar's trailing zone; the app supplies whatever
|
|
241
267
|
* trailing controls it needs (typically a `ToolbarControlGroup`).
|
|
242
268
|
*/
|
|
243
|
-
declare function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName, actions }: PanelHeaderProps): SafeHtml;
|
|
269
|
+
declare function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName, actions, headingLevel, placeholder }: PanelHeaderProps): SafeHtml;
|
|
244
270
|
|
|
245
271
|
export { PanelHeader, type PanelHeaderProps };
|
|
246
272
|
```
|
|
@@ -255,8 +281,10 @@ interface ValueTableRowProps {
|
|
|
255
281
|
value: string | SafeHtml;
|
|
256
282
|
icon?: SafeHtml;
|
|
257
283
|
className?: string;
|
|
284
|
+
/** Render the value as an unanimated loading skeleton, keeping the field label. */
|
|
285
|
+
placeholder?: boolean;
|
|
258
286
|
}
|
|
259
|
-
declare function ValueTableRow({ label, value, icon, className }: ValueTableRowProps): SafeHtml;
|
|
287
|
+
declare function ValueTableRow({ label, value, icon, className, placeholder }: ValueTableRowProps): SafeHtml;
|
|
260
288
|
|
|
261
289
|
interface ValueTableProps {
|
|
262
290
|
label: string;
|
|
@@ -294,9 +322,11 @@ interface AppTabProps {
|
|
|
294
322
|
selectAction?: string;
|
|
295
323
|
closeAction?: string;
|
|
296
324
|
className?: string;
|
|
325
|
+
/** Render as an unanimated loading skeleton, disabling select/close and dragging. */
|
|
326
|
+
placeholder?: boolean;
|
|
297
327
|
rootAttributes?: AppTabRootAttributes;
|
|
298
328
|
}
|
|
299
|
-
declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, closeIcon, selectAction, closeAction, className, rootAttributes }: AppTabProps): SafeHtml;
|
|
329
|
+
declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, closeIcon, selectAction, closeAction, className, placeholder, rootAttributes }: AppTabProps): SafeHtml;
|
|
300
330
|
|
|
301
331
|
export { AppTab, type AppTabProps };
|
|
302
332
|
```
|
|
@@ -683,8 +713,10 @@ interface SegmentedControlProps {
|
|
|
683
713
|
size?: SegmentedControlSize;
|
|
684
714
|
layout?: SegmentedControlLayout;
|
|
685
715
|
className?: string;
|
|
716
|
+
/** Render as an unanimated loading skeleton, disabling every segment. */
|
|
717
|
+
placeholder?: boolean;
|
|
686
718
|
}
|
|
687
|
-
declare function SegmentedControl({ id, label, value, choices, action, appearance, shape, size, layout, className, }: SegmentedControlProps): SafeHtml;
|
|
719
|
+
declare function SegmentedControl({ id, label, value, choices, action, appearance, shape, size, layout, className, placeholder, }: SegmentedControlProps): SafeHtml;
|
|
688
720
|
|
|
689
721
|
export { SegmentedControl, type SegmentedControlAppearance, type SegmentedControlChoice, type SegmentedControlLayout, type SegmentedControlProps, type SegmentedControlShape, type SegmentedControlSize };
|
|
690
722
|
```
|
|
@@ -703,8 +735,10 @@ interface StateBannerProps {
|
|
|
703
735
|
tone?: StateBannerTone;
|
|
704
736
|
urgency?: 'status' | 'alert';
|
|
705
737
|
className?: string;
|
|
738
|
+
/** Render the title and detail as unanimated loading skeletons, keeping the icon and tone. */
|
|
739
|
+
placeholder?: boolean;
|
|
706
740
|
}
|
|
707
|
-
declare function StateBanner({ title, detail, icon, action, tone, urgency, className }: StateBannerProps): SafeHtml;
|
|
741
|
+
declare function StateBanner({ title, detail, icon, action, tone, urgency, className, placeholder }: StateBannerProps): SafeHtml;
|
|
708
742
|
|
|
709
743
|
export { StateBanner, type StateBannerProps, type StateBannerTone };
|
|
710
744
|
```
|
|
@@ -742,6 +776,35 @@ declare function LoadingSpinner({ className, label }: LoadingSpinnerProps): kerf
|
|
|
742
776
|
export { LoadingSpinner, type LoadingSpinnerProps };
|
|
743
777
|
```
|
|
744
778
|
|
|
779
|
+
## `@kerfjs/ui/skeleton`
|
|
780
|
+
|
|
781
|
+
```ts
|
|
782
|
+
import * as kerfjs from 'kerfjs';
|
|
783
|
+
|
|
784
|
+
interface SkeletonProps {
|
|
785
|
+
/** Width as any CSS length (e.g. `remify(120px)`, `60%`). Defaults to filling its slot. */
|
|
786
|
+
width?: string;
|
|
787
|
+
/** Height as any CSS length. Defaults to a single text line. */
|
|
788
|
+
height?: string;
|
|
789
|
+
/** Corner radius override (a CSS length). Defaults to the small radius token. */
|
|
790
|
+
radius?: string;
|
|
791
|
+
/** Render this many stacked lines (the last one shorter), for multi-line text. */
|
|
792
|
+
lines?: number;
|
|
793
|
+
/** Accessible label. Omit to keep the block decorative (`aria-hidden`). */
|
|
794
|
+
label?: string;
|
|
795
|
+
className?: string;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* A subtle, deliberately **unanimated** loading placeholder block. Use it for a
|
|
799
|
+
* value slot whose content is not yet known, on its own or via a component's
|
|
800
|
+
* `placeholder` prop. Decorative by default (`aria-hidden`); pass `label` to
|
|
801
|
+
* announce it. Sizes to its slot unless `width`/`height` are given.
|
|
802
|
+
*/
|
|
803
|
+
declare function Skeleton({ width, height, radius, lines, label, className }: SkeletonProps): kerfjs.SafeHtml;
|
|
804
|
+
|
|
805
|
+
export { Skeleton, type SkeletonProps };
|
|
806
|
+
```
|
|
807
|
+
|
|
745
808
|
## `@kerfjs/ui/token-search-field`
|
|
746
809
|
|
|
747
810
|
```ts
|
package/ai/skill.md
CHANGED
|
@@ -32,6 +32,7 @@ Quick routing:
|
|
|
32
32
|
| Page, panel, or dialog heading | `Toolbar` or `PanelHeader` | Toolbar is persistent chrome; `PanelHeader` heads a panel, dialog, or page. |
|
|
33
33
|
| Exclusive choice | `TabBar`, `SegmentedControl`, or `Select` | Tabs switch tabpanels; segments expose a few choices; Select handles a longer value list. |
|
|
34
34
|
| Status or absent content | `StateBanner` or `EmptyState` | Web Awesome callouts suit ecosystem content; toasts are transient and never the only record of important state. |
|
|
35
|
+
| Loading placeholder | a component's `placeholder` prop, or `Skeleton` | Set `placeholder` on a value-bearing component (`Select`, `MenuHeader`, `MenuItem`, `ValueTableRow`, `PanelHeader`, `SegmentedControl`, `StateBanner`, `AppTab`, `ToolbarText`, `MenuActionRow`) to render its real chrome with value slots as subtle **unanimated** skeletons and interactivity disabled — do not hand-rebuild an empty state. `Skeleton` is the standalone block for a custom slot. Use `LoadingSpinner` for known busy activity, not a skeleton; never animate a skeleton; prefer it over `wa-skeleton`. |
|
|
35
36
|
| Adjustable or static columns | `ResizableRegion` or CSS grid | Use the component only for a user-operable controlled separator. |
|
|
36
37
|
| Structured or ordinary search | `TokenSearchField` or an input | Use token search only when text and ordered filter chips form one editor. |
|
|
37
38
|
| Key/value facts | `ValueTable` with `ValueTableRow` | Use rows with `icon` only when the optional 24px leading visual adds context. |
|
|
@@ -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.
|
|
3
|
+
Generated from the emitted `@kerfjs/ui@5.0.0-beta.8` 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/app-tab.d.ts
CHANGED
|
@@ -21,8 +21,10 @@ interface AppTabProps {
|
|
|
21
21
|
selectAction?: string;
|
|
22
22
|
closeAction?: string;
|
|
23
23
|
className?: string;
|
|
24
|
+
/** Render as an unanimated loading skeleton, disabling select/close and dragging. */
|
|
25
|
+
placeholder?: boolean;
|
|
24
26
|
rootAttributes?: AppTabRootAttributes;
|
|
25
27
|
}
|
|
26
|
-
declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, closeIcon, selectAction, closeAction, className, rootAttributes }: AppTabProps): SafeHtml;
|
|
28
|
+
declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, closeIcon, selectAction, closeAction, className, placeholder, rootAttributes }: AppTabProps): SafeHtml;
|
|
27
29
|
|
|
28
30
|
export { AppTab, type AppTabProps };
|
package/dist/app-tab.js
CHANGED
package/dist/browser/app-tab.js
CHANGED
package/dist/browser/select.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { filterDataAttributes } from './chunk-7BR3DO2A.js';
|
|
2
|
+
import { Skeleton } from './chunk-B24C4A6T.js';
|
|
2
3
|
import { jsxs, jsx } from 'kerfjs/jsx-runtime';
|
|
3
4
|
|
|
4
5
|
var PROTECTED_ROOT_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
@@ -15,14 +16,14 @@ function CloseIcon() {
|
|
|
15
16
|
/* @__PURE__ */ jsx("path", { d: "M17 7 7 17" })
|
|
16
17
|
] });
|
|
17
18
|
}
|
|
18
|
-
function AppTab({ id, name, selected = false, closable = true, draggable = false, leading, trailing, closeIcon, selectAction = "select-tab", closeAction = "close-tab", className = "", rootAttributes = {} }) {
|
|
19
|
+
function AppTab({ id, name, selected = false, closable = true, draggable = false, leading, trailing, closeIcon, selectAction = "select-tab", closeAction = "close-tab", className = "", placeholder = false, rootAttributes = {} }) {
|
|
19
20
|
const keyshortcuts = [closable ? "Delete Backspace" : "", draggable ? "Alt+Shift+ArrowLeft Alt+Shift+ArrowRight" : ""].filter(Boolean).join(" ");
|
|
20
21
|
const extensionAttributes = filterDataAttributes(rootAttributes, PROTECTED_ROOT_DATA_ATTRIBUTES);
|
|
21
|
-
return /* @__PURE__ */ jsxs("div", { ...extensionAttributes, class: `kui-app-tab ${className}`.trim(), "data-component": "app-tab", "data-tab-id": id, "data-selected": String(selected), draggable: draggable ? "true" : "false", children: [
|
|
22
|
-
closable && /* @__PURE__ */ jsx("button", { type: "button", tabindex: "-1", class: "kui-app-tab__close", "data-action": closeAction, "data-tab-id": id, "aria-label": `Close ${name}`, title: `Close ${name}`, children: /* @__PURE__ */ jsx("span", { class: "kui-app-tab__close-icon", "aria-hidden": "true", children: closeIcon ?? /* @__PURE__ */ jsx(CloseIcon, {}) }) }),
|
|
23
|
-
/* @__PURE__ */ jsxs("button", { type: "button", class: "kui-app-tab__select", role: "tab", "aria-selected": String(selected), "aria-keyshortcuts": keyshortcuts || void 0, "data-action": selectAction, "data-tab-id": id, tabindex: selected ? "0" : "-1", children: [
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", { ...extensionAttributes, class: `kui-app-tab ${className}`.trim(), "data-component": "app-tab", "data-tab-id": id, "data-selected": String(selected), "data-placeholder": placeholder ? "true" : void 0, draggable: placeholder ? "false" : draggable ? "true" : "false", "aria-busy": placeholder ? "true" : void 0, children: [
|
|
23
|
+
closable && /* @__PURE__ */ jsx("button", { type: "button", tabindex: "-1", class: "kui-app-tab__close", "data-action": placeholder ? void 0 : closeAction, "data-tab-id": id, disabled: placeholder || void 0, "aria-label": `Close ${name}`, title: `Close ${name}`, children: /* @__PURE__ */ jsx("span", { class: "kui-app-tab__close-icon", "aria-hidden": "true", children: closeIcon ?? /* @__PURE__ */ jsx(CloseIcon, {}) }) }),
|
|
24
|
+
/* @__PURE__ */ jsxs("button", { type: "button", class: "kui-app-tab__select", role: "tab", "aria-selected": String(selected), "aria-keyshortcuts": placeholder ? void 0 : keyshortcuts || void 0, "data-action": placeholder ? void 0 : selectAction, "data-tab-id": id, disabled: placeholder || void 0, tabindex: placeholder ? "-1" : selected ? "0" : "-1", children: [
|
|
24
25
|
leading,
|
|
25
|
-
/* @__PURE__ */ jsx("span", { class: "kui-app-tab__name", children: name }),
|
|
26
|
+
/* @__PURE__ */ jsx("span", { class: "kui-app-tab__name", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "7em" }) : name }),
|
|
26
27
|
closable || trailing ? /* @__PURE__ */ jsx("span", { class: "kui-app-tab__trailing", children: trailing }) : void 0
|
|
27
28
|
] })
|
|
28
29
|
] });
|
|
@@ -30,4 +31,4 @@ function AppTab({ id, name, selected = false, closable = true, draggable = false
|
|
|
30
31
|
|
|
31
32
|
export { AppTab };
|
|
32
33
|
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-2Z5TWHKQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app-tab.tsx"],"names":[],"mappings":"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","file":"chunk-2Z5TWHKQ.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { filterDataAttributes } from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-tab-id',\n 'data-selected',\n 'data-tab-dragging',\n 'data-tab-drop-position',\n]);\n\ntype AppTabRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-tab-id'?: never;\n 'data-selected'?: never;\n 'data-tab-dragging'?: never;\n 'data-tab-drop-position'?: never;\n }\n>;\n\nexport interface AppTabProps {\n id: string;\n name: string;\n selected?: boolean;\n closable?: boolean;\n draggable?: boolean;\n leading?: SafeHtml;\n trailing?: SafeHtml;\n /** Decorative dormant content for the close button. Must not contain interactive descendants. */\n closeIcon?: SafeHtml;\n selectAction?: string;\n closeAction?: string;\n className?: string;\n /** Render as an unanimated loading skeleton, disabling select/close and dragging. */\n placeholder?: boolean;\n rootAttributes?: AppTabRootAttributes;\n}\n\nfunction CloseIcon() {\n return <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\"><path d=\"m7 7 10 10\"></path><path d=\"M17 7 7 17\"></path></svg>;\n}\n\nexport function AppTab({ id, name, selected = false, closable = true, draggable = false, leading, trailing, closeIcon, selectAction = 'select-tab', closeAction = 'close-tab', className = '', placeholder = false, rootAttributes = {} }: AppTabProps) {\n const keyshortcuts = [closable ? 'Delete Backspace' : '', draggable ? 'Alt+Shift+ArrowLeft Alt+Shift+ArrowRight' : ''].filter(Boolean).join(' ');\n const extensionAttributes = filterDataAttributes(rootAttributes, PROTECTED_ROOT_DATA_ATTRIBUTES);\n return <div {...extensionAttributes} class={`kui-app-tab ${className}`.trim()} data-component=\"app-tab\" data-tab-id={id} data-selected={String(selected)} data-placeholder={placeholder ? 'true' : undefined} draggable={placeholder ? 'false' : draggable ? 'true' : 'false'} aria-busy={placeholder ? 'true' : undefined}>\n {closable && <button type=\"button\" tabindex=\"-1\" class=\"kui-app-tab__close\" data-action={placeholder ? undefined : closeAction} data-tab-id={id} disabled={placeholder || undefined} aria-label={`Close ${name}`} title={`Close ${name}`}><span class=\"kui-app-tab__close-icon\" aria-hidden=\"true\">{closeIcon ?? <CloseIcon />}</span></button>}\n <button type=\"button\" class=\"kui-app-tab__select\" role=\"tab\" aria-selected={String(selected)} aria-keyshortcuts={placeholder ? undefined : keyshortcuts || undefined} data-action={placeholder ? undefined : selectAction} data-tab-id={id} disabled={placeholder || undefined} tabindex={placeholder ? '-1' : selected ? '0' : '-1'}>\n {leading}<span class=\"kui-app-tab__name\">{placeholder ? <Skeleton width=\"7em\" /> : name}</span>{closable || trailing ? <span class=\"kui-app-tab__trailing\">{trailing}</span> : undefined}\n </button>\n </div>;\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { filterDataAttributes, filterControlAttributes } from './chunk-7BR3DO2A.js';
|
|
2
|
+
import { Skeleton } from './chunk-B24C4A6T.js';
|
|
2
3
|
import { jsxs, jsx } from 'kerfjs/jsx-runtime';
|
|
3
4
|
|
|
4
5
|
var PROTECTED_ROOT_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
@@ -16,18 +17,18 @@ var PROTECTED_TRAILING_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
16
17
|
"data-action",
|
|
17
18
|
"data-item-id"
|
|
18
19
|
]);
|
|
19
|
-
function MenuActionRow({ label, icon, action, itemId, selected = false, pressed, accessibleLabel, title, multiline = false, state, disabled = false, tabIndex, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled = false, trailingActionTitle, className = "", style, rootAttributes = {}, trailingActionAttributes = {} }) {
|
|
20
|
+
function MenuActionRow({ label, icon, action, itemId, selected = false, pressed, accessibleLabel, title, multiline = false, state, disabled = false, tabIndex, placeholder = false, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled = false, trailingActionTitle, className = "", style, rootAttributes = {}, trailingActionAttributes = {} }) {
|
|
20
21
|
const extensionRootAttributes = filterDataAttributes(rootAttributes, PROTECTED_ROOT_DATA_ATTRIBUTES);
|
|
21
22
|
const extensionTrailingAttributes = filterControlAttributes(trailingActionAttributes, PROTECTED_TRAILING_DATA_ATTRIBUTES);
|
|
22
|
-
return /* @__PURE__ */ jsxs("div", { ...extensionRootAttributes, class: `kui-menu-action-row ${className}`.trim(), style, "data-component": "menu-action-row", "data-item-id": itemId, "data-has-icon": String(Boolean(icon)), "data-multiline": multiline ? "true" : void 0, "data-state": state, "data-selected": String(selected), "data-pressed": pressed === void 0 ? void 0 : String(pressed), children: [
|
|
23
|
-
/* @__PURE__ */ jsxs("button", { type: "button", class: "kui-menu-action-row__primary", title, disabled, tabindex: tabIndex, "data-action": action, "data-item-id": itemId, "aria-label": accessibleLabel, "aria-current": selected ? "page" : void 0, "aria-pressed": pressed === void 0 ? void 0 : String(pressed), children: [
|
|
24
|
-
icon && /* @__PURE__ */ jsx("span", { class: "kui-menu-action-row__icon", children: icon }),
|
|
25
|
-
/* @__PURE__ */ jsx("span", { class: "kui-menu-action-row__label", children: label })
|
|
23
|
+
return /* @__PURE__ */ jsxs("div", { ...extensionRootAttributes, class: `kui-menu-action-row ${className}`.trim(), style, "data-component": "menu-action-row", "data-item-id": itemId, "data-has-icon": String(Boolean(icon)), "data-multiline": multiline ? "true" : void 0, "data-state": state, "data-selected": String(selected), "data-pressed": pressed === void 0 ? void 0 : String(pressed), "data-placeholder": placeholder ? "true" : void 0, "aria-busy": placeholder ? "true" : void 0, children: [
|
|
24
|
+
/* @__PURE__ */ jsxs("button", { type: "button", class: "kui-menu-action-row__primary", title: placeholder ? void 0 : title, disabled: disabled || placeholder, tabindex: placeholder ? -1 : tabIndex, "data-action": placeholder ? void 0 : action, "data-item-id": itemId, "aria-label": accessibleLabel, "aria-current": selected ? "page" : void 0, "aria-pressed": pressed === void 0 ? void 0 : String(pressed), children: [
|
|
25
|
+
icon && /* @__PURE__ */ jsx("span", { class: "kui-menu-action-row__icon", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "1em", height: "1em" }) : icon }),
|
|
26
|
+
/* @__PURE__ */ jsx("span", { class: "kui-menu-action-row__label", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "9em" }) : label })
|
|
26
27
|
] }),
|
|
27
|
-
/* @__PURE__ */ jsx("button", { ...extensionTrailingAttributes, type: "button", class: "kui-menu-action-row__trailing-action", "data-action": trailingAction, "data-item-id": itemId, "aria-label": trailingActionLabel, title: trailingActionTitle ?? trailingActionLabel, disabled: trailingActionDisabled || void 0, children: trailingActionIcon })
|
|
28
|
+
/* @__PURE__ */ jsx("button", { ...extensionTrailingAttributes, type: "button", class: "kui-menu-action-row__trailing-action", "data-action": placeholder ? void 0 : trailingAction, "data-item-id": itemId, "aria-label": trailingActionLabel, title: trailingActionTitle ?? trailingActionLabel, disabled: trailingActionDisabled || placeholder || void 0, children: trailingActionIcon })
|
|
28
29
|
] });
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export { MenuActionRow };
|
|
32
33
|
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-3YD6ZNRA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/menu-action-row.tsx"],"names":[],"mappings":"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","file":"chunk-3YD6ZNRA.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { filterControlAttributes, filterDataAttributes } from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-multiline',\n 'data-state',\n 'data-selected',\n 'data-pressed',\n]);\nconst PROTECTED_TRAILING_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n]);\n\ntype MenuActionRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-multiline'?: never;\n 'data-state'?: never;\n 'data-selected'?: never;\n 'data-pressed'?: never;\n }\n>;\n\ntype MenuActionRowTrailingAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: 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\nexport interface MenuActionRowProps {\n /** Visible dormant content for the primary button. Must not contain interactive descendants. */\n label: string | SafeHtml;\n /** Decorative dormant content for the primary button. Must not contain interactive descendants. */\n icon?: SafeHtml;\n action: string;\n itemId?: string;\n selected?: boolean;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render as an unanimated loading skeleton, disabling both actions. */\n placeholder?: boolean;\n trailingAction: string;\n trailingActionLabel: string;\n /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */\n trailingActionIcon: SafeHtml;\n trailingActionDisabled?: boolean;\n trailingActionTitle?: string;\n className?: string;\n style?: string;\n rootAttributes?: MenuActionRowRootAttributes;\n trailingActionAttributes?: MenuActionRowTrailingAttributes;\n}\n\nexport function MenuActionRow({ label, icon, action, itemId, selected = false, pressed, accessibleLabel, title, multiline = false, state, disabled = false, tabIndex, placeholder = false, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled = false, trailingActionTitle, className = '', style, rootAttributes = {}, trailingActionAttributes = {} }: MenuActionRowProps) {\n const extensionRootAttributes = filterDataAttributes(rootAttributes, PROTECTED_ROOT_DATA_ATTRIBUTES);\n const extensionTrailingAttributes = filterControlAttributes(trailingActionAttributes, PROTECTED_TRAILING_DATA_ATTRIBUTES);\n\n return <div {...extensionRootAttributes} class={`kui-menu-action-row ${className}`.trim()} style={style} data-component=\"menu-action-row\" data-item-id={itemId} data-has-icon={String(Boolean(icon))} data-multiline={multiline ? 'true' : undefined} data-state={state} data-selected={String(selected)} data-pressed={pressed === undefined ? undefined : String(pressed)} data-placeholder={placeholder ? 'true' : undefined} aria-busy={placeholder ? 'true' : undefined}>\n <button type=\"button\" class=\"kui-menu-action-row__primary\" title={placeholder ? undefined : title} disabled={disabled || placeholder} tabindex={placeholder ? -1 : tabIndex} data-action={placeholder ? undefined : action} data-item-id={itemId} aria-label={accessibleLabel} aria-current={selected ? 'page' : undefined} aria-pressed={pressed === undefined ? undefined : String(pressed)}>\n {icon && <span class=\"kui-menu-action-row__icon\">{placeholder ? <Skeleton width=\"1em\" height=\"1em\" /> : icon}</span>}\n <span class=\"kui-menu-action-row__label\">{placeholder ? <Skeleton width=\"9em\" /> : label}</span>\n </button>\n <button {...extensionTrailingAttributes} type=\"button\" class=\"kui-menu-action-row__trailing-action\" data-action={placeholder ? undefined : trailingAction} data-item-id={itemId} aria-label={trailingActionLabel} title={trailingActionTitle ?? trailingActionLabel} disabled={trailingActionDisabled || placeholder || undefined}>{trailingActionIcon}</button>\n </div>;\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx } from 'kerfjs/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
// src/skeleton.tsx
|
|
4
|
+
function blockStyle(width, height, radius) {
|
|
5
|
+
const parts = [
|
|
6
|
+
width && `width:${width}`,
|
|
7
|
+
height && `height:${height}`,
|
|
8
|
+
radius && `--kui-skeleton-radius:${radius}`
|
|
9
|
+
].filter(Boolean);
|
|
10
|
+
return parts.length ? parts.join(";") : void 0;
|
|
11
|
+
}
|
|
12
|
+
function Skeleton({ width, height, radius, lines, label, className = "" }) {
|
|
13
|
+
const a11y = { role: label ? "img" : void 0, "aria-label": label, "aria-hidden": label ? void 0 : "true" };
|
|
14
|
+
if (lines && lines > 1) {
|
|
15
|
+
return /* @__PURE__ */ jsx("span", { class: `kui-skeleton-lines ${className}`.trim(), "data-component": "skeleton", style: width ? `width:${width}` : void 0, ...a11y, children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx("span", { class: "kui-skeleton", "aria-hidden": "true", style: blockStyle(index === lines - 1 ? "60%" : void 0, height, radius) })) });
|
|
16
|
+
}
|
|
17
|
+
return /* @__PURE__ */ jsx("span", { class: `kui-skeleton ${className}`.trim(), "data-component": "skeleton", style: blockStyle(width, height, radius), ...a11y });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { Skeleton };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=chunk-B24C4A6T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/skeleton.tsx"],"names":[],"mappings":";;;AAcA,SAAS,UAAA,CAAW,KAAA,EAAgB,MAAA,EAAiB,MAAA,EAAqC;AACxF,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,KAAA,IAAS,SAAS,KAAK,CAAA,CAAA;AAAA,IACvB,MAAA,IAAU,UAAU,MAAM,CAAA,CAAA;AAAA,IAC1B,MAAA,IAAU,yBAAyB,MAAM,CAAA;AAAA,GAC3C,CAAE,OAAO,OAAO,CAAA;AAChB,EAAA,OAAO,KAAA,CAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA;AAC1C;AAQO,SAAS,QAAA,CAAS,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAQ,KAAA,EAAO,KAAA,EAAO,SAAA,GAAY,EAAA,EAAG,EAAkB;AAC/F,EAAA,MAAM,IAAA,GAAO,EAAE,IAAA,EAAM,KAAA,GAAQ,KAAA,GAAQ,MAAA,EAAW,YAAA,EAAc,KAAA,EAAO,aAAA,EAAe,KAAA,GAAQ,MAAA,GAAa,MAAA,EAAiB;AAC1H,EAAA,IAAI,KAAA,IAAS,QAAQ,CAAA,EAAG;AACtB,IAAA,uBAAO,GAAA,CAAC,UAAK,KAAA,EAAO,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAA,CAAG,IAAA,IAAQ,gBAAA,EAAe,UAAA,EAAW,OAAO,KAAA,GAAQ,CAAA,MAAA,EAAS,KAAK,CAAA,CAAA,GAAK,MAAA,EAAY,GAAG,IAAA,EACtI,QAAA,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,OAAM,EAAG,CAAC,GAAG,KAAA,qBAAU,GAAA,CAAC,UAAK,KAAA,EAAM,cAAA,EAAe,eAAY,MAAA,EAAO,KAAA,EAAO,WAAW,KAAA,KAAU,KAAA,GAAQ,IAAI,KAAA,GAAQ,MAAA,EAAW,QAAQ,MAAM,CAAA,EAAG,CAAO,CAAA,EAChL,CAAA;AAAA,EACF;AACA,EAAA,2BAAQ,MAAA,EAAA,EAAK,KAAA,EAAO,CAAA,aAAA,EAAgB,SAAS,GAAG,IAAA,EAAK,EAAG,gBAAA,EAAe,UAAA,EAAW,OAAO,UAAA,CAAW,KAAA,EAAO,QAAQ,MAAM,CAAA,EAAI,GAAG,IAAA,EAAM,CAAA;AACxI","file":"chunk-B24C4A6T.js","sourcesContent":["export interface SkeletonProps {\n /** Width as any CSS length (e.g. `remify(120px)`, `60%`). Defaults to filling its slot. */\n width?: string;\n /** Height as any CSS length. Defaults to a single text line. */\n height?: string;\n /** Corner radius override (a CSS length). Defaults to the small radius token. */\n radius?: string;\n /** Render this many stacked lines (the last one shorter), for multi-line text. */\n lines?: number;\n /** Accessible label. Omit to keep the block decorative (`aria-hidden`). */\n label?: string;\n className?: string;\n}\n\nfunction blockStyle(width?: string, height?: string, radius?: string): string | undefined {\n const parts = [\n width && `width:${width}`,\n height && `height:${height}`,\n radius && `--kui-skeleton-radius:${radius}`,\n ].filter(Boolean);\n return parts.length ? parts.join(';') : undefined;\n}\n\n/**\n * A subtle, deliberately **unanimated** loading placeholder block. Use it for a\n * value slot whose content is not yet known, on its own or via a component's\n * `placeholder` prop. Decorative by default (`aria-hidden`); pass `label` to\n * announce it. Sizes to its slot unless `width`/`height` are given.\n */\nexport function Skeleton({ width, height, radius, lines, label, className = '' }: SkeletonProps) {\n const a11y = { role: label ? 'img' : undefined, 'aria-label': label, 'aria-hidden': label ? undefined : ('true' as const) };\n if (lines && lines > 1) {\n return <span class={`kui-skeleton-lines ${className}`.trim()} data-component=\"skeleton\" style={width ? `width:${width}` : undefined} {...a11y}>\n {Array.from({ length: lines }, (_, index) => <span class=\"kui-skeleton\" aria-hidden=\"true\" style={blockStyle(index === lines - 1 ? '60%' : undefined, height, radius)}></span>)}\n </span>;\n }\n return <span class={`kui-skeleton ${className}`.trim()} data-component=\"skeleton\" style={blockStyle(width, height, radius)} {...a11y}></span>;\n}\n"]}
|