@kerfjs/ui 5.0.0-beta.50 → 5.0.0-beta.52
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 +29 -5
- package/ai/compile-time-contracts-v1.json +5 -2
- package/ai/component-catalog-v2.d.ts +19 -1
- package/ai/component-catalog-v2.json +842 -127
- package/ai/component-catalog-v2.schema.json +33 -1
- package/ai/component-catalog.json +603 -126
- package/ai/component-catalog.schema.json +21 -1
- package/ai/public-api-signatures-v1.md +218 -31
- package/ai/skill.md +27 -24
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/index.mjs +105 -35
- package/dist/app-tab.d.ts +10 -1
- package/dist/app-tab.js +1 -1
- package/dist/catalog-resources.d.ts +1 -1
- package/dist/catalog.d.ts +28 -5
- package/dist/catalog.js +66 -25
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-OL4TC3U2.js → chunk-2CE22Q2K.js} +9 -2
- package/dist/chunk-2CE22Q2K.js.map +1 -0
- package/dist/{chunk-SIU2AC5W.js → chunk-2S7OWAEV.js} +3 -3
- package/dist/{chunk-SIU2AC5W.js.map → chunk-2S7OWAEV.js.map} +1 -1
- package/dist/{chunk-2YOUUEWR.js → chunk-3S7OUHUN.js} +4 -4
- package/dist/{chunk-2YOUUEWR.js.map → chunk-3S7OUHUN.js.map} +1 -1
- package/dist/{chunk-2WMSE4MK.js → chunk-4XE2CDYB.js} +2 -2
- package/dist/{chunk-2WMSE4MK.js.map → chunk-4XE2CDYB.js.map} +1 -1
- package/dist/{chunk-V6RZWDII.js → chunk-7GUQYHKA.js} +19 -2
- package/dist/chunk-7GUQYHKA.js.map +1 -0
- package/dist/{chunk-ZNZ2JDBW.js → chunk-7IUSV4XG.js} +1 -1
- package/dist/chunk-7IUSV4XG.js.map +1 -0
- package/dist/{chunk-UMGY5JSP.js → chunk-7XJO4D6A.js} +22 -2
- package/dist/chunk-7XJO4D6A.js.map +1 -0
- package/dist/{chunk-KKNK3JUT.js → chunk-ABAXNUXU.js} +5 -5
- package/dist/chunk-ABAXNUXU.js.map +1 -0
- package/dist/{chunk-AQSKJ6U6.js → chunk-DNCOFEUL.js} +21 -2
- package/dist/chunk-DNCOFEUL.js.map +1 -0
- package/dist/chunk-EKYZCRCX.js +256 -0
- package/dist/chunk-EKYZCRCX.js.map +1 -0
- package/dist/{chunk-COUPLRZG.js → chunk-IR53BQUJ.js} +16 -12
- package/dist/chunk-IR53BQUJ.js.map +1 -0
- package/dist/{chunk-3V75EQIP.js → chunk-JGFZ42ZF.js} +3 -3
- package/dist/{chunk-3V75EQIP.js.map → chunk-JGFZ42ZF.js.map} +1 -1
- package/dist/{chunk-54HM36IQ.js → chunk-KAQUUTZR.js} +4 -2
- package/dist/chunk-KAQUUTZR.js.map +1 -0
- package/dist/{chunk-ZSYLBVWG.js → chunk-LIOXPQ7N.js} +4 -4
- package/dist/chunk-LIOXPQ7N.js.map +1 -0
- package/dist/{chunk-S6ZTTTV7.js → chunk-M6GLI6A6.js} +3 -3
- package/dist/{chunk-S6ZTTTV7.js.map → chunk-M6GLI6A6.js.map} +1 -1
- package/dist/{chunk-OQI7RCRP.js → chunk-MTM43SJO.js} +7 -1
- package/dist/chunk-MTM43SJO.js.map +1 -0
- package/dist/{chunk-5CE64WGC.js → chunk-OSCL5TKR.js} +3 -3
- package/dist/{chunk-5CE64WGC.js.map → chunk-OSCL5TKR.js.map} +1 -1
- package/dist/{chunk-DARTMI5Z.js → chunk-SV22UIW4.js} +2 -2
- package/dist/{chunk-DARTMI5Z.js.map → chunk-SV22UIW4.js.map} +1 -1
- package/dist/{chunk-ELRMBQEC.js → chunk-T7C2VZUB.js} +17 -2
- package/dist/chunk-T7C2VZUB.js.map +1 -0
- package/dist/{chunk-DJKWFYAA.js → chunk-YZV2PTY4.js} +3 -3
- package/dist/{chunk-DJKWFYAA.js.map → chunk-YZV2PTY4.js.map} +1 -1
- package/dist/collapsible-panel.d.ts +1 -1
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/css-values.d.ts +41 -3
- package/dist/css-values.js +1 -1
- package/dist/grid.d.ts +15 -1
- package/dist/grid.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -19
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +1 -1
- package/dist/list.d.ts +21 -2
- package/dist/list.js +2 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +17 -2
- package/dist/pane.js +1 -1
- package/dist/row.d.ts +19 -1
- package/dist/row.js +2 -1
- package/dist/segmented-control.js +1 -1
- package/dist/select.d.ts +13 -3
- package/dist/select.js +1 -1
- package/dist/skeleton.d.ts +5 -1
- package/dist/skeleton.js +1 -1
- package/dist/spacer.js +1 -1
- package/dist/split-view.js +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/app-tab.css +9 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +4 -1
- package/dist/styles/catalog/components/catalog-example.css +145 -0
- package/dist/styles/collapsible-panel.css +132 -4
- package/dist/styles/document.css +23 -0
- package/dist/styles/foundation.css +21 -7
- package/dist/styles/grid.css +10 -0
- package/dist/styles/list-header.css +45 -0
- package/dist/styles/list-inset-control.css +8 -1
- package/dist/styles/list-item.css +6 -0
- package/dist/styles/list.css +11 -0
- package/dist/styles/nav-stack.css +89 -2
- package/dist/styles/pane.css +86 -1
- package/dist/styles/resizable-region.css +93 -5
- package/dist/styles/row.css +10 -0
- package/dist/styles/select.css +39 -4
- package/dist/styles/skeleton.css +4 -1
- package/dist/styles/split-view.css +107 -1
- package/dist/styles/tab-scaffold.css +64 -1
- package/dist/styles/text.css +6 -0
- package/dist/styles/toolbar-control-group.css +90 -11
- package/dist/styles/toolbar-text.css +4 -1
- package/dist/styles/toolbar.css +130 -38
- package/dist/styles/webawesome.css +48 -2
- package/dist/styles/workbench.css +136 -4
- package/dist/text.d.ts +4 -3
- package/dist/text.js +1 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +24 -3
- package/dist/toolbar.js +1 -1
- package/dist/{types-CzgSrFXP.d.ts → types-CEsieBZi.d.ts} +6 -1
- package/dist/value-table.js +1 -1
- package/dist/wire-resizable-regions.js +1 -1
- package/dist/wire-sidebar.d.ts +18 -3
- package/dist/wire-sidebar.js +96 -15
- package/dist/wire-sidebar.js.map +1 -1
- package/docs/accessibility.md +49 -9
- package/docs/app-layouts.md +73 -0
- package/docs/catalog.md +23 -2
- package/docs/collapsible-panel.md +83 -9
- package/docs/component-contract.md +36 -12
- package/docs/component-integration.md +9 -4
- package/docs/component-selection.md +25 -6
- package/docs/design/templates/list/stack-dark.svg +1 -1
- package/docs/design/templates/list/stack.svg +1 -1
- package/docs/design/templates/list-dark.svg +1 -1
- package/docs/design/templates/list-header/action-dark.svg +1 -1
- package/docs/design/templates/list-header/action.svg +1 -1
- package/docs/design/templates/list-header/count-dark.svg +1 -1
- package/docs/design/templates/list-header/count.svg +1 -1
- package/docs/design/templates/list-header/inline-action-dark.svg +1 -1
- package/docs/design/templates/list-header/inline-action.svg +1 -1
- package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
- package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
- package/docs/design/templates/list-header-dark.svg +1 -1
- package/docs/design/templates/list-header.svg +1 -1
- package/docs/design/templates/list.svg +1 -1
- package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
- package/docs/design/templates/state-banner/info-badge.svg +1 -1
- package/docs/design/templates/state-banner-dark.svg +1 -1
- package/docs/design/templates/state-banner.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 +1 -1
- package/docs/design/templates/toolbar-text.svg +1 -1
- package/docs/design/templates/toolbar.svg +1 -1
- package/docs/document-baseline.md +31 -0
- package/docs/layout.md +86 -21
- package/docs/nav-stack.md +8 -0
- package/docs/recipes.md +81 -44
- package/docs/split-view.md +8 -0
- package/docs/tab-scaffold.md +4 -2
- package/docs/type-contracts.md +21 -17
- package/docs/ui-analyzer.md +19 -0
- package/docs/ui-evaluator.md +17 -0
- package/docs/ux-demo.md +5 -5
- package/docs/webawesome-theme.md +20 -2
- package/docs/workbench.md +20 -1
- package/evaluator/index.mjs +73 -8
- package/llms.txt +32 -14
- package/package.json +4 -2
- package/ux-demo/recipes/app-shell.tsx +209 -178
- package/ux-demo/recipes/collapsible-sidebar.tsx +189 -159
- package/ux-demo/recipes/compact-toolbar.tsx +48 -35
- package/ux-demo/recipes/composer-form.tsx +87 -79
- package/ux-demo/recipes/list-detail-dialog.tsx +124 -142
- package/ux-demo/recipes/list-workspace-states.tsx +83 -83
- package/ux-demo/recipes/loaders.ts +5 -2
- package/ux-demo/recipes/loading-inspector.tsx +157 -160
- package/ux-demo/recipes/navigation-sidebar.tsx +111 -109
- package/ux-demo/recipes/navigation-stack.tsx +50 -49
- package/ux-demo/recipes/types.ts +14 -0
- package/ux-demo/recipes/workspace-header.tsx +73 -56
- package/dist/chunk-54HM36IQ.js.map +0 -1
- package/dist/chunk-AQSKJ6U6.js.map +0 -1
- package/dist/chunk-COUPLRZG.js.map +0 -1
- package/dist/chunk-ELRMBQEC.js.map +0 -1
- package/dist/chunk-J3EE6XWD.js +0 -115
- package/dist/chunk-J3EE6XWD.js.map +0 -1
- package/dist/chunk-KKNK3JUT.js.map +0 -1
- package/dist/chunk-OL4TC3U2.js.map +0 -1
- package/dist/chunk-OQI7RCRP.js.map +0 -1
- package/dist/chunk-UMGY5JSP.js.map +0 -1
- package/dist/chunk-V6RZWDII.js.map +0 -1
- package/dist/chunk-ZNZ2JDBW.js.map +0 -1
- package/dist/chunk-ZSYLBVWG.js.map +0 -1
- package/ux-demo/recipes/app-shell.css +0 -87
- package/ux-demo/recipes/collapsible-sidebar.css +0 -83
- package/ux-demo/recipes/compact-toolbar.css +0 -35
- package/ux-demo/recipes/composer-form.css +0 -19
- package/ux-demo/recipes/list-detail-dialog.css +0 -42
- package/ux-demo/recipes/list-workspace-states.css +0 -30
- package/ux-demo/recipes/loading-inspector.css +0 -7
- package/ux-demo/recipes/navigation-sidebar.css +0 -12
- package/ux-demo/recipes/navigation-stack.css +0 -12
- package/ux-demo/recipes/recipe-root.css +0 -67
- package/ux-demo/recipes/recipe-root.tsx +0 -87
- package/ux-demo/recipes/workspace-header.css +0 -7
|
@@ -1,137 +1,139 @@
|
|
|
1
1
|
import '@kerfjs/ui/layout.css';
|
|
2
|
-
import './navigation-sidebar.css';
|
|
3
2
|
|
|
3
|
+
import { List } from '@kerfjs/ui/list';
|
|
4
4
|
import { ListHeader } from '@kerfjs/ui/list-header';
|
|
5
5
|
import { ListItem } from '@kerfjs/ui/list-item';
|
|
6
6
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
7
7
|
import { Pane } from '@kerfjs/ui/pane';
|
|
8
|
+
import { Text } from '@kerfjs/ui/text';
|
|
8
9
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
9
10
|
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
10
11
|
import { signal } from 'kerfjs';
|
|
11
12
|
import { Folder, Inbox, Plus, Settings, Users } from 'lucide';
|
|
12
13
|
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
import type { RecipeFactory, RecipePresentation } from './types.js';
|
|
15
|
+
|
|
16
|
+
export const presentation: RecipePresentation = {
|
|
17
|
+
viewport: {
|
|
18
|
+
layout: 'grid',
|
|
19
|
+
width: 'compact',
|
|
20
|
+
minHeight: 'medium',
|
|
21
|
+
frame: 'solid',
|
|
22
|
+
surface: 'default',
|
|
23
|
+
overflow: 'hidden',
|
|
24
|
+
shadow: true,
|
|
25
|
+
},
|
|
26
|
+
note: 'The recipe owns pane, content-item, and toolbar geometry. The app owns routes, permissions, labels, and disclosure state.',
|
|
27
|
+
};
|
|
19
28
|
|
|
20
29
|
export const createRecipe: RecipeFactory = (announce) => {
|
|
21
30
|
const selected = signal('inbox');
|
|
22
31
|
const expanded = signal(true);
|
|
23
32
|
const render = () => (
|
|
24
|
-
<
|
|
33
|
+
<Pane
|
|
25
34
|
element="aside"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
data-recipe-command="add"
|
|
44
|
-
>
|
|
45
|
-
<LucideIcon icon={Plus} name="plus" />
|
|
46
|
-
</button>
|
|
47
|
-
</ToolbarControlGroup>
|
|
48
|
-
}
|
|
49
|
-
trailing={
|
|
50
|
-
<ToolbarControlGroup appearance="borderless" single>
|
|
51
|
-
<button
|
|
52
|
-
type="button"
|
|
53
|
-
aria-label="Workspace settings"
|
|
54
|
-
data-action="recipe-action"
|
|
55
|
-
data-recipe-command="settings"
|
|
56
|
-
>
|
|
57
|
-
<LucideIcon icon={Settings} name="settings" />
|
|
58
|
-
</button>
|
|
59
|
-
</ToolbarControlGroup>
|
|
60
|
-
}
|
|
61
|
-
/>
|
|
35
|
+
label="Workspace navigation"
|
|
36
|
+
rootAttributes={{ 'data-recipe': 'recipe-navigation-sidebar' }}
|
|
37
|
+
footer={
|
|
38
|
+
<Toolbar
|
|
39
|
+
label="Sidebar actions"
|
|
40
|
+
dividerSides="t"
|
|
41
|
+
leading={
|
|
42
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
43
|
+
<button
|
|
44
|
+
type="button"
|
|
45
|
+
aria-label="Add project"
|
|
46
|
+
data-action="recipe-action"
|
|
47
|
+
data-recipe-command="add"
|
|
48
|
+
>
|
|
49
|
+
<LucideIcon icon={Plus} name="plus" />
|
|
50
|
+
</button>
|
|
51
|
+
</ToolbarControlGroup>
|
|
62
52
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
53
|
+
trailing={
|
|
54
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
aria-label="Workspace settings"
|
|
58
|
+
data-action="recipe-action"
|
|
59
|
+
data-recipe-command="settings"
|
|
60
|
+
>
|
|
61
|
+
<LucideIcon icon={Settings} name="settings" />
|
|
62
|
+
</button>
|
|
63
|
+
</ToolbarControlGroup>
|
|
64
|
+
}
|
|
65
|
+
/>
|
|
66
|
+
}
|
|
67
|
+
>
|
|
68
|
+
<section>
|
|
69
|
+
<ListHeader
|
|
70
|
+
label="Workspace"
|
|
71
|
+
count={3}
|
|
72
|
+
countLabel="3 workspaces"
|
|
73
|
+
action="recipe-action"
|
|
74
|
+
actionLabel="Add workspace item"
|
|
75
|
+
actionIcon={<LucideIcon icon={Plus} name="plus" />}
|
|
76
|
+
/>
|
|
77
|
+
<ListItem
|
|
78
|
+
action="recipe-action"
|
|
79
|
+
itemId="inbox"
|
|
80
|
+
label="Inbox"
|
|
81
|
+
icon={<LucideIcon icon={Inbox} name="inbox" />}
|
|
82
|
+
trailing={<span>12</span>}
|
|
83
|
+
selected={selected.value === 'inbox'}
|
|
84
|
+
/>
|
|
85
|
+
<ListItem
|
|
86
|
+
action="recipe-action"
|
|
87
|
+
itemId="shared"
|
|
88
|
+
label="Shared with me"
|
|
89
|
+
icon={<LucideIcon icon={Users} name="users" />}
|
|
90
|
+
selected={selected.value === 'shared'}
|
|
91
|
+
/>
|
|
92
|
+
<ListItem
|
|
93
|
+
action="recipe-action"
|
|
94
|
+
itemId="drafts"
|
|
95
|
+
label="Drafts without an icon"
|
|
96
|
+
selected={selected.value === 'drafts'}
|
|
97
|
+
/>
|
|
98
|
+
</section>
|
|
99
|
+
<section>
|
|
100
|
+
<ListHeader
|
|
101
|
+
label="Projects"
|
|
102
|
+
toggle
|
|
103
|
+
action="recipe-action"
|
|
104
|
+
expanded={expanded.value}
|
|
105
|
+
/>
|
|
106
|
+
{expanded.value && (
|
|
107
|
+
<>
|
|
81
108
|
<ListItem
|
|
82
109
|
action="recipe-action"
|
|
83
|
-
itemId="
|
|
84
|
-
label="
|
|
85
|
-
icon={<LucideIcon icon={
|
|
86
|
-
selected={selected.value === '
|
|
110
|
+
itemId="design"
|
|
111
|
+
label="Design system rollout across desktop and tablet"
|
|
112
|
+
icon={<LucideIcon icon={Folder} name="folder" />}
|
|
113
|
+
selected={selected.value === 'design'}
|
|
114
|
+
multiline
|
|
87
115
|
/>
|
|
88
116
|
<ListItem
|
|
89
117
|
action="recipe-action"
|
|
90
|
-
itemId="
|
|
91
|
-
label="
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
</section>
|
|
95
|
-
<section>
|
|
96
|
-
<ListHeader
|
|
97
|
-
label="Projects"
|
|
98
|
-
toggle
|
|
99
|
-
action="recipe-action"
|
|
100
|
-
expanded={expanded.value}
|
|
118
|
+
itemId="archive"
|
|
119
|
+
label="Archived"
|
|
120
|
+
disabled
|
|
121
|
+
title="Available to administrators"
|
|
101
122
|
/>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
action="recipe-action"
|
|
106
|
-
itemId="design"
|
|
107
|
-
label="Design system rollout across desktop and tablet"
|
|
108
|
-
icon={<LucideIcon icon={Folder} name="folder" />}
|
|
109
|
-
selected={selected.value === 'design'}
|
|
110
|
-
multiline
|
|
111
|
-
/>
|
|
112
|
-
<ListItem
|
|
113
|
-
action="recipe-action"
|
|
114
|
-
itemId="archive"
|
|
115
|
-
label="Archived"
|
|
116
|
-
disabled
|
|
117
|
-
title="Available to administrators"
|
|
118
|
-
/>
|
|
119
|
-
<div class="kui-content-item">
|
|
123
|
+
<div class="kui-content-item">
|
|
124
|
+
<List gap="2xs">
|
|
125
|
+
<Text variant="span">
|
|
120
126
|
<strong>Quarterly goal</strong>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
</
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
</RecipeOwnershipNote>
|
|
132
|
-
</Pane>
|
|
133
|
-
</div>
|
|
134
|
-
</RecipeRoot>
|
|
127
|
+
</Text>
|
|
128
|
+
<Text variant="span" tone="quiet" size="compact">
|
|
129
|
+
Ship accessible navigation patterns to every workspace.
|
|
130
|
+
</Text>
|
|
131
|
+
</List>
|
|
132
|
+
</div>
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
135
|
+
</section>
|
|
136
|
+
</Pane>
|
|
135
137
|
);
|
|
136
138
|
return {
|
|
137
139
|
render,
|
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
import '@kerfjs/ui/layout.css';
|
|
2
2
|
import '@kerfjs/ui/nav-stack.css';
|
|
3
3
|
import '@kerfjs/ui/toolbar-text.css';
|
|
4
|
-
import './navigation-stack.css';
|
|
5
4
|
|
|
6
5
|
import { List } from '@kerfjs/ui/list';
|
|
7
6
|
import { ListHeader } from '@kerfjs/ui/list-header';
|
|
8
7
|
import { ListItem } from '@kerfjs/ui/list-item';
|
|
9
8
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
10
9
|
import { NavStack, type NavStackView } from '@kerfjs/ui/nav-stack';
|
|
10
|
+
import { Row } from '@kerfjs/ui/row';
|
|
11
|
+
import { Text } from '@kerfjs/ui/text';
|
|
11
12
|
import { signal } from 'kerfjs';
|
|
12
13
|
import { ChevronRight, FileText, Folder } from 'lucide';
|
|
13
14
|
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
import type { RecipeFactory, RecipePresentation } from './types.js';
|
|
16
|
+
|
|
17
|
+
export const presentation: RecipePresentation = {
|
|
18
|
+
viewport: {
|
|
19
|
+
layout: 'grid',
|
|
20
|
+
width: 'compact',
|
|
21
|
+
height: 'tall',
|
|
22
|
+
frame: 'solid',
|
|
23
|
+
surface: 'default',
|
|
24
|
+
overflow: 'hidden',
|
|
25
|
+
shadow: true,
|
|
26
|
+
},
|
|
27
|
+
note: 'The recipe owns the stack as a signal of views and pushes/pops it; NavStack renders the stack and wireNavStack slides the content and settles the chrome. The app owns selection, data, and routing.',
|
|
28
|
+
};
|
|
20
29
|
|
|
21
30
|
interface LibraryItem {
|
|
22
31
|
id: string;
|
|
@@ -50,29 +59,20 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
50
59
|
key: 'library',
|
|
51
60
|
title: 'Library',
|
|
52
61
|
content: (
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
))}
|
|
68
|
-
</section>
|
|
69
|
-
<RecipeOwnershipNote>
|
|
70
|
-
The recipe owns the stack as a signal of views and pushes/pops it;
|
|
71
|
-
`NavStack` renders the stack and `wireNavStack` slides the content
|
|
72
|
-
and settles the chrome. The app owns selection, data, and routing.
|
|
73
|
-
</RecipeOwnershipNote>
|
|
74
|
-
</List>
|
|
75
|
-
</div>
|
|
62
|
+
<List>
|
|
63
|
+
<section>
|
|
64
|
+
<ListHeader label="Components" />
|
|
65
|
+
{ITEMS.map((item) => (
|
|
66
|
+
<ListItem
|
|
67
|
+
action="recipe-action"
|
|
68
|
+
itemId={item.id}
|
|
69
|
+
label={item.label}
|
|
70
|
+
icon={<LucideIcon icon={Folder} name="folder" />}
|
|
71
|
+
trailing={<LucideIcon icon={ChevronRight} name="chevron-right" />}
|
|
72
|
+
/>
|
|
73
|
+
))}
|
|
74
|
+
</section>
|
|
75
|
+
</List>
|
|
76
76
|
),
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -80,32 +80,33 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
80
80
|
key: item.id,
|
|
81
81
|
title: item.label,
|
|
82
82
|
content: (
|
|
83
|
-
<
|
|
84
|
-
<
|
|
85
|
-
<
|
|
83
|
+
<List controlInsets="t">
|
|
84
|
+
<div class="kui-content-item">
|
|
85
|
+
<Row gap="xs">
|
|
86
86
|
<LucideIcon icon={FileText} name="file-text" />
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
<List gap="2xs">
|
|
88
|
+
<Text variant="span">
|
|
89
|
+
<strong>{item.label}</strong>
|
|
90
|
+
</Text>
|
|
91
|
+
<Text variant="span" tone="quiet" size="compact">
|
|
92
|
+
{item.detail}
|
|
93
|
+
</Text>
|
|
94
|
+
</List>
|
|
95
|
+
</Row>
|
|
96
|
+
</div>
|
|
97
|
+
</List>
|
|
92
98
|
),
|
|
93
99
|
});
|
|
94
100
|
|
|
95
101
|
const views = signal<NavStackView[]>([listView()]);
|
|
96
102
|
|
|
97
103
|
const render = () => (
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
views={views.value}
|
|
105
|
-
/>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
</RecipeRoot>
|
|
104
|
+
<section
|
|
105
|
+
data-recipe="recipe-navigation-stack"
|
|
106
|
+
aria-label="Component library"
|
|
107
|
+
>
|
|
108
|
+
<NavStack id="recipe-nav" label="Component library" views={views.value} />
|
|
109
|
+
</section>
|
|
109
110
|
);
|
|
110
111
|
|
|
111
112
|
return {
|
package/ux-demo/recipes/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CatalogExampleViewport } from '@kerfjs/ui/catalog';
|
|
1
2
|
import type { SafeHtml } from 'kerfjs';
|
|
2
3
|
|
|
3
4
|
export interface RecipeController {
|
|
@@ -17,3 +18,16 @@ export interface RecipeController {
|
|
|
17
18
|
export type RecipeFactory = (
|
|
18
19
|
announce: (message: string) => void,
|
|
19
20
|
) => RecipeController;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Catalog-only presentation for one recipe. The UX catalog frames the recipe in
|
|
24
|
+
* a `CatalogExample` viewport and shows `note` when recipe notes are toggled on;
|
|
25
|
+
* an application that copies the recipe ignores this export and mounts the
|
|
26
|
+
* controller into its own container.
|
|
27
|
+
*/
|
|
28
|
+
export interface RecipePresentation {
|
|
29
|
+
/** Catalog-owned specimen frame: width, height, surface, and border. */
|
|
30
|
+
viewport?: CatalogExampleViewport;
|
|
31
|
+
/** Ownership note: what the recipe owns versus what the application owns. */
|
|
32
|
+
note: string;
|
|
33
|
+
}
|
|
@@ -1,75 +1,92 @@
|
|
|
1
1
|
import '@kerfjs/ui/layout.css';
|
|
2
|
-
import './workspace-header.css';
|
|
3
2
|
|
|
3
|
+
import { List } from '@kerfjs/ui/list';
|
|
4
|
+
import { ListInsetText } from '@kerfjs/ui/list-inset-text';
|
|
4
5
|
import { StateBanner } from '@kerfjs/ui/state-banner';
|
|
6
|
+
import { Text } from '@kerfjs/ui/text';
|
|
5
7
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
6
8
|
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
7
9
|
import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
8
10
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
+
import type { RecipeFactory, RecipePresentation } from './types.js';
|
|
12
|
+
|
|
13
|
+
export const presentation: RecipePresentation = {
|
|
14
|
+
viewport: {
|
|
15
|
+
width: 'full',
|
|
16
|
+
frame: 'solid',
|
|
17
|
+
surface: 'default',
|
|
18
|
+
overflow: 'hidden',
|
|
19
|
+
shadow: true,
|
|
20
|
+
},
|
|
21
|
+
note: 'The recipe owns page hierarchy and action relocation. The app owns authorization, command behavior, breadcrumbs, and product copy.',
|
|
22
|
+
};
|
|
11
23
|
|
|
12
24
|
export const createRecipe: RecipeFactory = (announce) => ({
|
|
13
25
|
render: () => (
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<button
|
|
46
|
-
type="button"
|
|
47
|
-
data-action="recipe-action"
|
|
48
|
-
data-recipe-command="more"
|
|
26
|
+
<section
|
|
27
|
+
data-recipe="recipe-workspace-header"
|
|
28
|
+
aria-labelledby="recipe-workspace-title"
|
|
29
|
+
>
|
|
30
|
+
<List gap="l" controlInsets="tb">
|
|
31
|
+
<List>
|
|
32
|
+
<ListInsetText sides="rl">
|
|
33
|
+
<Text variant="span" tone="quiet" size="compact">
|
|
34
|
+
Northstar workspace · Product planning
|
|
35
|
+
</Text>
|
|
36
|
+
</ListInsetText>
|
|
37
|
+
<Toolbar
|
|
38
|
+
label="Workspace heading"
|
|
39
|
+
dividerSides=""
|
|
40
|
+
responsive="stack"
|
|
41
|
+
responsiveAt="compact"
|
|
42
|
+
leading={
|
|
43
|
+
<ToolbarText
|
|
44
|
+
text="Accessibility readiness and responsive navigation rollout"
|
|
45
|
+
size="xlarge"
|
|
46
|
+
id="recipe-workspace-title"
|
|
47
|
+
headingLevel={1}
|
|
48
|
+
wrap
|
|
49
|
+
maxLines={2}
|
|
50
|
+
/>
|
|
51
|
+
}
|
|
52
|
+
trailing={
|
|
53
|
+
<ToolbarControlGroup
|
|
54
|
+
appearance="borderless"
|
|
55
|
+
buttonAppearance="push"
|
|
56
|
+
content="text"
|
|
49
57
|
>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
data-action="recipe-action"
|
|
61
|
+
data-recipe-command="share"
|
|
62
|
+
>
|
|
63
|
+
Share
|
|
64
|
+
</button>
|
|
65
|
+
<button
|
|
66
|
+
type="button"
|
|
67
|
+
data-action="recipe-action"
|
|
68
|
+
data-recipe-command="more"
|
|
69
|
+
>
|
|
70
|
+
More actions
|
|
71
|
+
</button>
|
|
72
|
+
<button
|
|
73
|
+
type="button"
|
|
74
|
+
data-action="recipe-action"
|
|
75
|
+
data-recipe-command="publish"
|
|
76
|
+
>
|
|
77
|
+
Publish update
|
|
78
|
+
</button>
|
|
79
|
+
</ToolbarControlGroup>
|
|
80
|
+
}
|
|
81
|
+
/>
|
|
82
|
+
</List>
|
|
62
83
|
<StateBanner
|
|
63
84
|
title="Ready for review"
|
|
64
85
|
detail="All required checks passed 18 minutes ago."
|
|
65
86
|
tone="success"
|
|
66
87
|
/>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
authorization, command behavior, breadcrumbs, and product copy.
|
|
70
|
-
</RecipeOwnershipNote>
|
|
71
|
-
</div>
|
|
72
|
-
</RecipeRoot>
|
|
88
|
+
</List>
|
|
89
|
+
</section>
|
|
73
90
|
),
|
|
74
91
|
action(command) {
|
|
75
92
|
announce(`${command} requested`);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/skeleton.tsx"],"names":[],"mappings":";;;AAkBA,SAAS,UAAA,CACP,KAAA,EACA,MAAA,EACA,MAAA,EACoB;AACpB,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;AAAA,EACvB,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAkB;AAChB,EAAA,MAAM,IAAA,GAAO;AAAA,IACX,IAAA,EAAM,QAAQ,KAAA,GAAQ,MAAA;AAAA,IACtB,YAAA,EAAc,KAAA;AAAA,IACd,aAAA,EAAe,QAAQ,MAAA,GAAa;AAAA,GACtC;AACA,EAAA,IAAI,KAAA,IAAS,QAAQ,CAAA,EAAG;AACtB,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,QAC9C,gBAAA,EAAe,UAAA;AAAA,QACf,KAAA,EAAO,KAAA,GAAQ,CAAA,MAAA,EAAS,KAAK,CAAA,CAAA,GAAK,MAAA;AAAA,QACjC,GAAG,IAAA;AAAA,QACJ,IAAA;AAAA,QAEC,QAAA,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,OAAM,EAAG,CAAC,GAAG,KAAA,qBACjC,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,cAAA;AAAA,YACN,aAAA,EAAY,MAAA;AAAA,YACZ,KAAA,EAAO,UAAA;AAAA,cACL,KAAA,KAAU,KAAA,GAAQ,CAAA,GAAI,GAAA,CAAI,EAAE,CAAA,GAAI,MAAA;AAAA,cAChC,MAAA;AAAA,cACA;AAAA;AACF;AAAA,SAEH;AAAA;AAAA,KACH;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,aAAA,EAAgB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACxC,gBAAA,EAAe,UAAA;AAAA,MACf,KAAA,EAAO,UAAA,CAAW,KAAA,EAAO,MAAA,EAAQ,MAAM,CAAA;AAAA,MACtC,GAAG,IAAA;AAAA,MACJ;AAAA;AAAA,GACD;AAEL","file":"chunk-54HM36IQ.js","sourcesContent":["import { type CssLength, type CssSize, pct } from './css-values.js';\n\nexport interface SkeletonProps {\n /** Typed width or intrinsic sizing keyword. Defaults to filling its slot. */\n width?: CssSize;\n /** Typed height or intrinsic sizing keyword. Defaults to a single text line. */\n height?: CssSize;\n /** Typed corner-radius override. Defaults to the small radius token. */\n radius?: CssLength;\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 /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nfunction blockStyle(\n width?: CssSize,\n height?: CssSize,\n radius?: CssLength,\n): 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({\n width,\n height,\n radius,\n lines,\n label,\n className = '',\n slot,\n}: SkeletonProps) {\n const a11y = {\n role: label ? 'img' : undefined,\n 'aria-label': label,\n 'aria-hidden': label ? undefined : ('true' as const),\n };\n if (lines && lines > 1) {\n return (\n <span\n class={`kui-skeleton-lines ${className}`.trim()}\n data-component=\"skeleton\"\n style={width ? `width:${width}` : undefined}\n {...a11y}\n slot={slot}\n >\n {Array.from({ length: lines }, (_, index) => (\n <span\n class=\"kui-skeleton\"\n aria-hidden=\"true\"\n style={blockStyle(\n index === lines - 1 ? pct(60) : undefined,\n height,\n radius,\n )}\n ></span>\n ))}\n </span>\n );\n }\n return (\n <span\n class={`kui-skeleton ${className}`.trim()}\n data-component=\"skeleton\"\n style={blockStyle(width, height, radius)}\n {...a11y}\n slot={slot}\n ></span>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/row.tsx"],"names":[],"mappings":";;;;AAgBA,IAAM,UAAA,GAAqC;AAAA,EACzC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA;AAwBO,SAAS,GAAA,CAAI;AAAA,EAClB,QAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,MAAA;AAAA,EACT,GAAA,GAAM,IAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,IAAA,GAAO,KAAA;AAAA,EACP,UAAA,GAAa,EAAA;AAAA,EACb,aAAA,GAAgB,EAAA;AAAA,EAChB,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAa;AACX,EAAA,MAAM,WAAW,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACnD,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA;AACJ,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,IAAA,IAAQ,MAAA;AACvD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,kBAAkB,QAAQ,CAAA,CAAA;AAAA,IAC1B,SAAA,GAAY,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAA,GAAK;AAAA,GAC/C,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,QAAA,EAAW,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACnC,gBAAA,EAAe,KAAA;AAAA,MACf,cAAA,EAAc,oBAAoB,MAAM,CAAA;AAAA,MACxC,cAAA,EAAc,kBAAkB,MAAM,CAAA;AAAA,MACtC,WAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MAC/B,WAAA,EAAW,OAAO,IAAI,CAAA;AAAA,MACtB,oBAAkB,UAAA,IAAc,MAAA;AAAA,MAChC,uBAAqB,aAAA,IAAiB,MAAA;AAAA,MACtC,KAAA;AAAA,MACA,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-AQSKJ6U6.js","sourcesContent":["import {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n space,\n type UiSpaceName,\n} from './css-values.js';\nimport type { Sides } from './divider-sides.js';\nimport {\n type HorizontalAlignment,\n horizontalAlignment,\n type VerticalAlignment,\n verticalAlignment,\n} from './flex-alignment.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nconst spaceNames: readonly UiSpaceName[] = [\n 'none',\n '2xs',\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n];\n\nexport interface RowProps {\n children?: KerfUiContent;\n /** Horizontal distribution. Defaults to left. */\n hAlign?: HorizontalAlignment;\n /** Vertical alignment and wrapped-line distribution. Defaults to full. */\n vAlign?: VerticalAlignment;\n /** A named UI spacing token or typed CSS length. Defaults to xs. */\n gap?: UiSpaceName | CssLength;\n /** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n /** Allow children to wrap onto additional lines. */\n wrap?: boolean;\n /** Physical sides that receive the standard 17px text inset. */\n textInsets?: Sides;\n /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */\n controlInsets?: Sides;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A horizontal flex row with explicit physical-axis alignment and spacing. */\nexport function Row({\n children,\n hAlign = 'left',\n vAlign = 'full',\n gap = 'xs',\n flex = false,\n wrap = false,\n textInsets = '',\n controlInsets = '',\n className = '',\n slot,\n}: RowProps) {\n const gapValue = spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n `--_kui-row-gap:${gapValue}`,\n flexValue ? `--_kui-row-flex:${flexValue}` : '',\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n class={`kui-row ${className}`.trim()}\n data-component=\"row\"\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-flex={String(Boolean(flex))}\n data-wrap={String(wrap)}\n data-text-insets={textInsets || undefined}\n data-control-insets={controlInsets || undefined}\n style={style}\n slot={slot}\n >\n {children}\n </div>\n );\n}\n\nexport type {\n CssFlex,\n CssFlexKeyword,\n CssLength,\n UiSpaceName,\n} from './css-values.js';\nexport type { Sides } from './divider-sides.js';\nexport type {\n HorizontalAlignment,\n VerticalAlignment,\n} from './flex-alignment.js';\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app-tab.tsx"],"names":[],"mappings":"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","file":"chunk-COUPLRZG.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { em } from './css-values.js';\nimport { filterDataAttributes } from './extension-attributes.js';\nimport type { KerfUiContent } from './semantic-content.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 type AppTabPresentation = 'pill' | 'segmented' | 'icon-only';\nexport type AppTabSize = 'default' | 'compact';\n\nexport interface AppTabProps {\n id: string;\n name: string;\n selected?: boolean;\n closable?: boolean;\n draggable?: boolean;\n leading?: KerfUiContent;\n trailing?: KerfUiContent;\n /** Visual treatment within a TabBar. Icon-only tabs retain `name` as their accessible name. */\n presentation?: AppTabPresentation;\n /** Compact tabs use the 32px application-rail height. */\n size?: AppTabSize;\n /** Maximum visible label width in CSS pixels before ellipsis. */\n labelMaxWidth?: number;\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 /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nfunction CloseIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.25\"\n stroke-linecap=\"round\"\n >\n <path d=\"m7 7 10 10\"></path>\n <path d=\"M17 7 7 17\"></path>\n </svg>\n );\n}\n\nexport function AppTab({\n id,\n name,\n selected = false,\n closable = true,\n draggable = false,\n leading,\n trailing,\n presentation = 'pill',\n size = 'default',\n labelMaxWidth,\n closeIcon,\n selectAction = 'select-tab',\n closeAction = 'close-tab',\n className = '',\n placeholder = false,\n rootAttributes = {},\n slot,\n}: AppTabProps) {\n const keyshortcuts = [\n closable ? 'Delete Backspace' : '',\n draggable ? 'Alt+Shift+ArrowLeft Alt+Shift+ArrowRight' : '',\n ]\n .filter(Boolean)\n .join(' ');\n const extensionAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n return (\n <div\n {...extensionAttributes}\n class={`kui-app-tab ${className}`.trim()}\n data-component=\"app-tab\"\n data-tab-id={id}\n data-selected={String(selected)}\n data-presentation={presentation}\n data-size={size}\n data-placeholder={placeholder ? 'true' : undefined}\n draggable={placeholder ? 'false' : draggable ? 'true' : 'false'}\n aria-busy={placeholder ? 'true' : undefined}\n style={\n labelMaxWidth === undefined\n ? undefined\n : `--kui-app-tab-label-max-width:${labelMaxWidth}px`\n }\n slot={slot}\n >\n {closable && (\n <button\n type=\"button\"\n tabindex=\"-1\"\n class=\"kui-app-tab__close\"\n data-action={placeholder ? undefined : closeAction}\n data-tab-id={id}\n disabled={placeholder || undefined}\n aria-label={`Close ${name}`}\n title={`Close ${name}`}\n >\n <span class=\"kui-app-tab__close-icon\" aria-hidden=\"true\">\n {closeIcon ?? <CloseIcon />}\n </span>\n </button>\n )}\n <button\n type=\"button\"\n class=\"kui-app-tab__select\"\n role=\"tab\"\n aria-selected={String(selected)}\n aria-label={presentation === 'icon-only' ? name : undefined}\n aria-keyshortcuts={placeholder ? undefined : keyshortcuts || undefined}\n data-action={placeholder ? undefined : selectAction}\n data-tab-id={id}\n disabled={placeholder || undefined}\n tabindex={placeholder ? '-1' : selected ? '0' : '-1'}\n >\n {leading}\n <span\n class=\"kui-app-tab__name\"\n aria-hidden={presentation === 'icon-only' ? 'true' : undefined}\n >\n {placeholder ? <Skeleton width={em(7)} /> : name}\n </span>\n {closable || trailing ? (\n <span class=\"kui-app-tab__trailing\">{trailing}</span>\n ) : undefined}\n </button>\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/grid.tsx"],"names":[],"mappings":";;;AASA,IAAM,UAAA,GAAqC;AAAA,EACzC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA;AAgBO,SAAS,IAAA,CAAK;AAAA,EACnB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA,GAAM,IAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAc;AACZ,EAAA,IAAI,CAAC,MAAA,CAAO,aAAA,CAAc,OAAO,CAAA,IAAK,UAAU,CAAA,EAAG;AACjD,IAAA,MAAM,IAAI,WAAW,8CAA8C,CAAA;AAAA,EACrE;AAEA,EAAA,MAAM,WAAW,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACnD,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA;AACJ,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,IAAA,IAAQ,MAAA;AACvD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,uBAAuB,OAAO,CAAA,CAAA;AAAA,IAC9B,mBAAmB,QAAQ,CAAA,CAAA;AAAA,IAC3B,SAAA,GAAY,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,GAAK;AAAA,GAChD,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,SAAA,EAAY,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACpC,gBAAA,EAAe,MAAA;AAAA,MACf,cAAA,EAAc,OAAO,OAAO,CAAA;AAAA,MAC5B,WAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MAC/B,KAAA;AAAA,MACA,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-ELRMBQEC.js","sourcesContent":["import {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n space,\n type UiSpaceName,\n} from './css-values.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nconst spaceNames: readonly UiSpaceName[] = [\n 'none',\n '2xs',\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n];\n\nexport interface GridProps {\n children?: KerfUiContent;\n /** Number of equal-width columns. Must be a positive safe integer. */\n columns: number;\n /** A named UI spacing token or typed CSS length. Defaults to xs. */\n gap?: UiSpaceName | CssLength;\n /** Allow this grid to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A fixed-count grid whose columns share the available width equally. */\nexport function Grid({\n children,\n columns,\n gap = 'xs',\n flex = false,\n className = '',\n slot,\n}: GridProps) {\n if (!Number.isSafeInteger(columns) || columns < 1) {\n throw new RangeError('Grid columns must be a positive safe integer');\n }\n\n const gapValue = spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n `--_kui-grid-columns:${columns}`,\n `--_kui-grid-gap:${gapValue}`,\n flexValue ? `--_kui-grid-flex:${flexValue}` : '',\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n class={`kui-grid ${className}`.trim()}\n data-component=\"grid\"\n data-columns={String(columns)}\n data-flex={String(Boolean(flex))}\n style={style}\n slot={slot}\n >\n {children}\n </div>\n );\n}\n\nexport type {\n CssFlex,\n CssFlexKeyword,\n CssLength,\n UiSpaceName,\n} from './css-values.js';\n"]}
|