@kerfjs/ui 5.0.0-beta.18 → 5.0.0-beta.22
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 +114 -3
- package/ai/application-ui-diagnostic-ids-v1.json +92 -0
- package/ai/application-ui-profile-sync.cjs +529 -0
- package/ai/application-ui-profile.d.mts +1 -0
- package/ai/application-ui-profile.d.ts +102 -0
- package/ai/application-ui-profile.defaults.json +41 -0
- package/ai/application-ui-profile.mjs +626 -0
- package/ai/application-ui-profile.schema.json +130 -0
- package/ai/catalog-authoring.json +25 -0
- package/ai/catalog-authoring.schema.json +61 -0
- package/ai/compile-time-contracts-v1.json +101 -0
- package/ai/compile-time-contracts-v1.schema.json +49 -0
- package/ai/component-catalog-extension-v2.d.ts +7 -0
- package/ai/component-catalog-extension-v2.schema.json +7 -0
- package/ai/component-catalog-v2-overrides.json +326 -0
- package/ai/component-catalog-v2.d.ts +67 -0
- package/ai/component-catalog-v2.json +4441 -0
- package/ai/component-catalog-v2.schema.json +246 -0
- package/ai/component-catalog.json +150 -6
- package/ai/public-api-signatures-v1.md +294 -64
- package/ai/skill.md +41 -5
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/cli.mjs +46 -0
- package/analyzer/index.d.mts +45 -0
- package/analyzer/index.mjs +743 -0
- package/analyzer/report.schema.json +66 -0
- package/dist/browser/pane.js +3 -0
- package/dist/browser/sunken-panel.js +3 -0
- package/dist/catalog-resources.d.ts +34 -0
- package/dist/catalog-resources.js +22 -0
- package/dist/catalog-resources.js.map +1 -0
- package/dist/catalog.d.ts +21 -3
- package/dist/catalog.js +239 -210
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-ZK2G3VR5.js → chunk-5VTB2BKP.js} +1 -1
- package/dist/chunk-5VTB2BKP.js.map +1 -0
- package/dist/{chunk-S3HKPI7I.js → chunk-7KEUJIIC.js} +1 -1
- package/dist/chunk-7KEUJIIC.js.map +1 -0
- package/dist/{chunk-NVWXKU37.js → chunk-AASLYRGE.js} +1 -1
- package/dist/chunk-AASLYRGE.js.map +1 -0
- package/dist/{chunk-QIRXYKCE.js → chunk-DSNIYOZ3.js} +3 -2
- package/dist/chunk-DSNIYOZ3.js.map +1 -0
- package/dist/{chunk-ENVTNLYC.js → chunk-GP5DP5DL.js} +55 -15
- package/dist/chunk-GP5DP5DL.js.map +1 -0
- package/dist/chunk-JRKSK2HX.js +79 -0
- package/dist/chunk-JRKSK2HX.js.map +1 -0
- package/dist/{chunk-U5IFGQCD.js → chunk-K57KRAOV.js} +1 -1
- package/dist/chunk-K57KRAOV.js.map +1 -0
- package/dist/{chunk-ZVI5YST2.js → chunk-M7JBER5U.js} +1 -1
- package/dist/chunk-M7JBER5U.js.map +1 -0
- package/dist/{chunk-43FUQH35.js → chunk-OHU6CI22.js} +2 -2
- package/dist/{chunk-43FUQH35.js.map → chunk-OHU6CI22.js.map} +1 -1
- package/dist/{chunk-4TRDV6RL.js → chunk-OZWU5ZPZ.js} +1 -1
- package/dist/chunk-OZWU5ZPZ.js.map +1 -0
- package/dist/{chunk-JTHUXDN2.js → chunk-RYRIFZCT.js} +3 -3
- package/dist/chunk-RYRIFZCT.js.map +1 -0
- package/dist/{chunk-6ETZKKAE.js → chunk-VLYV65LK.js} +1 -1
- package/dist/chunk-VLYV65LK.js.map +1 -0
- package/dist/chunk-W4CXQYSG.js +23 -0
- package/dist/chunk-W4CXQYSG.js.map +1 -0
- package/dist/{chunk-S3PCZ7NV.js → chunk-W7YD6E4N.js} +1 -1
- package/dist/chunk-W7YD6E4N.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +14 -12
- package/dist/list-header.d.ts +29 -8
- package/dist/list-header.js +1 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +49 -0
- package/dist/pane.js +4 -0
- package/dist/pane.js.map +1 -0
- package/dist/panel-header.d.ts +9 -3
- package/dist/panel-header.js +1 -1
- package/dist/segmented-control.d.ts +6 -6
- package/dist/segmented-control.js +1 -1
- package/dist/select.d.ts +10 -4
- package/dist/select.js +1 -1
- package/dist/split-view.js +2 -2
- package/dist/state-banner.d.ts +3 -2
- package/dist/state-banner.js +1 -1
- package/dist/styles/catalog.css +6 -6
- package/dist/styles/layout.css +2 -20
- package/dist/styles/pane.css +62 -0
- package/dist/styles/segmented-control.css +3 -7
- package/dist/styles/sunken-panel.css +18 -0
- package/dist/sunken-panel.d.ts +16 -0
- package/dist/sunken-panel.js +3 -0
- package/dist/sunken-panel.js.map +1 -0
- package/dist/tab-bar.d.ts +3 -2
- package/dist/tab-bar.js +1 -1
- package/dist/tab-scaffold.d.ts +6 -6
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/token-search-field.d.ts +25 -9
- package/dist/token-search-field.js +1 -1
- package/dist/toolbar-control-group.d.ts +9 -5
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +10 -11
- package/dist/toolbar-text.js +1 -1
- package/dist/wire-tab-bars.d.ts +5 -2
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-token-search-fields.d.ts +11 -6
- package/dist/wire-token-search-fields.js +1 -1
- package/docs/catalog.md +186 -67
- package/docs/component-contract.md +102 -5
- package/docs/component-selection.md +9 -5
- package/docs/design/templates/panel-header/icon-actions-dark.svg +1 -1
- package/docs/design/templates/panel-header/icon-actions.svg +1 -1
- package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +1 -1
- package/docs/design/templates/panel-header/icon-summary-actions.svg +1 -1
- package/docs/design/templates/panel-header/no-icon-dark.svg +1 -1
- package/docs/design/templates/panel-header/no-icon.svg +1 -1
- package/docs/design/templates/panel-header/page-heading-dark.svg +1 -1
- package/docs/design/templates/panel-header/page-heading.svg +1 -1
- package/docs/design/templates/panel-header/title-only-dark.svg +1 -1
- package/docs/design/templates/panel-header/title-only.svg +1 -1
- package/docs/design/templates/panel-header-dark.svg +5 -5
- package/docs/design/templates/panel-header.svg +5 -5
- package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
- package/docs/design/templates/segmented-control/equal.svg +1 -1
- package/docs/design/templates/segmented-control-dark.svg +1 -1
- package/docs/design/templates/segmented-control.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
- package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group.svg +1 -1
- package/docs/design/templates/toolbar-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/default.svg +1 -1
- package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/large.svg +1 -1
- package/docs/design/templates/toolbar-text/small-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/small.svg +1 -1
- package/docs/design/templates/toolbar-text-dark.svg +3 -3
- package/docs/design/templates/toolbar-text.svg +3 -3
- package/docs/design/templates/toolbar.svg +1 -1
- package/docs/design/templates.md +11 -6
- package/docs/design-philosophy.md +2 -4
- package/docs/examples/application-ui-profile.json +60 -0
- package/docs/examples/component-catalog-extension-v2.json +81 -0
- package/docs/layout.md +42 -23
- package/docs/sunken-panel.md +43 -0
- package/docs/type-contracts.md +99 -0
- package/docs/ui-analyzer.md +81 -0
- package/docs/ui-doctor.md +77 -0
- package/docs/ui-evaluator.md +122 -0
- package/doctor/cli.mjs +115 -0
- package/doctor/config.schema.json +68 -0
- package/doctor/index.d.mts +116 -0
- package/doctor/index.mjs +1256 -0
- package/doctor/report.schema.json +118 -0
- package/evaluator/cli.mjs +89 -0
- package/evaluator/index.d.mts +90 -0
- package/evaluator/index.mjs +1138 -0
- package/evaluator/report.schema.json +152 -0
- package/llms.txt +40 -3
- package/package.json +66 -8
- package/ux-demo/recipes/compact-toolbar.tsx +2 -2
- package/ux-demo/recipes/composer-form.tsx +1 -1
- package/dist/chunk-4TRDV6RL.js.map +0 -1
- package/dist/chunk-6ETZKKAE.js.map +0 -1
- package/dist/chunk-ENVTNLYC.js.map +0 -1
- package/dist/chunk-JTHUXDN2.js.map +0 -1
- package/dist/chunk-NVWXKU37.js.map +0 -1
- package/dist/chunk-QIRXYKCE.js.map +0 -1
- package/dist/chunk-S3HKPI7I.js.map +0 -1
- package/dist/chunk-S3PCZ7NV.js.map +0 -1
- package/dist/chunk-U5IFGQCD.js.map +0 -1
- package/dist/chunk-ZK2G3VR5.js.map +0 -1
- package/dist/chunk-ZVI5YST2.js.map +0 -1
package/dist/state-banner.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { SafeHtml } from 'kerfjs';
|
|
2
2
|
|
|
3
3
|
type StateBannerTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
|
|
4
|
+
type StateBannerUrgency = 'status' | 'alert';
|
|
4
5
|
interface StateBannerProps {
|
|
5
6
|
title: string;
|
|
6
7
|
detail?: string;
|
|
7
8
|
icon?: SafeHtml;
|
|
8
9
|
action?: SafeHtml;
|
|
9
10
|
tone?: StateBannerTone;
|
|
10
|
-
urgency?:
|
|
11
|
+
urgency?: StateBannerUrgency;
|
|
11
12
|
className?: string;
|
|
12
13
|
/** Render the title and detail as unanimated loading skeletons, keeping the icon and tone. */
|
|
13
14
|
placeholder?: boolean;
|
|
14
15
|
}
|
|
15
16
|
declare function StateBanner({ title, detail, icon, action, tone, urgency, className, placeholder, }: StateBannerProps): SafeHtml;
|
|
16
17
|
|
|
17
|
-
export { StateBanner, type StateBannerProps, type StateBannerTone };
|
|
18
|
+
export { StateBanner, type StateBannerProps, type StateBannerTone, type StateBannerUrgency };
|
package/dist/state-banner.js
CHANGED
package/dist/styles/catalog.css
CHANGED
|
@@ -23,15 +23,14 @@
|
|
|
23
23
|
padding: 0;
|
|
24
24
|
overflow: hidden;
|
|
25
25
|
justify-self: start;
|
|
26
|
-
border-inline-end: 1px solid var(--kui-color-border);
|
|
27
26
|
background: var(--kui-color-surface);
|
|
28
27
|
transition:
|
|
29
28
|
transform 200ms ease,
|
|
30
29
|
visibility 0s linear 0s;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
.kui-catalog[data-sidebar-collapsed="true"] .kui-catalog__sidebar {
|
|
34
|
-
|
|
32
|
+
.kui-catalog[data-sidebar-collapsed="true"] .kui-catalog__sidebar.kui-pane {
|
|
33
|
+
--kui-pane-separator-inline-end-width: 0;
|
|
35
34
|
/* Slide out first, then hide, so the panel animates offscreen and only then
|
|
36
35
|
leaves the tab order rather than snapping invisible mid-slide. */
|
|
37
36
|
transform: translateX(-100%);
|
|
@@ -510,15 +509,16 @@
|
|
|
510
509
|
.kui-catalog[data-sidebar-collapsed="true"] .kui-catalog__sidebar {
|
|
511
510
|
display: none;
|
|
512
511
|
}
|
|
513
|
-
.kui-catalog__sidebar {
|
|
512
|
+
.kui-catalog .kui-catalog__sidebar.kui-pane {
|
|
513
|
+
--kui-pane-separator-block-end-width: var(--kui-pane-separator-width, 1px);
|
|
514
|
+
--kui-pane-separator-inline-end-width: 0;
|
|
515
|
+
|
|
514
516
|
width: 100%;
|
|
515
517
|
min-width: 0;
|
|
516
518
|
height: auto;
|
|
517
519
|
justify-self: stretch;
|
|
518
520
|
/* Narrow layout collapses via display:none, not the desktop slide. */
|
|
519
521
|
transform: none;
|
|
520
|
-
border-inline-end: 0;
|
|
521
|
-
border-block-end: 1px solid var(--kui-color-border);
|
|
522
522
|
}
|
|
523
523
|
.kui-catalog__detail {
|
|
524
524
|
height: auto;
|
package/dist/styles/layout.css
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
.kui-pane {
|
|
3
|
-
display: grid;
|
|
4
|
-
min-width: 0;
|
|
5
|
-
min-height: 0;
|
|
6
|
-
padding: 0;
|
|
7
|
-
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.kui-pane__toolbar,
|
|
11
|
-
.kui-pane__footer {
|
|
12
|
-
min-width: 0;
|
|
13
|
-
}
|
|
1
|
+
@import "./pane.css";
|
|
14
2
|
|
|
15
|
-
.
|
|
16
|
-
min-width: 0;
|
|
17
|
-
min-height: 0;
|
|
18
|
-
padding: 0;
|
|
19
|
-
overflow: auto;
|
|
20
|
-
overscroll-behavior: contain;
|
|
21
|
-
}
|
|
3
|
+
/* Shared application content geometry for Pane children and standalone stacks. */
|
|
22
4
|
|
|
23
5
|
.kui-content {
|
|
24
6
|
display: flex;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
.kui-pane {
|
|
2
|
+
--kui-pane-separator-block-start-width: 0;
|
|
3
|
+
--kui-pane-separator-block-end-width: 0;
|
|
4
|
+
--kui-pane-separator-inline-start-width: 0;
|
|
5
|
+
--kui-pane-separator-inline-end-width: 0;
|
|
6
|
+
|
|
7
|
+
display: grid;
|
|
8
|
+
min-width: 0;
|
|
9
|
+
min-height: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
border: 0 solid var(--kui-pane-separator-color, var(--kui-color-border));
|
|
13
|
+
border-block-start-width: var(--kui-pane-separator-block-start-width);
|
|
14
|
+
border-block-end-width: var(--kui-pane-separator-block-end-width);
|
|
15
|
+
border-inline-start-width: var(--kui-pane-separator-inline-start-width);
|
|
16
|
+
border-inline-end-width: var(--kui-pane-separator-inline-end-width);
|
|
17
|
+
grid-template-areas:
|
|
18
|
+
"header"
|
|
19
|
+
"content"
|
|
20
|
+
"footer";
|
|
21
|
+
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.kui-pane[data-separator-block-start="true"] {
|
|
25
|
+
--kui-pane-separator-block-start-width: var(--kui-pane-separator-width, 1px);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.kui-pane[data-separator-block-end="true"] {
|
|
29
|
+
--kui-pane-separator-block-end-width: var(--kui-pane-separator-width, 1px);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.kui-pane[data-separator-inline-start="true"] {
|
|
33
|
+
--kui-pane-separator-inline-start-width: var(--kui-pane-separator-width, 1px);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.kui-pane[data-separator-inline-end="true"] {
|
|
37
|
+
--kui-pane-separator-inline-end-width: var(--kui-pane-separator-width, 1px);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.kui-pane__header,
|
|
41
|
+
.kui-pane__toolbar {
|
|
42
|
+
display: flex;
|
|
43
|
+
min-width: 0;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
grid-area: header;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.kui-pane__content {
|
|
49
|
+
min-width: 0;
|
|
50
|
+
min-height: 0;
|
|
51
|
+
padding: 0;
|
|
52
|
+
overflow: auto;
|
|
53
|
+
grid-area: content;
|
|
54
|
+
overscroll-behavior: contain;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.kui-pane__footer {
|
|
58
|
+
display: flex;
|
|
59
|
+
min-width: 0;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
grid-area: footer;
|
|
62
|
+
}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
--kui-layout-rounded-radius,
|
|
13
13
|
calc(1px + 0.6875rem)
|
|
14
14
|
);
|
|
15
|
-
--kui-segmented-item-radius:
|
|
16
|
-
|
|
17
|
-
calc(
|
|
15
|
+
--kui-segmented-item-radius: max(
|
|
16
|
+
0px,
|
|
17
|
+
calc(var(--kui-segmented-radius) - 2px)
|
|
18
18
|
);
|
|
19
19
|
display: inline-flex;
|
|
20
20
|
max-width: 100%;
|
|
@@ -82,10 +82,6 @@
|
|
|
82
82
|
--kui-layout-pill-radius,
|
|
83
83
|
calc(1px + 1.3125rem)
|
|
84
84
|
);
|
|
85
|
-
--kui-segmented-item-radius: var(
|
|
86
|
-
--kui-layout-pill-radius,
|
|
87
|
-
calc(1px + 1.3125rem)
|
|
88
|
-
);
|
|
89
85
|
}
|
|
90
86
|
|
|
91
87
|
.kui-segmented-control[data-layout="equal"] {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.kui-sunken-panel {
|
|
2
|
+
display: flex;
|
|
3
|
+
min-width: 0;
|
|
4
|
+
min-height: 0;
|
|
5
|
+
padding: var(--kui-sunken-panel-padding, 0.5rem);
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
border-radius: var(
|
|
8
|
+
--kui-sunken-panel-radius,
|
|
9
|
+
var(--kui-layout-rounded-radius, calc(1px + 0.6875rem))
|
|
10
|
+
);
|
|
11
|
+
color: var(--kui-sunken-panel-foreground, var(--kui-color-text));
|
|
12
|
+
background: var(
|
|
13
|
+
--kui-sunken-panel-background,
|
|
14
|
+
var(--kui-color-surface-lowered)
|
|
15
|
+
);
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
gap: var(--kui-sunken-panel-gap, 0.5rem);
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SafeHtml } from 'kerfjs';
|
|
2
|
+
|
|
3
|
+
interface SunkenPanelProps {
|
|
4
|
+
children?: SafeHtml | readonly SafeHtml[];
|
|
5
|
+
/** Optional accessible landmark name for a distinct application region. */
|
|
6
|
+
ariaLabel?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A lowered application surface with one compact inset and a vertical content
|
|
11
|
+
* stack. The panel owns its background and padding; children own their own
|
|
12
|
+
* borders and internal geometry.
|
|
13
|
+
*/
|
|
14
|
+
declare function SunkenPanel({ children, ariaLabel, className, }: SunkenPanelProps): SafeHtml;
|
|
15
|
+
|
|
16
|
+
export { SunkenPanel, type SunkenPanelProps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"sunken-panel.js"}
|
package/dist/tab-bar.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SafeHtml } from 'kerfjs';
|
|
2
2
|
|
|
3
|
+
type TabActivation = 'automatic' | 'manual';
|
|
3
4
|
interface TabBarProps {
|
|
4
5
|
id: string;
|
|
5
6
|
label: string;
|
|
@@ -13,9 +14,9 @@ interface TabBarProps {
|
|
|
13
14
|
* selects on arrow / Home / End; `'manual'` moves roving focus only and the user
|
|
14
15
|
* selects with Enter / Space / click — use it when selecting a tab is a heavy action.
|
|
15
16
|
*/
|
|
16
|
-
activation?:
|
|
17
|
+
activation?: TabActivation;
|
|
17
18
|
}
|
|
18
19
|
/** Render a controlled tab strip. The application owns selection, order, and persistence. */
|
|
19
20
|
declare function TabBar({ id, label, children, leading, trailing, className, activation, }: TabBarProps): SafeHtml;
|
|
20
21
|
|
|
21
|
-
export { TabBar, type TabBarProps };
|
|
22
|
+
export { type TabActivation, TabBar, type TabBarProps };
|
package/dist/tab-bar.js
CHANGED
package/dist/tab-scaffold.d.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { SafeHtml } from 'kerfjs';
|
|
2
2
|
|
|
3
|
-
interface TabScaffoldTab {
|
|
4
|
-
id:
|
|
3
|
+
interface TabScaffoldTab<Id extends string = string> {
|
|
4
|
+
id: Id;
|
|
5
5
|
label: string;
|
|
6
6
|
/** Decorative icon shown above the label in the bottom bar. */
|
|
7
7
|
icon?: SafeHtml;
|
|
8
8
|
/** The tab's content — typically a `NavStack` so each tab keeps its own stack. */
|
|
9
9
|
content: SafeHtml;
|
|
10
10
|
}
|
|
11
|
-
interface TabScaffoldProps {
|
|
11
|
+
interface TabScaffoldProps<Id extends string = string> {
|
|
12
12
|
id: string;
|
|
13
13
|
/** Accessible name for the tab bar. */
|
|
14
14
|
label: string;
|
|
15
|
-
tabs: TabScaffoldTab[];
|
|
15
|
+
tabs: readonly TabScaffoldTab<Id>[];
|
|
16
16
|
/** The controlled active tab id (the app owns selection). */
|
|
17
|
-
active:
|
|
17
|
+
active: NoInfer<Id>;
|
|
18
18
|
className?: string;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
@@ -25,6 +25,6 @@ interface TabScaffoldProps {
|
|
|
25
25
|
* On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of
|
|
26
26
|
* a bottom bar. See `docs/23-app-layouts.md` §3.4.
|
|
27
27
|
*/
|
|
28
|
-
declare function TabScaffold({ id, label, tabs, active, className, }: TabScaffoldProps): SafeHtml;
|
|
28
|
+
declare function TabScaffold<Id extends string>({ id, label, tabs, active, className, }: TabScaffoldProps<Id>): SafeHtml;
|
|
29
29
|
|
|
30
30
|
export { TabScaffold, type TabScaffoldProps, type TabScaffoldTab };
|
package/dist/tab-scaffold.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tab-scaffold.tsx"],"names":[],"mappings":";;;AA6BO,SAAS,WAAA,
|
|
1
|
+
{"version":3,"sources":["../src/tab-scaffold.tsx"],"names":[],"mappings":";;;AA6BO,SAAS,WAAA,CAA+B;AAAA,EAC7C,EAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,EAAyB;AACvB,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,EAAA;AAAA,MACA,gBAAA,EAAe,cAAA;AAAA,MACf,sBAAA,EAAsB,EAAA;AAAA,MAEtB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,SAAI,KAAA,EAAM,0BAAA,EACR,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBACT,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,yBAAA;AAAA,YACN,2BAAyB,GAAA,CAAI,EAAA;AAAA,YAC7B,aAAA,EAAa,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YACrC,aAAA,EAAa,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YAEpC,QAAA,EAAA,GAAA,CAAI;AAAA;AAAA,SAER,CAAA,EACH,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAwB,IAAA,EAAK,SAAA,EAAU,YAAA,EAAY,KAAA,EAC3D,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBACT,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAM,uBAAA;AAAA,YACN,IAAA,EAAK,KAAA;AAAA,YACL,yBAAuB,GAAA,CAAI,EAAA;AAAA,YAC3B,eAAA,EAAe,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YACvC,QAAA,EAAU,GAAA,CAAI,EAAA,KAAO,MAAA,GAAS,GAAA,GAAM,IAAA;AAAA,YAEnC,QAAA,EAAA;AAAA,cAAA,GAAA,CAAI,IAAA,wBACF,MAAA,EAAA,EAAK,KAAA,EAAM,8BAA6B,aAAA,EAAY,MAAA,EAClD,cAAI,IAAA,EACP,CAAA;AAAA,8BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,6BAAA,EAA+B,cAAI,KAAA,EAAM;AAAA;AAAA;AAAA,SAExD,CAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ","file":"tab-scaffold.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nexport interface TabScaffoldTab<Id extends string = string> {\n id: Id;\n label: string;\n /** Decorative icon shown above the label in the bottom bar. */\n icon?: SafeHtml;\n /** The tab's content — typically a `NavStack` so each tab keeps its own stack. */\n content: SafeHtml;\n}\n\nexport interface TabScaffoldProps<Id extends string = string> {\n id: string;\n /** Accessible name for the tab bar. */\n label: string;\n tabs: readonly TabScaffoldTab<Id>[];\n /** The controlled active tab id (the app owns selection). */\n active: NoInfer<Id>;\n className?: string;\n}\n\n/**\n * A mobile-first, iOS-like bottom tab scaffold: a bottom tab bar that switches\n * between major sections, each tab keeping its own content (usually a `NavStack`)\n * mounted so its stack and scroll survive a switch. Controlled — the app owns\n * `active`; wire selection with `@kerfjs/ui/wire-tab-scaffold`'s `wireTabScaffold`.\n * On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of\n * a bottom bar. See `docs/23-app-layouts.md` §3.4.\n */\nexport function TabScaffold<Id extends string>({\n id,\n label,\n tabs,\n active,\n className = '',\n}: TabScaffoldProps<Id>) {\n return (\n <section\n class={`kui-tab-scaffold ${className}`.trim()}\n id={id}\n data-component=\"tab-scaffold\"\n data-tab-scaffold-id={id}\n >\n <div class=\"kui-tab-scaffold__scenes\">\n {tabs.map((tab) => (\n <div\n class=\"kui-tab-scaffold__scene\"\n data-tab-scaffold-scene={tab.id}\n data-active={String(tab.id === active)}\n aria-hidden={String(tab.id !== active)}\n >\n {tab.content}\n </div>\n ))}\n </div>\n <nav class=\"kui-tab-scaffold__bar\" role=\"tablist\" aria-label={label}>\n {tabs.map((tab) => (\n <button\n type=\"button\"\n class=\"kui-tab-scaffold__tab\"\n role=\"tab\"\n data-tab-scaffold-tab={tab.id}\n aria-selected={String(tab.id === active)}\n tabindex={tab.id === active ? '0' : '-1'}\n >\n {tab.icon && (\n <span class=\"kui-tab-scaffold__tab-icon\" aria-hidden=\"true\">\n {tab.icon}\n </span>\n )}\n <span class=\"kui-tab-scaffold__tab-label\">{tab.label}</span>\n </button>\n ))}\n </nav>\n </section>\n );\n}\n"]}
|
|
@@ -6,7 +6,15 @@ interface TokenSearchToken {
|
|
|
6
6
|
offset?: number;
|
|
7
7
|
accessibleLabel?: string;
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
type TokenSearchEditorAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
10
|
+
'data-component'?: never;
|
|
11
|
+
'data-key'?: never;
|
|
12
|
+
'data-morph-skip'?: never;
|
|
13
|
+
'data-token-search-editor'?: never;
|
|
14
|
+
'data-token-count'?: never;
|
|
15
|
+
'data-placeholder'?: never;
|
|
16
|
+
}>;
|
|
17
|
+
interface TokenSearchFieldBaseProps {
|
|
10
18
|
id: string;
|
|
11
19
|
label: string;
|
|
12
20
|
query?: string;
|
|
@@ -15,12 +23,6 @@ interface TokenSearchFieldProps {
|
|
|
15
23
|
tokenPlaceholder?: string;
|
|
16
24
|
disabled?: boolean;
|
|
17
25
|
autofocus?: boolean;
|
|
18
|
-
/** Allow an empty field to render as one iconic action. */
|
|
19
|
-
collapsible?: boolean;
|
|
20
|
-
/** Keep an empty collapsible field open while the application owns focus. */
|
|
21
|
-
expanded?: boolean;
|
|
22
|
-
expandAction?: string;
|
|
23
|
-
expandLabel?: string;
|
|
24
26
|
leading?: SafeHtml;
|
|
25
27
|
trailing?: SafeHtml;
|
|
26
28
|
editAction?: string;
|
|
@@ -28,8 +30,22 @@ interface TokenSearchFieldProps {
|
|
|
28
30
|
clearAction?: string;
|
|
29
31
|
clearLabel?: string;
|
|
30
32
|
className?: string;
|
|
31
|
-
editorAttributes?:
|
|
33
|
+
editorAttributes?: TokenSearchEditorAttributes;
|
|
32
34
|
}
|
|
35
|
+
type TokenSearchCollapsibleProps = {
|
|
36
|
+
/** Allow an empty field to render as one iconic action. */
|
|
37
|
+
collapsible: true;
|
|
38
|
+
/** Keep an empty collapsible field open while the application owns focus. */
|
|
39
|
+
expanded?: boolean;
|
|
40
|
+
expandAction?: string;
|
|
41
|
+
expandLabel?: string;
|
|
42
|
+
} | {
|
|
43
|
+
collapsible?: false;
|
|
44
|
+
expanded?: never;
|
|
45
|
+
expandAction?: never;
|
|
46
|
+
expandLabel?: never;
|
|
47
|
+
};
|
|
48
|
+
type TokenSearchFieldProps = TokenSearchFieldBaseProps & TokenSearchCollapsibleProps;
|
|
33
49
|
interface TokenSearchFieldValue {
|
|
34
50
|
query: string;
|
|
35
51
|
tokens: TokenSearchToken[];
|
|
@@ -40,4 +56,4 @@ declare function readTokenSearchField(editor: HTMLElement, knownTokens?: readonl
|
|
|
40
56
|
/** Focus an editor and place its caret at a text offset, skipping atomic token chips. */
|
|
41
57
|
declare function placeTokenSearchCaret(editor: HTMLElement, offset?: number): void;
|
|
42
58
|
|
|
43
|
-
export { TokenSearchField, type TokenSearchFieldProps, type TokenSearchFieldValue, type TokenSearchToken, placeTokenSearchCaret, readTokenSearchField };
|
|
59
|
+
export { type TokenSearchEditorAttributes, TokenSearchField, type TokenSearchFieldProps, type TokenSearchFieldValue, type TokenSearchToken, placeTokenSearchCaret, readTokenSearchField };
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { SafeHtml } from 'kerfjs';
|
|
2
2
|
|
|
3
|
+
type ToolbarControlGroupAppearance = 'contained' | 'borderless';
|
|
4
|
+
type ToolbarControlGroupTone = 'default' | 'dark';
|
|
5
|
+
type ToolbarControlGroupButtonAppearance = 'plain' | 'push';
|
|
6
|
+
type ToolbarControlGroupShape = 'pill' | 'rounded';
|
|
3
7
|
interface ToolbarControlGroupProps {
|
|
4
8
|
children: SafeHtml | SafeHtml[];
|
|
5
9
|
label?: string;
|
|
6
10
|
className?: string;
|
|
7
11
|
expanded?: boolean;
|
|
8
12
|
single?: boolean;
|
|
9
|
-
appearance?:
|
|
10
|
-
tone?:
|
|
11
|
-
buttonAppearance?:
|
|
13
|
+
appearance?: ToolbarControlGroupAppearance;
|
|
14
|
+
tone?: ToolbarControlGroupTone;
|
|
15
|
+
buttonAppearance?: ToolbarControlGroupButtonAppearance;
|
|
12
16
|
/** Corner shape: fully round `pill` (default) or a softer `rounded` rectangle. */
|
|
13
|
-
shape?:
|
|
17
|
+
shape?: ToolbarControlGroupShape;
|
|
14
18
|
}
|
|
15
19
|
declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance, shape, }: ToolbarControlGroupProps): SafeHtml;
|
|
16
20
|
|
|
17
|
-
export { ToolbarControlGroup, type ToolbarControlGroupProps };
|
|
21
|
+
export { ToolbarControlGroup, type ToolbarControlGroupAppearance, type ToolbarControlGroupButtonAppearance, type ToolbarControlGroupProps, type ToolbarControlGroupShape, type ToolbarControlGroupTone };
|
package/dist/toolbar-text.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as kerfjs from 'kerfjs';
|
|
|
3
3
|
type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';
|
|
4
4
|
/** ARIA heading level for a title exposed as a heading landmark. */
|
|
5
5
|
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
6
|
-
interface
|
|
6
|
+
interface ToolbarTextBaseProps {
|
|
7
7
|
text: string;
|
|
8
8
|
size?: ToolbarTextSize;
|
|
9
9
|
className?: string;
|
|
@@ -17,23 +17,22 @@ interface ToolbarTextProps {
|
|
|
17
17
|
headingLevel?: HeadingLevel;
|
|
18
18
|
/** Render the text as an unanimated loading skeleton instead of its value. */
|
|
19
19
|
placeholder?: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Wrap onto multiple lines when the text does not fit, instead of the default
|
|
22
|
-
* single line. Combine with `maxLines` to cap the number of lines. Default false.
|
|
23
|
-
*/
|
|
24
|
-
wrap?: boolean;
|
|
25
20
|
/**
|
|
26
21
|
* Show a trailing ellipsis (…) where the text is truncated — on the single line
|
|
27
22
|
* (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip
|
|
28
23
|
* instead. Default true.
|
|
29
24
|
*/
|
|
30
25
|
ellipsis?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Cap wrapped text to this many lines, truncating past it. Only takes effect with
|
|
33
|
-
* `wrap`; ignored on a single line. `null`/omitted wraps without a line cap. Default null.
|
|
34
|
-
*/
|
|
35
|
-
maxLines?: number | null;
|
|
36
26
|
}
|
|
27
|
+
type ToolbarTextWrappingProps = {
|
|
28
|
+
/** Wrap onto multiple lines; combine with `maxLines` to cap them. */
|
|
29
|
+
wrap: true;
|
|
30
|
+
maxLines?: number | null;
|
|
31
|
+
} | {
|
|
32
|
+
wrap?: false;
|
|
33
|
+
maxLines?: never;
|
|
34
|
+
};
|
|
35
|
+
type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;
|
|
37
36
|
declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
38
37
|
|
|
39
38
|
export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
package/dist/toolbar-text.js
CHANGED
package/dist/wire-tab-bars.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { TabActivation } from './tab-bar.js';
|
|
2
|
+
import 'kerfjs';
|
|
3
|
+
|
|
1
4
|
type TabReorderSource = 'pointer' | 'keyboard';
|
|
2
5
|
type TabDropPosition = 'before' | 'after';
|
|
3
6
|
interface TabReorder {
|
|
@@ -7,7 +10,7 @@ interface TabReorder {
|
|
|
7
10
|
position: TabDropPosition;
|
|
8
11
|
source: TabReorderSource;
|
|
9
12
|
}
|
|
10
|
-
|
|
13
|
+
|
|
11
14
|
interface WireTabBarsOptions {
|
|
12
15
|
onReorder: (change: TabReorder) => void;
|
|
13
16
|
/**
|
|
@@ -27,4 +30,4 @@ declare function reorderTabs<T>(items: readonly T[], getId: (item: T) => string,
|
|
|
27
30
|
/** Wire reordering and keyboard navigation while leaving controlled state in the application. */
|
|
28
31
|
declare function wireTabBars(root: HTMLElement | Document, { onReorder, activation }: WireTabBarsOptions): () => void;
|
|
29
32
|
|
|
30
|
-
export {
|
|
33
|
+
export { TabActivation, type TabDropPosition, type TabReorder, type TabReorderSource, type WireTabBarsOptions, reorderTabs, wireTabBars };
|
package/dist/wire-tab-bars.js
CHANGED
|
@@ -29,21 +29,26 @@ interface TokenSearchTokenRemoval {
|
|
|
29
29
|
* for the caller to apply, while caret movement past a chip is a pure ephemeral
|
|
30
30
|
* mechanic the helper performs itself.
|
|
31
31
|
*/
|
|
32
|
-
interface
|
|
32
|
+
interface TokenSearchKeyboardBaseOptions {
|
|
33
33
|
/**
|
|
34
34
|
* From a collapsed caret with no selection, Backspace removes the token
|
|
35
35
|
* immediately before it and Delete the token immediately after — reported via
|
|
36
36
|
* `onRemoveToken` — instead of deleting a character. Default: true.
|
|
37
37
|
*/
|
|
38
|
-
removeAdjacentToken?: boolean;
|
|
39
38
|
/**
|
|
40
39
|
* ArrowRight moves the caret past a trailing atomic token so text typed next
|
|
41
40
|
* lands after the chip. Default: true.
|
|
42
41
|
*/
|
|
43
42
|
moveCaretPastToken?: boolean;
|
|
44
|
-
/** Apply the reported removal to your controlled state, then re-render. */
|
|
45
|
-
onRemoveToken?: (removal: TokenSearchTokenRemoval) => void;
|
|
46
43
|
}
|
|
44
|
+
type TokenSearchKeyboardOptions = TokenSearchKeyboardBaseOptions & ({
|
|
45
|
+
removeAdjacentToken?: true;
|
|
46
|
+
/** Apply the reported removal to your controlled state, then re-render. */
|
|
47
|
+
onRemoveToken: (removal: TokenSearchTokenRemoval) => void;
|
|
48
|
+
} | {
|
|
49
|
+
removeAdjacentToken: false;
|
|
50
|
+
onRemoveToken?: never;
|
|
51
|
+
});
|
|
47
52
|
/**
|
|
48
53
|
* Managed collapsible behavior for the iconic TokenSearchField. Every piece is on
|
|
49
54
|
* by default; disable a specific one to own it in the app. Provide `signals` to
|
|
@@ -76,8 +81,8 @@ interface WireTokenSearchFieldsOptions {
|
|
|
76
81
|
onEdit?: (edit: TokenSearchEdit) => void;
|
|
77
82
|
/** Managed collapsible transient behavior. `true`/omitted = on with defaults; `false` = fully off. */
|
|
78
83
|
collapsible?: boolean | TokenSearchCollapsibleOptions;
|
|
79
|
-
/** Opt-in atomic-chip keyboard behavior (off by default).
|
|
80
|
-
keyboard?:
|
|
84
|
+
/** Opt-in atomic-chip keyboard behavior (off by default). */
|
|
85
|
+
keyboard?: false | TokenSearchKeyboardOptions;
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
83
88
|
* The value returned from {@link wireTokenSearchFields}: call it (or `dispose()`) to
|