@kerfjs/ui 5.0.0-beta.49 → 5.0.0-beta.51
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 +69 -15
- package/ai/catalog-authoring.json +12 -1
- package/ai/catalog-authoring.schema.json +49 -1
- package/ai/compile-time-contracts-v1.json +19 -2
- package/ai/compile-time-contracts-v1.schema.json +1 -0
- package/ai/component-catalog-v2-overrides.json +7 -0
- package/ai/component-catalog-v2.d.ts +19 -1
- package/ai/component-catalog-v2.json +920 -149
- package/ai/component-catalog-v2.schema.json +33 -1
- package/ai/component-catalog.json +689 -153
- package/ai/component-catalog.schema.json +21 -1
- package/ai/public-api-signatures-v1.md +404 -184
- package/ai/skill.md +31 -14
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/index.mjs +105 -35
- package/dist/app-tab.d.ts +3 -1
- package/dist/app-tab.js +1 -1
- package/dist/badge.d.ts +24 -0
- package/dist/badge.js +3 -0
- package/dist/badge.js.map +1 -0
- package/dist/browser/badge.js +3 -0
- package/dist/browser/list-header.js +1 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +47 -125
- package/dist/catalog.js +429 -262
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-W2FK7ZNY.js → chunk-4R777DUZ.js} +10 -2
- package/dist/chunk-4R777DUZ.js.map +1 -0
- package/dist/{chunk-OMSRSL3B.js → chunk-5FZZMIMD.js} +6 -4
- package/dist/chunk-5FZZMIMD.js.map +1 -0
- package/dist/{chunk-AQFWBG23.js → chunk-5PMGQDG7.js} +5 -3
- package/dist/chunk-5PMGQDG7.js.map +1 -0
- package/dist/{chunk-SOK5EUF7.js → chunk-6ZXOQEAN.js} +4 -2
- package/dist/chunk-6ZXOQEAN.js.map +1 -0
- package/dist/{chunk-I4V3UDSA.js → chunk-7GUQYHKA.js} +25 -6
- package/dist/chunk-7GUQYHKA.js.map +1 -0
- package/dist/{chunk-XKFRMGMW.js → chunk-7IUSV4XG.js} +3 -1
- package/dist/chunk-7IUSV4XG.js.map +1 -0
- package/dist/{chunk-IU4QUY5I.js → chunk-AEPXGCNF.js} +20 -3
- package/dist/chunk-AEPXGCNF.js.map +1 -0
- package/dist/{chunk-VDUJZF5G.js → chunk-CMUIXJZM.js} +2 -2
- package/dist/{chunk-VDUJZF5G.js.map → chunk-CMUIXJZM.js.map} +1 -1
- package/dist/{chunk-DAO2VFTT.js → chunk-D547PH4L.js} +7 -5
- package/dist/chunk-D547PH4L.js.map +1 -0
- package/dist/{chunk-2TYUFZUC.js → chunk-D7GWXIAS.js} +4 -2
- package/dist/chunk-D7GWXIAS.js.map +1 -0
- package/dist/{chunk-E34TE2ZI.js → chunk-DVZCMMB3.js} +6 -4
- package/dist/chunk-DVZCMMB3.js.map +1 -0
- package/dist/{chunk-6NDBE2OK.js → chunk-E36EVCKG.js} +5 -3
- package/dist/chunk-E36EVCKG.js.map +1 -0
- package/dist/chunk-EKYZCRCX.js +256 -0
- package/dist/chunk-EKYZCRCX.js.map +1 -0
- package/dist/{chunk-TIGSG6BX.js → chunk-HJKRCKDR.js} +7 -3
- package/dist/chunk-HJKRCKDR.js.map +1 -0
- package/dist/{chunk-Y6LYKFXY.js → chunk-HMQ2ZDGG.js} +5 -3
- package/dist/chunk-HMQ2ZDGG.js.map +1 -0
- package/dist/{chunk-UDHHKZWO.js → chunk-JM53SMVF.js} +9 -5
- package/dist/chunk-JM53SMVF.js.map +1 -0
- package/dist/{chunk-OGTJNHRG.js → chunk-JMGKM7RK.js} +6 -4
- package/dist/chunk-JMGKM7RK.js.map +1 -0
- package/dist/{chunk-GYGM363P.js → chunk-KX7DP2GO.js} +17 -7
- package/dist/chunk-KX7DP2GO.js.map +1 -0
- package/dist/{chunk-OL4TC3U2.js → chunk-MO56ZZLG.js} +6 -2
- package/dist/chunk-MO56ZZLG.js.map +1 -0
- package/dist/{chunk-VXFGMDA7.js → chunk-MTM43SJO.js} +16 -2
- package/dist/chunk-MTM43SJO.js.map +1 -0
- package/dist/{chunk-ZPWZIVI6.js → chunk-N3GKMPDW.js} +7 -3
- package/dist/chunk-N3GKMPDW.js.map +1 -0
- package/dist/{chunk-DYBPI5O2.js → chunk-NDUGJ4TU.js} +4 -2
- package/dist/chunk-NDUGJ4TU.js.map +1 -0
- package/dist/{chunk-I45QO2IZ.js → chunk-NMGTHYW3.js} +7 -5
- package/dist/chunk-NMGTHYW3.js.map +1 -0
- package/dist/{chunk-WSXUPSID.js → chunk-NN6GYOA2.js} +7 -3
- package/dist/chunk-NN6GYOA2.js.map +1 -0
- package/dist/{chunk-OGNE3OFT.js → chunk-NZXWU4R5.js} +24 -3
- package/dist/chunk-NZXWU4R5.js.map +1 -0
- package/dist/{chunk-V6GQKOX2.js → chunk-O3RCCSQJ.js} +6 -4
- package/dist/chunk-O3RCCSQJ.js.map +1 -0
- package/dist/{chunk-WVLMZ5SG.js → chunk-S4QRSBFI.js} +25 -3
- package/dist/chunk-S4QRSBFI.js.map +1 -0
- package/dist/{chunk-CK6P5AUK.js → chunk-UBH743HV.js} +10 -7
- package/dist/chunk-UBH743HV.js.map +1 -0
- package/dist/{chunk-T7DOWS6T.js → chunk-ULCDZTWL.js} +7 -4
- package/dist/chunk-ULCDZTWL.js.map +1 -0
- package/dist/{chunk-V6HCTCVD.js → chunk-UPZ6EEJN.js} +9 -5
- package/dist/chunk-UPZ6EEJN.js.map +1 -0
- package/dist/{chunk-CAB6NQ2T.js → chunk-VOCPXGQN.js} +3 -1
- package/dist/chunk-VOCPXGQN.js.map +1 -0
- package/dist/chunk-XD7DWYXG.js +34 -0
- package/dist/chunk-XD7DWYXG.js.map +1 -0
- package/dist/{chunk-B6JYRX3P.js → chunk-ZIYOJFZD.js} +43 -4
- package/dist/chunk-ZIYOJFZD.js.map +1 -0
- package/dist/{chunk-EYALJQQD.js → chunk-ZK5EGVFP.js} +4 -2
- package/dist/chunk-ZK5EGVFP.js.map +1 -0
- package/dist/{chunk-6WTETUZ6.js → chunk-ZLWQZUGF.js} +8 -2
- package/dist/chunk-ZLWQZUGF.js.map +1 -0
- package/dist/collapsible-panel.d.ts +4 -2
- package/dist/collapsible-panel.js +4 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/css-values.d.ts +39 -3
- package/dist/css-values.js +1 -1
- package/dist/disclosure-arrow.d.ts +3 -1
- package/dist/disclosure-arrow.js +1 -1
- package/dist/empty-state.d.ts +3 -1
- package/dist/empty-state.js +1 -1
- package/dist/floating-toolbar.d.ts +3 -1
- package/dist/floating-toolbar.js +1 -1
- package/dist/grid.d.ts +17 -1
- package/dist/grid.js +2 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +34 -33
- package/dist/list-action-row.d.ts +3 -1
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.d.ts +6 -1
- package/dist/list-header.js +2 -1
- package/dist/list-inset-control.d.ts +3 -1
- package/dist/list-inset-control.js +1 -1
- package/dist/list-inset-text.d.ts +3 -1
- package/dist/list-inset-text.js +1 -1
- package/dist/list-item.d.ts +3 -1
- package/dist/list-item.js +1 -1
- package/dist/list.d.ts +23 -2
- package/dist/list.js +2 -1
- package/dist/loading-spinner.d.ts +3 -1
- package/dist/loading-spinner.js +1 -1
- package/dist/lucide-icon.d.ts +3 -1
- package/dist/lucide-icon.js +1 -1
- package/dist/nav-stack.d.ts +3 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +19 -2
- package/dist/pane.js +1 -1
- package/dist/resizable-region.d.ts +5 -2
- package/dist/resizable-region.js +1 -1
- package/dist/row.d.ts +21 -1
- package/dist/row.js +2 -1
- package/dist/segmented-control.d.ts +3 -1
- package/dist/segmented-control.js +1 -1
- package/dist/select.d.ts +16 -4
- package/dist/select.js +1 -1
- package/dist/skeleton.d.ts +3 -1
- package/dist/skeleton.js +1 -1
- package/dist/spacer.d.ts +3 -1
- package/dist/spacer.js +1 -1
- package/dist/split-view.d.ts +3 -1
- package/dist/split-view.js +24 -5
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +3 -1
- package/dist/state-banner.js +2 -1
- package/dist/styles/badge.css +86 -0
- package/dist/styles/catalog/components/catalog-detail.css +35 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
- package/dist/styles/catalog/components/catalog-example.css +180 -0
- package/dist/styles/catalog/components/catalog-resource-footer.css +37 -0
- package/dist/styles/catalog/components/catalog-secondary-sections.css +38 -0
- package/dist/styles/catalog/components/catalog-section-list.css +22 -0
- package/dist/styles/catalog/components/catalog-sidebar.css +82 -0
- package/dist/styles/catalog/components/catalog-stage.css +60 -0
- package/dist/styles/catalog/components/catalog.css +22 -0
- package/dist/styles/catalog.css +10 -587
- 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 +49 -60
- 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 +117 -5
- package/dist/styles/row.css +10 -0
- package/dist/styles/select.css +39 -7
- package/dist/styles/split-view.css +108 -2
- package/dist/styles/state-banner.css +0 -27
- package/dist/styles/styles.css +1 -0
- package/dist/styles/tab-bar.css +6 -1
- package/dist/styles/tab-scaffold.css +64 -1
- package/dist/styles/text.css +10 -0
- package/dist/styles/token-search-field.css +5 -40
- package/dist/styles/toolbar-control-group.css +198 -25
- package/dist/styles/toolbar-text.css +8 -1
- package/dist/styles/toolbar.css +169 -5
- package/dist/styles/webawesome.css +70 -9
- package/dist/styles/workbench.css +136 -4
- package/dist/sunken-panel.d.ts +3 -1
- package/dist/sunken-panel.js +1 -1
- package/dist/surface-scaffold.d.ts +6 -2
- package/dist/surface-scaffold.js +1 -1
- package/dist/tab-bar.d.ts +8 -1
- package/dist/tab-bar.js +1 -1
- package/dist/tab-scaffold.d.ts +3 -1
- package/dist/tab-scaffold.js +3 -1
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/text.d.ts +9 -5
- package/dist/text.js +1 -1
- package/dist/token-search-field.d.ts +5 -1
- package/dist/token-search-field.js +1 -1
- package/dist/toolbar-control-group.d.ts +33 -3
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +3 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +30 -1
- package/dist/toolbar.js +1 -1
- package/dist/types-CEsieBZi.d.ts +69 -0
- package/dist/value-table.d.ts +6 -2
- 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 +95 -14
- package/dist/wire-sidebar.js.map +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/workbench.d.ts +3 -1
- package/dist/workbench.js +3 -1
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +56 -9
- package/docs/app-layouts.md +73 -0
- package/docs/catalog.md +48 -9
- package/docs/collapsible-panel.md +81 -8
- package/docs/component-contract.md +96 -28
- package/docs/component-integration.md +9 -4
- package/docs/component-selection.md +36 -15
- 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/design-philosophy.md +6 -5
- package/docs/document-baseline.md +31 -0
- package/docs/layout.md +86 -21
- package/docs/nav-stack.md +8 -0
- package/docs/recipes.md +78 -43
- package/docs/split-view.md +8 -0
- package/docs/tab-scaffold.md +4 -2
- package/docs/type-contracts.md +21 -16
- package/docs/ui-analyzer.md +19 -0
- package/docs/ui-evaluator.md +17 -0
- package/docs/ux-demo.md +8 -8
- package/docs/webawesome-theme.md +25 -6
- package/docs/workbench.md +20 -1
- package/evaluator/index.mjs +73 -8
- package/llms.txt +61 -23
- package/package.json +12 -3
- package/ux-demo/recipes/app-shell.tsx +244 -184
- package/ux-demo/recipes/collapsible-sidebar.tsx +175 -116
- package/ux-demo/recipes/compact-toolbar.tsx +119 -102
- package/ux-demo/recipes/composer-form.tsx +79 -69
- package/ux-demo/recipes/list-detail-dialog.tsx +120 -136
- package/ux-demo/recipes/list-workspace-states.tsx +85 -79
- package/ux-demo/recipes/loaders.ts +5 -2
- package/ux-demo/recipes/loading-inspector.tsx +151 -134
- package/ux-demo/recipes/navigation-sidebar.tsx +93 -80
- package/ux-demo/recipes/navigation-stack.tsx +33 -22
- package/ux-demo/recipes/types.ts +14 -0
- package/ux-demo/recipes/workspace-header.tsx +73 -57
- package/dist/chunk-2TYUFZUC.js.map +0 -1
- package/dist/chunk-6NDBE2OK.js.map +0 -1
- package/dist/chunk-6WTETUZ6.js.map +0 -1
- package/dist/chunk-AQFWBG23.js.map +0 -1
- package/dist/chunk-B6JYRX3P.js.map +0 -1
- package/dist/chunk-CAB6NQ2T.js.map +0 -1
- package/dist/chunk-CK6P5AUK.js.map +0 -1
- package/dist/chunk-DAO2VFTT.js.map +0 -1
- package/dist/chunk-DYBPI5O2.js.map +0 -1
- package/dist/chunk-E34TE2ZI.js.map +0 -1
- package/dist/chunk-EYALJQQD.js.map +0 -1
- package/dist/chunk-GYGM363P.js.map +0 -1
- package/dist/chunk-I45QO2IZ.js.map +0 -1
- package/dist/chunk-I4V3UDSA.js.map +0 -1
- package/dist/chunk-IU4QUY5I.js.map +0 -1
- package/dist/chunk-OGNE3OFT.js.map +0 -1
- package/dist/chunk-OGTJNHRG.js.map +0 -1
- package/dist/chunk-OL4TC3U2.js.map +0 -1
- package/dist/chunk-OMSRSL3B.js.map +0 -1
- package/dist/chunk-SOK5EUF7.js.map +0 -1
- package/dist/chunk-T7DOWS6T.js.map +0 -1
- package/dist/chunk-TIGSG6BX.js.map +0 -1
- package/dist/chunk-UDHHKZWO.js.map +0 -1
- package/dist/chunk-V6GQKOX2.js.map +0 -1
- package/dist/chunk-V6HCTCVD.js.map +0 -1
- package/dist/chunk-VXFGMDA7.js.map +0 -1
- package/dist/chunk-W2FK7ZNY.js.map +0 -1
- package/dist/chunk-WN52USHV.js +0 -115
- package/dist/chunk-WN52USHV.js.map +0 -1
- package/dist/chunk-WSXUPSID.js.map +0 -1
- package/dist/chunk-WVLMZ5SG.js.map +0 -1
- package/dist/chunk-XKFRMGMW.js.map +0 -1
- package/dist/chunk-Y6LYKFXY.js.map +0 -1
- package/dist/chunk-ZPWZIVI6.js.map +0 -1
- package/ux-demo/recipes/recipes.css +0 -453
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
import '@kerfjs/ui/layout.css';
|
|
2
2
|
import '@kerfjs/ui/collapsible-panel.css';
|
|
3
|
-
import './recipes.css';
|
|
4
3
|
|
|
5
4
|
import {
|
|
6
5
|
CollapsiblePanel,
|
|
7
6
|
CollapsiblePanelToggle,
|
|
8
7
|
} from '@kerfjs/ui/collapsible-panel';
|
|
9
8
|
import { deviceClass } from '@kerfjs/ui/device-class';
|
|
9
|
+
import { Grid } from '@kerfjs/ui/grid';
|
|
10
|
+
import { List } from '@kerfjs/ui/list';
|
|
10
11
|
import { ListHeader } from '@kerfjs/ui/list-header';
|
|
11
12
|
import { ListItem } from '@kerfjs/ui/list-item';
|
|
12
13
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
14
|
+
import { Pane } from '@kerfjs/ui/pane';
|
|
15
|
+
import { Row } from '@kerfjs/ui/row';
|
|
13
16
|
import { Text } from '@kerfjs/ui/text';
|
|
14
17
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
15
18
|
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
16
19
|
import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
20
|
+
import { ValueTable, ValueTableRow } from '@kerfjs/ui/value-table';
|
|
17
21
|
import { type SidebarStorage, wireSidebar } from '@kerfjs/ui/wire-sidebar';
|
|
18
22
|
import { signal } from 'kerfjs';
|
|
19
23
|
import { Bell, Folder, Inbox, Users } from 'lucide';
|
|
20
24
|
|
|
21
|
-
import type { RecipeFactory } from './types.js';
|
|
25
|
+
import type { RecipeFactory, RecipePresentation } from './types.js';
|
|
22
26
|
|
|
23
27
|
const RAIL_ACTION = 'recipe-sidebar-rail';
|
|
24
28
|
const DRAWER_ACTION = 'recipe-sidebar-drawer';
|
|
25
29
|
|
|
30
|
+
export const presentation: RecipePresentation = {
|
|
31
|
+
viewport: {
|
|
32
|
+
width: 'full',
|
|
33
|
+
height: 'app',
|
|
34
|
+
frame: 'solid',
|
|
35
|
+
surface: 'default',
|
|
36
|
+
overflow: 'hidden',
|
|
37
|
+
shadow: true,
|
|
38
|
+
},
|
|
39
|
+
note: "The app owns each panel's collapsed signal, sizes, and content; wireSidebar owns the toggle, focus move/restore, the compact overlay, and persistence.",
|
|
40
|
+
};
|
|
41
|
+
|
|
26
42
|
/**
|
|
27
43
|
* A memory-backed store so the recipe demonstrates the persistence hook without
|
|
28
44
|
* writing to the shared `localStorage` the catalog page runs in.
|
|
@@ -37,23 +53,31 @@ function memoryStorage(): SidebarStorage {
|
|
|
37
53
|
};
|
|
38
54
|
}
|
|
39
55
|
|
|
56
|
+
const labels: Record<string, string> = {
|
|
57
|
+
inbox: 'Inbox',
|
|
58
|
+
projects: 'Projects',
|
|
59
|
+
shared: 'Shared with me',
|
|
60
|
+
};
|
|
61
|
+
|
|
40
62
|
export const createRecipe: RecipeFactory = (announce) => {
|
|
41
63
|
const selected = signal('inbox');
|
|
42
|
-
const railCollapsed = signal(false);
|
|
43
|
-
const drawerCollapsed = signal(true);
|
|
44
|
-
const storage = memoryStorage();
|
|
45
64
|
// A shared window-backed device class: when the viewport is compact the wire
|
|
46
65
|
// switches the rail/drawer to a dismissable overlay presentation.
|
|
47
66
|
const device = deviceClass();
|
|
67
|
+
// A compact overlay only opens on a user action, so the first render already
|
|
68
|
+
// matches: collapsed on a compact device, open inline otherwise. The wire's
|
|
69
|
+
// `inlineCollapsed` keeps the open inline default for a later wide crossing.
|
|
70
|
+
const railCollapsed = signal(device.value.compact);
|
|
71
|
+
const drawerCollapsed = signal(true);
|
|
72
|
+
const storage = memoryStorage();
|
|
48
73
|
|
|
49
|
-
const railToggle = (
|
|
74
|
+
const railToggle = () => (
|
|
50
75
|
<CollapsiblePanelToggle
|
|
51
76
|
side="left"
|
|
52
77
|
collapsed={railCollapsed.value}
|
|
53
78
|
action={RAIL_ACTION}
|
|
54
79
|
panelId="sidebar-rail"
|
|
55
80
|
label={railCollapsed.value ? 'Show navigation' : 'Hide navigation'}
|
|
56
|
-
className={inPanel ? '' : 'recipe-collapsible-sidebar__reveal'}
|
|
57
81
|
/>
|
|
58
82
|
);
|
|
59
83
|
const drawerToggle = () => (
|
|
@@ -66,133 +90,167 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
66
90
|
/>
|
|
67
91
|
);
|
|
68
92
|
|
|
69
|
-
const
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
93
|
+
const rail = () => (
|
|
94
|
+
<CollapsiblePanel
|
|
95
|
+
id="sidebar-rail"
|
|
96
|
+
side="left"
|
|
97
|
+
size={232}
|
|
98
|
+
collapsed={railCollapsed.value}
|
|
99
|
+
label="Workspace navigation"
|
|
75
100
|
>
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
101
|
+
<Pane
|
|
102
|
+
contentElement="nav"
|
|
103
|
+
contentLabel="Workspace"
|
|
104
|
+
header={
|
|
105
|
+
<Toolbar
|
|
106
|
+
label="Workspace navigation"
|
|
107
|
+
dividerSides=""
|
|
108
|
+
leading={<ToolbarText text="Atlas" />}
|
|
109
|
+
trailing={
|
|
110
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
111
|
+
{railToggle()}
|
|
112
|
+
</ToolbarControlGroup>
|
|
113
|
+
}
|
|
114
|
+
/>
|
|
115
|
+
}
|
|
83
116
|
>
|
|
84
|
-
<
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
</CollapsiblePanel>
|
|
121
|
-
<main class="recipe-collapsible-sidebar__main kui-pane">
|
|
117
|
+
<section>
|
|
118
|
+
<ListHeader label="Workspace" />
|
|
119
|
+
<ListItem
|
|
120
|
+
action="recipe-action"
|
|
121
|
+
itemId="inbox"
|
|
122
|
+
label="Inbox"
|
|
123
|
+
icon={<LucideIcon icon={Inbox} name="inbox" />}
|
|
124
|
+
trailing={<span>12</span>}
|
|
125
|
+
selected={selected.value === 'inbox'}
|
|
126
|
+
/>
|
|
127
|
+
<ListItem
|
|
128
|
+
action="recipe-action"
|
|
129
|
+
itemId="projects"
|
|
130
|
+
label="Projects"
|
|
131
|
+
icon={<LucideIcon icon={Folder} name="folder" />}
|
|
132
|
+
selected={selected.value === 'projects'}
|
|
133
|
+
/>
|
|
134
|
+
<ListItem
|
|
135
|
+
action="recipe-action"
|
|
136
|
+
itemId="shared"
|
|
137
|
+
label="Shared with me"
|
|
138
|
+
icon={<LucideIcon icon={Users} name="users" />}
|
|
139
|
+
selected={selected.value === 'shared'}
|
|
140
|
+
/>
|
|
141
|
+
</section>
|
|
142
|
+
</Pane>
|
|
143
|
+
</CollapsiblePanel>
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// Each panel's own header holds its collapse toggle; the always-visible main
|
|
147
|
+
// header holds its expand toggle only while it is collapsed, so exactly one
|
|
148
|
+
// control owns each action. wireSidebar hands focus between them.
|
|
149
|
+
const main = () => (
|
|
150
|
+
<Pane
|
|
151
|
+
element="main"
|
|
152
|
+
header={
|
|
122
153
|
<Toolbar
|
|
123
154
|
label="Current navigation view"
|
|
124
155
|
dividerSides=""
|
|
125
156
|
leading={
|
|
126
157
|
<>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
158
|
+
{railCollapsed.value ? (
|
|
159
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
160
|
+
{railToggle()}
|
|
161
|
+
</ToolbarControlGroup>
|
|
162
|
+
) : null}
|
|
130
163
|
<ToolbarText
|
|
131
|
-
text={
|
|
132
|
-
selected.value === 'projects'
|
|
133
|
-
? 'Projects'
|
|
134
|
-
: selected.value === 'shared'
|
|
135
|
-
? 'Shared with me'
|
|
136
|
-
: 'Inbox'
|
|
137
|
-
}
|
|
164
|
+
text={labels[selected.value] ?? 'Inbox'}
|
|
138
165
|
size="xlarge"
|
|
139
166
|
id="recipe-collapsible-main-title"
|
|
140
167
|
/>
|
|
141
168
|
</>
|
|
142
169
|
}
|
|
143
170
|
trailing={
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
171
|
+
drawerCollapsed.value ? (
|
|
172
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
173
|
+
{drawerToggle()}
|
|
174
|
+
</ToolbarControlGroup>
|
|
175
|
+
) : undefined
|
|
147
176
|
}
|
|
148
177
|
/>
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
</Text>
|
|
155
|
-
<article class="recipe-collapsible-sidebar__card kui-content-item">
|
|
178
|
+
}
|
|
179
|
+
>
|
|
180
|
+
<div class="kui-content-item">
|
|
181
|
+
<List gap="2xs">
|
|
182
|
+
<Text variant="span">
|
|
156
183
|
<strong>Narrow the window to a compact width</strong>
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
</
|
|
162
|
-
</
|
|
163
|
-
</
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
184
|
+
</Text>
|
|
185
|
+
<Text variant="span" tone="quiet" size="compact">
|
|
186
|
+
The rail and drawer start closed and open as a dismissable overlay:
|
|
187
|
+
a backdrop, Escape, and a trapped Tab ring, all managed by the wire.
|
|
188
|
+
</Text>
|
|
189
|
+
</List>
|
|
190
|
+
</div>
|
|
191
|
+
</Pane>
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
const drawer = () => (
|
|
195
|
+
<CollapsiblePanel
|
|
196
|
+
id="sidebar-console"
|
|
197
|
+
side="bottom"
|
|
198
|
+
size={168}
|
|
199
|
+
collapsed={drawerCollapsed.value}
|
|
200
|
+
label="Activity"
|
|
201
|
+
>
|
|
202
|
+
<Pane
|
|
203
|
+
header={
|
|
204
|
+
<Toolbar
|
|
205
|
+
label="Activity"
|
|
206
|
+
dividerSides="b"
|
|
207
|
+
leading={<ToolbarText text="Activity" size="small" />}
|
|
208
|
+
trailing={
|
|
209
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
210
|
+
{drawerToggle()}
|
|
211
|
+
</ToolbarControlGroup>
|
|
212
|
+
}
|
|
213
|
+
/>
|
|
214
|
+
}
|
|
171
215
|
>
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
216
|
+
<ValueTable label="Recent activity">
|
|
217
|
+
<ValueTableRow
|
|
218
|
+
label="Deploy finished"
|
|
219
|
+
value="2m ago"
|
|
220
|
+
icon={<LucideIcon icon={Bell} name="bell" />}
|
|
221
|
+
/>
|
|
222
|
+
<ValueTableRow
|
|
223
|
+
label="Review requested"
|
|
224
|
+
value="9m ago"
|
|
225
|
+
icon={<LucideIcon icon={Bell} name="bell" />}
|
|
226
|
+
/>
|
|
227
|
+
</ValueTable>
|
|
228
|
+
</Pane>
|
|
229
|
+
</CollapsiblePanel>
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// The root Row fills the frame's definite height with the rail beside a
|
|
233
|
+
// column whose main pane grows above the bottom drawer. Each CollapsiblePanel
|
|
234
|
+
// docks to a real frame edge, so it paints through that edge's safe area and
|
|
235
|
+
// hands the edge back to its siblings when it collapses.
|
|
236
|
+
const render = () => (
|
|
237
|
+
<Row
|
|
238
|
+
gap="none"
|
|
239
|
+
fill
|
|
240
|
+
rootAttributes={{
|
|
241
|
+
'data-recipe': 'recipe-collapsible-sidebar',
|
|
242
|
+
'data-rail-collapsed': String(railCollapsed.value),
|
|
243
|
+
'data-drawer-collapsed': String(drawerCollapsed.value),
|
|
244
|
+
}}
|
|
245
|
+
>
|
|
246
|
+
{rail()}
|
|
247
|
+
<List flex>
|
|
248
|
+
<Grid columns={1} gap="none" flex>
|
|
249
|
+
{main()}
|
|
250
|
+
</Grid>
|
|
251
|
+
{drawer()}
|
|
252
|
+
</List>
|
|
253
|
+
</Row>
|
|
196
254
|
);
|
|
197
255
|
|
|
198
256
|
return {
|
|
@@ -216,6 +274,7 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
216
274
|
collapsed: railCollapsed,
|
|
217
275
|
toggleAction: RAIL_ACTION,
|
|
218
276
|
storageKey: 'recipe-sidebar-rail',
|
|
277
|
+
inlineCollapsed: false,
|
|
219
278
|
},
|
|
220
279
|
{
|
|
221
280
|
id: 'sidebar-console',
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import '@kerfjs/ui/layout.css';
|
|
2
2
|
import '@kerfjs/ui/select/register';
|
|
3
|
-
import './recipes.css';
|
|
4
3
|
|
|
4
|
+
import { deviceClass } from '@kerfjs/ui/device-class';
|
|
5
|
+
import { Grid } from '@kerfjs/ui/grid';
|
|
6
|
+
import { List } from '@kerfjs/ui/list';
|
|
7
|
+
import { ListInsetText } from '@kerfjs/ui/list-inset-text';
|
|
5
8
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
6
9
|
import { SegmentedControl } from '@kerfjs/ui/segmented-control';
|
|
7
10
|
import { Select } from '@kerfjs/ui/select';
|
|
@@ -12,114 +15,128 @@ import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
|
12
15
|
import { signal } from 'kerfjs';
|
|
13
16
|
import { Filter, MoreHorizontal, RefreshCw } from 'lucide';
|
|
14
17
|
|
|
15
|
-
import type { RecipeFactory } from './types.js';
|
|
18
|
+
import type { RecipeFactory, RecipePresentation } from './types.js';
|
|
19
|
+
|
|
20
|
+
const guide = [
|
|
21
|
+
['ToolbarControlGroup', 'Related commands or pressed tools.'],
|
|
22
|
+
['SegmentedControl', 'A few visible exclusive choices.'],
|
|
23
|
+
['Select', 'A longer controlled value list.'],
|
|
24
|
+
['Ordinary button', 'One independent command.'],
|
|
25
|
+
] as const;
|
|
26
|
+
|
|
27
|
+
export const presentation: RecipePresentation = {
|
|
28
|
+
viewport: {
|
|
29
|
+
width: 'full',
|
|
30
|
+
frame: 'solid',
|
|
31
|
+
surface: 'default',
|
|
32
|
+
overflow: 'hidden',
|
|
33
|
+
shadow: true,
|
|
34
|
+
},
|
|
35
|
+
note: 'The recipe owns control semantics and wrapping. The app owns values, actions, persistence, and responsive priority.',
|
|
36
|
+
};
|
|
16
37
|
|
|
17
38
|
export const createRecipe: RecipeFactory = (announce) => {
|
|
18
39
|
const view = signal('list');
|
|
19
40
|
const sort = signal('updated');
|
|
20
41
|
const filtered = signal(false);
|
|
42
|
+
const device = deviceClass();
|
|
21
43
|
const render = () => (
|
|
22
|
-
<section
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{ value: 'board', label: 'Board' },
|
|
46
|
-
{ value: 'timeline', label: 'Timeline' },
|
|
47
|
-
]}
|
|
48
|
-
/>
|
|
49
|
-
</ToolbarControlGroup>
|
|
50
|
-
}
|
|
51
|
-
trailing={
|
|
52
|
-
<div class="kui-control-cluster">
|
|
53
|
-
<Select<string>
|
|
54
|
-
name="recipe-sort"
|
|
55
|
-
value={sort.value}
|
|
56
|
-
ariaLabel="Sort tasks"
|
|
57
|
-
fitMenu
|
|
58
|
-
choices={[
|
|
59
|
-
{ value: 'updated', label: 'Recently updated' },
|
|
60
|
-
{ value: 'priority', label: 'Priority' },
|
|
61
|
-
{ value: 'owner', label: 'Owner' },
|
|
62
|
-
{ value: 'created', label: 'Created date' },
|
|
63
|
-
]}
|
|
64
|
-
/>
|
|
65
|
-
<ToolbarControlGroup label="Task actions" buttonAppearance="push">
|
|
66
|
-
<button
|
|
67
|
-
type="button"
|
|
68
|
-
aria-label="Toggle filters"
|
|
69
|
-
aria-pressed={String(filtered.value)}
|
|
70
|
-
data-action="recipe-action"
|
|
71
|
-
data-recipe-command="filter"
|
|
72
|
-
>
|
|
73
|
-
<LucideIcon icon={Filter} name="filter" />
|
|
74
|
-
</button>
|
|
75
|
-
<button
|
|
76
|
-
type="button"
|
|
77
|
-
aria-label="Refresh tasks"
|
|
78
|
-
data-action="recipe-action"
|
|
79
|
-
data-recipe-command="refresh"
|
|
80
|
-
>
|
|
81
|
-
<LucideIcon icon={RefreshCw} name="refresh-cw" />
|
|
82
|
-
</button>
|
|
83
|
-
</ToolbarControlGroup>
|
|
84
|
-
<ToolbarControlGroup label="More task actions" single>
|
|
85
|
-
<button
|
|
86
|
-
type="button"
|
|
87
|
-
aria-label="More task actions"
|
|
88
|
-
data-action="recipe-action"
|
|
89
|
-
data-recipe-command="more"
|
|
90
|
-
>
|
|
91
|
-
<LucideIcon icon={MoreHorizontal} name="more-horizontal" />
|
|
92
|
-
</button>
|
|
44
|
+
<section data-recipe="recipe-compact-toolbar" aria-label="Task workspace">
|
|
45
|
+
<List gap="l" controlInsets="b">
|
|
46
|
+
<Toolbar
|
|
47
|
+
label="Task workspace controls"
|
|
48
|
+
responsive="stack"
|
|
49
|
+
responsiveAt="compact"
|
|
50
|
+
leading={<ToolbarText text="Tasks" size="small" />}
|
|
51
|
+
center={
|
|
52
|
+
<ToolbarControlGroup>
|
|
53
|
+
<SegmentedControl<string>
|
|
54
|
+
id="recipe-view"
|
|
55
|
+
label="View"
|
|
56
|
+
value={view.value}
|
|
57
|
+
action="recipe-action"
|
|
58
|
+
appearance="toolbar"
|
|
59
|
+
shape="pill"
|
|
60
|
+
size="small"
|
|
61
|
+
choices={[
|
|
62
|
+
{ value: 'list', label: 'List' },
|
|
63
|
+
{ value: 'board', label: 'Board' },
|
|
64
|
+
{ value: 'timeline', label: 'Timeline' },
|
|
65
|
+
]}
|
|
66
|
+
/>
|
|
93
67
|
</ToolbarControlGroup>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
68
|
+
}
|
|
69
|
+
trailing={
|
|
70
|
+
<>
|
|
71
|
+
<ToolbarControlGroup single focusRing="outline">
|
|
72
|
+
<Select<string>
|
|
73
|
+
name="recipe-sort"
|
|
74
|
+
value={sort.value}
|
|
75
|
+
ariaLabel="Sort tasks"
|
|
76
|
+
fitMenu
|
|
77
|
+
presentation="toolbar-borderless"
|
|
78
|
+
size="compact"
|
|
79
|
+
focusRingOwner="group"
|
|
80
|
+
choices={[
|
|
81
|
+
{ value: 'updated', label: 'Recently updated' },
|
|
82
|
+
{ value: 'priority', label: 'Priority' },
|
|
83
|
+
{ value: 'owner', label: 'Owner' },
|
|
84
|
+
{ value: 'created', label: 'Created date' },
|
|
85
|
+
]}
|
|
86
|
+
/>
|
|
87
|
+
</ToolbarControlGroup>
|
|
88
|
+
<ToolbarControlGroup label="Task actions" buttonAppearance="push">
|
|
89
|
+
<button
|
|
90
|
+
type="button"
|
|
91
|
+
aria-label="Toggle filters"
|
|
92
|
+
aria-pressed={String(filtered.value)}
|
|
93
|
+
data-action="recipe-action"
|
|
94
|
+
data-recipe-command="filter"
|
|
95
|
+
>
|
|
96
|
+
<LucideIcon icon={Filter} name="filter" />
|
|
97
|
+
</button>
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
aria-label="Refresh tasks"
|
|
101
|
+
data-action="recipe-action"
|
|
102
|
+
data-recipe-command="refresh"
|
|
103
|
+
>
|
|
104
|
+
<LucideIcon icon={RefreshCw} name="refresh-cw" />
|
|
105
|
+
</button>
|
|
106
|
+
</ToolbarControlGroup>
|
|
107
|
+
<ToolbarControlGroup label="More task actions" single>
|
|
108
|
+
<button
|
|
109
|
+
type="button"
|
|
110
|
+
aria-label="More task actions"
|
|
111
|
+
data-action="recipe-action"
|
|
112
|
+
data-recipe-command="more"
|
|
113
|
+
>
|
|
114
|
+
<LucideIcon icon={MoreHorizontal} name="more-horizontal" />
|
|
115
|
+
</button>
|
|
116
|
+
</ToolbarControlGroup>
|
|
117
|
+
</>
|
|
118
|
+
}
|
|
119
|
+
/>
|
|
120
|
+
<Grid
|
|
121
|
+
columns={
|
|
122
|
+
device.value.compact ? 1 : device.value.atLeast('desktop') ? 4 : 2
|
|
123
|
+
}
|
|
124
|
+
gap="none"
|
|
125
|
+
>
|
|
126
|
+
{guide.map(([name, use]) => (
|
|
127
|
+
<ListInsetText>
|
|
128
|
+
<List gap="2xs">
|
|
129
|
+
<Text variant="span">
|
|
130
|
+
<strong>{name}</strong>
|
|
131
|
+
</Text>
|
|
132
|
+
<Text variant="span" tone="quiet" size="compact">
|
|
133
|
+
{use}
|
|
134
|
+
</Text>
|
|
135
|
+
</List>
|
|
136
|
+
</ListInsetText>
|
|
137
|
+
))}
|
|
138
|
+
</Grid>
|
|
139
|
+
</List>
|
|
123
140
|
</section>
|
|
124
141
|
);
|
|
125
142
|
return {
|