@kerfjs/ui 5.0.0-beta.7 → 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/ai/component-catalog.json +7 -3
- package/ai/public-api-signatures-v1.md +20 -4
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/{chunk-N3SUXLLS.js → chunk-BLK3UEEI.js} +2 -2
- package/dist/{chunk-N3SUXLLS.js.map → chunk-BLK3UEEI.js.map} +1 -1
- package/dist/{chunk-TZNCCM5H.js → chunk-BNQ2YDV4.js} +4 -4
- package/dist/chunk-BNQ2YDV4.js.map +1 -0
- package/dist/{chunk-KJYXOTG3.js → chunk-RUNWEPR4.js} +3 -3
- package/dist/chunk-RUNWEPR4.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/nav-stack.js +1 -1
- package/dist/panel-header.d.ts +9 -1
- package/dist/panel-header.js +1 -1
- package/dist/split-view.js +1 -1
- package/dist/toolbar-text.d.ts +10 -2
- package/dist/toolbar-text.js +1 -1
- package/docs/accessibility.md +10 -5
- package/docs/component-selection.md +2 -2
- package/package.json +1 -1
- package/dist/chunk-KJYXOTG3.js.map +0 -1
- package/dist/chunk-TZNCCM5H.js.map +0 -1
|
@@ -488,7 +488,9 @@
|
|
|
488
488
|
"small",
|
|
489
489
|
"placeholder (loading)"
|
|
490
490
|
],
|
|
491
|
-
"accessibility": [
|
|
491
|
+
"accessibility": [
|
|
492
|
+
"Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title."
|
|
493
|
+
],
|
|
492
494
|
"delivery": {
|
|
493
495
|
"browserImport": "@kerfjs/ui/toolbar-text",
|
|
494
496
|
"manualCssImport": "@kerfjs/ui/toolbar-text.css",
|
|
@@ -614,11 +616,13 @@
|
|
|
614
616
|
"optional summary",
|
|
615
617
|
"icon",
|
|
616
618
|
"actions",
|
|
617
|
-
"placeholder (loading)"
|
|
619
|
+
"placeholder (loading)",
|
|
620
|
+
"page heading (headingLevel)"
|
|
618
621
|
],
|
|
619
622
|
"accessibility": [
|
|
620
623
|
"Connect the title id and any provided summary id to the dialog or panel host.",
|
|
621
|
-
"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."
|
|
622
626
|
],
|
|
623
627
|
"delivery": {
|
|
624
628
|
"browserImport": "@kerfjs/ui/panel-header",
|
|
@@ -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,18 +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;
|
|
54
62
|
/** Render the text as an unanimated loading skeleton instead of its value. */
|
|
55
63
|
placeholder?: boolean;
|
|
56
64
|
}
|
|
57
|
-
declare function ToolbarText({ text, size, className, id, placeholder }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
65
|
+
declare function ToolbarText({ text, size, className, id, headingLevel, placeholder }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
58
66
|
|
|
59
|
-
export { ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
67
|
+
export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
## `@kerfjs/ui/toolbar-control-group`
|
|
@@ -226,6 +234,7 @@ export { MenuItem, type MenuItemProps };
|
|
|
226
234
|
|
|
227
235
|
```ts
|
|
228
236
|
import { SafeHtml } from 'kerfjs';
|
|
237
|
+
import { HeadingLevel } from './toolbar-text.js';
|
|
229
238
|
|
|
230
239
|
interface PanelHeaderProps {
|
|
231
240
|
title: string;
|
|
@@ -235,6 +244,13 @@ interface PanelHeaderProps {
|
|
|
235
244
|
icon?: SafeHtml;
|
|
236
245
|
iconClassName?: string;
|
|
237
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;
|
|
238
254
|
/** Render the title and summary as unanimated loading skeletons, keeping the icon and actions. */
|
|
239
255
|
placeholder?: boolean;
|
|
240
256
|
}
|
|
@@ -250,7 +266,7 @@ interface PanelHeaderProps {
|
|
|
250
266
|
* is passed straight into the toolbar's trailing zone; the app supplies whatever
|
|
251
267
|
* trailing controls it needs (typically a `ToolbarControlGroup`).
|
|
252
268
|
*/
|
|
253
|
-
declare function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName, actions, placeholder }: PanelHeaderProps): SafeHtml;
|
|
269
|
+
declare function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName, actions, headingLevel, placeholder }: PanelHeaderProps): SafeHtml;
|
|
254
270
|
|
|
255
271
|
export { PanelHeader, type PanelHeaderProps };
|
|
256
272
|
```
|
|
@@ -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';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ToolbarText } from './chunk-
|
|
1
|
+
import { ToolbarText } from './chunk-RUNWEPR4.js';
|
|
2
2
|
import { jsxs, jsx } from 'kerfjs/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
function NavStack({ id, label, views, backLabel = "Back", hideToolbar = false, bottomToolbar, className = "" }) {
|
|
@@ -20,4 +20,4 @@ function NavStack({ id, label, views, backLabel = "Back", hideToolbar = false, b
|
|
|
20
20
|
|
|
21
21
|
export { NavStack };
|
|
22
22
|
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
23
|
+
//# sourceMappingURL=chunk-BLK3UEEI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":";;;AAuCO,SAAS,QAAA,CAAS,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,SAAA,GAAY,MAAA,EAAQ,WAAA,GAAc,KAAA,EAAO,aAAA,EAAe,SAAA,GAAY,EAAA,EAAG,EAAkB;AACpI,EAAA,MAAM,QAAA,GAAW,MAAM,MAAA,GAAS,CAAA;AAChC,EAAA,MAAM,GAAA,GAAM,MAAM,QAAQ,CAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,GAAS,CAAA;AAC9B,EAAA,4BAAQ,SAAA,EAAA,EAAQ,KAAA,EAAO,iBAAiB,SAAS,CAAA,CAAA,CAAG,MAAK,EAAG,EAAA,EAAQ,kBAAe,WAAA,EAAY,mBAAA,EAAmB,IAAI,YAAA,EAAY,MAAA,CAAO,MAAM,MAAM,CAAA,EAAG,cAAY,KAAA,EACjK,QAAA,EAAA;AAAA,IAAA,CAAC,+BAAe,IAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,uBAAA,EAAwB,yBAAqB,IAAA,EAC1E,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,OAAM,qBAAA,EACR,QAAA,EAAA;AAAA,QAAA,MAAA,wBAAW,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,KAAA,EAAM,uBAAsB,eAAA,EAAa,IAAA,EAAC,YAAA,EAAY,SAAA,EACrF,8BAAC,KAAA,EAAA,EAAI,KAAA,EAAM,0BAAA,EAA2B,OAAA,EAAQ,aAAY,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,eAAY,MAAA,EAAO,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,gBAAe,cAAA,EAAa,GAAA,EAAI,gBAAA,EAAe,OAAA,EAAQ,mBAAgB,OAAA,EAAQ,QAAA,kBAAA,GAAA,CAAC,UAAK,CAAA,EAAE,gBAAA,EAAiB,GAAE,CAAA,EACnO,CAAA;AAAA,wBACA,GAAA,CAAC,eAAY,IAAA,EAAM,GAAA,EAAK,SAAS,EAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,SAAA,EAAU,sBAAA,EAAuB;AAAA,OAAA,EACrF,CAAA;AAAA,MACC,KAAK,OAAA,oBAAW,GAAA,CAAC,SAAI,KAAA,EAAM,wBAAA,EAA0B,cAAI,OAAA,EAAQ;AAAA,KAAA,EACpE,CAAA;AAAA,oBACA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,yBAAA,EAA0B,2BAAuB,IAAA,EACzD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,qBAAU,GAAA,CAAC,SAAA,EAAA,EAAQ,KAAA,EAAM,uBAAsB,UAAA,EAAU,IAAA,CAAK,GAAA,EAAK,cAAA,EAAc,IAAA,CAAK,GAAA,EAAK,iBAAA,EAAiB,MAAA,CAAO,UAAU,QAAQ,CAAA,EAAG,aAAA,EAAa,MAAA,CAAO,UAAU,QAAQ,CAAA,EAAI,QAAA,EAAA,IAAA,CAAK,OAAA,EAAQ,CAAU,CAAA,EAC7N,CAAA;AAAA,IACC,iCAAiB,GAAA,CAAC,QAAA,EAAA,EAAO,OAAM,uBAAA,EAAwB,uBAAA,EAAqB,MAAE,QAAA,EAAA,aAAA,EAAc;AAAA,GAAA,EAC/F,CAAA;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":";;;AAuCO,SAAS,QAAA,CAAS,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,SAAA,GAAY,MAAA,EAAQ,WAAA,GAAc,KAAA,EAAO,aAAA,EAAe,SAAA,GAAY,EAAA,EAAG,EAAkB;AACpI,EAAA,MAAM,QAAA,GAAW,MAAM,MAAA,GAAS,CAAA;AAChC,EAAA,MAAM,GAAA,GAAM,MAAM,QAAQ,CAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,GAAS,CAAA;AAC9B,EAAA,4BAAQ,SAAA,EAAA,EAAQ,KAAA,EAAO,iBAAiB,SAAS,CAAA,CAAA,CAAG,MAAK,EAAG,EAAA,EAAQ,kBAAe,WAAA,EAAY,mBAAA,EAAmB,IAAI,YAAA,EAAY,MAAA,CAAO,MAAM,MAAM,CAAA,EAAG,cAAY,KAAA,EACjK,QAAA,EAAA;AAAA,IAAA,CAAC,+BAAe,IAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,uBAAA,EAAwB,yBAAqB,IAAA,EAC1E,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,OAAM,qBAAA,EACR,QAAA,EAAA;AAAA,QAAA,MAAA,wBAAW,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,KAAA,EAAM,uBAAsB,eAAA,EAAa,IAAA,EAAC,YAAA,EAAY,SAAA,EACrF,8BAAC,KAAA,EAAA,EAAI,KAAA,EAAM,0BAAA,EAA2B,OAAA,EAAQ,aAAY,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,eAAY,MAAA,EAAO,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,gBAAe,cAAA,EAAa,GAAA,EAAI,gBAAA,EAAe,OAAA,EAAQ,mBAAgB,OAAA,EAAQ,QAAA,kBAAA,GAAA,CAAC,UAAK,CAAA,EAAE,gBAAA,EAAiB,GAAE,CAAA,EACnO,CAAA;AAAA,wBACA,GAAA,CAAC,eAAY,IAAA,EAAM,GAAA,EAAK,SAAS,EAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,SAAA,EAAU,sBAAA,EAAuB;AAAA,OAAA,EACrF,CAAA;AAAA,MACC,KAAK,OAAA,oBAAW,GAAA,CAAC,SAAI,KAAA,EAAM,wBAAA,EAA0B,cAAI,OAAA,EAAQ;AAAA,KAAA,EACpE,CAAA;AAAA,oBACA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,yBAAA,EAA0B,2BAAuB,IAAA,EACzD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,qBAAU,GAAA,CAAC,SAAA,EAAA,EAAQ,KAAA,EAAM,uBAAsB,UAAA,EAAU,IAAA,CAAK,GAAA,EAAK,cAAA,EAAc,IAAA,CAAK,GAAA,EAAK,iBAAA,EAAiB,MAAA,CAAO,UAAU,QAAQ,CAAA,EAAG,aAAA,EAAa,MAAA,CAAO,UAAU,QAAQ,CAAA,EAAI,QAAA,EAAA,IAAA,CAAK,OAAA,EAAQ,CAAU,CAAA,EAC7N,CAAA;AAAA,IACC,iCAAiB,GAAA,CAAC,QAAA,EAAA,EAAO,OAAM,uBAAA,EAAwB,uBAAA,EAAqB,MAAE,QAAA,EAAA,aAAA,EAAc;AAAA,GAAA,EAC/F,CAAA;AACF","file":"chunk-BLK3UEEI.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { ToolbarText } from './toolbar-text.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n content: SafeHtml;\n /** Title shown in the top toolbar for this view. */\n title?: string;\n /** Trailing actions for this view's top toolbar. */\n toolbar?: SafeHtml;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the back control (default \"Back\"). */\n backLabel?: string;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar. */\n bottomToolbar?: SafeHtml;\n className?: string;\n}\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. A single-pane layout is a `NavStack`\n * with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({ id, label, views, backLabel = 'Back', hideToolbar = false, bottomToolbar, className = '' }: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const canPop = views.length > 1;\n return <section class={`kui-nav-stack ${className}`.trim()} id={id} data-component=\"nav-stack\" data-nav-stack-id={id} data-depth={String(views.length)} aria-label={label}>\n {!hideToolbar && <header class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <div class=\"kui-nav-stack__lead\">\n {canPop && <button type=\"button\" class=\"kui-nav-stack__back\" data-nav-back aria-label={backLabel}>\n <svg class=\"kui-nav-stack__back-icon\" viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" aria-hidden=\"true\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m15 18-6-6 6-6\" /></svg>\n </button>}\n <ToolbarText text={top?.title ?? ''} size=\"large\" className=\"kui-nav-stack__title\" />\n </div>\n {top?.toolbar && <div class=\"kui-nav-stack__actions\">{top.toolbar}</div>}\n </header>}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => <article class=\"kui-nav-stack__view\" data-key={view.key} data-nav-key={view.key} data-nav-active={String(index === topIndex)} aria-hidden={String(index !== topIndex)}>{view.content}</article>)}\n </div>\n {bottomToolbar && <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>{bottomToolbar}</footer>}\n </section>;\n}\n"]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Toolbar } from './chunk-DAFFDO33.js';
|
|
2
2
|
import { ToolbarControlGroup } from './chunk-MFKMHK5W.js';
|
|
3
|
-
import { ToolbarText } from './chunk-
|
|
3
|
+
import { ToolbarText } from './chunk-RUNWEPR4.js';
|
|
4
4
|
import { Skeleton } from './chunk-B24C4A6T.js';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'kerfjs/jsx-runtime';
|
|
6
6
|
|
|
7
|
-
function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName = "", actions, placeholder = false }) {
|
|
7
|
+
function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName = "", actions, headingLevel, placeholder = false }) {
|
|
8
8
|
const identity = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9
9
|
icon && /* @__PURE__ */ jsx(ToolbarControlGroup, { single: true, className: `kui-panel-header__icon ${iconClassName}`.trim(), children: icon }),
|
|
10
|
-
/* @__PURE__ */ jsx(ToolbarText, { text: title, size: "xlarge", id: titleId, className: "kui-panel-header__title", placeholder })
|
|
10
|
+
/* @__PURE__ */ jsx(ToolbarText, { text: title, size: "xlarge", id: titleId, className: "kui-panel-header__title", headingLevel, placeholder })
|
|
11
11
|
] });
|
|
12
12
|
return /* @__PURE__ */ jsxs("div", { class: "kui-panel-header", "data-component": "panel-header", "data-has-icon": String(Boolean(icon)), "data-has-actions": String(Boolean(actions)), "data-has-summary": String(Boolean(summary)), "data-placeholder": placeholder ? "true" : void 0, children: [
|
|
13
13
|
/* @__PURE__ */ jsx(Toolbar, { leading: identity, trailing: actions, divider: false }),
|
|
@@ -17,4 +17,4 @@ function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName =
|
|
|
17
17
|
|
|
18
18
|
export { PanelHeader };
|
|
19
19
|
|
|
20
|
-
//# sourceMappingURL=chunk-
|
|
20
|
+
//# sourceMappingURL=chunk-BNQ2YDV4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/panel-header.tsx"],"names":[],"mappings":";;;;;;AAsCO,SAAS,WAAA,CAAY,EAAE,KAAA,EAAO,OAAA,EAAS,OAAA,EAAS,SAAA,EAAW,IAAA,EAAM,aAAA,GAAgB,EAAA,EAAI,OAAA,EAAS,YAAA,EAAc,WAAA,GAAc,OAAM,EAAqB;AAC1J,EAAA,MAAM,2BAAW,IAAA,CAAA,QAAA,EAAA,EACd,QAAA,EAAA;AAAA,IAAA,IAAA,oBAAQ,GAAA,CAAC,mBAAA,EAAA,EAAoB,MAAA,EAAM,IAAA,EAAC,SAAA,EAAW,0BAA0B,aAAa,CAAA,CAAA,CAAG,IAAA,EAAK,EAAI,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,oBACxG,GAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,QAAA,EAAS,EAAA,EAAI,OAAA,EAAS,SAAA,EAAU,yBAAA,EAA0B,YAAA,EAA4B,WAAA,EAA0B;AAAA,GAAA,EACjJ,CAAA;AAEA,EAAA,uBAAO,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,kBAAA,EAAmB,gBAAA,EAAe,cAAA,EAAe,eAAA,EAAe,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA,EAAG,kBAAA,EAAkB,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAC,CAAA,EAAG,kBAAA,EAAkB,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAC,CAAA,EAAG,kBAAA,EAAkB,WAAA,GAAc,MAAA,GAAS,MAAA,EACxO,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,WAAQ,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,SAAS,KAAA,EAAO,CAAA;AAAA,IAC9D,OAAA,oBAAW,GAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAM,2BAAA,EAA4B,EAAA,EAAI,SAAA,EAAY,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,MAAA,EAAO,IAAK,OAAA,EAAQ;AAAA,GAAA,EACrH,CAAA;AACF","file":"chunk-BNQ2YDV4.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { Skeleton } from './skeleton.js';\nimport { Toolbar } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\nimport { type HeadingLevel, ToolbarText } from './toolbar-text.js';\n\nexport interface PanelHeaderProps {\n title: string;\n titleId: string;\n summary?: string;\n summaryId?: string;\n icon?: SafeHtml;\n iconClassName?: string;\n actions?: SafeHtml;\n /**\n * Expose the title as a heading landmark (`role=\"heading\"` + `aria-level`). Set it\n * for a PAGE or view heading so screen-reader heading navigation works and the view\n * has a primary heading; omit it (the default) for a dialog title, which is instead\n * referenced via `aria-labelledby={titleId}` and needs no heading landmark.\n */\n headingLevel?: HeadingLevel;\n /** Render the title and summary as unanimated loading skeletons, keeping the icon and actions. */\n placeholder?: boolean;\n}\n\n/**\n * The heading of a panel, dialog, or page: a plain `Toolbar` whose leading zone\n * holds an optional icon control group and the title as extra-large `ToolbarText`,\n * whose trailing zone holds the app's action controls, and with an optional\n * subtitle on its own row, left-aligned with the title.\n *\n * PanelHeader overrides no Toolbar styles — it is just a Toolbar with an xl title.\n * The only styling it adds is the icon group's fill/border color and the subtitle.\n * When no icon is provided, the icon group is omitted entirely. The `actions` slot\n * is passed straight into the toolbar's trailing zone; the app supplies whatever\n * trailing controls it needs (typically a `ToolbarControlGroup`).\n */\nexport function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName = '', actions, headingLevel, placeholder = false }: PanelHeaderProps) {\n const identity = <>\n {icon && <ToolbarControlGroup single className={`kui-panel-header__icon ${iconClassName}`.trim()}>{icon}</ToolbarControlGroup>}\n <ToolbarText text={title} size=\"xlarge\" id={titleId} className=\"kui-panel-header__title\" headingLevel={headingLevel} placeholder={placeholder} />\n </>;\n\n return <div class=\"kui-panel-header\" data-component=\"panel-header\" data-has-icon={String(Boolean(icon))} data-has-actions={String(Boolean(actions))} data-has-summary={String(Boolean(summary))} data-placeholder={placeholder ? 'true' : undefined}>\n <Toolbar leading={identity} trailing={actions} divider={false} />\n {summary && <p class=\"kui-panel-header__summary\" id={summaryId}>{placeholder ? <Skeleton width=\"18em\" /> : summary}</p>}\n </div>;\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Skeleton } from './chunk-B24C4A6T.js';
|
|
2
2
|
import { jsx } from 'kerfjs/jsx-runtime';
|
|
3
3
|
|
|
4
|
-
function ToolbarText({ text, size = "default", className = "", id, placeholder = false }) {
|
|
5
|
-
return /* @__PURE__ */ jsx("span", { class: `kui-toolbar-text ${className}`.trim(), "data-component": "toolbar-text", "data-size": size, "data-placeholder": placeholder ? "true" : void 0, id, "aria-busy": placeholder ? "true" : void 0, children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "8em" }) : text });
|
|
4
|
+
function ToolbarText({ text, size = "default", className = "", id, headingLevel, placeholder = false }) {
|
|
5
|
+
return /* @__PURE__ */ jsx("span", { class: `kui-toolbar-text ${className}`.trim(), "data-component": "toolbar-text", "data-size": size, "data-placeholder": placeholder ? "true" : void 0, id, role: headingLevel ? "heading" : void 0, "aria-level": headingLevel ? String(headingLevel) : void 0, "aria-busy": placeholder ? "true" : void 0, children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "8em" }) : text });
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export { ToolbarText };
|
|
9
9
|
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
10
|
+
//# sourceMappingURL=chunk-RUNWEPR4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/toolbar-text.tsx"],"names":[],"mappings":";;;AAuBO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAM,IAAA,GAAO,SAAA,EAAW,SAAA,GAAY,EAAA,EAAI,EAAA,EAAI,YAAA,EAAc,WAAA,GAAc,KAAA,EAAM,EAAqB;AAC/H,EAAA,2BAAQ,MAAA,EAAA,EAAK,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,GAAG,IAAA,EAAK,EAAG,gBAAA,EAAe,cAAA,EAAe,aAAW,IAAA,EAAM,kBAAA,EAAkB,WAAA,GAAc,MAAA,GAAS,QAAW,EAAA,EAAQ,IAAA,EAAM,YAAA,GAAe,SAAA,GAAY,QAAW,YAAA,EAAY,YAAA,GAAe,MAAA,CAAO,YAAY,IAAI,MAAA,EAAW,WAAA,EAAW,WAAA,GAAc,MAAA,GAAS,QAAY,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,YAAS,KAAA,EAAM,KAAA,EAAM,IAAK,IAAA,EAAK,CAAA;AAC9W","file":"chunk-RUNWEPR4.js","sourcesContent":["import { Skeleton } from './skeleton.js';\n\nexport type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';\n\n/** ARIA heading level for a title exposed as a heading landmark. */\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface ToolbarTextProps {\n text: string;\n size?: ToolbarTextSize;\n className?: string;\n /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */\n id?: string;\n /**\n * Expose heading semantics (`role=\"heading\"` + `aria-level`) so the text acts as\n * a heading landmark — e.g. a page's primary title. Omit to keep the plain span\n * (the default), which suits a dialog title referenced via `aria-labelledby`.\n */\n headingLevel?: HeadingLevel;\n /** Render the text as an unanimated loading skeleton instead of its value. */\n placeholder?: boolean;\n}\n\nexport function ToolbarText({ text, size = 'default', className = '', id, headingLevel, placeholder = false }: ToolbarTextProps) {\n return <span class={`kui-toolbar-text ${className}`.trim()} data-component=\"toolbar-text\" data-size={size} data-placeholder={placeholder ? 'true' : undefined} id={id} role={headingLevel ? 'heading' : undefined} aria-level={headingLevel ? String(headingLevel) : undefined} aria-busy={placeholder ? 'true' : undefined}>{placeholder ? <Skeleton width=\"8em\" /> : text}</span>;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { TabBar, TabBarProps } from './tab-bar.js';
|
|
|
16
16
|
export { TokenSearchField, TokenSearchFieldProps, TokenSearchFieldValue, TokenSearchToken, placeTokenSearchCaret, readTokenSearchField } from './token-search-field.js';
|
|
17
17
|
export { Toolbar, ToolbarProps } from './toolbar.js';
|
|
18
18
|
export { ToolbarControlGroup, ToolbarControlGroupProps } from './toolbar-control-group.js';
|
|
19
|
-
export { ToolbarText, ToolbarTextProps, ToolbarTextSize } from './toolbar-text.js';
|
|
19
|
+
export { HeadingLevel, ToolbarText, ToolbarTextProps, ToolbarTextSize } from './toolbar-text.js';
|
|
20
20
|
export { ValueTable, ValueTableProps, ValueTableRow, ValueTableRowProps } from './value-table.js';
|
|
21
21
|
export { ResizeCommit, WireResizableRegionsOptions, wireResizableRegions } from './wire-resizable-regions.js';
|
|
22
22
|
export { TabDropPosition, TabReorder, TabReorderSource, WireTabBarsOptions, reorderTabs, wireTabBars } from './wire-tab-bars.js';
|
package/dist/index.js
CHANGED
|
@@ -7,10 +7,10 @@ export { TabBar } from './chunk-MBR3TYNL.js';
|
|
|
7
7
|
export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-7LDCTU7D.js';
|
|
8
8
|
export { MenuHeader } from './chunk-H6URQGJI.js';
|
|
9
9
|
export { MenuItem } from './chunk-YKUUZPED.js';
|
|
10
|
-
export { PanelHeader } from './chunk-
|
|
10
|
+
export { PanelHeader } from './chunk-BNQ2YDV4.js';
|
|
11
11
|
export { Toolbar } from './chunk-DAFFDO33.js';
|
|
12
12
|
export { ToolbarControlGroup } from './chunk-MFKMHK5W.js';
|
|
13
|
-
export { ToolbarText } from './chunk-
|
|
13
|
+
export { ToolbarText } from './chunk-RUNWEPR4.js';
|
|
14
14
|
export { ResizableRegion, clampRegionSize, resizeRegionFromPointer } from './chunk-M5JRI6MN.js';
|
|
15
15
|
export { SegmentedControl } from './chunk-YGN7OMLT.js';
|
|
16
16
|
export { Select } from './chunk-LC3YSAZC.js';
|
package/dist/nav-stack.js
CHANGED
package/dist/panel-header.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SafeHtml } from 'kerfjs';
|
|
2
|
+
import { HeadingLevel } from './toolbar-text.js';
|
|
2
3
|
|
|
3
4
|
interface PanelHeaderProps {
|
|
4
5
|
title: string;
|
|
@@ -8,6 +9,13 @@ interface PanelHeaderProps {
|
|
|
8
9
|
icon?: SafeHtml;
|
|
9
10
|
iconClassName?: string;
|
|
10
11
|
actions?: SafeHtml;
|
|
12
|
+
/**
|
|
13
|
+
* Expose the title as a heading landmark (`role="heading"` + `aria-level`). Set it
|
|
14
|
+
* for a PAGE or view heading so screen-reader heading navigation works and the view
|
|
15
|
+
* has a primary heading; omit it (the default) for a dialog title, which is instead
|
|
16
|
+
* referenced via `aria-labelledby={titleId}` and needs no heading landmark.
|
|
17
|
+
*/
|
|
18
|
+
headingLevel?: HeadingLevel;
|
|
11
19
|
/** Render the title and summary as unanimated loading skeletons, keeping the icon and actions. */
|
|
12
20
|
placeholder?: boolean;
|
|
13
21
|
}
|
|
@@ -23,6 +31,6 @@ interface PanelHeaderProps {
|
|
|
23
31
|
* is passed straight into the toolbar's trailing zone; the app supplies whatever
|
|
24
32
|
* trailing controls it needs (typically a `ToolbarControlGroup`).
|
|
25
33
|
*/
|
|
26
|
-
declare function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName, actions, placeholder }: PanelHeaderProps): SafeHtml;
|
|
34
|
+
declare function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName, actions, headingLevel, placeholder }: PanelHeaderProps): SafeHtml;
|
|
27
35
|
|
|
28
36
|
export { PanelHeader, type PanelHeaderProps };
|
package/dist/panel-header.js
CHANGED
package/dist/split-view.js
CHANGED
package/dist/toolbar-text.d.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import * as kerfjs from 'kerfjs';
|
|
2
2
|
|
|
3
3
|
type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';
|
|
4
|
+
/** ARIA heading level for a title exposed as a heading landmark. */
|
|
5
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
4
6
|
interface ToolbarTextProps {
|
|
5
7
|
text: string;
|
|
6
8
|
size?: ToolbarTextSize;
|
|
7
9
|
className?: string;
|
|
8
10
|
/** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */
|
|
9
11
|
id?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Expose heading semantics (`role="heading"` + `aria-level`) so the text acts as
|
|
14
|
+
* a heading landmark — e.g. a page's primary title. Omit to keep the plain span
|
|
15
|
+
* (the default), which suits a dialog title referenced via `aria-labelledby`.
|
|
16
|
+
*/
|
|
17
|
+
headingLevel?: HeadingLevel;
|
|
10
18
|
/** Render the text as an unanimated loading skeleton instead of its value. */
|
|
11
19
|
placeholder?: boolean;
|
|
12
20
|
}
|
|
13
|
-
declare function ToolbarText({ text, size, className, id, placeholder }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
21
|
+
declare function ToolbarText({ text, size, className, id, headingLevel, placeholder }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
14
22
|
|
|
15
|
-
export { ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
23
|
+
export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
package/dist/toolbar-text.js
CHANGED
package/docs/accessibility.md
CHANGED
|
@@ -46,11 +46,16 @@ The application owns persistence and collapsed/expanded policy. Keep the last ex
|
|
|
46
46
|
`PanelHeader` is a plain `Toolbar` heading. Its leading zone holds an optional
|
|
47
47
|
icon (a normal bordered `ToolbarControlGroup`) and the title as extra-large
|
|
48
48
|
`ToolbarText`, and the app's trailing controls go straight into the trailing
|
|
49
|
-
zone.
|
|
50
|
-
`titleId` and an optional `summaryId` to the
|
|
51
|
-
`aria-labelledby` and `aria-describedby
|
|
52
|
-
|
|
53
|
-
`
|
|
49
|
+
zone. By default the title carries no native heading role, so for a **dialog or
|
|
50
|
+
panel** the application connects `titleId` and an optional `summaryId` to the
|
|
51
|
+
owning host through `aria-labelledby` and `aria-describedby`. For a **page or
|
|
52
|
+
view** title, pass `headingLevel` (usually `1`): the title then exposes
|
|
53
|
+
`role="heading"` with a matching `aria-level`, giving the view a heading landmark
|
|
54
|
+
so screen-reader heading navigation and "main heading" semantics work — the same
|
|
55
|
+
role/level pair `ToolbarText` exposes when it is given `headingLevel` directly.
|
|
56
|
+
Keep the levels meaningful and non-skipping within a view. Pass the trailing
|
|
57
|
+
controls as a labeled `ToolbarControlGroup` when that group needs an accessible
|
|
58
|
+
name.
|
|
54
59
|
|
|
55
60
|
## Tabs
|
|
56
61
|
|
|
@@ -62,7 +62,7 @@ an upstream component or recipe request.
|
|
|
62
62
|
| Disclosure indicator — `DisclosureArrow` | A control needs one animated 18px root-scaled visual for open and closed state, including configurable directions or a replacement icon. | Do not use it as the interactive control or accessible name; place it inside the button or control that exposes expanded state. | Pass the controlled `open` state, render it inside the owning control, author replacement icon content facing right before transforms, and override `--kui-disclosure-arrow-size` only when another visual size is required. Direction changes use the shortest rotation path, with counterclockwise chosen for a 180-degree closed-to-open tie. | Open state, interaction, accessible name, size override, replacement glyph, direction choices, and shortest-path rotation. | `@kerfjs/ui/disclosure-arrow` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
63
63
|
| Application toolbar — `Toolbar` | Leading identity, optional centered content, and trailing controls form one horizontal app bar. | Do not use it for a page, panel, or dialog heading; use `PanelHeader`. | Compose `ToolbarText` and `ToolbarControlGroup` where their contracts fit. | Actions, command availability, responsive relocation, and state. | `@kerfjs/ui/toolbar` | [Toolbar composition](../README.md#component-subpaths) |
|
|
64
64
|
| Toolbar control cluster — `ToolbarControlGroup` | Related toolbar controls need contained, borderless, pressed, or single-control treatment. | Do not use it merely to align unrelated buttons; use toolbar slots or ordinary layout. Web Awesome `wa-button-group` is only for an exceptional grouped-action contract. | Delegate child actions; use `SegmentedControl` for an exclusive choice. | Actions, pressed/expanded state, and policy. | `@kerfjs/ui/toolbar-control-group` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
65
|
-
| Toolbar identity text — `ToolbarText` | A toolbar needs extra-large (page/panel title), large, default, or compact textual identity. |
|
|
65
|
+
| Toolbar identity text — `ToolbarText` | A toolbar needs extra-large (page/panel title), large, default, or compact textual identity. | Plain text is not a heading by default; when a title needs heading semantics pass `headingLevel` (or prefer `PanelHeader`, which forwards it). | Optional `headingLevel` for `role="heading"` + `aria-level`. | Text, heading level, and responsive priority. | `@kerfjs/ui/toolbar-text` | [Toolbar composition](../README.md#component-subpaths) |
|
|
66
66
|
| Navigation row — `MenuItem` | A pane or navigation area needs a selectable, disabled, dormant-trailing, or multiline action row. | Do not put a control in `trailing`; use `MenuActionRow` when the trailing region must be independently interactive. Use an `<a>` for navigation that must retain link behavior, a native `<button>` for an ordinary action, or implement the complete ARIA menu widget. | Delegate its `data-action`; compose inside a `.kui-content` section. Put domain event/drop metadata in `rootAttributes` rather than adding wrapper markup. | Routing, selection, permissions, copy, action handling, and domain `data-*` values. | `@kerfjs/ui/menu-item` | [Pane geometry](../README.md#pane-and-content-geometry) |
|
|
67
67
|
| Navigation row with trailing action — `MenuActionRow` | A full-width row needs a selectable primary action and an independently focusable trailing action. | Use `MenuItem` when trailing content is dormant metadata. Do not put controls inside the row's `label`, `icon`, or `trailingActionIcon` SafeHtml slots. Do not use `AppTab` outside tablist semantics or `ToolbarControlGroup` outside a toolbar. | Delegate both action strings; update controlled selection and any popover/context-menu state in the app. | Routing, selection, both action policies, domain metadata, and popover/context-menu behavior. | `@kerfjs/ui/menu-action-row` | [Accessibility](./accessibility.md#menuactionrow) |
|
|
68
68
|
| Navigation section heading — `MenuHeader` | A menu section needs a full-width label, semantic count, non-count badge, logical-end action, or real disclosure state. | Do not concatenate counts into `label` or put numeric content in `badge`; use `count` with the localized full phrase in `countLabel`. Do not add a disclosure arrow to navigation that reveals nothing. Do not shrink its 44px action target to the 18px visual. Do not use it as a page, panel, or dialog title; use `PanelHeader`. | Delegate its optional action; the app controls expanded state and revealed content. Toggle mode supplies `DisclosureArrow` unless `actionIcon` replaces it. Use `triggerAttributes` only for domain `data-*` or a native popover relationship. | Section organization, valid count and localized count label, disclosure state and content, non-count badge content, popover target behavior, and policy. | `@kerfjs/ui/menu-header` | [Pane geometry](../README.md#pane-and-content-geometry) |
|
|
@@ -71,7 +71,7 @@ an upstream component or recipe request.
|
|
|
71
71
|
| Resizable application pane — `ResizableRegion`, `clampRegionSize`, `resizeRegionFromPointer` | A controlled split pane needs the Kerf separator, collapse state, pointer plus keyboard resizing, or a product-specific decorative grip. | Do not use it for a static two-column layout; use CSS grid. Prefer it over Web Awesome `wa-split-panel` unless that component's distinct API is required. Keep `handleIcon` noninteractive. | Call `wireResizableRegions` from `@kerfjs/ui/wire-resizable-regions` once and retain its disposer. | Size signal, min/max policy, collapse policy, persistence, and optional decorative handle icon. | `@kerfjs/ui/resizable-region` | [ResizableRegion contract](./accessibility.md#resizableregion) |
|
|
72
72
|
| One application tab — `AppTab` | A controlled app tab needs selection, close, drag, leading/trailing anatomy, safe domain metadata, or a product-specific close glyph. | Do not render it alone or use it for a small settings choice; compose in `TabBar`, or use `SegmentedControl`. Keep `closeIcon` noninteractive. | Compose in `TabBar`; let `wireTabBars` manage interaction. Put only domain `data-*` values in `rootAttributes`. | Tab identity, order, selection, close policy, content, and domain metadata values. | `@kerfjs/ui/app-tab` | [Tabs contract](./accessibility.md#tabs) |
|
|
73
73
|
| Application tab strip — `TabBar`, `wireTabBars`, `reorderTabs` | Tabs switch page regions and may overflow, close, or reorder. | Do not use it for a compact local view toggle; use `SegmentedControl`. Do not use it for a long choice list; use `Select`. Prefer it over Web Awesome `wa-tab-group`, `wa-tab`, and `wa-tab-panel` for Kerf app tabs. | Call `wireTabBars` once, retain the disposer, and apply `onReorder` synchronously; `reorderTabs` is the default array helper. | Ordered tabs, selection, panels, routing, closing, and persistence. | `@kerfjs/ui/tab-bar` plus `@kerfjs/ui/wire-tab-bars` | [Tabs contract](./accessibility.md#tabs) |
|
|
74
|
-
| Panel, dialog, or page heading — `PanelHeader` | A panel, dialog, or page needs a heading with an extra-large title, an optional icon and subtitle, and trailing actions. | Do not use it as persistent app chrome; use `Toolbar`. It supplies header structure, not modal behavior; use an application overlay or Web Awesome `wa-dialog` for that behavior. | Connect the title id and any provided summary id to the dialog or panel host, pass the trailing controls (typically a `ToolbarControlGroup`), and delegate their actions. | Open state, focus lifecycle, dismissal, the trailing controls, labels, and
|
|
74
|
+
| Panel, dialog, or page heading — `PanelHeader` | A panel, dialog, or page needs a heading with an extra-large title, an optional icon and subtitle, and trailing actions. | Do not use it as persistent app chrome; use `Toolbar`. It supplies header structure, not modal behavior; use an application overlay or Web Awesome `wa-dialog` for that behavior. | Connect the title id and any provided summary id to the dialog or panel host, pass the trailing controls (typically a `ToolbarControlGroup`), and delegate their actions. **For a page or view title set `headingLevel` (usually `1`)** so the title is a real heading landmark (`role="heading"` + `aria-level`) for screen-reader heading navigation; omit it for a dialog title, which is referenced via `aria-labelledby` to `titleId` and needs no heading. | Open state, focus lifecycle, dismissal, the trailing controls, labels, copy, and the heading level for page use. | `@kerfjs/ui/panel-header` | [Header ownership](./component-contract.md#extracted-versus-application-specific) |
|
|
75
75
|
| Key/value facts — `ValueTable`, `ValueTableRow` | Read-only labels and values form a semantic definition list, optionally with a leading icon. | Do not use it for editable form fields or a row/column data grid; use native form or table semantics. | Compose typed `ValueTableRow` entries; pass `icon` when a 24px leading icon adds useful context. | Values, formatting, icon meaning, and empty/loading policy. | `@kerfjs/ui/value-table` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
76
76
|
| Indeterminate activity — `LoadingSpinner` | A Kerf surface needs compact, labeled or decorative indeterminate progress. | Do not use it for known progress; use Web Awesome `wa-progress-bar` or `wa-progress-ring`. Direct Web Awesome UI may use `wa-spinner`; do not mix spinner systems within one surface. | None; pass a label when the spinner conveys status. | Loading lifecycle and adjacent status copy. | `@kerfjs/ui/loading-spinner` | [Accessibility](./accessibility.md#shared-rules) |
|
|
77
77
|
| Loading placeholder — `Skeleton` + a component's `placeholder` prop | A value or a whole component is still loading and should hold its space as a subtle, unanimated block, keeping the layout stable — an inspector or detail view rendering its real chrome with per-record values absent. | Do not use it for known progress (use `LoadingSpinner`), do not animate it, and do not hand-rebuild a component's empty state — set `placeholder` on the component instead. Prefer it over `wa-skeleton`, which the pure-Kerf primitives avoid to stay Web-Awesome-free. | Set `placeholder` on a value-bearing component (`Select`, `MenuHeader`, `MenuItem`, `ValueTableRow`, `PanelHeader`, `SegmentedControl`, `StateBanner`, `AppTab`, `ToolbarText`, `MenuActionRow`) to render skeletons in its value slots with interactivity disabled; use the standalone `Skeleton` for a custom slot. | Loading lifecycle, which slots are unknown, and announcing the loading region. | `@kerfjs/ui/skeleton` | [Accessibility](./accessibility.md#shared-rules) |
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/toolbar-text.tsx"],"names":[],"mappings":";;;AAcO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAM,IAAA,GAAO,SAAA,EAAW,YAAY,EAAA,EAAI,EAAA,EAAI,WAAA,GAAc,KAAA,EAAM,EAAqB;AACjH,EAAA,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK,EAAG,gBAAA,EAAe,cAAA,EAAe,WAAA,EAAW,IAAA,EAAM,kBAAA,EAAkB,WAAA,GAAc,MAAA,GAAS,MAAA,EAAW,EAAA,EAAQ,WAAA,EAAW,WAAA,GAAc,MAAA,GAAS,MAAA,EAAY,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,KAAA,EAAM,CAAA,GAAK,IAAA,EAAK,CAAA;AACrQ","file":"chunk-KJYXOTG3.js","sourcesContent":["import { Skeleton } from './skeleton.js';\n\nexport type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';\n\nexport interface ToolbarTextProps {\n text: string;\n size?: ToolbarTextSize;\n className?: string;\n /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */\n id?: string;\n /** Render the text as an unanimated loading skeleton instead of its value. */\n placeholder?: boolean;\n}\n\nexport function ToolbarText({ text, size = 'default', className = '', id, placeholder = false }: ToolbarTextProps) {\n return <span class={`kui-toolbar-text ${className}`.trim()} data-component=\"toolbar-text\" data-size={size} data-placeholder={placeholder ? 'true' : undefined} id={id} aria-busy={placeholder ? 'true' : undefined}>{placeholder ? <Skeleton width=\"8em\" /> : text}</span>;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/panel-header.tsx"],"names":[],"mappings":";;;;;;AA+BO,SAAS,WAAA,CAAY,EAAE,KAAA,EAAO,OAAA,EAAS,OAAA,EAAS,SAAA,EAAW,IAAA,EAAM,aAAA,GAAgB,EAAA,EAAI,OAAA,EAAS,WAAA,GAAc,KAAA,EAAM,EAAqB;AAC5I,EAAA,MAAM,2BAAW,IAAA,CAAA,QAAA,EAAA,EACd,QAAA,EAAA;AAAA,IAAA,IAAA,oBAAQ,GAAA,CAAC,mBAAA,EAAA,EAAoB,MAAA,EAAM,IAAA,EAAC,SAAA,EAAW,0BAA0B,aAAa,CAAA,CAAA,CAAG,IAAA,EAAK,EAAI,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,oBACxG,GAAA,CAAC,WAAA,EAAA,EAAY,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,UAAS,EAAA,EAAI,OAAA,EAAS,SAAA,EAAU,yBAAA,EAA0B,WAAA,EAA0B;AAAA,GAAA,EACrH,CAAA;AAEA,EAAA,uBAAO,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,kBAAA,EAAmB,gBAAA,EAAe,cAAA,EAAe,eAAA,EAAe,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA,EAAG,kBAAA,EAAkB,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAC,CAAA,EAAG,kBAAA,EAAkB,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAC,CAAA,EAAG,kBAAA,EAAkB,WAAA,GAAc,MAAA,GAAS,MAAA,EACxO,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,WAAQ,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,SAAS,KAAA,EAAO,CAAA;AAAA,IAC9D,OAAA,oBAAW,GAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAM,2BAAA,EAA4B,EAAA,EAAI,SAAA,EAAY,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,MAAA,EAAO,IAAK,OAAA,EAAQ;AAAA,GAAA,EACrH,CAAA;AACF","file":"chunk-TZNCCM5H.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { Skeleton } from './skeleton.js';\nimport { Toolbar } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\nimport { ToolbarText } from './toolbar-text.js';\n\nexport interface PanelHeaderProps {\n title: string;\n titleId: string;\n summary?: string;\n summaryId?: string;\n icon?: SafeHtml;\n iconClassName?: string;\n actions?: SafeHtml;\n /** Render the title and summary as unanimated loading skeletons, keeping the icon and actions. */\n placeholder?: boolean;\n}\n\n/**\n * The heading of a panel, dialog, or page: a plain `Toolbar` whose leading zone\n * holds an optional icon control group and the title as extra-large `ToolbarText`,\n * whose trailing zone holds the app's action controls, and with an optional\n * subtitle on its own row, left-aligned with the title.\n *\n * PanelHeader overrides no Toolbar styles — it is just a Toolbar with an xl title.\n * The only styling it adds is the icon group's fill/border color and the subtitle.\n * When no icon is provided, the icon group is omitted entirely. The `actions` slot\n * is passed straight into the toolbar's trailing zone; the app supplies whatever\n * trailing controls it needs (typically a `ToolbarControlGroup`).\n */\nexport function PanelHeader({ title, titleId, summary, summaryId, icon, iconClassName = '', actions, placeholder = false }: PanelHeaderProps) {\n const identity = <>\n {icon && <ToolbarControlGroup single className={`kui-panel-header__icon ${iconClassName}`.trim()}>{icon}</ToolbarControlGroup>}\n <ToolbarText text={title} size=\"xlarge\" id={titleId} className=\"kui-panel-header__title\" placeholder={placeholder} />\n </>;\n\n return <div class=\"kui-panel-header\" data-component=\"panel-header\" data-has-icon={String(Boolean(icon))} data-has-actions={String(Boolean(actions))} data-has-summary={String(Boolean(summary))} data-placeholder={placeholder ? 'true' : undefined}>\n <Toolbar leading={identity} trailing={actions} divider={false} />\n {summary && <p class=\"kui-panel-header__summary\" id={summaryId}>{placeholder ? <Skeleton width=\"18em\" /> : summary}</p>}\n </div>;\n}\n"]}
|