cursedbelt 5.78.0 → 5.79.0
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/dist/react/canvas-hud/HudControls.d.ts +8 -2
- package/dist/react/canvas-hud/HudControls.d.ts.map +1 -1
- package/dist/react/canvas-hud/HudControls.js +6 -3
- package/dist/react/canvas-hud/HudControls.js.map +1 -1
- package/dist/react/components/AppShell.d.ts +14 -0
- package/dist/react/components/AppShell.d.ts.map +1 -1
- package/dist/react/components/AppShell.js +7 -31
- package/dist/react/components/AppShell.js.map +1 -1
- package/dist/react/components/ChipFilterStrip.d.ts.map +1 -1
- package/dist/react/components/ChipFilterStrip.js +2 -18
- package/dist/react/components/ChipFilterStrip.js.map +1 -1
- package/dist/react/components/KanbanBoard.d.ts +55 -0
- package/dist/react/components/KanbanBoard.d.ts.map +1 -0
- package/dist/react/components/KanbanBoard.js +89 -0
- package/dist/react/components/KanbanBoard.js.map +1 -0
- package/dist/react/components/ResponsiveWorkbench.d.ts +14 -1
- package/dist/react/components/ResponsiveWorkbench.d.ts.map +1 -1
- package/dist/react/components/ResponsiveWorkbench.js +33 -4
- package/dist/react/components/ResponsiveWorkbench.js.map +1 -1
- package/dist/react/components/SelectField.d.ts +18 -48
- package/dist/react/components/SelectField.d.ts.map +1 -1
- package/dist/react/components/SelectField.js +88 -11
- package/dist/react/components/SelectField.js.map +1 -1
- package/dist/react/components/SelectFieldImpl.d.ts +7 -0
- package/dist/react/components/SelectFieldImpl.d.ts.map +1 -0
- package/dist/react/components/SelectFieldImpl.js +26 -0
- package/dist/react/components/SelectFieldImpl.js.map +1 -0
- package/dist/react/components/filterChip.d.ts +8 -0
- package/dist/react/components/filterChip.d.ts.map +1 -0
- package/dist/react/components/filterChip.js +20 -0
- package/dist/react/components/filterChip.js.map +1 -0
- package/dist/react/hooks/pointerDnd.d.ts +37 -3
- package/dist/react/hooks/pointerDnd.d.ts.map +1 -1
- package/dist/react/hooks/pointerDnd.js +101 -9
- package/dist/react/hooks/pointerDnd.js.map +1 -1
- package/dist/react/hooks/pragmaticDnd.d.ts +4 -1
- package/dist/react/hooks/pragmaticDnd.d.ts.map +1 -1
- package/dist/react/hooks/pragmaticDnd.js +9 -3
- package/dist/react/hooks/pragmaticDnd.js.map +1 -1
- package/dist/react/hooks/usePublishedBottomChrome.d.ts +12 -0
- package/dist/react/hooks/usePublishedBottomChrome.d.ts.map +1 -0
- package/dist/react/hooks/usePublishedBottomChrome.js +31 -0
- package/dist/react/hooks/usePublishedBottomChrome.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +3 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/lib/selectField.d.ts +72 -0
- package/dist/react/lib/selectField.d.ts.map +1 -0
- package/dist/react/lib/selectField.js +23 -0
- package/dist/react/lib/selectField.js.map +1 -0
- package/dist/react/media/VideoChapterEditor.d.ts.map +1 -1
- package/dist/react/media/VideoChapterEditor.js +2 -1
- package/dist/react/media/VideoChapterEditor.js.map +1 -1
- package/dist/react/media/VideoCutEditor.d.ts.map +1 -1
- package/dist/react/media/VideoCutEditor.js +2 -1
- package/dist/react/media/VideoCutEditor.js.map +1 -1
- package/dist/react/media/denseGallery.css +2 -0
- package/dist/react/media-gallery/MediaGallery.d.ts.map +1 -1
- package/dist/react/media-gallery/MediaGallery.js +6 -7
- package/dist/react/media-gallery/MediaGallery.js.map +1 -1
- package/dist/react/media-gallery/MediaMetaEditor.d.ts.map +1 -1
- package/dist/react/media-gallery/MediaMetaEditor.js +2 -1
- package/dist/react/media-gallery/MediaMetaEditor.js.map +1 -1
- package/dist/react/nav/CommandBar.d.ts.map +1 -1
- package/dist/react/nav/CommandBar.js +2 -1
- package/dist/react/nav/CommandBar.js.map +1 -1
- package/dist/react/palette/CommandPalette.d.ts +15 -1
- package/dist/react/palette/CommandPalette.d.ts.map +1 -1
- package/dist/react/palette/CommandPalette.js +58 -8
- package/dist/react/palette/CommandPalette.js.map +1 -1
- package/dist/react/palette/Kbd.d.ts +15 -0
- package/dist/react/palette/Kbd.d.ts.map +1 -0
- package/dist/react/palette/Kbd.js +17 -0
- package/dist/react/palette/Kbd.js.map +1 -0
- package/dist/react/palette/ShortcutSheet.d.ts +30 -0
- package/dist/react/palette/ShortcutSheet.d.ts.map +1 -0
- package/dist/react/palette/ShortcutSheet.js +15 -0
- package/dist/react/palette/ShortcutSheet.js.map +1 -0
- package/dist/react/palette/commandSources.d.ts +14 -0
- package/dist/react/palette/commandSources.d.ts.map +1 -1
- package/dist/react/palette/commandSources.js +11 -1
- package/dist/react/palette/commandSources.js.map +1 -1
- package/dist/react/palette/index.d.ts +4 -2
- package/dist/react/palette/index.d.ts.map +1 -1
- package/dist/react/palette/index.js +2 -0
- package/dist/react/palette/index.js.map +1 -1
- package/dist/scripts/guardrailsEnforce.d.ts.map +1 -1
- package/dist/styles-areas/canvas-hud.css +2 -2
- package/dist/styles-areas/kanban.css +31 -0
- package/dist/styles-areas/palette.css +3 -3
- package/dist/styles-areas/workbench.css +15 -13
- package/dist/styles-utilities.css +42 -0
- package/package.json +3 -2
- package/scripts/guardrails-baseline.json +2 -1
- package/scripts/guardrailsEnforce.spec.ts +62 -0
- package/scripts/guardrailsEnforce.ts +77 -6
- package/scripts/styleAreas.ts +2 -0
- package/src/react/canvas-hud/HudControls.spec.tsx +11 -0
- package/src/react/canvas-hud/HudControls.tsx +33 -9
- package/src/react/components/AppShell.spec.tsx +40 -0
- package/src/react/components/AppShell.tsx +25 -27
- package/src/react/components/ChipFilterStrip.tsx +2 -38
- package/src/react/components/KanbanBoard.spec.tsx +89 -0
- package/src/react/components/KanbanBoard.tsx +270 -0
- package/src/react/components/ResponsiveWorkbench.spec.tsx +57 -0
- package/src/react/components/ResponsiveWorkbench.tsx +69 -4
- package/src/react/components/SelectField.spec.tsx +117 -0
- package/src/react/components/SelectField.tsx +131 -166
- package/src/react/components/SelectFieldImpl.tsx +140 -0
- package/src/react/components/filterChip.tsx +43 -0
- package/src/react/hooks/pointerDnd.spec.ts +89 -3
- package/src/react/hooks/pointerDnd.ts +103 -8
- package/src/react/hooks/pragmaticDnd.ts +13 -2
- package/src/react/hooks/usePublishedBottomChrome.ts +30 -0
- package/src/react/hooks/useScrollMemory.spec.tsx +7 -5
- package/src/react/index.ts +3 -0
- package/src/react/lib/floatingStyles.spec.ts +1 -1
- package/src/react/lib/selectField.ts +96 -0
- package/src/react/media/VideoChapterEditor.tsx +3 -2
- package/src/react/media/VideoCutEditor.tsx +3 -2
- package/src/react/media/denseGallery.css +2 -0
- package/src/react/media-gallery/MediaGallery.spec.tsx +15 -11
- package/src/react/media-gallery/MediaGallery.tsx +16 -18
- package/src/react/media-gallery/MediaMetaEditor.tsx +2 -1
- package/src/react/nav/CommandBar.tsx +2 -3
- package/src/react/palette/CommandPalette.spec.tsx +73 -0
- package/src/react/palette/CommandPalette.tsx +153 -13
- package/src/react/palette/Kbd.tsx +46 -0
- package/src/react/palette/ShortcutSheet.spec.tsx +58 -0
- package/src/react/palette/ShortcutSheet.tsx +110 -0
- package/src/react/palette/commandSources.tsx +30 -1
- package/src/react/palette/index.ts +9 -0
- package/src/styles-areas/canvas-hud.css +2 -2
- package/src/styles-areas/kanban.css +31 -0
- package/src/styles-areas/palette.css +3 -3
- package/src/styles-areas/workbench.css +15 -13
- package/src/styles-utilities.css +42 -0
|
@@ -26,10 +26,16 @@ export interface HudZoomControlsProps {
|
|
|
26
26
|
/** The canvas's own utilities, drawn before the zoom keys in the same pill (CNV-4 — utilities
|
|
27
27
|
* only; preferences and primary actions belong in the page's panel). */
|
|
28
28
|
children?: ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* `vertical` stacks the keys down an edge — +, the zoom %, −, Fit, Center — the way Figma and
|
|
31
|
+
* Miro draw them on a phone, where a bottom-centre pill sits over the drawing and the thumb's
|
|
32
|
+
* sheet handle. Place it with `absolute right-3 top-1/2 -translate-y-1/2` or the like.
|
|
33
|
+
*/
|
|
34
|
+
orientation?: 'horizontal' | 'vertical';
|
|
29
35
|
className?: string;
|
|
30
36
|
}
|
|
31
|
-
/** CNV-3's essentials as one pill: −, the zoom %, +, Fit and Center. */
|
|
32
|
-
export declare function HudZoomControls({ scale, onZoomIn, onZoomOut, onFit, onCenter, fitLabel, centerLabel, children, className, }: HudZoomControlsProps): import("react").JSX.Element;
|
|
37
|
+
/** CNV-3's essentials as one pill: −, the zoom %, +, Fit and Center (a column: + on top). */
|
|
38
|
+
export declare function HudZoomControls({ scale, onZoomIn, onZoomOut, onFit, onCenter, fitLabel, centerLabel, children, orientation, className, }: HudZoomControlsProps): import("react").JSX.Element;
|
|
33
39
|
export interface CanvasZoomHintProps {
|
|
34
40
|
/** `useCanvasWheel(…).hint` — up while the reader wheels over an embedded canvas. */
|
|
35
41
|
show: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HudControls.d.ts","sourceRoot":"","sources":["../../../src/react/canvas-hud/HudControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAoBvC,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,EAAE,cAAc,+BAa5G;AAED,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,qCAAqC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6EACyE;IACzE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,
|
|
1
|
+
{"version":3,"file":"HudControls.d.ts","sourceRoot":"","sources":["../../../src/react/canvas-hud/HudControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAoBvC,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,EAAE,cAAc,+BAa5G;AAED,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,qCAAqC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6EACyE;IACzE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,SAAS,EACT,KAAK,EACL,QAAQ,EACR,QAA0B,EAC1B,WAAuC,EACvC,QAAQ,EACR,WAA0B,EAC1B,SAAS,GACV,EAAE,oBAAoB,+BAwCtB;AAED,MAAM,WAAW,mBAAmB;IAClC,qFAAqF;IACrF,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,mBAAmB,+BAetE"}
|
|
@@ -7,9 +7,12 @@ import { cn } from '../lib/cn.js';
|
|
|
7
7
|
export function HudButton({ label, onClick, children, pressed, unavailableReason, className }) {
|
|
8
8
|
return (_jsx(IconButton, { label: label, size: 'sm', "aria-pressed": pressed, unavailableReason: unavailableReason ?? undefined, onClick: onClick, className: cn('text-muted-foreground aria-pressed:bg-muted aria-pressed:text-foreground', className), children: children }));
|
|
9
9
|
}
|
|
10
|
-
/** CNV-3's essentials as one pill: −, the zoom %, +, Fit and Center. */
|
|
11
|
-
export function HudZoomControls({ scale, onZoomIn, onZoomOut, onFit, onCenter, fitLabel = 'Fit to screen', centerLabel = 'Center on the selection', children, className, }) {
|
|
12
|
-
|
|
10
|
+
/** CNV-3's essentials as one pill: −, the zoom %, +, Fit and Center (a column: + on top). */
|
|
11
|
+
export function HudZoomControls({ scale, onZoomIn, onZoomOut, onFit, onCenter, fitLabel = 'Fit to screen', centerLabel = 'Center on the selection', children, orientation = 'horizontal', className, }) {
|
|
12
|
+
const vertical = orientation === 'vertical';
|
|
13
|
+
const zoomOut = (_jsx(HudButton, { label: 'Zoom out', onClick: onZoomOut, children: _jsx(IconZoomOut, {}) }));
|
|
14
|
+
const zoomIn = (_jsx(HudButton, { label: 'Zoom in', onClick: onZoomIn, children: _jsx(IconZoomIn, {}) }));
|
|
15
|
+
return (_jsxs(HudPill, { role: 'group', "aria-label": 'View', "aria-orientation": orientation, "data-orientation": orientation, className: cn('gap-0.5 rounded-lg px-1 py-1', vertical && 'flex-col py-1.5', className), children: [children, vertical ? zoomIn : zoomOut, _jsxs("span", { className: cn('text-center text-xs text-muted-foreground tabular-nums', vertical ? 'w-full' : 'min-w-11'), "data-testid": 'hud-zoom', children: [Math.round(scale * 100), "%"] }), vertical ? zoomOut : zoomIn, _jsx(HudButton, { label: fitLabel, onClick: onFit, children: _jsx(IconFit, {}) }), onCenter ? (_jsx(HudButton, { label: centerLabel, onClick: onCenter, children: _jsx(IconCenter, {}) })) : null] }));
|
|
13
16
|
}
|
|
14
17
|
/**
|
|
15
18
|
* CNV-1's "Hold ⌘ to zoom" — what an embedded canvas says when a plain wheel scrolled the page
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HudControls.js","sourceRoot":"","sources":["../../../src/react/canvas-hud/HudControls.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AA4BlC,4FAA4F;AAC5F,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAkB;IAC3G,OAAO,CACL,KAAC,UAAU,IACT,KAAK,EAAE,KAAK,EACZ,IAAI,EAAC,IAAI,kBACK,OAAO,EACrB,iBAAiB,EAAE,iBAAiB,IAAI,SAAS,EACjD,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,EAAE,CAAC,0EAA0E,EAAE,SAAS,CAAC,YAEnG,QAAQ,GACE,CACd,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"HudControls.js","sourceRoot":"","sources":["../../../src/react/canvas-hud/HudControls.tsx"],"names":[],"mappings":"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"}
|
|
@@ -92,6 +92,20 @@ export interface AppShellProps {
|
|
|
92
92
|
commandHint?: ReactNode;
|
|
93
93
|
/** App slot at the trailing edge of the command spine (e.g. presence dots). */
|
|
94
94
|
commandBarExtra?: ReactNode;
|
|
95
|
+
/**
|
|
96
|
+
* The header's center zone, for an app with no places and no command spine: a one-place
|
|
97
|
+
* canvas app's own toolbar (its depth switch, Save, Export) folded INTO the header instead of
|
|
98
|
+
* stacked under it as a second bar. On a phone that row is a quarter of what the canvas gets
|
|
99
|
+
* (arch, forge task 3059). Ignored when `nav` gives the header places to draw; otherwise it
|
|
100
|
+
* REPLACES the command spine (`onOpenCommand`, `onCapture`, `commandBarExtra`) — put them in it.
|
|
101
|
+
*/
|
|
102
|
+
headerCenter?: ReactNode;
|
|
103
|
+
/**
|
|
104
|
+
* Presentation mode: the header and the bottom chrome (dock, `PlaceBar`) step aside so the
|
|
105
|
+
* content has the whole viewport, until the app turns it off — a canvas's double-tap on blank
|
|
106
|
+
* space (Figma's and Miro's ⌘\). Banners stay: one is a fault the reader must still see.
|
|
107
|
+
*/
|
|
108
|
+
immersive?: boolean;
|
|
95
109
|
/** Account chrome behind the avatar (profile/settings/sign-out) — NOT a nav door
|
|
96
110
|
* (§6). Rendered at the trailing edge of the top spine. */
|
|
97
111
|
account?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect,
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
3
|
import { allowAllGate, deriveSideNavDomains, } from 'cursedbelt-core/navigation';
|
|
4
4
|
import { useKeyboardInset } from '../hooks/useKeyboardInset.js';
|
|
5
5
|
import { cn } from '../lib/cn.js';
|
|
@@ -8,6 +8,7 @@ import { whenIdle } from '../lib/whenIdle.js';
|
|
|
8
8
|
import { CommandBar } from '../nav/CommandBar.js';
|
|
9
9
|
import { isDomainActive, renderIcon, routeClick } from '../nav/navShared.js';
|
|
10
10
|
import { PlaceBar } from '../nav/PlaceBar.js';
|
|
11
|
+
import { usePublishedBottomChrome } from '../hooks/usePublishedBottomChrome.js';
|
|
11
12
|
import { SideNav } from '../nav/SideNav.js';
|
|
12
13
|
import { TopBarPlaces } from '../nav/TopBar.js';
|
|
13
14
|
import { CommandSourceProvider, useCommandSources } from '../palette/commandSources.js';
|
|
@@ -67,7 +68,7 @@ export function AppShell(props) {
|
|
|
67
68
|
// palette the shell mounts, and the shell can read what they contributed.
|
|
68
69
|
return (_jsx(CommandSourceProvider, { children: _jsx(Shell, { ...props }) }));
|
|
69
70
|
}
|
|
70
|
-
function Shell({ children, nav, navGate = allowAllGate, activeHref, onNavigate, navLinkComponent, resolveIcon, navPrefs, onNavPrefsChange, navCollapsedSections, onNavSectionToggle, navBadges, navBadgeTone, navHeader, navFooter, banners, density, commandPalette = 'auto', onCapture, captureLabel, onOpenCommand, commandLabel, commandHint, commandBarExtra, account, bottomDock, palette, placeBarMax = 5, placeBarLabels = 'active', scrollSpace = 'default', scrollRef, ambient, className, }) {
|
|
71
|
+
function Shell({ children, nav, navGate = allowAllGate, activeHref, onNavigate, navLinkComponent, resolveIcon, navPrefs, onNavPrefsChange, navCollapsedSections, onNavSectionToggle, navBadges, navBadgeTone, navHeader, navFooter, banners, density, commandPalette = 'auto', onCapture, captureLabel, onOpenCommand, commandLabel, commandHint, commandBarExtra, headerCenter, immersive = false, account, bottomDock, palette, placeBarMax = 5, placeBarLabels = 'active', scrollSpace = 'default', scrollRef, ambient, className, }) {
|
|
71
72
|
useKeyboardInset();
|
|
72
73
|
const places = nav ? deriveSideNavDomains(nav, navGate) : [];
|
|
73
74
|
const pattern = !nav ? 'none' : places.length <= TOP_BAR_MAX_PLACES ? 'top' : 'side';
|
|
@@ -96,8 +97,8 @@ function Shell({ children, nav, navGate = allowAllGate, activeHref, onNavigate,
|
|
|
96
97
|
else
|
|
97
98
|
window.location.assign(path);
|
|
98
99
|
};
|
|
99
|
-
const showSpine = Boolean(nav || navHeader || account || openCommand || onCapture || commandBarExtra);
|
|
100
|
-
const showBottom = Boolean(bottomDock || nav);
|
|
100
|
+
const showSpine = !immersive && Boolean(nav || navHeader || account || openCommand || onCapture || commandBarExtra || headerCenter);
|
|
101
|
+
const showBottom = !immersive && Boolean(bottomDock || nav);
|
|
101
102
|
const bottomChromeRef = usePublishedBottomChrome(showBottom);
|
|
102
103
|
// Chrome that lets the field through. The rails/spine keep their own directional
|
|
103
104
|
// border either way — only the FILL changes, so the layout is byte-identical and
|
|
@@ -124,7 +125,7 @@ function Shell({ children, nav, navGate = allowAllGate, activeHref, onNavigate,
|
|
|
124
125
|
badgeTone: navBadgeTone,
|
|
125
126
|
footer: navFooter,
|
|
126
127
|
};
|
|
127
|
-
return (_jsxs("div", { "data-cb-appshell": '', "data-cb-nav-pattern": pattern, className: cn('flex h-dvh flex-col overflow-hidden bg-background text-foreground',
|
|
128
|
+
return (_jsxs("div", { "data-cb-appshell": '', "data-cb-nav-pattern": pattern, "data-cb-immersive": immersive ? '' : undefined, className: cn('flex h-dvh flex-col overflow-hidden bg-background text-foreground',
|
|
128
129
|
// `isolation: isolate` is load-bearing, not decoration: the blobs blend with
|
|
129
130
|
// `mix-blend-mode: screen`, and without a stacking context here they would
|
|
130
131
|
// blend against whatever is painted behind the app instead of against it.
|
|
@@ -146,31 +147,6 @@ function Shell({ children, nav, navGate = allowAllGate, activeHref, onNavigate,
|
|
|
146
147
|
badgeTone: navBadgeTone,
|
|
147
148
|
unavailable: d.hostLimit && d.hostLimit.navigable !== true ? d.hostLimit.reason : undefined,
|
|
148
149
|
linkProps: navLinkComponent ? undefined : { onClick: routeClick(d.path, onNavigate) },
|
|
149
|
-
})) })) : (commandBar) }), (pattern === 'top' || account) && (_jsxs("div", { "data-cb-header-zone": 'right', className: 'flex shrink-0 items-center gap-2', children: [pattern === 'top' ? commandBar : null, account && (_jsx("div", { "data-cb-account": '', className: 'shrink-0', children: account }))] }))] })), banners && banners.length > 0 ? _jsx(BannerLane, { banners: banners, className: cn(ambient && chrome) }) : null, _jsxs("div", { className: 'relative flex min-h-0 grow overflow-hidden', children: [pattern === 'side' && (_jsxs(_Fragment, { children: [_jsx("aside", { "data-cb-nav-rail": '', "data-cb-nav-collapsed": '', className: cn('hidden w-[var(--rail-w-collapsed)] border-r border-border md:flex md:shrink-0 md:flex-col lg:hidden', chrome), children: _jsx(SideNav, { ...sideNavProps, collapsed: true }) }), _jsx("aside", { "data-cb-nav-rail": '', className: cn('hidden w-[var(--rail-w)] border-r border-border lg:flex lg:shrink-0 lg:flex-col', chrome), children: _jsx(SideNav, { ...sideNavProps, onPrefsChange: onNavPrefsChange, collapsedSections: navCollapsedSections, onSectionToggle: onNavSectionToggle }) })] })), _jsx("main", { className: 'flex min-h-0 min-w-0 grow flex-col', children: _jsx(ScrollArea, { space: scrollSpace, scrollRef: scrollRef, children: children }) })] }), showBottom && (_jsxs("div", { ref: bottomChromeRef, className: 'shrink-0 pb-[env(safe-area-inset-bottom,0px)]', children: [bottomDock && _jsx("div", { className: 'border-t border-border', children: bottomDock }), nav && (_jsx(PlaceBar, { className: cn('border-t border-border md:hidden', ambient && chrome), model: nav, gate: navGate, activeHref: activeHref, onNavigate: onNavigate, linkComponent: navLinkComponent, resolveIcon: resolveIcon, badges: navBadges, badgeTone: navBadgeTone, onCapture: onCapture, captureLabel: captureLabel, max: placeBarMax, labels: placeBarLabels }))] })), palette, ownPalette && nav && paletteMounted ? (_jsx(ShellCommandPalette, { model: nav, gate: navGate, open: paletteControls.open, onOpenChange: paletteControls.setOpen, onNavigate: navigate, resolveIcon: resolveIcon, currentPath: activeHref, places: true, sources: sources })) : null] }));
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Publishes the bottom chrome's height (dock + `PlaceBar` + safe area) as
|
|
153
|
-
* `--cb-bottom-chrome-h` on the root, so what floats over the page — the `Toaster`'s stack
|
|
154
|
-
* (OVL-9) — rises above the navigation instead of covering it. A `PlaceBar` hidden at `md` up
|
|
155
|
-
* measures 0, so the desktop stack drops back to the corner by itself.
|
|
156
|
-
*/
|
|
157
|
-
function usePublishedBottomChrome(shown) {
|
|
158
|
-
const ref = useRef(null);
|
|
159
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: `shown` mounts or drops the element the ref points at.
|
|
160
|
-
useLayoutEffect(() => {
|
|
161
|
-
const el = ref.current;
|
|
162
|
-
const root = document.documentElement;
|
|
163
|
-
if (!el)
|
|
164
|
-
return;
|
|
165
|
-
const publish = () => root.style.setProperty('--cb-bottom-chrome-h', `${el.offsetHeight}px`);
|
|
166
|
-
publish();
|
|
167
|
-
const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(publish);
|
|
168
|
-
observer?.observe(el);
|
|
169
|
-
return () => {
|
|
170
|
-
observer?.disconnect();
|
|
171
|
-
root.style.removeProperty('--cb-bottom-chrome-h');
|
|
172
|
-
};
|
|
173
|
-
}, [shown]);
|
|
174
|
-
return ref;
|
|
150
|
+
})) })) : headerCenter ? (headerCenter) : (commandBar) }), (pattern === 'top' || account) && (_jsxs("div", { "data-cb-header-zone": 'right', className: 'flex shrink-0 items-center gap-2', children: [pattern === 'top' ? commandBar : null, account && (_jsx("div", { "data-cb-account": '', className: 'shrink-0', children: account }))] }))] })), banners && banners.length > 0 ? _jsx(BannerLane, { banners: banners, className: cn(ambient && chrome) }) : null, _jsxs("div", { className: 'relative flex min-h-0 grow overflow-hidden', children: [pattern === 'side' && (_jsxs(_Fragment, { children: [_jsx("aside", { "data-cb-nav-rail": '', "data-cb-nav-collapsed": '', className: cn('hidden w-[var(--rail-w-collapsed)] border-r border-border md:flex md:shrink-0 md:flex-col lg:hidden', chrome), children: _jsx(SideNav, { ...sideNavProps, collapsed: true }) }), _jsx("aside", { "data-cb-nav-rail": '', className: cn('hidden w-[var(--rail-w)] border-r border-border lg:flex lg:shrink-0 lg:flex-col', chrome), children: _jsx(SideNav, { ...sideNavProps, onPrefsChange: onNavPrefsChange, collapsedSections: navCollapsedSections, onSectionToggle: onNavSectionToggle }) })] })), _jsx("main", { className: 'flex min-h-0 min-w-0 grow flex-col', children: _jsx(ScrollArea, { space: scrollSpace, scrollRef: scrollRef, children: children }) })] }), showBottom && (_jsxs("div", { ref: bottomChromeRef, className: 'shrink-0 pb-[env(safe-area-inset-bottom,0px)]', children: [bottomDock && _jsx("div", { className: 'border-t border-border', children: bottomDock }), nav && (_jsx(PlaceBar, { className: cn('border-t border-border md:hidden', ambient && chrome), model: nav, gate: navGate, activeHref: activeHref, onNavigate: onNavigate, linkComponent: navLinkComponent, resolveIcon: resolveIcon, badges: navBadges, badgeTone: navBadgeTone, onCapture: onCapture, captureLabel: captureLabel, max: placeBarMax, labels: placeBarLabels }))] })), palette, ownPalette && nav && paletteMounted ? (_jsx(ShellCommandPalette, { model: nav, gate: navGate, open: paletteControls.open, onOpenChange: paletteControls.setOpen, onNavigate: navigate, resolveIcon: resolveIcon, currentPath: activeHref, places: true, sources: sources })) : null] }));
|
|
175
151
|
}
|
|
176
152
|
//# sourceMappingURL=AppShell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.js","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":";AAAA,OAAO,EAA8C,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"AppShell.js","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChipFilterStrip.d.ts","sourceRoot":"","sources":["../../../src/react/components/ChipFilterStrip.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChipFilterStrip.d.ts","sourceRoot":"","sources":["../../../src/react/components/ChipFilterStrip.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACpD,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,KAAK,EACL,QAAQ,EACR,KAAa,EACb,QAAgB,EAChB,SAAS,GACV,EAAE,oBAAoB,+BAmDtB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn
|
|
3
|
-
import {
|
|
2
|
+
import { cn } from '../lib/cn.js';
|
|
3
|
+
import { Chip } from './filterChip.js';
|
|
4
4
|
import { ScrollArea } from './ScrollArea.js';
|
|
5
5
|
function isActive(value, option) {
|
|
6
6
|
if (value === null)
|
|
@@ -43,20 +43,4 @@ export function ChipFilterStrip({ options, value, onChange, multi = false, allLa
|
|
|
43
43
|
// Hide scrollbar visually but keep it functional (cross-browser).
|
|
44
44
|
'[scrollbar-width:none] [&::-webkit-scrollbar]:hidden'), children: [_jsx(Chip, { active: allActive, onClick: handleAll, children: allLabel }), options.map((opt) => (_jsxs(Chip, { active: isActive(value, opt.value), onClick: () => handleOption(opt.value), children: [opt.label, opt.count != null && (_jsx("span", { className: 'ml-1 tabular-nums text-xs', children: opt.count }))] }, opt.value)))] }) }));
|
|
45
45
|
}
|
|
46
|
-
function Chip({ active, onClick, children }) {
|
|
47
|
-
return (_jsx("button", {
|
|
48
|
-
// guardrails-ignore no-raw-action-button: presentational filter-chip toggle —
|
|
49
|
-
// reflects local filter state (aria-pressed), no destructive/mutating intent.
|
|
50
|
-
type: 'button', onClick: onClick, "aria-pressed": active, className: cn(RAW_BUTTON,
|
|
51
|
-
// 44 px min tap target height via py + min-h (STANDARDS §4a). px-4 keeps every
|
|
52
|
-
// pill's internal padding identical regardless of label length.
|
|
53
|
-
'inline-flex min-h-11 shrink-0 cursor-pointer items-center rounded-full px-4 text-sm font-medium', PRESS, 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
54
|
-
// Soft active state — an accent tint + accent text (the standardized active
|
|
55
|
-
// treatment shared with nav items and the `accent` Badge tone), not a stark
|
|
56
|
-
// solid accent block. `text-accent-strong` (not plain `text-accent`) — the
|
|
57
|
-
// /15 tint only clears 4.43:1 with the base accent hue, under AA (cbux-101).
|
|
58
|
-
active
|
|
59
|
-
? 'bg-accent/15 text-accent-strong ring-1 ring-inset ring-accent/30'
|
|
60
|
-
: 'bg-muted text-muted-foreground hover:bg-muted/80 hover:text-foreground'), children: children }));
|
|
61
|
-
}
|
|
62
46
|
//# sourceMappingURL=ChipFilterStrip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChipFilterStrip.js","sourceRoot":"","sources":["../../../src/react/components/ChipFilterStrip.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ChipFilterStrip.js","sourceRoot":"","sources":["../../../src/react/components/ChipFilterStrip.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAwB7C,SAAS,QAAQ,CAAC,KAA+B,EAAE,MAAc;IAC/D,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,KAAK,KAAK,MAAM,CAAC;AAC1B,CAAC;AAED,SAAS,KAAK,CAAC,KAA+B;IAC5C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,OAAO,EACP,KAAK,EACL,QAAQ,EACR,KAAK,GAAG,KAAK,EACb,QAAQ,GAAG,KAAK,EAChB,SAAS,GACY;IACrB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAE/B,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,EAAE;QACnC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,CAAC;YAC1F,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAKL,iCAAqB,gBAAgB,EAAC,SAAS,EAAE,EAAE,CAAC,qCAAqC,EAAE,SAAS,CAAC,YACnG,MAAC,UAAU,IACT,IAAI,EAAC,GAAG,EACR,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,KAAK,EACf,SAAS,EAAE,EAAE,CACX,kCAAkC;YAClC,kEAAkE;YAClE,sDAAsD,CACvD,aAED,KAAC,IAAI,IAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,YACxC,QAAQ,GACJ,EACN,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,MAAC,IAAI,IAEH,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,EAClC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,aAErC,GAAG,CAAC,KAAK,EACT,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI,CACpB,eAAM,SAAS,EAAC,2BAA2B,YAAE,GAAG,CAAC,KAAK,GAAQ,CAC/D,KAPI,GAAG,CAAC,KAAK,CAQT,CACR,CAAC,IACS,GACJ,CACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/** One column of a {@link KanbanBoard}: what it is called, and the cards in it, in order. */
|
|
3
|
+
export interface KanbanColumn<T> {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
items: readonly T[];
|
|
7
|
+
/** A glyph before the title. */
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export interface KanbanBoardProps<T> {
|
|
11
|
+
columns: readonly KanbanColumn<T>[];
|
|
12
|
+
/** A stable key per card, unique across every column. */
|
|
13
|
+
getKey: (item: T) => string;
|
|
14
|
+
/** What is ON the card — a glyph, a title, one detail line. The board draws the card around it. */
|
|
15
|
+
renderCard: (item: T) => ReactNode;
|
|
16
|
+
/** The card's accessible name, and the text of the ghost that follows a drag. */
|
|
17
|
+
cardLabel: (item: T) => string;
|
|
18
|
+
/** A card was clicked, tapped, or Enter'd. */
|
|
19
|
+
onOpen: (item: T) => void;
|
|
20
|
+
/** The card that is open — drawn as the active place (NAV-6). */
|
|
21
|
+
selectedKey?: string | null;
|
|
22
|
+
/**
|
|
23
|
+
* A card was dropped in ANOTHER column. Omit it and the board is read-only: nothing drags.
|
|
24
|
+
* Order within a column is the consumer's (the board never reorders), so a drop back into
|
|
25
|
+
* its own column is not a move.
|
|
26
|
+
*/
|
|
27
|
+
onMove?: (itemKey: string, fromColumn: string, toColumn: string) => void;
|
|
28
|
+
/** The column's `+`: start a new card in it. */
|
|
29
|
+
onAdd?: (columnId: string) => void;
|
|
30
|
+
/** The `+`'s verb — "Add entry", "Add task". */
|
|
31
|
+
addLabel?: string;
|
|
32
|
+
/** A trailing "New column" button after the last column. */
|
|
33
|
+
onNewColumn?: () => void;
|
|
34
|
+
newColumnLabel?: string;
|
|
35
|
+
/** What an empty column says. */
|
|
36
|
+
emptyText?: string;
|
|
37
|
+
'aria-label': string;
|
|
38
|
+
className?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Cards in columns, dragged between them — the board Linear and Trello settle on (forge task
|
|
42
|
+
* 3030, the vault's Kanban canvas). The columns scroll sideways as a strip and each column
|
|
43
|
+
* scrolls on its own; a card is the whole tap target (`CardTapTarget`) and drags through
|
|
44
|
+
* {@link useCrossContainerDrag} (pointer, touch, the edge indicator, auto-scroll).
|
|
45
|
+
*
|
|
46
|
+
* Under 768px a phone sees ONE column at a time: the strip snaps column by column, and the
|
|
47
|
+
* column titles become a pill tray above it — tap one to glide there, and the one in view is
|
|
48
|
+
* lit (forge task 3033, the redesign's "Pill Segmenter"). Under 1024px the strip snaps too.
|
|
49
|
+
*
|
|
50
|
+
* 🔴 Dragging is a PLUS. Every move a drag makes must also be reachable from the card's own
|
|
51
|
+
* detail (a folder or status picker): the hook's keyboard lift does not yet carry a card across
|
|
52
|
+
* columns, so the board never relies on it.
|
|
53
|
+
*/
|
|
54
|
+
export declare function KanbanBoard<T>({ columns, getKey, renderCard, cardLabel, onOpen, selectedKey, onMove, onAdd, addLabel, onNewColumn, newColumnLabel, emptyText, 'aria-label': ariaLabel, className, }: KanbanBoardProps<T>): import("react").JSX.Element;
|
|
55
|
+
//# sourceMappingURL=KanbanBoard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanBoard.d.ts","sourceRoot":"","sources":["../../../src/react/components/KanbanBoard.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAqD,MAAM,OAAO,CAAC;AAW1F,6FAA6F;AAC7F,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IACpB,gCAAgC;IAChC,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,OAAO,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,yDAAyD;IACzD,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC5B,mGAAmG;IACnG,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IACnC,iFAAiF;IACjF,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IAC/B,8CAA8C;IAC9C,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC1B,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE,gDAAgD;IAChD,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAC7B,OAAO,EACP,MAAM,EACN,UAAU,EACV,SAAS,EACT,MAAM,EACN,WAAkB,EAClB,MAAM,EACN,KAAK,EACL,QAAgB,EAChB,WAAW,EACX,cAA6B,EAC7B,SAA8B,EAC9B,YAAY,EAAE,SAAS,EACvB,SAAS,GACV,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BA4LrB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Plus } from 'lucide-react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { registerAutoScroll } from '../hooks/pragmaticDnd.js';
|
|
5
|
+
import { useCrossContainerDrag } from '../hooks/useCrossContainerDrag.js';
|
|
6
|
+
import { cn } from '../lib/cn.js';
|
|
7
|
+
import { Badge } from './Badge.js';
|
|
8
|
+
import { Button } from './Button.js';
|
|
9
|
+
import { CardTapTarget } from './CardTapTarget.js';
|
|
10
|
+
import { Chip } from './filterChip.js';
|
|
11
|
+
import { IconButton } from './IconButton.js';
|
|
12
|
+
import { ScrollArea } from './ScrollArea.js';
|
|
13
|
+
/**
|
|
14
|
+
* Cards in columns, dragged between them — the board Linear and Trello settle on (forge task
|
|
15
|
+
* 3030, the vault's Kanban canvas). The columns scroll sideways as a strip and each column
|
|
16
|
+
* scrolls on its own; a card is the whole tap target (`CardTapTarget`) and drags through
|
|
17
|
+
* {@link useCrossContainerDrag} (pointer, touch, the edge indicator, auto-scroll).
|
|
18
|
+
*
|
|
19
|
+
* Under 768px a phone sees ONE column at a time: the strip snaps column by column, and the
|
|
20
|
+
* column titles become a pill tray above it — tap one to glide there, and the one in view is
|
|
21
|
+
* lit (forge task 3033, the redesign's "Pill Segmenter"). Under 1024px the strip snaps too.
|
|
22
|
+
*
|
|
23
|
+
* 🔴 Dragging is a PLUS. Every move a drag makes must also be reachable from the card's own
|
|
24
|
+
* detail (a folder or status picker): the hook's keyboard lift does not yet carry a card across
|
|
25
|
+
* columns, so the board never relies on it.
|
|
26
|
+
*/
|
|
27
|
+
export function KanbanBoard({ columns, getKey, renderCard, cardLabel, onOpen, selectedKey = null, onMove, onAdd, addLabel = 'Add', onNewColumn, newColumnLabel = 'New column', emptyText = 'Nothing here yet', 'aria-label': ariaLabel, className, }) {
|
|
28
|
+
const containers = useMemo(() => columns.map((c) => ({ id: c.id, items: [...c.items] })), [columns]);
|
|
29
|
+
const onDrop = useCallback((from, to, fromIndex) => {
|
|
30
|
+
if (from === to || !onMove)
|
|
31
|
+
return;
|
|
32
|
+
const item = containers.find((c) => c.id === from)?.items[fromIndex];
|
|
33
|
+
if (item !== undefined)
|
|
34
|
+
onMove(getKey(item), from, to);
|
|
35
|
+
}, [containers, getKey, onMove]);
|
|
36
|
+
const { ContainerContext, Container, Item } = useCrossContainerDrag({
|
|
37
|
+
containers,
|
|
38
|
+
getKey,
|
|
39
|
+
onMove: onDrop,
|
|
40
|
+
disabled: !onMove,
|
|
41
|
+
renderOverlay: (item) => (_jsx("div", { className: 'max-w-64 truncate rounded-md bg-surface px-3 py-2 text-sm font-medium text-foreground shadow-2xl ring-1 ring-accent', children: cardLabel(item) })),
|
|
42
|
+
});
|
|
43
|
+
// The phone's tray follows the column in view. Columns are the strip's full width there, so
|
|
44
|
+
// at most one is 60 % visible; wider, the tray is not drawn and this is unused.
|
|
45
|
+
const stripRef = useRef(null);
|
|
46
|
+
const columnEls = useRef(new Map());
|
|
47
|
+
const [inView, setInView] = useState(null);
|
|
48
|
+
const columnIds = columns.map((c) => c.id).join('\n');
|
|
49
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: `columnIds` is the trigger — a column added or gone re-observes the set held in the ref.
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const root = stripRef.current;
|
|
52
|
+
if (!root || typeof IntersectionObserver === 'undefined')
|
|
53
|
+
return;
|
|
54
|
+
const io = new IntersectionObserver((records) => {
|
|
55
|
+
for (const r of records)
|
|
56
|
+
if (r.isIntersecting)
|
|
57
|
+
setInView(r.target.dataset.cbKanbanColumn ?? null);
|
|
58
|
+
}, { root, threshold: 0.6 });
|
|
59
|
+
for (const el of columnEls.current.values())
|
|
60
|
+
io.observe(el);
|
|
61
|
+
return () => io.disconnect();
|
|
62
|
+
}, [columnIds]);
|
|
63
|
+
// A card carried to the strip's edge scrolls the strip, for a mouse and a finger: the hook
|
|
64
|
+
// only registers each card's NEAREST scroller, which is its column.
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const strip = stripRef.current;
|
|
67
|
+
return strip && onMove ? registerAutoScroll(strip) : undefined;
|
|
68
|
+
}, [onMove]);
|
|
69
|
+
const current = columns.some((c) => c.id === inView) ? inView : (columns[0]?.id ?? null);
|
|
70
|
+
const showColumn = (id) => {
|
|
71
|
+
columnEls.current.get(id)?.scrollIntoView({ behavior: 'smooth', inline: 'start', block: 'nearest' });
|
|
72
|
+
setInView(id);
|
|
73
|
+
};
|
|
74
|
+
return (_jsx(ContainerContext, { children: _jsxs("div", { className: cn('flex min-h-0 min-w-0 flex-1 flex-col gap-2', className), "data-cb-kanban-frame": true, children: [_jsx("nav", { "aria-label": `${ariaLabel}: columns`, "data-cb-kanban-tray": true, className: 'min-w-0 md:hidden', children: _jsx(ScrollArea, { axis: 'x', space: 'none', safeArea: false, className: 'flex items-center gap-1.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden', children: columns.map((column) => (_jsxs(Chip, { active: column.id === current, onClick: () => showColumn(column.id), children: [column.title, _jsx("span", { className: 'ml-1 text-xs tabular-nums', children: column.items.length })] }, column.id))) }) }), _jsx(ScrollArea, { axis: 'x', fade: true, space: 'compact', safeArea: false, role: 'group', "aria-label": ariaLabel, "data-cb-kanban": true, scrollRef: stripRef, className: 'min-h-0 flex-1 max-lg:snap-x max-lg:snap-mandatory', children: _jsxs("div", { className: 'flex h-full items-start gap-3', children: [columns.map((column) => (_jsx(Container, { containerId: column.id, children: ({ setNodeRef, isOver, items }) => (_jsxs("section", { ref: (node) => {
|
|
75
|
+
setNodeRef(node);
|
|
76
|
+
if (node)
|
|
77
|
+
columnEls.current.set(column.id, node);
|
|
78
|
+
else
|
|
79
|
+
columnEls.current.delete(column.id);
|
|
80
|
+
}, "aria-label": `${column.title}, ${items.length} ${items.length === 1 ? 'card' : 'cards'}`, "data-cb-kanban-column": column.id, className: cn('flex max-h-full w-72 shrink-0 snap-start flex-col gap-2 rounded-lg bg-muted/40 p-2 transition-colors max-md:w-full', isOver && 'bg-muted ring-1 ring-inset ring-accent/50'), children: [_jsxs("header", { className: 'flex min-h-8 items-center gap-2 px-1', children: [column.icon && (_jsx("span", { "aria-hidden": true, className: 'flex shrink-0 text-muted-foreground [&_svg]:size-4', children: column.icon })), _jsx("h3", { className: 'm-0 min-w-0 truncate text-sm font-medium text-foreground', children: column.title }), _jsx(Badge, { tone: 'neutral', className: 'tabular-nums', children: items.length }), onAdd && (_jsx(IconButton, { size: 'sm', className: 'ml-auto', label: `${addLabel} to ${column.title}`, onClick: () => onAdd(column.id), children: _jsx(Plus, {}) }))] }), _jsx(ScrollArea, { axis: 'y', space: 'compact', safeArea: false, fade: true, className: 'flex flex-col gap-2 overscroll-x-auto', children: items.length === 0 ? (_jsx("p", { className: 'm-0 rounded-md border border-dashed border-border px-3 py-6 text-center text-caption text-muted-foreground', children: emptyText })) : (items.map((item) => {
|
|
81
|
+
const key = getKey(item);
|
|
82
|
+
const selected = key === selectedKey;
|
|
83
|
+
return (_jsx(Item, { containerId: column.id, itemKey: key, children: ({ setNodeRef: cardRef, isDragging }) => (_jsx("div", { ref: cardRef, "data-cb-kanban-card": key, "data-selected": selected || undefined, className: cn('relative isolate', isDragging && 'opacity-40'), children: _jsx(CardTapTarget, { "aria-label": cardLabel(item), onClick: () => onOpen(item), className: cn(
|
|
84
|
+
// A border, not a ring: the column scrolls, and a scroller clips the
|
|
85
|
+
// ring a card draws OUTSIDE itself (seen on vault-stage, 2026-10-13).
|
|
86
|
+
'flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-sm transition-colors hover:border-border-strong focus-visible:border-accent focus-visible:outline-none', onMove && 'cursor-grab active:cursor-grabbing', selected && 'border-accent/70'), children: renderCard(item) }) })) }, key));
|
|
87
|
+
})) })] })) }, column.id))), onNewColumn && (_jsx(Button, { variant: 'ghost', size: 'sm', className: 'shrink-0', leftIcon: _jsx(Plus, {}), tooltip: `${newColumnLabel} — a new column at the end`, onClick: onNewColumn, children: newColumnLabel }))] }) })] }) }));
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=KanbanBoard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanBoard.js","sourceRoot":"","sources":["../../../src/react/components/KanbanBoard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -41,6 +41,19 @@ export interface ResponsiveWorkbenchProps {
|
|
|
41
41
|
* here; put quick actions here that open the drawers above (e.g. "+ Add", "Inspector").
|
|
42
42
|
*/
|
|
43
43
|
mobileUtilityBar?: ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* How the rails come in below the breakpoint.
|
|
46
|
+
*
|
|
47
|
+
* - `drawers` (default): each rail slides in from its own side, and `mobileUtilityBar` is a
|
|
48
|
+
* row under the main area.
|
|
49
|
+
* - `sheets`: each rail rises as a bottom sheet, and `mobileUtilityBar` FLOATS over the bottom
|
|
50
|
+
* of the main area as a handle (a grabber over the caller's buttons) instead of taking a row —
|
|
51
|
+
* a canvas keeps the whole height, the way Apple Maps' and Figma's phone panels do. Swiping
|
|
52
|
+
* the handle up opens `mobileSwipeOpens`.
|
|
53
|
+
*/
|
|
54
|
+
mobilePanels?: 'drawers' | 'sheets';
|
|
55
|
+
/** The rail a swipe up on the `sheets` handle opens. Default `right` (or `left` when there is no right). */
|
|
56
|
+
mobileSwipeOpens?: 'left' | 'right';
|
|
44
57
|
className?: string;
|
|
45
58
|
}
|
|
46
59
|
/**
|
|
@@ -58,5 +71,5 @@ export interface ResponsiveWorkbenchProps {
|
|
|
58
71
|
* This is the reusable answer to "sidebars must become drawers on mobile" — write the
|
|
59
72
|
* responsive behavior once here, not per app.
|
|
60
73
|
*/
|
|
61
|
-
export declare function ResponsiveWorkbench({ left, right, children, leftOpen: leftOpenProp, onLeftOpenChange, defaultLeftOpen, rightOpen: rightOpenProp, onRightOpenChange, defaultRightOpen, leftWidth, rightWidth, leftTitle, rightTitle, leftCollapsedRail, rightCollapsedRail, breakpoint, mobileUtilityBar, className, }: ResponsiveWorkbenchProps): import("react").JSX.Element;
|
|
74
|
+
export declare function ResponsiveWorkbench({ left, right, children, leftOpen: leftOpenProp, onLeftOpenChange, defaultLeftOpen, rightOpen: rightOpenProp, onRightOpenChange, defaultRightOpen, leftWidth, rightWidth, leftTitle, rightTitle, leftCollapsedRail, rightCollapsedRail, breakpoint, mobileUtilityBar, mobilePanels, mobileSwipeOpens, className, }: ResponsiveWorkbenchProps): import("react").JSX.Element;
|
|
62
75
|
//# sourceMappingURL=ResponsiveWorkbench.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponsiveWorkbench.d.ts","sourceRoot":"","sources":["../../../src/react/components/ResponsiveWorkbench.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"ResponsiveWorkbench.d.ts","sourceRoot":"","sources":["../../../src/react/components/ResponsiveWorkbench.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,OAAO,CAAC;AASzD;;yFAEyF;AACzF,wBAAgB,sBAAsB,CAAC,UAAU,GAAE,MAA2B,GAAG,OAAO,CAEvF;AAaD,MAAM,WAAW,wBAAwB;IACvC,mFAAmF;IACnF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,EAAE,SAAS,CAAC;IAEpB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,qFAAqF;IACrF,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C;yEACqE;IACrE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE7B,gDAAgD;IAChD,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,kBAAkB,CAAC,EAAE,SAAS,CAAC;IAE/B,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAE7B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACpC,4GAA4G;IAC5G,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAEpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAChB,eAAsB,EACtB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,gBAAwB,EACxB,SAAe,EACf,UAAgB,EAChB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,UAA+B,EAC/B,gBAAgB,EAChB,YAAwB,EACxB,gBAAgB,EAChB,SAAS,GACV,EAAE,wBAAwB,+BAiI1B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
3
|
import { useMediaQuery } from '../hooks/useMediaQuery.js';
|
|
4
4
|
import { cn } from '../lib/cn.js';
|
|
5
5
|
import { Drawer } from './Drawer.js';
|
|
@@ -18,6 +18,8 @@ function useOpenState(controlled, onChange, defaultValue) {
|
|
|
18
18
|
const setOpen = onChange ?? setUncontrolled;
|
|
19
19
|
return [open, setOpen];
|
|
20
20
|
}
|
|
21
|
+
/** Travel, in px, that turns a press on the sheets handle into a swipe up. */
|
|
22
|
+
const SWIPE_UP = 32;
|
|
21
23
|
/**
|
|
22
24
|
* The three-pane workbench (left rail / main / right rail) used by builder-style apps.
|
|
23
25
|
* At/above `breakpoint` (default 1024, Tailwind `lg`) both rails render as persistent,
|
|
@@ -33,12 +35,39 @@ function useOpenState(controlled, onChange, defaultValue) {
|
|
|
33
35
|
* This is the reusable answer to "sidebars must become drawers on mobile" — write the
|
|
34
36
|
* responsive behavior once here, not per app.
|
|
35
37
|
*/
|
|
36
|
-
export function ResponsiveWorkbench({ left, right, children, leftOpen: leftOpenProp, onLeftOpenChange, defaultLeftOpen = true, rightOpen: rightOpenProp, onRightOpenChange, defaultRightOpen = false, leftWidth = 280, rightWidth = 280, leftTitle, rightTitle, leftCollapsedRail, rightCollapsedRail, breakpoint = DEFAULT_BREAKPOINT, mobileUtilityBar, className, }) {
|
|
38
|
+
export function ResponsiveWorkbench({ left, right, children, leftOpen: leftOpenProp, onLeftOpenChange, defaultLeftOpen = true, rightOpen: rightOpenProp, onRightOpenChange, defaultRightOpen = false, leftWidth = 280, rightWidth = 280, leftTitle, rightTitle, leftCollapsedRail, rightCollapsedRail, breakpoint = DEFAULT_BREAKPOINT, mobileUtilityBar, mobilePanels = 'drawers', mobileSwipeOpens, className, }) {
|
|
37
39
|
const isDesktop = useWorkbenchBreakpoint(breakpoint);
|
|
38
40
|
const [leftOpen, setLeftOpen] = useOpenState(leftOpenProp, onLeftOpenChange, defaultLeftOpen);
|
|
39
41
|
const [rightOpen, setRightOpen] = useOpenState(rightOpenProp, onRightOpenChange, defaultRightOpen);
|
|
42
|
+
const sheets = mobilePanels === 'sheets';
|
|
43
|
+
// The handle's swipe up. A swipe that starts on one of the caller's buttons must not ALSO click
|
|
44
|
+
// it (Explore opening on top of the sheet the swipe opened), so the click after a swipe is eaten.
|
|
45
|
+
const swipe = useRef(null);
|
|
46
|
+
const swiped = useRef(false);
|
|
47
|
+
const swipeTarget = mobileSwipeOpens ?? (right ? 'right' : 'left');
|
|
40
48
|
return (_jsxs("div", { "data-cb-page-width": 'full', className: cn('relative flex min-h-0 flex-1 flex-col overflow-hidden', className), children: [_jsxs("div", { className: 'flex min-h-0 flex-1 overflow-hidden', children: [left &&
|
|
41
|
-
(isDesktop ? (leftOpen ? (_jsx("aside", { "data-cb-workbench-rail": 'left', style: { width: leftWidth }, className: 'flex shrink-0 flex-col overflow-hidden border-r border-border bg-card', children: left })) : ((leftCollapsedRail ?? null))) : (_jsx(Drawer, { open: leftOpen, onClose: () => setLeftOpen(false), side: 'left', title: leftTitle, scrollBody: false, children: _jsx("div", { className: 'flex min-h-0 flex-1 flex-col', children: left }) }))), _jsx("div", { "data-cb-workbench-main": '', className: 'flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden', children: children }), right &&
|
|
42
|
-
(isDesktop ? (rightOpen ? (_jsx("aside", { "data-cb-workbench-rail": 'right', style: { width: rightWidth }, className: 'flex shrink-0 flex-col overflow-hidden border-l border-border bg-card', children: right })) : ((rightCollapsedRail ?? null))) : (_jsx(Drawer, { open: rightOpen, onClose: () => setRightOpen(false), side: 'right', title: rightTitle, scrollBody: false, children: _jsx("div", { className: 'flex min-h-0 flex-1 flex-col', children: right }) })))] }), !isDesktop && mobileUtilityBar && (_jsx("div", { "data-cb-workbench-
|
|
49
|
+
(isDesktop ? (leftOpen ? (_jsx("aside", { "data-cb-workbench-rail": 'left', style: { width: leftWidth }, className: 'flex shrink-0 flex-col overflow-hidden border-r border-border bg-card', children: left })) : ((leftCollapsedRail ?? null))) : (_jsx(Drawer, { open: leftOpen, onClose: () => setLeftOpen(false), side: sheets ? 'bottom' : 'left', size: sheets ? 'lg' : undefined, title: leftTitle, scrollBody: false, children: _jsx("div", { className: 'flex min-h-0 flex-1 flex-col', children: left }) }))), _jsx("div", { "data-cb-workbench-main": '', className: 'flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden', children: children }), right &&
|
|
50
|
+
(isDesktop ? (rightOpen ? (_jsx("aside", { "data-cb-workbench-rail": 'right', style: { width: rightWidth }, className: 'flex shrink-0 flex-col overflow-hidden border-l border-border bg-card', children: right })) : ((rightCollapsedRail ?? null))) : (_jsx(Drawer, { open: rightOpen, onClose: () => setRightOpen(false), side: sheets ? 'bottom' : 'right', size: sheets ? 'lg' : undefined, title: rightTitle, scrollBody: false, children: _jsx("div", { className: 'flex min-h-0 flex-1 flex-col', children: right }) })))] }), !isDesktop && mobileUtilityBar && sheets && (_jsx("div", { className: 'pointer-events-none absolute inset-x-3 bottom-[max(env(safe-area-inset-bottom,0px),0.75rem)] flex justify-center', children: _jsxs("div", { "data-cb-workbench-sheet-handle": '', className: cn('pointer-events-auto flex w-full max-w-md touch-none flex-col items-stretch gap-1.5', 'rounded-2xl border border-border/60 bg-background/85 px-2 pt-1.5 pb-2 shadow-raised backdrop-blur-md'), onPointerDown: (e) => {
|
|
51
|
+
swipe.current = { id: e.pointerId, y: e.clientY };
|
|
52
|
+
swiped.current = false;
|
|
53
|
+
}, onPointerUp: (e) => {
|
|
54
|
+
const start = swipe.current;
|
|
55
|
+
swipe.current = null;
|
|
56
|
+
if (!start || start.id !== e.pointerId || start.y - e.clientY < SWIPE_UP)
|
|
57
|
+
return;
|
|
58
|
+
swiped.current = true;
|
|
59
|
+
if (swipeTarget === 'right')
|
|
60
|
+
setRightOpen(true);
|
|
61
|
+
else
|
|
62
|
+
setLeftOpen(true);
|
|
63
|
+
}, onPointerCancel: () => {
|
|
64
|
+
swipe.current = null;
|
|
65
|
+
}, onClickCapture: (e) => {
|
|
66
|
+
if (!swiped.current)
|
|
67
|
+
return;
|
|
68
|
+
swiped.current = false;
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
e.stopPropagation();
|
|
71
|
+
}, children: [_jsx("span", { "aria-hidden": true, className: 'mx-auto h-1 w-9 shrink-0 rounded-full bg-border' }), mobileUtilityBar] }) })), !isDesktop && mobileUtilityBar && !sheets && (_jsx("div", { "data-cb-workbench-utility-bar": '', className: cn('flex shrink-0 items-center justify-between gap-2', 'border-t border-border bg-background px-3 py-2', 'pb-[max(env(safe-area-inset-bottom,0px),0.5rem)]'), style: { marginBottom: 'var(--keyboard-inset, 0px)' }, children: mobileUtilityBar }))] }));
|
|
43
72
|
}
|
|
44
73
|
//# sourceMappingURL=ResponsiveWorkbench.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponsiveWorkbench.js","sourceRoot":"","sources":["../../../src/react/components/ResponsiveWorkbench.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ResponsiveWorkbench.js","sourceRoot":"","sources":["../../../src/react/components/ResponsiveWorkbench.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;wDACwD;AACxD,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;;yFAEyF;AACzF,MAAM,UAAU,sBAAsB,CAAC,aAAqB,kBAAkB;IAC5E,OAAO,aAAa,CAAC,eAAe,UAAU,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,YAAY,CACnB,UAA+B,EAC/B,QAA+C,EAC/C,YAAqB;IAErB,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,UAAU,IAAI,YAAY,CAAC;IACxC,MAAM,OAAO,GAAG,QAAQ,IAAI,eAAe,CAAC;IAC5C,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACzB,CAAC;AAiED,8EAA8E;AAC9E,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAChB,eAAe,GAAG,IAAI,EACtB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,gBAAgB,GAAG,KAAK,EACxB,SAAS,GAAG,GAAG,EACf,UAAU,GAAG,GAAG,EAChB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,GAAG,kBAAkB,EAC/B,gBAAgB,EAChB,YAAY,GAAG,SAAS,EACxB,gBAAgB,EAChB,SAAS,GACgB;IACzB,MAAM,SAAS,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAAC,YAAY,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAC9F,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,YAAY,CAAC,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IACnG,MAAM,MAAM,GAAG,YAAY,KAAK,QAAQ,CAAC;IAEzC,gGAAgG;IAChG,kGAAkG;IAClG,MAAM,KAAK,GAAG,MAAM,CAAmC,IAAI,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,gBAAgB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAEnE,OAAO,CAGL,qCAAwB,MAAM,EAAC,SAAS,EAAE,EAAE,CAAC,uDAAuD,EAAE,SAAS,CAAC,aAC9G,eAAK,SAAS,EAAC,qCAAqC,aACjD,IAAI;wBACH,CAAC,SAAS,CAAC,CAAC,CAAC,CACX,QAAQ,CAAC,CAAC,CAAC,CACT,0CACyB,MAAM,EAC7B,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAC3B,SAAS,EAAC,uEAAuE,YAEhF,IAAI,GACC,CACT,CAAC,CAAC,CAAC,CACF,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAC5B,CACF,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IACL,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EACjC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAChC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAC/B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,KAAK,YAEjB,cAAK,SAAS,EAAC,8BAA8B,YAAE,IAAI,GAAO,GACnD,CACV,CAAC,EAEJ,wCACyB,EAAE,EACzB,SAAS,EAAC,sDAAsD,YAE/D,QAAQ,GACL,EAEL,KAAK;wBACJ,CAAC,SAAS,CAAC,CAAC,CAAC,CACX,SAAS,CAAC,CAAC,CAAC,CACV,0CACyB,OAAO,EAC9B,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAC5B,SAAS,EAAC,uEAAuE,YAEhF,KAAK,GACA,CACT,CAAC,CAAC,CAAC,CACF,CAAC,kBAAkB,IAAI,IAAI,CAAC,CAC7B,CACF,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IACL,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAClC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EACjC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAC/B,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,KAAK,YAEjB,cAAK,SAAS,EAAC,8BAA8B,YAAE,KAAK,GAAO,GACpD,CACV,CAAC,IACA,EAEL,CAAC,SAAS,IAAI,gBAAgB,IAAI,MAAM,IAAI,CAE3C,cAAK,SAAS,EAAC,kHAAkH,YAC/H,iDACiC,EAAE,EACjC,SAAS,EAAE,EAAE,CACX,oFAAoF,EACpF,sGAAsG,CACvG,EACD,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE;wBACnB,KAAK,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;wBAClD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;oBACzB,CAAC,EACD,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE;wBACjB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;wBAC5B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;wBACrB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,QAAQ;4BAAE,OAAO;wBACjF,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;wBACtB,IAAI,WAAW,KAAK,OAAO;4BAAE,YAAY,CAAC,IAAI,CAAC,CAAC;;4BAC3C,WAAW,CAAC,IAAI,CAAC,CAAC;oBACzB,CAAC,EACD,eAAe,EAAE,GAAG,EAAE;wBACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,CAAC,EACD,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;wBACpB,IAAI,CAAC,MAAM,CAAC,OAAO;4BAAE,OAAO;wBAC5B,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;wBACvB,CAAC,CAAC,cAAc,EAAE,CAAC;wBACnB,CAAC,CAAC,eAAe,EAAE,CAAC;oBACtB,CAAC,aAED,oCAAkB,SAAS,EAAC,iDAAiD,GAAG,EAC/E,gBAAgB,IACb,GACF,CACP,EAEA,CAAC,SAAS,IAAI,gBAAgB,IAAI,CAAC,MAAM,IAAI,CAC5C,+CACgC,EAAE,EAChC,SAAS,EAAE,EAAE,CACX,kDAAkD,EAClD,gDAAgD,EAChD,kDAAkD,CACnD,EACD,KAAK,EAAE,EAAE,YAAY,EAAE,4BAA4B,EAAE,YAEpD,gBAAgB,GACb,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
|