@kerfjs/ui 5.0.0-beta.54 → 5.0.0-beta.56
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 +14 -11
- package/ai/compile-time-contracts-v1.json +2 -2
- package/ai/component-catalog-v2.json +206 -39
- package/ai/component-catalog.json +306 -58
- package/ai/public-api-signatures-v1.md +671 -92
- package/ai/skill.md +43 -38
- package/ai/webawesome-jsx-signatures-v1.md +8 -2
- package/dist/app-tab.js +1 -1
- package/dist/badge.d.ts +35 -7
- package/dist/badge.js +1 -1
- package/dist/browser/content-item.js +3 -0
- package/dist/browser/popup-menu.js +3 -0
- package/dist/browser/select.js +1 -0
- package/dist/catalog-resources.d.ts +12 -1
- package/dist/catalog.d.ts +21 -4
- package/dist/catalog.js +260 -308
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-7IUSV4XG.js → chunk-24PHKUR3.js} +2 -2
- package/dist/chunk-24PHKUR3.js.map +1 -0
- package/dist/{chunk-WZ2GLEY4.js → chunk-2G2ZJQYK.js} +2 -14
- package/dist/chunk-2G2ZJQYK.js.map +1 -0
- package/dist/{chunk-D7GWXIAS.js → chunk-5I7QGQVT.js} +1 -1
- package/dist/chunk-5I7QGQVT.js.map +1 -0
- package/dist/{chunk-HJKRCKDR.js → chunk-63ZWBGE3.js} +6 -3
- package/dist/chunk-63ZWBGE3.js.map +1 -0
- package/dist/{chunk-44IG7PFV.js → chunk-6CINWX2E.js} +3 -3
- package/dist/{chunk-44IG7PFV.js.map → chunk-6CINWX2E.js.map} +1 -1
- package/dist/{chunk-C2FAYFDE.js → chunk-AGXQQFKZ.js} +2 -2
- package/dist/{chunk-C2FAYFDE.js.map → chunk-AGXQQFKZ.js.map} +1 -1
- package/dist/{chunk-ATHXW6RP.js → chunk-AHEG27M7.js} +2 -2
- package/dist/{chunk-ATHXW6RP.js.map → chunk-AHEG27M7.js.map} +1 -1
- package/dist/{chunk-7GUQYHKA.js → chunk-AK67F6QN.js} +4 -1
- package/dist/chunk-AK67F6QN.js.map +1 -0
- package/dist/chunk-BFPBS5Y4.js +250 -0
- package/dist/chunk-BFPBS5Y4.js.map +1 -0
- package/dist/chunk-DG6G5EPF.js +35 -0
- package/dist/chunk-DG6G5EPF.js.map +1 -0
- package/dist/{chunk-MTM43SJO.js → chunk-G33XC2NB.js} +1 -1
- package/dist/chunk-G33XC2NB.js.map +1 -0
- package/dist/{chunk-TZ5IHWB2.js → chunk-K6UNVKDK.js} +3 -3
- package/dist/{chunk-TZ5IHWB2.js.map → chunk-K6UNVKDK.js.map} +1 -1
- package/dist/chunk-KH6VUGHU.js +399 -0
- package/dist/chunk-KH6VUGHU.js.map +1 -0
- package/dist/{chunk-HMQ2ZDGG.js → chunk-KROD7KZK.js} +3 -2
- package/dist/chunk-KROD7KZK.js.map +1 -0
- package/dist/{chunk-5NDQABWK.js → chunk-M7QV3IHH.js} +3 -1
- package/dist/chunk-M7QV3IHH.js.map +1 -0
- package/dist/{chunk-RNZAKSME.js → chunk-MA6Z6EIM.js} +3 -3
- package/dist/{chunk-RNZAKSME.js.map → chunk-MA6Z6EIM.js.map} +1 -1
- package/dist/chunk-MA73TA6D.js +42 -0
- package/dist/chunk-MA73TA6D.js.map +1 -0
- package/dist/{chunk-ZMBU522F.js → chunk-MEY33VWB.js} +2 -2
- package/dist/{chunk-ZMBU522F.js.map → chunk-MEY33VWB.js.map} +1 -1
- package/dist/{chunk-T22EM4ET.js → chunk-MOBRFZH3.js} +81 -31
- package/dist/chunk-MOBRFZH3.js.map +1 -0
- package/dist/chunk-MP2GDBQZ.js +50 -0
- package/dist/chunk-MP2GDBQZ.js.map +1 -0
- package/dist/{chunk-3NBL3OUQ.js → chunk-NAPE7WUS.js} +2 -2
- package/dist/chunk-NAPE7WUS.js.map +1 -0
- package/dist/{chunk-CMUIXJZM.js → chunk-NBYTIVHS.js} +2 -2
- package/dist/{chunk-CMUIXJZM.js.map → chunk-NBYTIVHS.js.map} +1 -1
- package/dist/chunk-O3EXIBEZ.js +114 -0
- package/dist/chunk-O3EXIBEZ.js.map +1 -0
- package/dist/{chunk-KPNTVB7A.js → chunk-PK4N5QTO.js} +8 -7
- package/dist/chunk-PK4N5QTO.js.map +1 -0
- package/dist/chunk-QQOTQTDD.js +415 -0
- package/dist/chunk-QQOTQTDD.js.map +1 -0
- package/dist/{chunk-BJJKFVWW.js → chunk-T4UZTNZ4.js} +5 -5
- package/dist/chunk-T4UZTNZ4.js.map +1 -0
- package/dist/chunk-V65EOWNF.js +83 -0
- package/dist/chunk-V65EOWNF.js.map +1 -0
- package/dist/{chunk-GUIHMIT2.js → chunk-VNPQDCQZ.js} +3 -3
- package/dist/{chunk-GUIHMIT2.js.map → chunk-VNPQDCQZ.js.map} +1 -1
- package/dist/{chunk-5I22LMCV.js → chunk-VZOFZPSO.js} +2 -2
- package/dist/chunk-VZOFZPSO.js.map +1 -0
- package/dist/chunk-WLG6SSNT.js +94 -0
- package/dist/chunk-WLG6SSNT.js.map +1 -0
- package/dist/{chunk-NE5JAOQS.js → chunk-WOUF7YXM.js} +3 -3
- package/dist/{chunk-NE5JAOQS.js.map → chunk-WOUF7YXM.js.map} +1 -1
- package/dist/collapsible-panel.d.ts +51 -13
- package/dist/collapsible-panel.js +38 -10
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/content-item.d.ts +46 -0
- package/dist/content-item.js +4 -0
- package/dist/content-item.js.map +1 -0
- package/dist/css-values.d.ts +5 -11
- package/dist/css-values.js +1 -1
- package/dist/disclosure-arrow.d.ts +4 -1
- package/dist/disclosure-arrow.js +1 -1
- package/dist/floating-toolbar.d.ts +17 -6
- package/dist/floating-toolbar.js +1 -1
- package/dist/grid.js +1 -1
- package/dist/help-tags-register.d.ts +13 -0
- package/dist/help-tags-register.js +9 -0
- package/dist/help-tags-register.js.map +1 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +31 -29
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.d.ts +14 -1
- package/dist/list-header.js +1 -1
- package/dist/list-inset-control.d.ts +1 -1
- package/dist/list-inset-control.js +1 -1
- package/dist/list-inset-text.d.ts +9 -10
- package/dist/list-inset-text.js +2 -1
- package/dist/list-item.js +1 -1
- package/dist/list.d.ts +10 -3
- package/dist/list.js +1 -1
- package/dist/nav-stack.d.ts +38 -5
- package/dist/nav-stack.js +4 -1
- package/dist/pane.d.ts +20 -2
- package/dist/pane.js +1 -1
- package/dist/panel-toolbar-C8sF-YZC.d.ts +63 -0
- package/dist/popup-menu-register.d.ts +9 -0
- package/dist/popup-menu-register.js +31 -0
- package/dist/popup-menu-register.js.map +1 -0
- package/dist/popup-menu.d.ts +71 -0
- package/dist/popup-menu.js +3 -0
- package/dist/popup-menu.js.map +1 -0
- package/dist/row.d.ts +1 -1
- package/dist/row.js +1 -1
- package/dist/select-register.js +70 -3
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +46 -8
- package/dist/select.js +2 -1
- package/dist/{divider-sides-BzB6rphT.d.ts → sides-BPSWde0A.d.ts} +1 -3
- package/dist/skeleton.js +1 -1
- package/dist/spacer.js +1 -1
- package/dist/split-view.d.ts +31 -3
- package/dist/split-view.js +33 -5
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/badge.css +13 -0
- package/dist/styles/catalog/components/catalog-example.css +1 -17
- package/dist/styles/catalog/components/catalog-stage.css +9 -14
- package/dist/styles/catalog/components/catalog.css +8 -18
- package/dist/styles/catalog.css +0 -5
- package/dist/styles/collapsible-panel.css +192 -39
- package/dist/styles/content-item.css +30 -0
- package/dist/styles/floating-toolbar.css +5 -0
- package/dist/styles/foundation.css +28 -19
- package/dist/styles/layout.css +1 -21
- package/dist/styles/list-action-row.css +13 -1
- package/dist/styles/list-inset-text.css +1 -2
- package/dist/styles/list-item.css +14 -1
- package/dist/styles/list.css +1 -1
- package/dist/styles/nav-stack.css +29 -64
- package/dist/styles/pane.css +33 -1
- package/dist/styles/popup-menu.css +90 -0
- package/dist/styles/resizable-region.css +53 -10
- package/dist/styles/select.css +39 -12
- package/dist/styles/split-view.css +21 -25
- package/dist/styles/state-banner.css +13 -4
- package/dist/styles/styles.css +1 -0
- package/dist/styles/tab-bar.css +31 -3
- package/dist/styles/tab-scaffold.css +36 -14
- package/dist/styles/text.css +1 -1
- package/dist/styles/token-search-field.css +4 -4
- package/dist/styles/toolbar-control-group.css +44 -12
- package/dist/styles/toolbar.css +57 -7
- package/dist/styles/value-table.css +19 -2
- package/dist/styles/webawesome.css +3 -1
- package/dist/styles/workbench.css +165 -31
- package/dist/tab-scaffold.d.ts +35 -1
- package/dist/tab-scaffold.js +50 -16
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/text.js +1 -1
- package/dist/token-search-field.d.ts +13 -2
- package/dist/token-search-field.js +1 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +12 -4
- package/dist/toolbar.js +1 -1
- package/dist/{types-CEsieBZi.d.ts → types-DXAGogOS.d.ts} +48 -0
- package/dist/value-table.js +1 -1
- package/dist/webawesome.d.ts +7 -1
- package/dist/wire-catalog.d.ts +24 -1
- package/dist/wire-catalog.js +26 -3
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-sidebar.js +6 -3
- package/dist/wire-sidebar.js.map +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/wire-workbench.js +1 -350
- package/dist/wire-workbench.js.map +1 -1
- package/dist/workbench.d.ts +144 -6
- package/dist/workbench.js +11 -208
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +126 -6
- package/docs/app-layouts.md +9 -7
- package/docs/catalog.md +41 -9
- package/docs/collapsible-panel.md +79 -5
- package/docs/component-contract.md +38 -12
- package/docs/component-selection.md +64 -55
- package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
- package/docs/design/templates/empty-state/with-action.svg +1 -1
- package/docs/design/templates/empty-state-dark.svg +1 -1
- package/docs/design/templates/empty-state.svg +1 -1
- package/docs/design/templates/list/compact-dark.svg +1 -1
- package/docs/design/templates/list/compact.svg +1 -1
- package/docs/design/templates/list/stack-dark.svg +1 -1
- package/docs/design/templates/list/stack.svg +1 -1
- package/docs/design/templates/list-action-row/default-dark.svg +1 -1
- package/docs/design/templates/list-action-row/default.svg +1 -1
- package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
- package/docs/design/templates/list-action-row/selected.svg +1 -1
- package/docs/design/templates/list-action-row-dark.svg +1 -1
- package/docs/design/templates/list-action-row.svg +1 -1
- package/docs/design/templates/list-dark.svg +1 -1
- package/docs/design/templates/list-item/default-dark.svg +1 -1
- package/docs/design/templates/list-item/default.svg +1 -1
- package/docs/design/templates/list-item/selected-dark.svg +1 -1
- package/docs/design/templates/list-item/selected.svg +1 -1
- package/docs/design/templates/list-item/trailing-dark.svg +1 -1
- package/docs/design/templates/list-item/trailing.svg +1 -1
- package/docs/design/templates/list-item-dark.svg +1 -1
- package/docs/design/templates/list-item.svg +1 -1
- package/docs/design/templates/list.svg +1 -1
- package/docs/design/templates/state-banner/danger-dark.svg +1 -1
- package/docs/design/templates/state-banner/danger.svg +1 -1
- package/docs/design/templates/state-banner/info-dark.svg +1 -1
- package/docs/design/templates/state-banner/info.svg +1 -1
- package/docs/design/templates/state-banner/success-dark.svg +1 -1
- package/docs/design/templates/state-banner/success.svg +1 -1
- package/docs/design/templates/state-banner/warning-dark.svg +1 -1
- package/docs/design/templates/state-banner/warning.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/value-table/details-dark.svg +1 -1
- package/docs/design/templates/value-table/details.svg +1 -1
- package/docs/design/templates/value-table-dark.svg +1 -1
- package/docs/design/templates/value-table.svg +1 -1
- package/docs/design-philosophy.md +1 -1
- package/docs/examples/command-palette-adapter.tsx +3 -2
- package/docs/layout.md +74 -29
- package/docs/nav-stack.md +45 -1
- package/docs/recipes.md +48 -40
- package/docs/split-view.md +46 -2
- package/docs/surface-scaffold.md +1 -1
- package/docs/tab-scaffold.md +50 -1
- package/docs/type-contracts.md +17 -17
- package/docs/ux-demo.md +8 -4
- package/docs/webawesome-theme.md +1 -2
- package/docs/workbench.md +131 -10
- package/llms.txt +38 -9
- package/package.json +24 -2
- package/ux-demo/recipes/app-shell.tsx +141 -223
- package/ux-demo/recipes/collapsible-sidebar.tsx +47 -77
- package/ux-demo/recipes/list-detail-dialog.tsx +150 -54
- package/ux-demo/recipes/mount-recipe.ts +0 -5
- package/ux-demo/recipes/navigation-sidebar.tsx +3 -2
- package/ux-demo/recipes/navigation-stack.tsx +3 -2
- package/ux-demo/recipes/types.ts +0 -1
- package/dist/chunk-3NBL3OUQ.js.map +0 -1
- package/dist/chunk-5I22LMCV.js.map +0 -1
- package/dist/chunk-5NDQABWK.js.map +0 -1
- package/dist/chunk-7GUQYHKA.js.map +0 -1
- package/dist/chunk-7IUSV4XG.js.map +0 -1
- package/dist/chunk-BJJKFVWW.js.map +0 -1
- package/dist/chunk-D7GWXIAS.js.map +0 -1
- package/dist/chunk-DQA5FMOX.js +0 -85
- package/dist/chunk-DQA5FMOX.js.map +0 -1
- package/dist/chunk-HJKRCKDR.js.map +0 -1
- package/dist/chunk-HMQ2ZDGG.js.map +0 -1
- package/dist/chunk-KPNTVB7A.js.map +0 -1
- package/dist/chunk-MTM43SJO.js.map +0 -1
- package/dist/chunk-T22EM4ET.js.map +0 -1
- package/dist/chunk-WZ2GLEY4.js.map +0 -1
- package/dist/chunk-XD7DWYXG.js +0 -34
- package/dist/chunk-XD7DWYXG.js.map +0 -1
- package/dist/chunk-ZK5EGVFP.js +0 -27
- package/dist/chunk-ZK5EGVFP.js.map +0 -1
- package/dist/styles/catalog/components/catalog-detail.css +0 -35
- package/dist/styles/catalog/components/catalog-resource-footer.css +0 -37
- package/dist/styles/catalog/components/catalog-secondary-sections.css +0 -38
- package/dist/styles/catalog/components/catalog-section-list.css +0 -22
- package/dist/styles/catalog/components/catalog-sidebar.css +0 -82
|
@@ -1,32 +1,22 @@
|
|
|
1
1
|
import '@kerfjs/ui/layout.css';
|
|
2
|
+
import '@kerfjs/ui/workbench.css';
|
|
2
3
|
|
|
3
|
-
import { deviceClass } from '@kerfjs/ui/device-class';
|
|
4
|
-
import { Grid } from '@kerfjs/ui/grid';
|
|
5
4
|
import { List } from '@kerfjs/ui/list';
|
|
6
|
-
import { ListHeader } from '@kerfjs/ui/list-header';
|
|
7
5
|
import { ListItem } from '@kerfjs/ui/list-item';
|
|
8
6
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
9
|
-
import { Pane, type PaneSeparatorSide } from '@kerfjs/ui/pane';
|
|
10
|
-
import { ResizableRegion } from '@kerfjs/ui/resizable-region';
|
|
11
|
-
import { Row } from '@kerfjs/ui/row';
|
|
12
7
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
13
8
|
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
14
9
|
import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
15
10
|
import { ValueTable, ValueTableRow } from '@kerfjs/ui/value-table';
|
|
16
|
-
import {
|
|
11
|
+
import { wireWorkbench } from '@kerfjs/ui/wire-workbench';
|
|
12
|
+
import { Workbench } from '@kerfjs/ui/workbench';
|
|
13
|
+
import { delegate, signal } from 'kerfjs';
|
|
17
14
|
import { Bell, Folder, Inbox, Settings } from 'lucide';
|
|
18
15
|
|
|
19
16
|
import type { RecipeFactory, RecipePresentation } from './types.js';
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// Safe areas: the app bar claims the top edge and both sides, so it clears the
|
|
25
|
-
// status area. Each pane below compensates only for the screen edges it
|
|
26
|
-
// actually reaches: the bottom, plus its outer side in the three-pane layout or
|
|
27
|
-
// both sides when it is the only pane shown.
|
|
28
|
-
const appBarEdges: ScreenEdges = ['block-start', 'inline-start', 'inline-end'];
|
|
29
|
-
const soleEdges: ScreenEdges = ['block-end', 'inline-start', 'inline-end'];
|
|
18
|
+
const NAVIGATION_ACTION = 'recipe-shell-toggle-navigation';
|
|
19
|
+
const INSPECTOR_ACTION = 'recipe-shell-toggle-inspector';
|
|
30
20
|
|
|
31
21
|
const tasks = [
|
|
32
22
|
['Release accessibility audit', 'Interface systems · due this week'],
|
|
@@ -44,46 +34,19 @@ export const presentation: RecipePresentation = {
|
|
|
44
34
|
overflow: 'hidden',
|
|
45
35
|
shadow: true,
|
|
46
36
|
},
|
|
47
|
-
note: 'The recipe
|
|
37
|
+
note: 'The recipe is a Workbench under an app bar: resizable navigation and inspector rails beside the task list, each rail toggled by its standard control, which moves into the work-area toolbar while the rail is hidden. On a small screen the rails overlay the task list one at a time. The app owns routing, data, rail visibility, sizes, and persistence.',
|
|
48
38
|
};
|
|
49
39
|
|
|
50
40
|
export const createRecipe: RecipeFactory = (announce) => {
|
|
51
41
|
const selected = signal('inbox');
|
|
52
42
|
const navigationSize = signal(224);
|
|
53
43
|
const inspectorSize = signal(240);
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
// at a time and let the toolbar switch between them.
|
|
57
|
-
const device = deviceClass();
|
|
58
|
-
|
|
59
|
-
const paneButton = (
|
|
60
|
-
pane: ShellPane,
|
|
61
|
-
label: string,
|
|
62
|
-
icon: typeof Folder,
|
|
63
|
-
iconName: string,
|
|
64
|
-
) => (
|
|
65
|
-
<button
|
|
66
|
-
type="button"
|
|
67
|
-
aria-label={label}
|
|
68
|
-
aria-controls={`recipe-shell-${pane}`}
|
|
69
|
-
aria-pressed={String(responsivePane.value === pane)}
|
|
70
|
-
data-action="recipe-action"
|
|
71
|
-
data-recipe-command={`show-${pane}`}
|
|
72
|
-
>
|
|
73
|
-
<LucideIcon icon={icon} name={iconName} />
|
|
74
|
-
</button>
|
|
75
|
-
);
|
|
44
|
+
const navigationCollapsed = signal(false);
|
|
45
|
+
const inspectorCollapsed = signal(false);
|
|
76
46
|
|
|
77
|
-
const navigation = (
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
safeAreaEdges={edges}
|
|
81
|
-
id="recipe-shell-navigation"
|
|
82
|
-
contentElement="nav"
|
|
83
|
-
contentLabel="Workspace"
|
|
84
|
-
>
|
|
85
|
-
<section>
|
|
86
|
-
<ListHeader label="Workspace" />
|
|
47
|
+
const navigation = () => (
|
|
48
|
+
<nav aria-label="Workspace">
|
|
49
|
+
<List gap="2xs">
|
|
87
50
|
<ListItem
|
|
88
51
|
action="recipe-action"
|
|
89
52
|
itemId="inbox"
|
|
@@ -99,204 +62,159 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
99
62
|
selected={selected.value === 'projects'}
|
|
100
63
|
multiline
|
|
101
64
|
/>
|
|
102
|
-
</
|
|
103
|
-
</
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
const content = (edges: ScreenEdges) => (
|
|
107
|
-
<Pane
|
|
108
|
-
element="main"
|
|
109
|
-
safeAreaEdges={edges}
|
|
110
|
-
id="recipe-shell-content"
|
|
111
|
-
header={
|
|
112
|
-
<Toolbar
|
|
113
|
-
label="Current workspace view"
|
|
114
|
-
dividerSides=""
|
|
115
|
-
leading={
|
|
116
|
-
<ToolbarText
|
|
117
|
-
text={
|
|
118
|
-
selected.value === 'inbox' ? 'Inbox triage' : 'Active projects'
|
|
119
|
-
}
|
|
120
|
-
size="xlarge"
|
|
121
|
-
id="recipe-shell-main-title"
|
|
122
|
-
/>
|
|
123
|
-
}
|
|
124
|
-
trailing={
|
|
125
|
-
<ToolbarControlGroup appearance="borderless" content="text" single>
|
|
126
|
-
<button
|
|
127
|
-
type="button"
|
|
128
|
-
data-action="recipe-action"
|
|
129
|
-
data-recipe-command="new"
|
|
130
|
-
>
|
|
131
|
-
New task
|
|
132
|
-
</button>
|
|
133
|
-
</ToolbarControlGroup>
|
|
134
|
-
}
|
|
135
|
-
/>
|
|
136
|
-
}
|
|
137
|
-
>
|
|
138
|
-
<section aria-label="Tasks">
|
|
139
|
-
{tasks.map(([title, detail]) => (
|
|
140
|
-
<ListItem
|
|
141
|
-
action="recipe-action"
|
|
142
|
-
label={title}
|
|
143
|
-
description={detail}
|
|
144
|
-
multiline
|
|
145
|
-
rootAttributes={{ 'data-recipe-command': 'open-task' }}
|
|
146
|
-
/>
|
|
147
|
-
))}
|
|
148
|
-
</section>
|
|
149
|
-
</Pane>
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
const inspector = (edges: ScreenEdges) => (
|
|
153
|
-
<Pane
|
|
154
|
-
element="aside"
|
|
155
|
-
safeAreaEdges={edges}
|
|
156
|
-
id="recipe-shell-inspector"
|
|
157
|
-
header={
|
|
158
|
-
<Toolbar
|
|
159
|
-
label="Inspector"
|
|
160
|
-
dividerSides=""
|
|
161
|
-
leading={
|
|
162
|
-
<ToolbarText
|
|
163
|
-
text="Inspector"
|
|
164
|
-
size="xlarge"
|
|
165
|
-
id="recipe-shell-inspector-title"
|
|
166
|
-
/>
|
|
167
|
-
}
|
|
168
|
-
/>
|
|
169
|
-
}
|
|
170
|
-
>
|
|
171
|
-
<ValueTable label="Selected task">
|
|
172
|
-
<ValueTableRow label="Status" value="In review" />
|
|
173
|
-
<ValueTableRow label="Owner" value="Mara Chen" />
|
|
174
|
-
<ValueTableRow label="Priority" value="High" />
|
|
175
|
-
</ValueTable>
|
|
176
|
-
</Pane>
|
|
65
|
+
</List>
|
|
66
|
+
</nav>
|
|
177
67
|
);
|
|
178
68
|
|
|
179
|
-
const render = () =>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
69
|
+
const render = () => (
|
|
70
|
+
<List fill rootAttributes={{ 'data-recipe': 'recipe-app-shell' }}>
|
|
71
|
+
<Toolbar
|
|
72
|
+
label="Atlas workspace"
|
|
73
|
+
safeAreaEdges={['block-start', 'inline-start', 'inline-end']}
|
|
74
|
+
dividerSides="b"
|
|
75
|
+
leading={<ToolbarText text="Atlas" />}
|
|
76
|
+
trailing={
|
|
77
|
+
<ToolbarControlGroup
|
|
78
|
+
appearance="borderless"
|
|
79
|
+
label="Workspace controls"
|
|
80
|
+
>
|
|
81
|
+
<button
|
|
82
|
+
type="button"
|
|
83
|
+
aria-label="Notifications"
|
|
84
|
+
data-action="recipe-action"
|
|
85
|
+
data-recipe-command="notify"
|
|
86
|
+
>
|
|
87
|
+
<LucideIcon icon={Bell} name="bell" />
|
|
88
|
+
</button>
|
|
89
|
+
<button
|
|
90
|
+
type="button"
|
|
91
|
+
aria-label="Settings"
|
|
92
|
+
data-action="recipe-action"
|
|
93
|
+
data-recipe-command="settings"
|
|
94
|
+
>
|
|
95
|
+
<LucideIcon icon={Settings} name="settings" />
|
|
96
|
+
</button>
|
|
97
|
+
</ToolbarControlGroup>
|
|
98
|
+
}
|
|
99
|
+
/>
|
|
100
|
+
<List flex>
|
|
101
|
+
<Workbench
|
|
102
|
+
id="recipe-shell"
|
|
103
|
+
label="Atlas workspace panes"
|
|
104
|
+
leftRail={{
|
|
105
|
+
label: 'Navigation',
|
|
106
|
+
size: navigationSize.value,
|
|
107
|
+
resizable: { min: 180, max: 320 },
|
|
108
|
+
collapsed: navigationCollapsed.value,
|
|
109
|
+
toolbar: {
|
|
110
|
+
label: 'Navigation',
|
|
111
|
+
title: <ToolbarText text="Workspace" />,
|
|
112
|
+
toggle: { action: NAVIGATION_ACTION, name: 'navigation' },
|
|
113
|
+
},
|
|
114
|
+
content: navigation(),
|
|
115
|
+
}}
|
|
116
|
+
mainToolbar={{
|
|
117
|
+
label: 'Current workspace view',
|
|
118
|
+
title: (
|
|
119
|
+
<ToolbarText
|
|
120
|
+
text={
|
|
121
|
+
selected.value === 'inbox'
|
|
122
|
+
? 'Inbox triage'
|
|
123
|
+
: 'Active projects'
|
|
124
|
+
}
|
|
125
|
+
size="xlarge"
|
|
126
|
+
id="recipe-shell-main-title"
|
|
127
|
+
/>
|
|
128
|
+
),
|
|
129
|
+
responsive: 'wrap',
|
|
130
|
+
trailing: (
|
|
216
131
|
<ToolbarControlGroup
|
|
217
132
|
appearance="borderless"
|
|
218
|
-
|
|
133
|
+
content="text"
|
|
134
|
+
single
|
|
219
135
|
>
|
|
220
136
|
<button
|
|
221
137
|
type="button"
|
|
222
|
-
aria-label="Notifications"
|
|
223
138
|
data-action="recipe-action"
|
|
224
|
-
data-recipe-command="
|
|
139
|
+
data-recipe-command="new"
|
|
225
140
|
>
|
|
226
|
-
|
|
227
|
-
</button>
|
|
228
|
-
<button
|
|
229
|
-
type="button"
|
|
230
|
-
aria-label="Settings"
|
|
231
|
-
data-action="recipe-action"
|
|
232
|
-
data-recipe-command="settings"
|
|
233
|
-
>
|
|
234
|
-
<LucideIcon icon={Settings} name="settings" />
|
|
141
|
+
New task
|
|
235
142
|
</button>
|
|
236
143
|
</ToolbarControlGroup>
|
|
237
|
-
|
|
144
|
+
),
|
|
145
|
+
}}
|
|
146
|
+
main={
|
|
147
|
+
<section aria-label="Tasks">
|
|
148
|
+
{tasks.map(([title, detail]) => (
|
|
149
|
+
<ListItem
|
|
150
|
+
action="recipe-action"
|
|
151
|
+
label={title}
|
|
152
|
+
description={detail}
|
|
153
|
+
multiline
|
|
154
|
+
rootAttributes={{ 'data-recipe-command': 'open-task' }}
|
|
155
|
+
/>
|
|
156
|
+
))}
|
|
157
|
+
</section>
|
|
238
158
|
}
|
|
159
|
+
rightRail={{
|
|
160
|
+
label: 'Inspector',
|
|
161
|
+
size: inspectorSize.value,
|
|
162
|
+
resizable: { min: 200, max: 360 },
|
|
163
|
+
collapsed: inspectorCollapsed.value,
|
|
164
|
+
toolbar: {
|
|
165
|
+
label: 'Inspector',
|
|
166
|
+
title: <ToolbarText text="Inspector" />,
|
|
167
|
+
toggle: { action: INSPECTOR_ACTION, name: 'inspector' },
|
|
168
|
+
},
|
|
169
|
+
content: (
|
|
170
|
+
<ValueTable label="Selected task">
|
|
171
|
+
<ValueTableRow label="Status" value="In review" />
|
|
172
|
+
<ValueTableRow label="Owner" value="Mara Chen" />
|
|
173
|
+
<ValueTableRow label="Priority" value="High" />
|
|
174
|
+
</ValueTable>
|
|
175
|
+
),
|
|
176
|
+
}}
|
|
239
177
|
/>
|
|
240
|
-
{onePane ? (
|
|
241
|
-
<Grid columns={1} gap="none" flex>
|
|
242
|
-
{responsivePane.value === 'navigation'
|
|
243
|
-
? navigation(soleEdges)
|
|
244
|
-
: responsivePane.value === 'inspector'
|
|
245
|
-
? inspector(soleEdges)
|
|
246
|
-
: content(soleEdges)}
|
|
247
|
-
</Grid>
|
|
248
|
-
) : (
|
|
249
|
-
<Row gap="none" flex>
|
|
250
|
-
<ResizableRegion
|
|
251
|
-
id="recipe-navigation"
|
|
252
|
-
label="Navigation"
|
|
253
|
-
size={navigationSize.value}
|
|
254
|
-
min={180}
|
|
255
|
-
max={320}
|
|
256
|
-
>
|
|
257
|
-
{navigation(['block-end', 'inline-start'])}
|
|
258
|
-
</ResizableRegion>
|
|
259
|
-
<Grid columns={1} gap="none" flex>
|
|
260
|
-
{content(['block-end'])}
|
|
261
|
-
</Grid>
|
|
262
|
-
<ResizableRegion
|
|
263
|
-
id="recipe-inspector"
|
|
264
|
-
label="Inspector"
|
|
265
|
-
size={inspectorSize.value}
|
|
266
|
-
min={200}
|
|
267
|
-
max={360}
|
|
268
|
-
edge="start"
|
|
269
|
-
>
|
|
270
|
-
{inspector(['block-end', 'inline-end'])}
|
|
271
|
-
</ResizableRegion>
|
|
272
|
-
</Row>
|
|
273
|
-
)}
|
|
274
178
|
</List>
|
|
275
|
-
|
|
276
|
-
|
|
179
|
+
</List>
|
|
180
|
+
);
|
|
181
|
+
|
|
277
182
|
return {
|
|
278
183
|
render,
|
|
279
184
|
action(command, element) {
|
|
280
|
-
const pane = command.match(
|
|
281
|
-
/^show-(navigation|content|inspector)$/,
|
|
282
|
-
)?.[1] as ShellPane | undefined;
|
|
283
|
-
if (pane) responsivePane.value = pane;
|
|
284
185
|
const id = element.dataset.itemId;
|
|
285
186
|
if (id) selected.value = id;
|
|
286
187
|
announce(
|
|
287
188
|
id
|
|
288
189
|
? `Opened ${id}`
|
|
289
|
-
:
|
|
290
|
-
?
|
|
291
|
-
: command
|
|
292
|
-
? 'New task requested'
|
|
293
|
-
: `${command} requested`,
|
|
190
|
+
: command === 'new'
|
|
191
|
+
? 'New task requested'
|
|
192
|
+
: `${command} requested`,
|
|
294
193
|
);
|
|
295
194
|
},
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
195
|
+
wire(root) {
|
|
196
|
+
const toggle = (action: string, collapsed: typeof navigationCollapsed) =>
|
|
197
|
+
delegate(root, 'click', `[data-action="${action}"]`, () => {
|
|
198
|
+
collapsed.value = !collapsed.value;
|
|
199
|
+
});
|
|
200
|
+
const stops = [
|
|
201
|
+
toggle(NAVIGATION_ACTION, navigationCollapsed),
|
|
202
|
+
toggle(INSPECTOR_ACTION, inspectorCollapsed),
|
|
203
|
+
wireWorkbench(root, {
|
|
204
|
+
id: 'recipe-shell',
|
|
205
|
+
panels: {
|
|
206
|
+
leftRail: { size: navigationSize, collapsed: navigationCollapsed },
|
|
207
|
+
rightRail: { size: inspectorSize, collapsed: inspectorCollapsed },
|
|
208
|
+
},
|
|
209
|
+
onResize: ({ panel, size }) =>
|
|
210
|
+
announce(
|
|
211
|
+
`${panel === 'leftRail' ? 'Navigation' : 'Inspector'} resized to ${size}px`,
|
|
212
|
+
),
|
|
213
|
+
}),
|
|
214
|
+
];
|
|
215
|
+
return () => {
|
|
216
|
+
for (const stop of stops) stop();
|
|
217
|
+
};
|
|
300
218
|
},
|
|
301
219
|
};
|
|
302
220
|
};
|
|
@@ -4,8 +4,10 @@ import '@kerfjs/ui/floating-toolbar.css';
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
CollapsiblePanel,
|
|
7
|
-
|
|
7
|
+
CollapsiblePanelRelocated,
|
|
8
|
+
type CollapsiblePanelToolbar,
|
|
8
9
|
} from '@kerfjs/ui/collapsible-panel';
|
|
10
|
+
import { ContentItem } from '@kerfjs/ui/content-item';
|
|
9
11
|
import { deviceClass } from '@kerfjs/ui/device-class';
|
|
10
12
|
import { FloatingToolbar } from '@kerfjs/ui/floating-toolbar';
|
|
11
13
|
import { Grid } from '@kerfjs/ui/grid';
|
|
@@ -17,7 +19,6 @@ import { Pane } from '@kerfjs/ui/pane';
|
|
|
17
19
|
import { Row } from '@kerfjs/ui/row';
|
|
18
20
|
import { Text } from '@kerfjs/ui/text';
|
|
19
21
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
20
|
-
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
21
22
|
import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
22
23
|
import { ValueTable, ValueTableRow } from '@kerfjs/ui/value-table';
|
|
23
24
|
import { type SidebarStorage, wireSidebar } from '@kerfjs/ui/wire-sidebar';
|
|
@@ -73,24 +74,20 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
73
74
|
const drawerCollapsed = signal(true);
|
|
74
75
|
const storage = memoryStorage();
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
panelId="sidebar-console"
|
|
91
|
-
label={drawerCollapsed.value ? 'Show activity' : 'Hide activity'}
|
|
92
|
-
/>
|
|
93
|
-
);
|
|
77
|
+
// Each panel composes its own toolbar with the standard toggle last. While a
|
|
78
|
+
// panel is collapsed, CollapsiblePanelRelocated carries that toggle: the
|
|
79
|
+
// rail's leads the main toolbar, the drawer's floats in its container's
|
|
80
|
+
// bottom-end corner. wireSidebar hands focus between the two positions.
|
|
81
|
+
const railToolbar: CollapsiblePanelToolbar = {
|
|
82
|
+
label: 'Workspace navigation',
|
|
83
|
+
title: <ToolbarText text="Atlas" />,
|
|
84
|
+
toggle: { action: RAIL_ACTION, name: 'navigation' },
|
|
85
|
+
};
|
|
86
|
+
const drawerToolbar: CollapsiblePanelToolbar = {
|
|
87
|
+
label: 'Activity',
|
|
88
|
+
title: <ToolbarText text="Activity" size="small" />,
|
|
89
|
+
toggle: { action: DRAWER_ACTION, name: 'activity' },
|
|
90
|
+
};
|
|
94
91
|
|
|
95
92
|
const rail = () => (
|
|
96
93
|
<CollapsiblePanel
|
|
@@ -99,23 +96,9 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
99
96
|
size={232}
|
|
100
97
|
collapsed={railCollapsed.value}
|
|
101
98
|
label="Workspace navigation"
|
|
99
|
+
toolbar={railToolbar}
|
|
102
100
|
>
|
|
103
|
-
<
|
|
104
|
-
contentElement="nav"
|
|
105
|
-
contentLabel="Workspace"
|
|
106
|
-
header={
|
|
107
|
-
<Toolbar
|
|
108
|
-
label="Workspace navigation"
|
|
109
|
-
dividerSides=""
|
|
110
|
-
leading={<ToolbarText text="Atlas" />}
|
|
111
|
-
trailing={
|
|
112
|
-
<ToolbarControlGroup appearance="borderless" single>
|
|
113
|
-
{railToggle()}
|
|
114
|
-
</ToolbarControlGroup>
|
|
115
|
-
}
|
|
116
|
-
/>
|
|
117
|
-
}
|
|
118
|
-
>
|
|
101
|
+
<nav aria-label="Workspace">
|
|
119
102
|
<section>
|
|
120
103
|
<ListHeader label="Workspace" />
|
|
121
104
|
<ListItem
|
|
@@ -141,15 +124,10 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
141
124
|
selected={selected.value === 'shared'}
|
|
142
125
|
/>
|
|
143
126
|
</section>
|
|
144
|
-
</
|
|
127
|
+
</nav>
|
|
145
128
|
</CollapsiblePanel>
|
|
146
129
|
);
|
|
147
130
|
|
|
148
|
-
// Each panel's own header holds its collapse toggle; its expand toggle shows
|
|
149
|
-
// only while it is collapsed, so exactly one control owns each action. The
|
|
150
|
-
// rail's sits in the main header; the drawer's is the drawer's own
|
|
151
|
-
// `restoreControl`, which the panel floats in its container's bottom-end
|
|
152
|
-
// corner. wireSidebar hands focus between them.
|
|
153
131
|
const main = () => (
|
|
154
132
|
<Pane
|
|
155
133
|
element="main"
|
|
@@ -159,11 +137,12 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
159
137
|
dividerSides=""
|
|
160
138
|
leading={
|
|
161
139
|
<>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
140
|
+
<CollapsiblePanelRelocated
|
|
141
|
+
panelId="sidebar-rail"
|
|
142
|
+
side="left"
|
|
143
|
+
collapsed={railCollapsed.value}
|
|
144
|
+
toolbar={railToolbar}
|
|
145
|
+
/>
|
|
167
146
|
<ToolbarText
|
|
168
147
|
text={labels[selected.value] ?? 'Inbox'}
|
|
169
148
|
size="xlarge"
|
|
@@ -174,7 +153,7 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
174
153
|
/>
|
|
175
154
|
}
|
|
176
155
|
>
|
|
177
|
-
<
|
|
156
|
+
<ContentItem>
|
|
178
157
|
<List gap="2xs">
|
|
179
158
|
<Text variant="span">
|
|
180
159
|
<strong>Narrow the window to a compact width</strong>
|
|
@@ -184,7 +163,7 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
184
163
|
a backdrop, Escape, and a trapped Tab ring, all managed by the wire.
|
|
185
164
|
</Text>
|
|
186
165
|
</List>
|
|
187
|
-
</
|
|
166
|
+
</ContentItem>
|
|
188
167
|
</Pane>
|
|
189
168
|
);
|
|
190
169
|
|
|
@@ -195,39 +174,30 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
195
174
|
size={168}
|
|
196
175
|
collapsed={drawerCollapsed.value}
|
|
197
176
|
label="Activity"
|
|
177
|
+
toolbar={drawerToolbar}
|
|
198
178
|
restoreControl={
|
|
199
179
|
<FloatingToolbar label="Activity drawer">
|
|
200
|
-
<
|
|
180
|
+
<CollapsiblePanelRelocated
|
|
181
|
+
panelId="sidebar-console"
|
|
182
|
+
side="bottom"
|
|
183
|
+
collapsed={drawerCollapsed.value}
|
|
184
|
+
toolbar={drawerToolbar}
|
|
185
|
+
/>
|
|
201
186
|
</FloatingToolbar>
|
|
202
187
|
}
|
|
203
188
|
>
|
|
204
|
-
<
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
>
|
|
218
|
-
<ValueTable label="Recent activity">
|
|
219
|
-
<ValueTableRow
|
|
220
|
-
label="Deploy finished"
|
|
221
|
-
value="2m ago"
|
|
222
|
-
icon={<LucideIcon icon={Bell} name="bell" />}
|
|
223
|
-
/>
|
|
224
|
-
<ValueTableRow
|
|
225
|
-
label="Review requested"
|
|
226
|
-
value="9m ago"
|
|
227
|
-
icon={<LucideIcon icon={Bell} name="bell" />}
|
|
228
|
-
/>
|
|
229
|
-
</ValueTable>
|
|
230
|
-
</Pane>
|
|
189
|
+
<ValueTable label="Recent activity">
|
|
190
|
+
<ValueTableRow
|
|
191
|
+
label="Deploy finished"
|
|
192
|
+
value="2m ago"
|
|
193
|
+
icon={<LucideIcon icon={Bell} name="bell" />}
|
|
194
|
+
/>
|
|
195
|
+
<ValueTableRow
|
|
196
|
+
label="Review requested"
|
|
197
|
+
value="9m ago"
|
|
198
|
+
icon={<LucideIcon icon={Bell} name="bell" />}
|
|
199
|
+
/>
|
|
200
|
+
</ValueTable>
|
|
231
201
|
</CollapsiblePanel>
|
|
232
202
|
);
|
|
233
203
|
|