@hilum/designer 3.8.1 → 3.8.3
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 +49 -0
- package/dist/index.d.ts +58 -10
- package/dist/index.js +200 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,10 +7,59 @@ For the actual canvas (pan/zoom viewport, layers, drag/resize), use `@hilum/desi
|
|
|
7
7
|
## Components
|
|
8
8
|
|
|
9
9
|
- `<DesignerShell>` — root layout (full viewport, themed)
|
|
10
|
+
- `<DesignerWorkspace>` / `<DesignerWorkspaceViewport>` — floating-chrome positioning boundary and safe canvas region
|
|
10
11
|
- `<DesignerHeader>` / `<DesignerSidebar>` / `<DesignerPanel>` — chrome
|
|
11
12
|
- `<DesignerPane>` — collapsible property panel section with `showFor` predicate
|
|
12
13
|
- `<DesignerToolbar>` + `Group` / `Button` / `Separator` — composable toolbar
|
|
13
14
|
|
|
15
|
+
## Floating workspace
|
|
16
|
+
|
|
17
|
+
Use the workspace primitives when desktop editor chrome should float over a
|
|
18
|
+
full-bleed surface. Without `safeInsets`, the viewport fills the workspace and
|
|
19
|
+
floating panels overlay the canvas. Add `safeInsets` when an editor instead
|
|
20
|
+
needs an unobscured region for fit and center calculations.
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
<DesignerWorkspace>
|
|
24
|
+
<DesignerWorkspaceViewport>{canvas}</DesignerWorkspaceViewport>
|
|
25
|
+
|
|
26
|
+
<DesignerSidebar variant="floating" floatingInset={{ left: 0 }} items={tools} />
|
|
27
|
+
<DesignerPanel side="left" variant="floating" width={280} floatingInset={{ left: 60 }}>
|
|
28
|
+
{library}
|
|
29
|
+
</DesignerPanel>
|
|
30
|
+
<DesignerPanel side="right" variant="floating" width={304}>
|
|
31
|
+
{inspector}
|
|
32
|
+
</DesignerPanel>
|
|
33
|
+
|
|
34
|
+
<DesignerToolbar boundary="workspace" center="boundary">
|
|
35
|
+
{actions}
|
|
36
|
+
</DesignerToolbar>
|
|
37
|
+
</DesignerWorkspace>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
To reserve an unobscured canvas between the floating surfaces, configure safe
|
|
41
|
+
insets and center the toolbar within the same region:
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
<DesignerWorkspace safeInsets={{ top: 16, right: 336, bottom: 72, left: 376 }}>
|
|
45
|
+
<DesignerWorkspaceViewport>{canvas}</DesignerWorkspaceViewport>
|
|
46
|
+
|
|
47
|
+
<DesignerSidebar variant="floating" items={tools} />
|
|
48
|
+
<DesignerPanel side="left" variant="floating" width={280} floatingInset={{ left: 76 }}>
|
|
49
|
+
{library}
|
|
50
|
+
</DesignerPanel>
|
|
51
|
+
<DesignerPanel side="right" variant="floating" width={304}>
|
|
52
|
+
{inspector}
|
|
53
|
+
</DesignerPanel>
|
|
54
|
+
|
|
55
|
+
<DesignerToolbar boundary="workspace" center="safe-area">
|
|
56
|
+
{actions}
|
|
57
|
+
</DesignerToolbar>
|
|
58
|
+
</DesignerWorkspace>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The existing inline desktop and sheet/bottom mobile variants remain available.
|
|
62
|
+
|
|
14
63
|
## Hooks
|
|
15
64
|
|
|
16
65
|
- `useHistory<T>(initial)` — generic undo/redo stack
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { Dispatch, SetStateAction, ReactNode, ComponentType,
|
|
3
|
+
import { Dispatch, SetStateAction, ReactNode, ComponentPropsWithoutRef, ComponentType, CSSProperties } from 'react';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The minimal contract a designer shell needs from the engine beneath it.
|
|
@@ -56,7 +56,41 @@ interface DesignerShellProps {
|
|
|
56
56
|
*/
|
|
57
57
|
declare function DesignerShell({ className, children }: DesignerShellProps): react_jsx_runtime.JSX.Element;
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
type DesignerWorkspaceInsetValue = number | string;
|
|
60
|
+
interface DesignerWorkspaceInsets {
|
|
61
|
+
top: DesignerWorkspaceInsetValue;
|
|
62
|
+
right: DesignerWorkspaceInsetValue;
|
|
63
|
+
bottom: DesignerWorkspaceInsetValue;
|
|
64
|
+
left: DesignerWorkspaceInsetValue;
|
|
65
|
+
}
|
|
66
|
+
type DesignerWorkspaceInsetsInput = DesignerWorkspaceInsetValue | Partial<DesignerWorkspaceInsets>;
|
|
67
|
+
|
|
68
|
+
interface DesignerWorkspaceProps extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
|
|
69
|
+
/**
|
|
70
|
+
* Insets that describe the unobscured canvas area between floating chrome.
|
|
71
|
+
* Numbers are interpreted as pixels; CSS lengths and calc() expressions are
|
|
72
|
+
* accepted for responsive shells.
|
|
73
|
+
*/
|
|
74
|
+
safeInsets?: DesignerWorkspaceInsetsInput;
|
|
75
|
+
children: ReactNode;
|
|
76
|
+
}
|
|
77
|
+
interface DesignerWorkspaceViewportProps extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
|
|
78
|
+
children: ReactNode;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Positioning boundary for a canvas editor. Floating rails, panels, and
|
|
82
|
+
* toolbars are layered over this surface while DesignerWorkspaceViewport uses
|
|
83
|
+
* the configured safe insets to keep document content unobscured.
|
|
84
|
+
*/
|
|
85
|
+
declare function DesignerWorkspace({ safeInsets, className, style, children, ...props }: DesignerWorkspaceProps): react_jsx_runtime.JSX.Element;
|
|
86
|
+
/**
|
|
87
|
+
* Safe, canvas-sized region within DesignerWorkspace. Its bounds are derived
|
|
88
|
+
* from the workspace's safeInsets so fit/center calculations use the visible
|
|
89
|
+
* area between floating editor chrome.
|
|
90
|
+
*/
|
|
91
|
+
declare function DesignerWorkspaceViewport({ className, style, children, ...props }: DesignerWorkspaceViewportProps): react_jsx_runtime.JSX.Element;
|
|
92
|
+
|
|
93
|
+
interface DesignerHeaderProps extends Omit<ComponentPropsWithoutRef<"header">, "children"> {
|
|
60
94
|
/** Left-aligned content — file name, breadcrumbs, project switcher. */
|
|
61
95
|
left?: ReactNode;
|
|
62
96
|
/** Center content — typically the active document title. */
|
|
@@ -70,7 +104,7 @@ interface DesignerHeaderProps {
|
|
|
70
104
|
* Top bar of an editor app. Slot-driven — the chrome doesn't know what
|
|
71
105
|
* goes in each region. Use <DesignerHeader left={...} center={...} right={...} />.
|
|
72
106
|
*/
|
|
73
|
-
declare function DesignerHeader({ left, center, right, className, children }: DesignerHeaderProps): react_jsx_runtime.JSX.Element;
|
|
107
|
+
declare function DesignerHeader({ left, center, right, className, children, ...props }: DesignerHeaderProps): react_jsx_runtime.JSX.Element;
|
|
74
108
|
|
|
75
109
|
interface SidebarItem {
|
|
76
110
|
id: string;
|
|
@@ -90,10 +124,13 @@ interface DesignerSidebarProps {
|
|
|
90
124
|
items: SidebarItem[];
|
|
91
125
|
/** Optional bottom group (settings, help, account). */
|
|
92
126
|
bottomItems?: SidebarItem[];
|
|
93
|
-
/** Layout variant. `rail` preserves the desktop vertical rail. */
|
|
94
|
-
variant?: "rail" | "bottom";
|
|
127
|
+
/** Layout variant. `rail` preserves the inline desktop vertical rail. */
|
|
128
|
+
variant?: "rail" | "floating" | "bottom";
|
|
95
129
|
side?: "left" | "right";
|
|
130
|
+
/** Insets used to position a floating rail within DesignerWorkspace. Default: 16px. */
|
|
131
|
+
floatingInset?: DesignerWorkspaceInsetsInput;
|
|
96
132
|
className?: string;
|
|
133
|
+
style?: CSSProperties;
|
|
97
134
|
children?: ReactNode;
|
|
98
135
|
}
|
|
99
136
|
/**
|
|
@@ -101,16 +138,18 @@ interface DesignerSidebarProps {
|
|
|
101
138
|
* editor. Driven by an `items` array — no engine coupling. Each item gets
|
|
102
139
|
* a tooltip showing its label.
|
|
103
140
|
*/
|
|
104
|
-
declare function DesignerSidebar({ items, bottomItems, variant, side, className, children, }: DesignerSidebarProps): react_jsx_runtime.JSX.Element;
|
|
141
|
+
declare function DesignerSidebar({ items, bottomItems, variant, side, floatingInset, className, style, children, }: DesignerSidebarProps): react_jsx_runtime.JSX.Element;
|
|
105
142
|
|
|
106
143
|
interface DesignerPanelProps {
|
|
107
144
|
side: "left" | "right";
|
|
108
145
|
/** Presentation mode. `inline` preserves the desktop side-panel behavior. */
|
|
109
|
-
variant?: "inline" | "sheet";
|
|
146
|
+
variant?: "inline" | "floating" | "sheet";
|
|
110
147
|
/** Width in pixels. Default: 240. */
|
|
111
148
|
width?: number;
|
|
112
149
|
/** Add a separator border on the inner edge. Default: true. */
|
|
113
150
|
bordered?: boolean;
|
|
151
|
+
/** Insets used to position a floating panel within DesignerWorkspace. Default: 16px. */
|
|
152
|
+
floatingInset?: DesignerWorkspaceInsetsInput;
|
|
114
153
|
/** Controlled open state when `variant="sheet"`. */
|
|
115
154
|
open?: boolean;
|
|
116
155
|
/** Controlled open-state handler when `variant="sheet"`. */
|
|
@@ -123,6 +162,7 @@ interface DesignerPanelProps {
|
|
|
123
162
|
sheetSide?: "left" | "right" | "top" | "bottom";
|
|
124
163
|
sheetClassName?: string;
|
|
125
164
|
className?: string;
|
|
165
|
+
style?: CSSProperties;
|
|
126
166
|
children?: ReactNode;
|
|
127
167
|
}
|
|
128
168
|
/**
|
|
@@ -130,7 +170,7 @@ interface DesignerPanelProps {
|
|
|
130
170
|
* inspector / properties, history, comments, etc. Static-width for v1.
|
|
131
171
|
* (Resize handles arrive in a later iteration if needed.)
|
|
132
172
|
*/
|
|
133
|
-
declare function DesignerPanel({ side, variant, width, bordered, open, onOpenChange, sheetTitle, sheetDescription, sheetSide, sheetClassName, className, children, }: DesignerPanelProps): react_jsx_runtime.JSX.Element;
|
|
173
|
+
declare function DesignerPanel({ side, variant, width, bordered, floatingInset, open, onOpenChange, sheetTitle, sheetDescription, sheetSide, sheetClassName, className, style, children, }: DesignerPanelProps): react_jsx_runtime.JSX.Element;
|
|
134
174
|
|
|
135
175
|
interface DesignerPaneProps {
|
|
136
176
|
/**
|
|
@@ -197,9 +237,17 @@ interface DesignerToolbarProps {
|
|
|
197
237
|
className?: string;
|
|
198
238
|
/** Position. Default: 'floating' (centered, floating above content). */
|
|
199
239
|
variant?: "floating" | "inline" | "dock";
|
|
240
|
+
/**
|
|
241
|
+
* Position floating chrome against the viewport or the nearest positioned
|
|
242
|
+
* workspace ancestor. Default: 'viewport'.
|
|
243
|
+
*/
|
|
244
|
+
boundary?: "viewport" | "workspace";
|
|
245
|
+
/** Center against the full boundary or its configured workspace safe area. */
|
|
246
|
+
center?: "boundary" | "safe-area";
|
|
247
|
+
style?: CSSProperties;
|
|
200
248
|
children: ReactNode;
|
|
201
249
|
}
|
|
202
|
-
declare function DesignerToolbar({ className, variant, children }: DesignerToolbarProps): react_jsx_runtime.JSX.Element;
|
|
250
|
+
declare function DesignerToolbar({ className, variant, boundary, center, style, children, }: DesignerToolbarProps): react_jsx_runtime.JSX.Element;
|
|
203
251
|
interface DesignerToolbarGroupProps {
|
|
204
252
|
className?: string;
|
|
205
253
|
children: ReactNode;
|
|
@@ -358,4 +406,4 @@ interface UseKeybindingsOptions {
|
|
|
358
406
|
*/
|
|
359
407
|
declare function useKeybindings(bindings: KeybindingConfig[], { disabled, target }?: UseKeybindingsOptions): void;
|
|
360
408
|
|
|
361
|
-
export { CornerRadiusControl, type CornerRadiusControlProps, type CornerSide, type DesignerControlValue, DesignerHeader, type DesignerHeaderProps, DesignerPane, DesignerPaneContent, type DesignerPaneContentProps, type DesignerPaneProps, DesignerPaneTitle, type DesignerPaneTitleProps, DesignerPanel, type DesignerPanelProps, DesignerPropertyControls, type DesignerPropertyControlsProps, DesignerPropertyGroup, type DesignerPropertyGroupProps, DesignerPropertyLabel, type DesignerPropertyLabelProps, DesignerPropertyRow, type DesignerPropertyRowProps, DesignerShell, type DesignerShellProps, DesignerSidebar, type DesignerSidebarProps, DesignerToolbar, DesignerToolbarButton, type DesignerToolbarButtonProps, DesignerToolbarGroup, type DesignerToolbarGroupProps, type DesignerToolbarProps, DesignerToolbarSeparator, type DesignerToolbarSeparatorProps, type DesignerValueItem, FourValueControl, type FourValueControlProps, type KeybindingConfig, type ShellContextValue, ShellProvider, type SidebarItem, SpacingControl, type SpacingControlProps, type SpacingSide, TwoValueControl, type TwoValueControlProps, useHistory, useKeybindings, useShellContext };
|
|
409
|
+
export { CornerRadiusControl, type CornerRadiusControlProps, type CornerSide, type DesignerControlValue, DesignerHeader, type DesignerHeaderProps, DesignerPane, DesignerPaneContent, type DesignerPaneContentProps, type DesignerPaneProps, DesignerPaneTitle, type DesignerPaneTitleProps, DesignerPanel, type DesignerPanelProps, DesignerPropertyControls, type DesignerPropertyControlsProps, DesignerPropertyGroup, type DesignerPropertyGroupProps, DesignerPropertyLabel, type DesignerPropertyLabelProps, DesignerPropertyRow, type DesignerPropertyRowProps, DesignerShell, type DesignerShellProps, DesignerSidebar, type DesignerSidebarProps, DesignerToolbar, DesignerToolbarButton, type DesignerToolbarButtonProps, DesignerToolbarGroup, type DesignerToolbarGroupProps, type DesignerToolbarProps, DesignerToolbarSeparator, type DesignerToolbarSeparatorProps, type DesignerValueItem, DesignerWorkspace, type DesignerWorkspaceInsetValue, type DesignerWorkspaceInsets, type DesignerWorkspaceInsetsInput, type DesignerWorkspaceProps, DesignerWorkspaceViewport, type DesignerWorkspaceViewportProps, FourValueControl, type FourValueControlProps, type KeybindingConfig, type ShellContextValue, ShellProvider, type SidebarItem, SpacingControl, type SpacingControlProps, type SpacingSide, TwoValueControl, type TwoValueControlProps, useHistory, useKeybindings, useShellContext };
|
package/dist/index.js
CHANGED
|
@@ -53,18 +53,118 @@ function DesignerShell({ className, children }) {
|
|
|
53
53
|
}
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
// src/components/designer-workspace-insets.ts
|
|
58
|
+
function toCssLength(value) {
|
|
59
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
60
|
+
}
|
|
61
|
+
function resolveDesignerWorkspaceInsets(input, fallback = 0) {
|
|
62
|
+
const fallbackValue = toCssLength(fallback);
|
|
63
|
+
if (typeof input === "number" || typeof input === "string") {
|
|
64
|
+
const value = toCssLength(input);
|
|
65
|
+
return { top: value, right: value, bottom: value, left: value };
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
top: input?.top === void 0 ? fallbackValue : toCssLength(input.top),
|
|
69
|
+
right: input?.right === void 0 ? fallbackValue : toCssLength(input.right),
|
|
70
|
+
bottom: input?.bottom === void 0 ? fallbackValue : toCssLength(input.bottom),
|
|
71
|
+
left: input?.left === void 0 ? fallbackValue : toCssLength(input.left)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function DesignerWorkspace({
|
|
75
|
+
safeInsets,
|
|
76
|
+
className,
|
|
77
|
+
style,
|
|
78
|
+
children,
|
|
79
|
+
...props
|
|
80
|
+
}) {
|
|
81
|
+
const insets = resolveDesignerWorkspaceInsets(safeInsets);
|
|
82
|
+
const workspaceStyle = {
|
|
83
|
+
"--designer-workspace-inset-top": insets.top,
|
|
84
|
+
"--designer-workspace-inset-right": insets.right,
|
|
85
|
+
"--designer-workspace-inset-bottom": insets.bottom,
|
|
86
|
+
"--designer-workspace-inset-left": insets.left,
|
|
87
|
+
...style
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ jsx(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
"data-designer-workspace": true,
|
|
93
|
+
className: cn(
|
|
94
|
+
"relative isolate flex min-h-0 min-w-0 flex-1 overflow-hidden bg-muted",
|
|
95
|
+
className
|
|
96
|
+
),
|
|
97
|
+
style: workspaceStyle,
|
|
98
|
+
...props,
|
|
99
|
+
children
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
function DesignerWorkspaceViewport({
|
|
104
|
+
className,
|
|
105
|
+
style,
|
|
106
|
+
children,
|
|
107
|
+
...props
|
|
108
|
+
}) {
|
|
109
|
+
return /* @__PURE__ */ jsx(
|
|
110
|
+
"div",
|
|
111
|
+
{
|
|
112
|
+
"data-designer-workspace-viewport": true,
|
|
113
|
+
className: cn("absolute z-0 flex min-h-0 min-w-0 overflow-hidden", className),
|
|
114
|
+
style: {
|
|
115
|
+
top: "var(--designer-workspace-inset-top)",
|
|
116
|
+
right: "var(--designer-workspace-inset-right)",
|
|
117
|
+
bottom: "var(--designer-workspace-inset-bottom)",
|
|
118
|
+
left: "var(--designer-workspace-inset-left)",
|
|
119
|
+
...style
|
|
120
|
+
},
|
|
121
|
+
...props,
|
|
122
|
+
children
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
function DesignerHeader({
|
|
127
|
+
left,
|
|
128
|
+
center,
|
|
129
|
+
right,
|
|
130
|
+
className,
|
|
131
|
+
children,
|
|
132
|
+
...props
|
|
133
|
+
}) {
|
|
57
134
|
return /* @__PURE__ */ jsxs(
|
|
58
135
|
"header",
|
|
59
136
|
{
|
|
137
|
+
"data-designer-header": true,
|
|
60
138
|
className: cn(
|
|
61
|
-
"
|
|
139
|
+
"grid h-12 shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3 border-b border-border bg-card px-3",
|
|
62
140
|
className
|
|
63
141
|
),
|
|
142
|
+
...props,
|
|
64
143
|
children: [
|
|
65
|
-
/* @__PURE__ */ jsx(
|
|
66
|
-
|
|
67
|
-
|
|
144
|
+
/* @__PURE__ */ jsx(
|
|
145
|
+
"div",
|
|
146
|
+
{
|
|
147
|
+
"data-designer-header-slot": "left",
|
|
148
|
+
className: "flex min-w-0 items-center gap-2 justify-self-start",
|
|
149
|
+
children: left
|
|
150
|
+
}
|
|
151
|
+
),
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
"div",
|
|
154
|
+
{
|
|
155
|
+
"data-designer-header-slot": "center",
|
|
156
|
+
className: "flex min-w-0 items-center gap-2 justify-self-center",
|
|
157
|
+
children: center
|
|
158
|
+
}
|
|
159
|
+
),
|
|
160
|
+
/* @__PURE__ */ jsx(
|
|
161
|
+
"div",
|
|
162
|
+
{
|
|
163
|
+
"data-designer-header-slot": "right",
|
|
164
|
+
className: "flex min-w-0 items-center gap-2 justify-self-end",
|
|
165
|
+
children: right
|
|
166
|
+
}
|
|
167
|
+
),
|
|
68
168
|
children
|
|
69
169
|
]
|
|
70
170
|
}
|
|
@@ -75,7 +175,9 @@ function DesignerSidebar({
|
|
|
75
175
|
bottomItems,
|
|
76
176
|
variant = "rail",
|
|
77
177
|
side = "left",
|
|
178
|
+
floatingInset,
|
|
78
179
|
className,
|
|
180
|
+
style,
|
|
79
181
|
children
|
|
80
182
|
}) {
|
|
81
183
|
if (variant === "bottom") {
|
|
@@ -89,6 +191,7 @@ function DesignerSidebar({
|
|
|
89
191
|
"rounded-xl border border-border bg-card p-1 shadow-natural",
|
|
90
192
|
className
|
|
91
193
|
),
|
|
194
|
+
style,
|
|
92
195
|
children: /* @__PURE__ */ jsxs(TooltipProvider, { children: [
|
|
93
196
|
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-1 overflow-x-auto overscroll-x-contain", children: allItems.map((item) => /* @__PURE__ */ jsx(SidebarButton, { item, tooltipSide: "top", touchTarget: true }, item.id)) }),
|
|
94
197
|
children
|
|
@@ -96,20 +199,60 @@ function DesignerSidebar({
|
|
|
96
199
|
}
|
|
97
200
|
);
|
|
98
201
|
}
|
|
202
|
+
const content = /* @__PURE__ */ jsxs(TooltipProvider, { children: [
|
|
203
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col items-center gap-0.5 overflow-y-auto overscroll-contain p-1.5", children: items.map((item) => /* @__PURE__ */ jsx(
|
|
204
|
+
SidebarButton,
|
|
205
|
+
{
|
|
206
|
+
item,
|
|
207
|
+
tooltipSide: side === "left" ? "right" : "left"
|
|
208
|
+
},
|
|
209
|
+
item.id
|
|
210
|
+
)) }),
|
|
211
|
+
children,
|
|
212
|
+
bottomItems && bottomItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 flex-col items-center gap-0.5 p-1.5", children: bottomItems.map((item) => /* @__PURE__ */ jsx(
|
|
213
|
+
SidebarButton,
|
|
214
|
+
{
|
|
215
|
+
item,
|
|
216
|
+
tooltipSide: side === "left" ? "right" : "left"
|
|
217
|
+
},
|
|
218
|
+
item.id
|
|
219
|
+
)) })
|
|
220
|
+
] });
|
|
221
|
+
if (variant === "floating") {
|
|
222
|
+
const insets = resolveDesignerWorkspaceInsets(floatingInset, 16);
|
|
223
|
+
return /* @__PURE__ */ jsx(
|
|
224
|
+
"nav",
|
|
225
|
+
{
|
|
226
|
+
"aria-label": "Editor tools",
|
|
227
|
+
"data-side": side,
|
|
228
|
+
"data-variant": variant,
|
|
229
|
+
className: cn(
|
|
230
|
+
"absolute z-30 flex w-12 flex-col overflow-hidden rounded-xl border border-border bg-card shadow-natural",
|
|
231
|
+
className
|
|
232
|
+
),
|
|
233
|
+
style: {
|
|
234
|
+
top: insets.top,
|
|
235
|
+
bottom: insets.bottom,
|
|
236
|
+
[side]: insets[side],
|
|
237
|
+
...style
|
|
238
|
+
},
|
|
239
|
+
children: content
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
}
|
|
99
243
|
return /* @__PURE__ */ jsx(
|
|
100
244
|
"aside",
|
|
101
245
|
{
|
|
246
|
+
"data-side": side,
|
|
247
|
+
"data-variant": variant,
|
|
102
248
|
className: cn(
|
|
103
249
|
"flex flex-col w-12 bg-card shrink-0",
|
|
104
250
|
side === "left" ? "border-r" : "border-l",
|
|
105
251
|
"border-border",
|
|
106
252
|
className
|
|
107
253
|
),
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
children,
|
|
111
|
-
bottomItems && bottomItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col items-center gap-0.5 p-1.5", children: bottomItems.map((item) => /* @__PURE__ */ jsx(SidebarButton, { item, tooltipSide: side === "left" ? "right" : "left" }, item.id)) })
|
|
112
|
-
] })
|
|
254
|
+
style,
|
|
255
|
+
children: content
|
|
113
256
|
}
|
|
114
257
|
);
|
|
115
258
|
}
|
|
@@ -149,6 +292,7 @@ function DesignerPanel({
|
|
|
149
292
|
variant = "inline",
|
|
150
293
|
width = 240,
|
|
151
294
|
bordered = true,
|
|
295
|
+
floatingInset,
|
|
152
296
|
open,
|
|
153
297
|
onOpenChange,
|
|
154
298
|
sheetTitle,
|
|
@@ -156,6 +300,7 @@ function DesignerPanel({
|
|
|
156
300
|
sheetSide = "bottom",
|
|
157
301
|
sheetClassName,
|
|
158
302
|
className,
|
|
303
|
+
style,
|
|
159
304
|
children
|
|
160
305
|
}) {
|
|
161
306
|
if (variant === "sheet") {
|
|
@@ -174,25 +319,44 @@ function DesignerPanel({
|
|
|
174
319
|
sheetClassName
|
|
175
320
|
),
|
|
176
321
|
children: [
|
|
177
|
-
/* @__PURE__ */ jsxs(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
322
|
+
/* @__PURE__ */ jsxs(
|
|
323
|
+
SheetHeader,
|
|
324
|
+
{
|
|
325
|
+
className: cn(sheetTitle ? "mb-0 border-b border-border px-4 py-3" : "sr-only"),
|
|
326
|
+
children: [
|
|
327
|
+
/* @__PURE__ */ jsx(SheetTitle, { children: sheetTitle ?? `${side} panel` }),
|
|
328
|
+
/* @__PURE__ */ jsx(SheetDescription, { className: sheetDescription ? void 0 : "sr-only", children: resolvedSheetDescription })
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
),
|
|
181
332
|
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col overflow-x-hidden overflow-y-auto", children })
|
|
182
333
|
]
|
|
183
334
|
}
|
|
184
335
|
) });
|
|
185
336
|
}
|
|
337
|
+
const floatingInsets = resolveDesignerWorkspaceInsets(floatingInset, 16);
|
|
338
|
+
const floatingStyle = variant === "floating" ? {
|
|
339
|
+
top: floatingInsets.top,
|
|
340
|
+
bottom: floatingInsets.bottom,
|
|
341
|
+
[side]: floatingInsets[side],
|
|
342
|
+
width,
|
|
343
|
+
maxWidth: "calc(100% - 2rem)",
|
|
344
|
+
...style
|
|
345
|
+
} : { width, maxWidth: "100%", ...style };
|
|
186
346
|
return /* @__PURE__ */ jsx(
|
|
187
347
|
"aside",
|
|
188
348
|
{
|
|
349
|
+
"data-side": side,
|
|
350
|
+
"data-variant": variant,
|
|
189
351
|
className: cn(
|
|
190
352
|
"flex min-w-0 max-w-full shrink-0 flex-col overflow-hidden bg-card",
|
|
191
|
-
bordered && (side === "left" ? "border-r" : "border-l"),
|
|
192
|
-
bordered && "border-border",
|
|
353
|
+
variant === "inline" && bordered && (side === "left" ? "border-r" : "border-l"),
|
|
354
|
+
variant === "inline" && bordered && "border-border",
|
|
355
|
+
variant === "floating" && "absolute z-20 rounded-2xl shadow-natural",
|
|
356
|
+
variant === "floating" && bordered && "border border-border",
|
|
193
357
|
className
|
|
194
358
|
),
|
|
195
|
-
style:
|
|
359
|
+
style: floatingStyle,
|
|
196
360
|
children: /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col overflow-x-hidden overflow-y-auto", children })
|
|
197
361
|
}
|
|
198
362
|
);
|
|
@@ -340,20 +504,35 @@ function DesignerPropertyGroup({
|
|
|
340
504
|
children
|
|
341
505
|
] });
|
|
342
506
|
}
|
|
343
|
-
function DesignerToolbar({
|
|
507
|
+
function DesignerToolbar({
|
|
508
|
+
className,
|
|
509
|
+
variant = "floating",
|
|
510
|
+
boundary = "viewport",
|
|
511
|
+
center = "boundary",
|
|
512
|
+
style,
|
|
513
|
+
children
|
|
514
|
+
}) {
|
|
515
|
+
const positioned = boundary === "workspace" ? "absolute" : "fixed";
|
|
516
|
+
const safeAreaStyle = variant === "floating" && boundary === "workspace" && center === "safe-area" ? {
|
|
517
|
+
left: "calc(var(--designer-workspace-inset-left) + (100% - var(--designer-workspace-inset-left) - var(--designer-workspace-inset-right)) / 2)"
|
|
518
|
+
} : void 0;
|
|
344
519
|
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(
|
|
345
520
|
"div",
|
|
346
521
|
{
|
|
347
522
|
role: "toolbar",
|
|
348
523
|
className: cn(
|
|
349
524
|
"flex items-center gap-0.5 rounded-lg bg-card p-1 shadow-natural",
|
|
350
|
-
variant === "floating" &&
|
|
525
|
+
variant === "floating" && positioned,
|
|
526
|
+
variant === "floating" && "bottom-4 -translate-x-1/2 z-30",
|
|
527
|
+
variant === "floating" && center === "boundary" && "left-1/2",
|
|
351
528
|
variant === "dock" && [
|
|
352
|
-
|
|
529
|
+
positioned,
|
|
530
|
+
"inset-x-3 bottom-[max(0.75rem,env(safe-area-inset-bottom))] z-30",
|
|
353
531
|
"overflow-x-auto overscroll-x-contain rounded-xl"
|
|
354
532
|
],
|
|
355
533
|
className
|
|
356
534
|
),
|
|
535
|
+
style: { ...safeAreaStyle, ...style },
|
|
357
536
|
children
|
|
358
537
|
}
|
|
359
538
|
) });
|
|
@@ -680,6 +859,6 @@ function useKeybindings(bindings, { disabled, target } = {}) {
|
|
|
680
859
|
}, [bindings, disabled, target]);
|
|
681
860
|
}
|
|
682
861
|
|
|
683
|
-
export { CornerRadiusControl, DesignerHeader, DesignerPane, DesignerPaneContent, DesignerPaneTitle, DesignerPanel, DesignerPropertyControls, DesignerPropertyGroup, DesignerPropertyLabel, DesignerPropertyRow, DesignerShell, DesignerSidebar, DesignerToolbar, DesignerToolbarButton, DesignerToolbarGroup, DesignerToolbarSeparator, FourValueControl, ShellProvider, SpacingControl, TwoValueControl, useHistory, useKeybindings, useShellContext };
|
|
862
|
+
export { CornerRadiusControl, DesignerHeader, DesignerPane, DesignerPaneContent, DesignerPaneTitle, DesignerPanel, DesignerPropertyControls, DesignerPropertyGroup, DesignerPropertyLabel, DesignerPropertyRow, DesignerShell, DesignerSidebar, DesignerToolbar, DesignerToolbarButton, DesignerToolbarGroup, DesignerToolbarSeparator, DesignerWorkspace, DesignerWorkspaceViewport, FourValueControl, ShellProvider, SpacingControl, TwoValueControl, useHistory, useKeybindings, useShellContext };
|
|
684
863
|
//# sourceMappingURL=index.js.map
|
|
685
864
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shell/ShellContext.tsx","../src/components/DesignerShell.tsx","../src/components/DesignerHeader.tsx","../src/components/DesignerSidebar.tsx","../src/components/DesignerPanel.tsx","../src/components/DesignerPane.tsx","../src/components/DesignerPropertyRow.tsx","../src/components/DesignerToolbar.tsx","../src/components/DesignerValueControls.tsx","../src/hooks/useHistory.ts","../src/hooks/useKeybindings.ts"],"names":["jsx","cn","jsxs","useState","createContext","useContext","TooltipProvider","Tooltip","TooltipTrigger","TooltipContent"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext, useMemo, useState } from \"react\";\nimport type { Dispatch, ReactNode, SetStateAction } from \"react\";\n\n/**\n * The minimal contract a designer shell needs from the engine beneath it.\n *\n * The chrome (toolbar, panel, pane, sidebar) reads from this context.\n * It does NOT know what is being edited — selection IDs are opaque strings\n * (layer IDs, field IDs, node IDs — whatever the engine uses), and active\n * tool is an open string the app defines (`select`, `hand`, `text`, …).\n *\n * @hilum/designer-canvas wires this up for canvas apps. A form-builder app\n * could wire its own engine to ShellContext with the same primitives.\n */\nexport interface ShellContextValue {\n /** IDs of currently-selected items. Engine-defined meaning. */\n selectedIds: string[];\n setSelectedIds: Dispatch<SetStateAction<string[]>>;\n\n /** Active tool. App-defined enum (e.g. 'select' | 'hand' | 'text'). */\n activeTool: string;\n setActiveTool: Dispatch<SetStateAction<string>>;\n\n /** When true, mutating actions should no-op. Used for previews. */\n readOnly: boolean;\n\n /**\n * Optional resolver: given a `selectedId`, return its engine-defined \"kind\"\n * (e.g. 'text', 'image'). DesignerPane.showFor uses this to decide whether\n * to render. Apps that don't have typed selections can leave this undefined.\n */\n resolveKind?: (id: string) => string | undefined;\n}\n\nconst noop = () => {};\n\nconst DEFAULT: ShellContextValue = {\n selectedIds: [],\n setSelectedIds: noop as Dispatch<SetStateAction<string[]>>,\n activeTool: \"select\",\n setActiveTool: noop as Dispatch<SetStateAction<string>>,\n readOnly: false,\n};\n\nconst ShellContext = createContext<ShellContextValue>(DEFAULT);\n\nexport function useShellContext(): ShellContextValue {\n return useContext(ShellContext);\n}\n\ninterface ShellProviderProps {\n /** Initial selected IDs. Default: []. */\n initialSelectedIds?: string[];\n /** Initial active tool. Default: 'select'. */\n initialTool?: string;\n /** Read-only flag. */\n readOnly?: boolean;\n /** Kind resolver — see ShellContextValue.resolveKind. */\n resolveKind?: (id: string) => string | undefined;\n /** Controlled override — pass a value to lift state out of the provider. */\n value?: Partial<ShellContextValue>;\n children: ReactNode;\n}\n\nexport function ShellProvider({\n initialSelectedIds = [],\n initialTool = \"select\",\n readOnly = false,\n resolveKind,\n value: controlled,\n children,\n}: ShellProviderProps) {\n const [selectedIds, setSelectedIds] = useState<string[]>(initialSelectedIds);\n const [activeTool, setActiveTool] = useState<string>(initialTool);\n\n const resolvedKind = controlled?.resolveKind ?? resolveKind;\n\n const value = useMemo<ShellContextValue>(\n () => ({\n selectedIds: controlled?.selectedIds ?? selectedIds,\n setSelectedIds: controlled?.setSelectedIds ?? setSelectedIds,\n activeTool: controlled?.activeTool ?? activeTool,\n setActiveTool: controlled?.setActiveTool ?? setActiveTool,\n readOnly: controlled?.readOnly ?? readOnly,\n ...(resolvedKind !== undefined && { resolveKind: resolvedKind }),\n }),\n [selectedIds, activeTool, readOnly, resolvedKind, controlled],\n );\n\n return <ShellContext.Provider value={value}>{children}</ShellContext.Provider>;\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\n\ninterface DesignerShellProps {\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Root layout for an editor app — full viewport, themed surface.\n * Place a <DesignerHeader>, <DesignerSidebar>, <DesignerPanel>, and the\n * canvas content as children.\n */\nfunction DesignerShell({ className, children }: DesignerShellProps) {\n return (\n <div\n className={cn(\n \"flex flex-col h-screen w-screen overflow-hidden bg-muted text-foreground\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nexport { DesignerShell };\nexport type { DesignerShellProps };\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\n\ninterface DesignerHeaderProps {\n /** Left-aligned content — file name, breadcrumbs, project switcher. */\n left?: ReactNode;\n /** Center content — typically the active document title. */\n center?: ReactNode;\n /** Right-aligned content — share, export, presence, account. */\n right?: ReactNode;\n className?: string;\n children?: ReactNode;\n}\n\n/**\n * Top bar of an editor app. Slot-driven — the chrome doesn't know what\n * goes in each region. Use <DesignerHeader left={...} center={...} right={...} />.\n */\nfunction DesignerHeader({ left, center, right, className, children }: DesignerHeaderProps) {\n return (\n <header\n className={cn(\n \"flex h-12 items-center justify-between gap-3 border-b border-border bg-card px-3 shrink-0\",\n className,\n )}\n >\n <div className=\"flex items-center gap-2 min-w-0\">{left}</div>\n {center && <div className=\"flex items-center gap-2 min-w-0\">{center}</div>}\n <div className=\"flex items-center gap-2 min-w-0\">{right}</div>\n {children}\n </header>\n );\n}\n\nexport { DesignerHeader };\nexport type { DesignerHeaderProps };\n","import type { ComponentType, ReactNode } from \"react\";\nimport { cn, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@hilum/ui\";\n\ninterface SidebarItem {\n id: string;\n label: string;\n icon: ComponentType<{ size?: number; className?: string }>;\n onClick?: () => void;\n /** Caller-computed active flag. */\n active?: boolean;\n disabled?: boolean;\n badge?: ReactNode;\n}\n\ninterface DesignerSidebarProps {\n /** Top group of icon buttons. */\n items: SidebarItem[];\n /** Optional bottom group (settings, help, account). */\n bottomItems?: SidebarItem[];\n /** Layout variant. `rail` preserves the desktop vertical rail. */\n variant?: \"rail\" | \"bottom\";\n side?: \"left\" | \"right\";\n className?: string;\n children?: ReactNode;\n}\n\n/**\n * Vertical icon rail used as the primary tool / navigation column in an\n * editor. Driven by an `items` array — no engine coupling. Each item gets\n * a tooltip showing its label.\n */\nfunction DesignerSidebar({\n items,\n bottomItems,\n variant = \"rail\",\n side = \"left\",\n className,\n children,\n}: DesignerSidebarProps) {\n if (variant === \"bottom\") {\n const allItems = [...items, ...(bottomItems ?? [])];\n\n return (\n <nav\n aria-label=\"Editor tools\"\n className={cn(\n \"fixed inset-x-3 bottom-[max(0.75rem,env(safe-area-inset-bottom))] z-40\",\n \"rounded-xl border border-border bg-card p-1 shadow-natural\",\n className,\n )}\n >\n <TooltipProvider>\n <div className=\"flex min-w-0 items-center gap-1 overflow-x-auto overscroll-x-contain\">\n {allItems.map((item) => (\n <SidebarButton key={item.id} item={item} tooltipSide=\"top\" touchTarget />\n ))}\n </div>\n {children}\n </TooltipProvider>\n </nav>\n );\n }\n\n return (\n <aside\n className={cn(\n \"flex flex-col w-12 bg-card shrink-0\",\n side === \"left\" ? \"border-r\" : \"border-l\",\n \"border-border\",\n className,\n )}\n >\n <TooltipProvider>\n <div className=\"flex flex-col items-center gap-0.5 p-1.5\">\n {items.map((item) => (\n <SidebarButton key={item.id} item={item} tooltipSide={side === \"left\" ? \"right\" : \"left\"} />\n ))}\n </div>\n\n {children}\n\n {bottomItems && bottomItems.length > 0 && (\n <div className=\"mt-auto flex flex-col items-center gap-0.5 p-1.5\">\n {bottomItems.map((item) => (\n <SidebarButton key={item.id} item={item} tooltipSide={side === \"left\" ? \"right\" : \"left\"} />\n ))}\n </div>\n )}\n </TooltipProvider>\n </aside>\n );\n}\n\nfunction SidebarButton({\n item,\n tooltipSide,\n touchTarget = false,\n}: {\n item: SidebarItem;\n tooltipSide: \"top\" | \"right\" | \"left\";\n touchTarget?: boolean;\n}) {\n const Icon = item.icon;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={item.onClick}\n disabled={item.disabled}\n aria-label={item.label}\n aria-pressed={item.active}\n className={cn(\n \"relative flex size-9 items-center justify-center rounded-md transition-[background-color,color,opacity,scale] active:scale-[0.96]\",\n \"[@media(pointer:coarse)]:size-11\",\n touchTarget && \"size-11 shrink-0\",\n item.active\n ? \"bg-foreground text-background\"\n : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n item.disabled && \"opacity-50 cursor-not-allowed\",\n )}\n >\n <Icon size={touchTarget ? 18 : 16} />\n {item.badge != null && (\n <span className=\"absolute -top-0.5 -right-0.5 caption-xs\">{item.badge}</span>\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side={tooltipSide}>{item.label}</TooltipContent>\n </Tooltip>\n );\n}\n\nexport { DesignerSidebar };\nexport type { DesignerSidebarProps, SidebarItem };\n","import type { ReactNode } from \"react\";\nimport { cn, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from \"@hilum/ui\";\n\ninterface DesignerPanelProps {\n side: \"left\" | \"right\";\n /** Presentation mode. `inline` preserves the desktop side-panel behavior. */\n variant?: \"inline\" | \"sheet\";\n /** Width in pixels. Default: 240. */\n width?: number;\n /** Add a separator border on the inner edge. Default: true. */\n bordered?: boolean;\n /** Controlled open state when `variant=\"sheet\"`. */\n open?: boolean;\n /** Controlled open-state handler when `variant=\"sheet\"`. */\n onOpenChange?: (open: boolean) => void;\n /** Accessible sheet title when `variant=\"sheet\"`. */\n sheetTitle?: ReactNode;\n /** Optional sheet description. */\n sheetDescription?: ReactNode;\n /** Sheet edge. Defaults to `bottom` for mobile editor panels. */\n sheetSide?: \"left\" | \"right\" | \"top\" | \"bottom\";\n sheetClassName?: string;\n className?: string;\n children?: ReactNode;\n}\n\n/**\n * Left or right side panel of an editor — typically holds layer lists,\n * inspector / properties, history, comments, etc. Static-width for v1.\n * (Resize handles arrive in a later iteration if needed.)\n */\nfunction DesignerPanel({\n side,\n variant = \"inline\",\n width = 240,\n bordered = true,\n open,\n onOpenChange,\n sheetTitle,\n sheetDescription,\n sheetSide = \"bottom\",\n sheetClassName,\n className,\n children,\n}: DesignerPanelProps) {\n if (variant === \"sheet\") {\n const sheetProps = {\n ...(open !== undefined ? { open } : {}),\n ...(onOpenChange ? { onOpenChange } : {}),\n };\n const resolvedSheetDescription = sheetDescription ?? \"Editor panel controls\";\n\n return (\n <Sheet {...sheetProps}>\n <SheetContent\n side={sheetSide}\n className={cn(\n \"flex max-h-[min(86svh,44rem)] flex-col overflow-hidden p-0\",\n sheetSide === \"bottom\" && \"rounded-t-2xl\",\n sheetClassName,\n )}\n >\n <SheetHeader className={cn(sheetTitle ? \"mb-0 border-b border-border px-4 py-3\" : \"sr-only\")}>\n <SheetTitle>{sheetTitle ?? `${side} panel`}</SheetTitle>\n <SheetDescription className={sheetDescription ? undefined : \"sr-only\"}>\n {resolvedSheetDescription}\n </SheetDescription>\n </SheetHeader>\n <div className=\"flex min-w-0 flex-1 flex-col overflow-x-hidden overflow-y-auto\">\n {children}\n </div>\n </SheetContent>\n </Sheet>\n );\n }\n\n return (\n <aside\n className={cn(\n \"flex min-w-0 max-w-full shrink-0 flex-col overflow-hidden bg-card\",\n bordered && (side === \"left\" ? \"border-r\" : \"border-l\"),\n bordered && \"border-border\",\n className,\n )}\n style={{ width, maxWidth: \"100%\" }}\n >\n <div className=\"flex min-w-0 flex-1 flex-col overflow-x-hidden overflow-y-auto\">\n {children}\n </div>\n </aside>\n );\n}\n\nexport { DesignerPanel };\nexport type { DesignerPanelProps };\n","import { useState, type ReactNode } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"@hilum/ui\";\nimport { useShellContext } from \"../shell/ShellContext\";\n\ninterface DesignerPaneProps {\n /**\n * Predicate or list of allowed kinds. The pane renders only when matched.\n *\n * - `string[]`: render when at least one selected ID resolves to one of\n * these kinds (requires `ShellContext.resolveKind`).\n * - `(selectedIds: string[]) => boolean`: full predicate.\n * - omitted: always render.\n */\n showFor?: string[] | ((selectedIds: string[]) => boolean);\n collapsible?: boolean;\n defaultOpen?: boolean;\n className?: string;\n children: ReactNode;\n}\n\ninterface DesignerPaneTitleProps {\n className?: string;\n children: ReactNode;\n /** Right-aligned action / control. */\n action?: ReactNode;\n}\n\ninterface DesignerPaneContentProps {\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Collapsible inspector section. Use inside a <DesignerPanel>.\n *\n * <DesignerPane showFor={[\"text\"]} collapsible>\n * <DesignerPaneTitle>Typography</DesignerPaneTitle>\n * <DesignerPaneContent>...</DesignerPaneContent>\n * </DesignerPane>\n */\nfunction DesignerPane({\n showFor,\n collapsible = false,\n defaultOpen = true,\n className,\n children,\n}: DesignerPaneProps) {\n const { selectedIds, resolveKind } = useShellContext();\n const [open, setOpen] = useState(defaultOpen);\n\n // Visibility check.\n let visible = true;\n if (typeof showFor === \"function\") {\n visible = showFor(selectedIds);\n } else if (Array.isArray(showFor)) {\n if (!resolveKind) {\n // No resolver: best effort — show only if any IDs are selected.\n visible = selectedIds.length > 0;\n } else {\n visible = selectedIds.some((id) => {\n const kind = resolveKind(id);\n return kind != null && showFor.includes(kind);\n });\n }\n }\n if (!visible) return null;\n\n return (\n <PaneContext.Provider value={{ open, toggle: () => setOpen((v) => !v), collapsible }}>\n <section\n className={cn(\n \"flex min-w-0 max-w-full flex-col overflow-x-hidden border-b border-border last:border-b-0\",\n className,\n )}\n >\n {children}\n </section>\n </PaneContext.Provider>\n );\n}\n\nfunction DesignerPaneTitle({ className, children, action }: DesignerPaneTitleProps) {\n const { open, toggle, collapsible } = usePaneContext();\n\n const Tag = collapsible ? \"button\" : \"div\";\n return (\n <Tag\n type={collapsible ? \"button\" : undefined}\n onClick={collapsible ? toggle : undefined}\n className={cn(\n \"flex min-h-10 w-full items-center justify-between gap-2 px-3 py-2 text-left\",\n \"caption-xs uppercase tracking-wider font-semibold text-muted-foreground\",\n collapsible && \"hover:text-foreground transition-colors\",\n className,\n )}\n >\n <span className=\"flex items-center gap-1.5\">\n {collapsible && (\n <ChevronDown\n size={12}\n className={cn(\"transition-transform duration-150\", !open && \"-rotate-90\")}\n />\n )}\n {children}\n </span>\n {action && <span className=\"ml-auto\">{action}</span>}\n </Tag>\n );\n}\n\nfunction DesignerPaneContent({ className, children }: DesignerPaneContentProps) {\n const { open } = usePaneContext();\n if (!open) return null;\n return (\n <div\n className={cn(\n \"flex min-w-0 max-w-full flex-col gap-2 overflow-x-hidden px-3 pb-3\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// --- internal pane context (so title and content stay in sync) ---\n\nimport { createContext, useContext } from \"react\";\n\ninterface PaneCtx {\n open: boolean;\n toggle: () => void;\n collapsible: boolean;\n}\nconst PaneContext = createContext<PaneCtx>({ open: true, toggle: () => {}, collapsible: false });\nfunction usePaneContext() {\n return useContext(PaneContext);\n}\n\nexport { DesignerPane, DesignerPaneTitle, DesignerPaneContent };\nexport type { DesignerPaneProps, DesignerPaneTitleProps, DesignerPaneContentProps };\n","import type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\n\ninterface DesignerPropertyRowProps extends ComponentPropsWithoutRef<\"div\"> {\n /** Optional label for direct row usage. Compound usage can use DesignerPropertyLabel. */\n label?: ReactNode;\n /** htmlFor forwarded to the generated label when label is provided. */\n labelFor?: string;\n /** Class name for the generated controls container when label is provided. */\n controlsClassName?: string;\n children: ReactNode;\n}\n\ninterface DesignerPropertyLabelProps extends ComponentPropsWithoutRef<\"label\"> {\n children: ReactNode;\n}\n\ninterface DesignerPropertyControlsProps extends ComponentPropsWithoutRef<\"div\"> {\n children: ReactNode;\n}\n\ninterface DesignerPropertyGroupProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\"> {\n title?: ReactNode;\n children: ReactNode;\n}\n\nfunction DesignerPropertyRow({\n label,\n labelFor,\n controlsClassName,\n className,\n children,\n ...rest\n}: DesignerPropertyRowProps) {\n return (\n <div\n className={cn(\n \"flex w-full min-w-0 max-w-full flex-col items-stretch gap-1.5 py-1.5\",\n className,\n )}\n {...rest}\n >\n {label === undefined ? (\n children\n ) : (\n <>\n <DesignerPropertyLabel htmlFor={labelFor}>{label}</DesignerPropertyLabel>\n <DesignerPropertyControls className={controlsClassName}>\n {children}\n </DesignerPropertyControls>\n </>\n )}\n </div>\n );\n}\n\nfunction DesignerPropertyLabel({ className, children, ...rest }: DesignerPropertyLabelProps) {\n return (\n <label\n className={cn(\n \"caption w-full min-w-0 max-w-full select-none text-muted-foreground\",\n className,\n )}\n {...rest}\n >\n {children}\n </label>\n );\n}\n\nfunction DesignerPropertyControls({ className, children, ...rest }: DesignerPropertyControlsProps) {\n return (\n <div\n className={cn(\n \"flex w-full min-w-0 max-w-full flex-1 items-center gap-2 overflow-visible\",\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nfunction DesignerPropertyGroup({\n title,\n className,\n children,\n ...rest\n}: DesignerPropertyGroupProps) {\n return (\n <div className={cn(\"flex min-w-0 max-w-full flex-col gap-3\", className)} {...rest}>\n {title && (\n <div className=\"caption-xs min-w-0 max-w-full select-none overflow-hidden text-ellipsis uppercase tracking-wider text-muted-foreground\">\n {title}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nexport {\n DesignerPropertyRow,\n DesignerPropertyLabel,\n DesignerPropertyControls,\n DesignerPropertyGroup,\n};\nexport type {\n DesignerPropertyRowProps,\n DesignerPropertyLabelProps,\n DesignerPropertyControlsProps,\n DesignerPropertyGroupProps,\n};\n","import type { ComponentType, ReactNode } from \"react\";\nimport { cn, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@hilum/ui\";\n\n/* ============================================================== *\n * Toolbar — outer container *\n * ============================================================== */\n\ninterface DesignerToolbarProps {\n className?: string;\n /** Position. Default: 'floating' (centered, floating above content). */\n variant?: \"floating\" | \"inline\" | \"dock\";\n children: ReactNode;\n}\n\nfunction DesignerToolbar({ className, variant = \"floating\", children }: DesignerToolbarProps) {\n return (\n <TooltipProvider>\n <div\n role=\"toolbar\"\n className={cn(\n \"flex items-center gap-0.5 rounded-lg bg-card p-1 shadow-natural\",\n variant === \"floating\" && \"fixed bottom-4 left-1/2 -translate-x-1/2 z-30\",\n variant === \"dock\" &&\n [\n \"fixed inset-x-3 bottom-[max(0.75rem,env(safe-area-inset-bottom))] z-30\",\n \"overflow-x-auto overscroll-x-contain rounded-xl\",\n ],\n className,\n )}\n >\n {children}\n </div>\n </TooltipProvider>\n );\n}\n\n/* ============================================================== *\n * ToolbarGroup — visual group of buttons *\n * ============================================================== */\n\ninterface DesignerToolbarGroupProps {\n className?: string;\n children: ReactNode;\n}\n\nfunction DesignerToolbarGroup({ className, children }: DesignerToolbarGroupProps) {\n return <div className={cn(\"flex items-center gap-0.5\", className)}>{children}</div>;\n}\n\n/* ============================================================== *\n * ToolbarSeparator *\n * ============================================================== */\n\ninterface DesignerToolbarSeparatorProps {\n className?: string;\n}\n\nfunction DesignerToolbarSeparator({ className }: DesignerToolbarSeparatorProps) {\n return <div className={cn(\"mx-1 h-5 w-px bg-muted\", className)} role=\"separator\" />;\n}\n\n/* ============================================================== *\n * ToolbarButton — single tool / action *\n * ============================================================== */\n\ninterface DesignerToolbarButtonProps {\n label: string;\n icon?: ComponentType<{ size?: number; className?: string }>;\n onClick?: () => void;\n active?: boolean;\n disabled?: boolean;\n /** Optional keyboard shortcut shown in the tooltip (e.g. 'V', 'Cmd+Z'). */\n shortcut?: string;\n size?: \"default\" | \"touch\";\n className?: string;\n children?: ReactNode;\n}\n\nfunction DesignerToolbarButton({\n label,\n icon: Icon,\n onClick,\n active,\n disabled,\n shortcut,\n size = \"default\",\n className,\n children,\n}: DesignerToolbarButtonProps) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-label={label}\n aria-pressed={active}\n className={cn(\n \"flex h-9 min-w-9 items-center justify-center gap-1 rounded-md px-2 caption transition-[background-color,color,opacity,scale] active:scale-[0.96]\",\n \"[@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:min-w-11\",\n size === \"touch\" && \"h-11 min-w-11\",\n active\n ? \"bg-foreground text-background\"\n : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n disabled && \"opacity-50 cursor-not-allowed\",\n className,\n )}\n >\n {Icon && <Icon size={16} />}\n {children}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n <span>{label}</span>\n {shortcut && <span className=\"ml-2 caption-xs text-muted-foreground\">{shortcut}</span>}\n </TooltipContent>\n </Tooltip>\n );\n}\n\nexport { DesignerToolbar, DesignerToolbarGroup, DesignerToolbarSeparator, DesignerToolbarButton };\nexport type {\n DesignerToolbarProps,\n DesignerToolbarGroupProps,\n DesignerToolbarSeparatorProps,\n DesignerToolbarButtonProps,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Link2, Unlink2 } from \"lucide-react\";\nimport { Button, InputNumber, cn } from \"@hilum/ui\";\n\ntype DesignerControlValue = number | null;\n\ninterface DesignerValueItem<K extends string> {\n key: K;\n label: React.ReactNode;\n ariaLabel?: string;\n min?: number;\n max?: number;\n step?: number;\n precision?: number;\n unit?: string;\n disabled?: boolean;\n}\n\ninterface DesignerValueControlBaseProps<K extends string> {\n label?: React.ReactNode;\n values: Record<K, DesignerControlValue>;\n items: readonly DesignerValueItem<K>[];\n onChange: (key: K, value: number) => void;\n onChangeAll?: (value: number) => void;\n onCommit?: () => void;\n linked?: boolean;\n onLinkedChange?: (linked: boolean) => void;\n unit?: string;\n min?: number;\n max?: number;\n step?: number;\n precision?: number;\n disabled?: boolean;\n readOnly?: boolean;\n mixedLabel?: string;\n hideSteppers?: boolean;\n className?: string;\n labelClassName?: string;\n inputClassName?: string;\n controlsClassName?: string;\n linkButtonClassName?: string;\n linkLabel?: string;\n unlinkLabel?: string;\n}\n\ninterface TwoValueControlProps<K extends string = string>\n extends DesignerValueControlBaseProps<K> {\n items: readonly [DesignerValueItem<K>, DesignerValueItem<K>];\n}\n\ninterface FourValueControlProps<K extends string = string>\n extends DesignerValueControlBaseProps<K> {\n items: readonly [\n DesignerValueItem<K>,\n DesignerValueItem<K>,\n DesignerValueItem<K>,\n DesignerValueItem<K>,\n ];\n layout?: \"grid\" | \"single-when-linked\";\n}\n\ntype SpacingSide = \"top\" | \"right\" | \"bottom\" | \"left\";\ntype CornerSide = \"topLeft\" | \"topRight\" | \"bottomLeft\" | \"bottomRight\";\n\ntype SpacingControlProps = Omit<\n FourValueControlProps<SpacingSide>,\n \"items\" | \"values\" | \"onChange\" | \"onChangeAll\"\n> & {\n values: Record<SpacingSide, DesignerControlValue>;\n onChange: (side: SpacingSide, value: number) => void;\n onChangeAll?: (value: number) => void;\n};\n\ntype CornerRadiusControlProps = Omit<\n FourValueControlProps<CornerSide>,\n \"items\" | \"values\" | \"onChange\" | \"onChangeAll\"\n> & {\n values: Record<CornerSide, DesignerControlValue>;\n onChange: (side: CornerSide, value: number) => void;\n onChangeAll?: (value: number) => void;\n};\n\nfunction getSharedValue<K extends string>(\n items: readonly DesignerValueItem<K>[],\n values: Record<K, DesignerControlValue>,\n) {\n const first = values[items[0].key];\n if (first === null) return null;\n return items.every((item) => values[item.key] === first) ? first : null;\n}\n\nfunction DesignerValueField<K extends string>({\n item,\n value,\n unit,\n min,\n max,\n step,\n precision,\n disabled,\n readOnly,\n mixedLabel,\n hideSteppers,\n inputClassName,\n onChange,\n onCommit,\n}: {\n item: DesignerValueItem<K>;\n value: DesignerControlValue;\n unit?: string | undefined;\n min?: number | undefined;\n max?: number | undefined;\n step?: number | undefined;\n precision?: number | undefined;\n disabled?: boolean | undefined;\n readOnly?: boolean | undefined;\n mixedLabel?: string | undefined;\n hideSteppers?: boolean | undefined;\n inputClassName?: string | undefined;\n onChange: (value: number) => void;\n onCommit?: (() => void) | undefined;\n}) {\n return (\n <div className=\"relative min-w-0\">\n <span className=\"caption-xs pointer-events-none absolute left-2 top-1/2 z-10 -translate-y-1/2 select-none font-semibold uppercase text-muted-foreground\">\n {item.label}\n </span>\n <InputNumber\n value={value}\n onChange={onChange}\n min={item.min ?? min}\n max={item.max ?? max}\n step={item.step ?? step}\n precision={item.precision ?? precision}\n unit={item.unit ?? unit}\n mixedLabel={mixedLabel}\n commitOnChange\n hideSteppers={hideSteppers}\n disabled={disabled || item.disabled}\n readOnly={readOnly}\n aria-label={item.ariaLabel}\n onBlur={onCommit}\n className={cn(\"h-9 w-full bg-muted/60\", inputClassName)}\n inputMode=\"decimal\"\n />\n </div>\n );\n}\n\nfunction DesignerValueControl<K extends string>({\n label,\n values,\n items,\n onChange,\n onChangeAll,\n onCommit,\n linked,\n onLinkedChange,\n unit,\n min = -Infinity,\n max = Infinity,\n step = 1,\n precision = 0,\n disabled = false,\n readOnly = false,\n mixedLabel = \"Mixed\",\n hideSteppers = true,\n className,\n labelClassName,\n inputClassName,\n controlsClassName,\n linkButtonClassName,\n linkLabel = \"Link values\",\n unlinkLabel = \"Unlink values\",\n singleWhenLinked = false,\n}: DesignerValueControlBaseProps<K> & { singleWhenLinked?: boolean }) {\n const hasLinkControl = typeof linked === \"boolean\" && Boolean(onLinkedChange);\n const sharedValue = getSharedValue(items, values);\n const showSingleInput = singleWhenLinked && linked;\n\n const handleChange = (key: K, value: number) => {\n if (linked) {\n if (onChangeAll) {\n onChangeAll(value);\n } else {\n items.forEach((item) => onChange(item.key, value));\n }\n return;\n }\n\n onChange(key, value);\n };\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-1.5\", className)}>\n {(label || hasLinkControl) && (\n <div className=\"flex min-w-0 items-center justify-between gap-2\">\n {label && (\n <div className={cn(\"caption select-none text-muted-foreground\", labelClassName)}>\n {label}\n </div>\n )}\n {hasLinkControl && (\n <Button\n type=\"button\"\n variant={linked ? \"secondary\" : \"ghost\"}\n size=\"icon-xs\"\n aria-label={linked ? unlinkLabel : linkLabel}\n title={linked ? unlinkLabel : linkLabel}\n aria-pressed={linked}\n disabled={disabled || readOnly}\n onClick={() => onLinkedChange?.(!linked)}\n className={linkButtonClassName}\n >\n {linked ? <Link2 size={12} /> : <Unlink2 size={12} />}\n </Button>\n )}\n </div>\n )}\n\n {showSingleInput ? (\n <DesignerValueField\n item={{ ...items[0], label: \"All\", ariaLabel: \"All values\" }}\n value={sharedValue}\n unit={unit}\n min={min}\n max={max}\n step={step}\n precision={precision}\n disabled={disabled}\n readOnly={readOnly}\n mixedLabel={mixedLabel}\n hideSteppers={hideSteppers}\n inputClassName={inputClassName}\n onChange={(value) => handleChange(items[0].key, value)}\n onCommit={onCommit}\n />\n ) : (\n <div\n className={cn(\n \"grid min-w-0 gap-2\",\n items.length === 2 ? \"grid-cols-2\" : \"grid-cols-2\",\n controlsClassName,\n )}\n >\n {items.map((item) => (\n <DesignerValueField\n key={item.key}\n item={item}\n value={values[item.key]}\n unit={unit}\n min={min}\n max={max}\n step={step}\n precision={precision}\n disabled={disabled}\n readOnly={readOnly}\n mixedLabel={mixedLabel}\n hideSteppers={hideSteppers}\n inputClassName={inputClassName}\n onChange={(value) => handleChange(item.key, value)}\n onCommit={onCommit}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction TwoValueControl<K extends string = string>(props: TwoValueControlProps<K>) {\n return <DesignerValueControl {...props} />;\n}\n\nfunction FourValueControl<K extends string = string>({\n layout = \"single-when-linked\",\n ...props\n}: FourValueControlProps<K>) {\n return <DesignerValueControl {...props} singleWhenLinked={layout === \"single-when-linked\"} />;\n}\n\nconst spacingItems = [\n { key: \"top\", label: \"T\", ariaLabel: \"Top\" },\n { key: \"right\", label: \"R\", ariaLabel: \"Right\" },\n { key: \"bottom\", label: \"B\", ariaLabel: \"Bottom\" },\n { key: \"left\", label: \"L\", ariaLabel: \"Left\" },\n] as const satisfies readonly [\n DesignerValueItem<SpacingSide>,\n DesignerValueItem<SpacingSide>,\n DesignerValueItem<SpacingSide>,\n DesignerValueItem<SpacingSide>,\n];\n\nconst cornerItems = [\n { key: \"topLeft\", label: \"TL\", ariaLabel: \"Top left radius\" },\n { key: \"topRight\", label: \"TR\", ariaLabel: \"Top right radius\" },\n { key: \"bottomLeft\", label: \"BL\", ariaLabel: \"Bottom left radius\" },\n { key: \"bottomRight\", label: \"BR\", ariaLabel: \"Bottom right radius\" },\n] as const satisfies readonly [\n DesignerValueItem<CornerSide>,\n DesignerValueItem<CornerSide>,\n DesignerValueItem<CornerSide>,\n DesignerValueItem<CornerSide>,\n];\n\nfunction SpacingControl(props: SpacingControlProps) {\n return <FourValueControl {...props} items={spacingItems} />;\n}\n\nfunction CornerRadiusControl(props: CornerRadiusControlProps) {\n return <FourValueControl {...props} items={cornerItems} min={props.min ?? 0} />;\n}\n\nexport {\n CornerRadiusControl,\n FourValueControl,\n SpacingControl,\n TwoValueControl,\n};\nexport type {\n CornerRadiusControlProps,\n CornerSide,\n DesignerControlValue,\n DesignerValueItem,\n FourValueControlProps,\n SpacingControlProps,\n SpacingSide,\n TwoValueControlProps,\n};\n","import { useCallback, useState } from \"react\";\n\ninterface HistoryState<T> {\n past: T[];\n present: T;\n future: T[];\n}\n\ninterface UseHistoryReturn<T> {\n state: T;\n /**\n * Record a new state. Use when the user makes a logical edit. Pushes the\n * current `state` into `past` and clears `future`. Pass `{ skipHistory: true }`\n * (via a separate setter) to overwrite without pushing — apps that need that\n * can set state directly via a wrapper.\n */\n setState: (next: T | ((prev: T) => T)) => void;\n /** Replace `state` without pushing onto the history stack. */\n replaceState: (next: T | ((prev: T) => T)) => void;\n undo: () => void;\n redo: () => void;\n reset: (next: T) => void;\n canUndo: boolean;\n canRedo: boolean;\n /** Number of past entries (undo depth). */\n pastSize: number;\n /** Number of future entries (redo depth). */\n futureSize: number;\n}\n\n/**\n * Generic, engine-agnostic undo/redo stack.\n *\n * @hilum/designer-canvas wires this with `useHistory<Layer[]>(layers)`.\n * A form-builder app could wire `useHistory<FormSchema>(schema)`.\n */\nexport function useHistory<T>(initial: T): UseHistoryReturn<T> {\n const [history, setHistory] = useState<HistoryState<T>>({\n past: [],\n present: initial,\n future: [],\n });\n\n const setState = useCallback((next: T | ((prev: T) => T)) => {\n setHistory((prev) => {\n const value = typeof next === \"function\" ? (next as (p: T) => T)(prev.present) : next;\n if (Object.is(value, prev.present)) return prev;\n return {\n past: [...prev.past, prev.present],\n present: value,\n future: [],\n };\n });\n }, []);\n\n const replaceState = useCallback((next: T | ((prev: T) => T)) => {\n setHistory((prev) => {\n const value = typeof next === \"function\" ? (next as (p: T) => T)(prev.present) : next;\n return { ...prev, present: value };\n });\n }, []);\n\n const undo = useCallback(() => {\n setHistory((prev) => {\n if (prev.past.length === 0) return prev;\n const past = prev.past.slice(0, -1);\n const previous = prev.past[prev.past.length - 1]!;\n return {\n past,\n present: previous,\n future: [prev.present, ...prev.future],\n };\n });\n }, []);\n\n const redo = useCallback(() => {\n setHistory((prev) => {\n if (prev.future.length === 0) return prev;\n const [next, ...rest] = prev.future;\n return {\n past: [...prev.past, prev.present],\n present: next!,\n future: rest,\n };\n });\n }, []);\n\n const reset = useCallback((next: T) => {\n setHistory({ past: [], present: next, future: [] });\n }, []);\n\n return {\n state: history.present,\n setState,\n replaceState,\n undo,\n redo,\n reset,\n canUndo: history.past.length > 0,\n canRedo: history.future.length > 0,\n pastSize: history.past.length,\n futureSize: history.future.length,\n };\n}\n","import { useEffect } from \"react\";\n\nexport interface KeybindingConfig {\n /** Lower-case key (e.g. 'z', 'arrowup', 'escape', '+', '-'). */\n key: string;\n ctrl?: boolean;\n /** Cmd on macOS. Use both `meta` and `ctrl: true` if you want both. */\n meta?: boolean;\n shift?: boolean;\n alt?: boolean;\n /**\n * Treat both ctrl and meta as the same modifier (for cross-platform\n * shortcuts like Cmd+Z / Ctrl+Z). Default: false. Set to true to match\n * either modifier.\n */\n mod?: boolean;\n action: (event: KeyboardEvent) => void;\n /** Don't run when target is an input / textarea / contenteditable. Default: true. */\n skipInputs?: boolean;\n /** Call event.preventDefault() before action. Default: true. */\n preventDefault?: boolean;\n}\n\ninterface UseKeybindingsOptions {\n /** Skip all bindings entirely. */\n disabled?: boolean;\n /** Element to attach the listener to. Default: window. */\n target?: Window | HTMLElement | null;\n}\n\n/**\n * Generic keyboard shortcut registry. Engine-agnostic — the package doesn't\n * know what an action does. Pass an array of bindings; the hook attaches\n * a single keydown listener and dispatches on match.\n *\n * @hilum/designer-canvas wires its standard editor shortcuts (Cmd+Z, V, T,\n * arrow nudge, etc.) on top of this hook.\n */\nexport function useKeybindings(\n bindings: KeybindingConfig[],\n { disabled, target }: UseKeybindingsOptions = {},\n) {\n useEffect(() => {\n if (disabled) return;\n const node = target ?? (typeof window !== \"undefined\" ? window : null);\n if (!node) return;\n\n const handler = (rawEvent: Event) => {\n const e = rawEvent as KeyboardEvent;\n\n const tgt = e.target as HTMLElement | null;\n const isInput =\n tgt instanceof HTMLInputElement ||\n tgt instanceof HTMLTextAreaElement ||\n tgt instanceof HTMLSelectElement ||\n tgt?.isContentEditable === true;\n\n const key = e.key.toLowerCase();\n\n for (const b of bindings) {\n if (b.key.toLowerCase() !== key) continue;\n if (b.skipInputs !== false && isInput) continue;\n\n const ctrlMatches = b.ctrl ? e.ctrlKey : !e.ctrlKey || b.mod;\n const metaMatches = b.meta ? e.metaKey : !e.metaKey || b.mod;\n const modMatches = b.mod ? e.ctrlKey || e.metaKey : true;\n const shiftMatches = b.shift ? e.shiftKey : !e.shiftKey;\n const altMatches = b.alt ? e.altKey : !e.altKey;\n\n if (!modMatches) continue;\n if (!b.mod && (!ctrlMatches || !metaMatches)) continue;\n if (!shiftMatches || !altMatches) continue;\n\n if (b.preventDefault !== false) e.preventDefault();\n b.action(e);\n return;\n }\n };\n\n (node as Window).addEventListener(\"keydown\", handler);\n return () => (node as Window).removeEventListener(\"keydown\", handler);\n }, [bindings, disabled, target]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/shell/ShellContext.tsx","../src/components/DesignerShell.tsx","../src/components/designer-workspace-insets.ts","../src/components/DesignerWorkspace.tsx","../src/components/DesignerHeader.tsx","../src/components/DesignerSidebar.tsx","../src/components/DesignerPanel.tsx","../src/components/DesignerPane.tsx","../src/components/DesignerPropertyRow.tsx","../src/components/DesignerToolbar.tsx","../src/components/DesignerValueControls.tsx","../src/hooks/useHistory.ts","../src/hooks/useKeybindings.ts"],"names":["jsx","cn","jsxs","useState","createContext","useContext","TooltipProvider","Tooltip","TooltipTrigger","TooltipContent"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext, useMemo, useState } from \"react\";\nimport type { Dispatch, ReactNode, SetStateAction } from \"react\";\n\n/**\n * The minimal contract a designer shell needs from the engine beneath it.\n *\n * The chrome (toolbar, panel, pane, sidebar) reads from this context.\n * It does NOT know what is being edited — selection IDs are opaque strings\n * (layer IDs, field IDs, node IDs — whatever the engine uses), and active\n * tool is an open string the app defines (`select`, `hand`, `text`, …).\n *\n * @hilum/designer-canvas wires this up for canvas apps. A form-builder app\n * could wire its own engine to ShellContext with the same primitives.\n */\nexport interface ShellContextValue {\n /** IDs of currently-selected items. Engine-defined meaning. */\n selectedIds: string[];\n setSelectedIds: Dispatch<SetStateAction<string[]>>;\n\n /** Active tool. App-defined enum (e.g. 'select' | 'hand' | 'text'). */\n activeTool: string;\n setActiveTool: Dispatch<SetStateAction<string>>;\n\n /** When true, mutating actions should no-op. Used for previews. */\n readOnly: boolean;\n\n /**\n * Optional resolver: given a `selectedId`, return its engine-defined \"kind\"\n * (e.g. 'text', 'image'). DesignerPane.showFor uses this to decide whether\n * to render. Apps that don't have typed selections can leave this undefined.\n */\n resolveKind?: (id: string) => string | undefined;\n}\n\nconst noop = () => {};\n\nconst DEFAULT: ShellContextValue = {\n selectedIds: [],\n setSelectedIds: noop as Dispatch<SetStateAction<string[]>>,\n activeTool: \"select\",\n setActiveTool: noop as Dispatch<SetStateAction<string>>,\n readOnly: false,\n};\n\nconst ShellContext = createContext<ShellContextValue>(DEFAULT);\n\nexport function useShellContext(): ShellContextValue {\n return useContext(ShellContext);\n}\n\ninterface ShellProviderProps {\n /** Initial selected IDs. Default: []. */\n initialSelectedIds?: string[];\n /** Initial active tool. Default: 'select'. */\n initialTool?: string;\n /** Read-only flag. */\n readOnly?: boolean;\n /** Kind resolver — see ShellContextValue.resolveKind. */\n resolveKind?: (id: string) => string | undefined;\n /** Controlled override — pass a value to lift state out of the provider. */\n value?: Partial<ShellContextValue>;\n children: ReactNode;\n}\n\nexport function ShellProvider({\n initialSelectedIds = [],\n initialTool = \"select\",\n readOnly = false,\n resolveKind,\n value: controlled,\n children,\n}: ShellProviderProps) {\n const [selectedIds, setSelectedIds] = useState<string[]>(initialSelectedIds);\n const [activeTool, setActiveTool] = useState<string>(initialTool);\n\n const resolvedKind = controlled?.resolveKind ?? resolveKind;\n\n const value = useMemo<ShellContextValue>(\n () => ({\n selectedIds: controlled?.selectedIds ?? selectedIds,\n setSelectedIds: controlled?.setSelectedIds ?? setSelectedIds,\n activeTool: controlled?.activeTool ?? activeTool,\n setActiveTool: controlled?.setActiveTool ?? setActiveTool,\n readOnly: controlled?.readOnly ?? readOnly,\n ...(resolvedKind !== undefined && { resolveKind: resolvedKind }),\n }),\n [selectedIds, activeTool, readOnly, resolvedKind, controlled],\n );\n\n return <ShellContext.Provider value={value}>{children}</ShellContext.Provider>;\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\n\ninterface DesignerShellProps {\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Root layout for an editor app — full viewport, themed surface.\n * Place a <DesignerHeader>, <DesignerSidebar>, <DesignerPanel>, and the\n * canvas content as children.\n */\nfunction DesignerShell({ className, children }: DesignerShellProps) {\n return (\n <div\n className={cn(\n \"flex flex-col h-screen w-screen overflow-hidden bg-muted text-foreground\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nexport { DesignerShell };\nexport type { DesignerShellProps };\n","export type DesignerWorkspaceInsetValue = number | string;\n\nexport interface DesignerWorkspaceInsets {\n top: DesignerWorkspaceInsetValue;\n right: DesignerWorkspaceInsetValue;\n bottom: DesignerWorkspaceInsetValue;\n left: DesignerWorkspaceInsetValue;\n}\n\nexport type DesignerWorkspaceInsetsInput =\n | DesignerWorkspaceInsetValue\n | Partial<DesignerWorkspaceInsets>;\n\nfunction toCssLength(value: DesignerWorkspaceInsetValue): string {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nexport function resolveDesignerWorkspaceInsets(\n input: DesignerWorkspaceInsetsInput | undefined,\n fallback: DesignerWorkspaceInsetValue = 0,\n): Record<keyof DesignerWorkspaceInsets, string> {\n const fallbackValue = toCssLength(fallback);\n\n if (typeof input === \"number\" || typeof input === \"string\") {\n const value = toCssLength(input);\n return { top: value, right: value, bottom: value, left: value };\n }\n\n return {\n top: input?.top === undefined ? fallbackValue : toCssLength(input.top),\n right: input?.right === undefined ? fallbackValue : toCssLength(input.right),\n bottom: input?.bottom === undefined ? fallbackValue : toCssLength(input.bottom),\n left: input?.left === undefined ? fallbackValue : toCssLength(input.left),\n };\n}\n","import type { ComponentPropsWithoutRef, CSSProperties, ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\nimport {\n resolveDesignerWorkspaceInsets,\n type DesignerWorkspaceInsets,\n type DesignerWorkspaceInsetsInput,\n type DesignerWorkspaceInsetValue,\n} from \"./designer-workspace-insets\";\n\ninterface DesignerWorkspaceProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /**\n * Insets that describe the unobscured canvas area between floating chrome.\n * Numbers are interpreted as pixels; CSS lengths and calc() expressions are\n * accepted for responsive shells.\n */\n safeInsets?: DesignerWorkspaceInsetsInput;\n children: ReactNode;\n}\n\ninterface DesignerWorkspaceViewportProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n children: ReactNode;\n}\n\ntype WorkspaceStyle = CSSProperties & {\n \"--designer-workspace-inset-top\": string;\n \"--designer-workspace-inset-right\": string;\n \"--designer-workspace-inset-bottom\": string;\n \"--designer-workspace-inset-left\": string;\n};\n\n/**\n * Positioning boundary for a canvas editor. Floating rails, panels, and\n * toolbars are layered over this surface while DesignerWorkspaceViewport uses\n * the configured safe insets to keep document content unobscured.\n */\nfunction DesignerWorkspace({\n safeInsets,\n className,\n style,\n children,\n ...props\n}: DesignerWorkspaceProps) {\n const insets = resolveDesignerWorkspaceInsets(safeInsets);\n const workspaceStyle = {\n \"--designer-workspace-inset-top\": insets.top,\n \"--designer-workspace-inset-right\": insets.right,\n \"--designer-workspace-inset-bottom\": insets.bottom,\n \"--designer-workspace-inset-left\": insets.left,\n ...style,\n } as WorkspaceStyle;\n\n return (\n <div\n data-designer-workspace\n className={cn(\n \"relative isolate flex min-h-0 min-w-0 flex-1 overflow-hidden bg-muted\",\n className,\n )}\n style={workspaceStyle}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Safe, canvas-sized region within DesignerWorkspace. Its bounds are derived\n * from the workspace's safeInsets so fit/center calculations use the visible\n * area between floating editor chrome.\n */\nfunction DesignerWorkspaceViewport({\n className,\n style,\n children,\n ...props\n}: DesignerWorkspaceViewportProps) {\n return (\n <div\n data-designer-workspace-viewport\n className={cn(\"absolute z-0 flex min-h-0 min-w-0 overflow-hidden\", className)}\n style={{\n top: \"var(--designer-workspace-inset-top)\",\n right: \"var(--designer-workspace-inset-right)\",\n bottom: \"var(--designer-workspace-inset-bottom)\",\n left: \"var(--designer-workspace-inset-left)\",\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nexport { DesignerWorkspace, DesignerWorkspaceViewport };\nexport type {\n DesignerWorkspaceProps,\n DesignerWorkspaceViewportProps,\n DesignerWorkspaceInsets,\n DesignerWorkspaceInsetsInput,\n DesignerWorkspaceInsetValue,\n};\n","import type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\n\ninterface DesignerHeaderProps extends Omit<ComponentPropsWithoutRef<\"header\">, \"children\"> {\n /** Left-aligned content — file name, breadcrumbs, project switcher. */\n left?: ReactNode;\n /** Center content — typically the active document title. */\n center?: ReactNode;\n /** Right-aligned content — share, export, presence, account. */\n right?: ReactNode;\n className?: string;\n children?: ReactNode;\n}\n\n/**\n * Top bar of an editor app. Slot-driven — the chrome doesn't know what\n * goes in each region. Use <DesignerHeader left={...} center={...} right={...} />.\n */\nfunction DesignerHeader({\n left,\n center,\n right,\n className,\n children,\n ...props\n}: DesignerHeaderProps) {\n return (\n <header\n data-designer-header\n className={cn(\n \"grid h-12 shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3 border-b border-border bg-card px-3\",\n className,\n )}\n {...props}\n >\n <div\n data-designer-header-slot=\"left\"\n className=\"flex min-w-0 items-center gap-2 justify-self-start\"\n >\n {left}\n </div>\n <div\n data-designer-header-slot=\"center\"\n className=\"flex min-w-0 items-center gap-2 justify-self-center\"\n >\n {center}\n </div>\n <div\n data-designer-header-slot=\"right\"\n className=\"flex min-w-0 items-center gap-2 justify-self-end\"\n >\n {right}\n </div>\n {children}\n </header>\n );\n}\n\nexport { DesignerHeader };\nexport type { DesignerHeaderProps };\n","import type { ComponentType, CSSProperties, ReactNode } from \"react\";\nimport { cn, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@hilum/ui\";\nimport {\n resolveDesignerWorkspaceInsets,\n type DesignerWorkspaceInsetsInput,\n} from \"./designer-workspace-insets\";\n\ninterface SidebarItem {\n id: string;\n label: string;\n icon: ComponentType<{ size?: number; className?: string }>;\n onClick?: () => void;\n /** Caller-computed active flag. */\n active?: boolean;\n disabled?: boolean;\n badge?: ReactNode;\n}\n\ninterface DesignerSidebarProps {\n /** Top group of icon buttons. */\n items: SidebarItem[];\n /** Optional bottom group (settings, help, account). */\n bottomItems?: SidebarItem[];\n /** Layout variant. `rail` preserves the inline desktop vertical rail. */\n variant?: \"rail\" | \"floating\" | \"bottom\";\n side?: \"left\" | \"right\";\n /** Insets used to position a floating rail within DesignerWorkspace. Default: 16px. */\n floatingInset?: DesignerWorkspaceInsetsInput;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n}\n\n/**\n * Vertical icon rail used as the primary tool / navigation column in an\n * editor. Driven by an `items` array — no engine coupling. Each item gets\n * a tooltip showing its label.\n */\nfunction DesignerSidebar({\n items,\n bottomItems,\n variant = \"rail\",\n side = \"left\",\n floatingInset,\n className,\n style,\n children,\n}: DesignerSidebarProps) {\n if (variant === \"bottom\") {\n const allItems = [...items, ...(bottomItems ?? [])];\n\n return (\n <nav\n aria-label=\"Editor tools\"\n className={cn(\n \"fixed inset-x-3 bottom-[max(0.75rem,env(safe-area-inset-bottom))] z-40\",\n \"rounded-xl border border-border bg-card p-1 shadow-natural\",\n className,\n )}\n style={style}\n >\n <TooltipProvider>\n <div className=\"flex min-w-0 items-center gap-1 overflow-x-auto overscroll-x-contain\">\n {allItems.map((item) => (\n <SidebarButton key={item.id} item={item} tooltipSide=\"top\" touchTarget />\n ))}\n </div>\n {children}\n </TooltipProvider>\n </nav>\n );\n }\n\n const content = (\n <TooltipProvider>\n <div className=\"flex min-h-0 flex-1 flex-col items-center gap-0.5 overflow-y-auto overscroll-contain p-1.5\">\n {items.map((item) => (\n <SidebarButton\n key={item.id}\n item={item}\n tooltipSide={side === \"left\" ? \"right\" : \"left\"}\n />\n ))}\n </div>\n\n {children}\n\n {bottomItems && bottomItems.length > 0 && (\n <div className=\"flex shrink-0 flex-col items-center gap-0.5 p-1.5\">\n {bottomItems.map((item) => (\n <SidebarButton\n key={item.id}\n item={item}\n tooltipSide={side === \"left\" ? \"right\" : \"left\"}\n />\n ))}\n </div>\n )}\n </TooltipProvider>\n );\n\n if (variant === \"floating\") {\n const insets = resolveDesignerWorkspaceInsets(floatingInset, 16);\n\n return (\n <nav\n aria-label=\"Editor tools\"\n data-side={side}\n data-variant={variant}\n className={cn(\n \"absolute z-30 flex w-12 flex-col overflow-hidden rounded-xl border border-border bg-card shadow-natural\",\n className,\n )}\n style={{\n top: insets.top,\n bottom: insets.bottom,\n [side]: insets[side],\n ...style,\n }}\n >\n {content}\n </nav>\n );\n }\n\n return (\n <aside\n data-side={side}\n data-variant={variant}\n className={cn(\n \"flex flex-col w-12 bg-card shrink-0\",\n side === \"left\" ? \"border-r\" : \"border-l\",\n \"border-border\",\n className,\n )}\n style={style}\n >\n {content}\n </aside>\n );\n}\n\nfunction SidebarButton({\n item,\n tooltipSide,\n touchTarget = false,\n}: {\n item: SidebarItem;\n tooltipSide: \"top\" | \"right\" | \"left\";\n touchTarget?: boolean;\n}) {\n const Icon = item.icon;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={item.onClick}\n disabled={item.disabled}\n aria-label={item.label}\n aria-pressed={item.active}\n className={cn(\n \"relative flex size-9 items-center justify-center rounded-md transition-[background-color,color,opacity,scale] active:scale-[0.96]\",\n \"[@media(pointer:coarse)]:size-11\",\n touchTarget && \"size-11 shrink-0\",\n item.active\n ? \"bg-foreground text-background\"\n : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n item.disabled && \"opacity-50 cursor-not-allowed\",\n )}\n >\n <Icon size={touchTarget ? 18 : 16} />\n {item.badge != null && (\n <span className=\"absolute -top-0.5 -right-0.5 caption-xs\">{item.badge}</span>\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side={tooltipSide}>{item.label}</TooltipContent>\n </Tooltip>\n );\n}\n\nexport { DesignerSidebar };\nexport type { DesignerSidebarProps, SidebarItem };\n","import type { CSSProperties, ReactNode } from \"react\";\nimport { cn, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from \"@hilum/ui\";\nimport {\n resolveDesignerWorkspaceInsets,\n type DesignerWorkspaceInsetsInput,\n} from \"./designer-workspace-insets\";\n\ninterface DesignerPanelProps {\n side: \"left\" | \"right\";\n /** Presentation mode. `inline` preserves the desktop side-panel behavior. */\n variant?: \"inline\" | \"floating\" | \"sheet\";\n /** Width in pixels. Default: 240. */\n width?: number;\n /** Add a separator border on the inner edge. Default: true. */\n bordered?: boolean;\n /** Insets used to position a floating panel within DesignerWorkspace. Default: 16px. */\n floatingInset?: DesignerWorkspaceInsetsInput;\n /** Controlled open state when `variant=\"sheet\"`. */\n open?: boolean;\n /** Controlled open-state handler when `variant=\"sheet\"`. */\n onOpenChange?: (open: boolean) => void;\n /** Accessible sheet title when `variant=\"sheet\"`. */\n sheetTitle?: ReactNode;\n /** Optional sheet description. */\n sheetDescription?: ReactNode;\n /** Sheet edge. Defaults to `bottom` for mobile editor panels. */\n sheetSide?: \"left\" | \"right\" | \"top\" | \"bottom\";\n sheetClassName?: string;\n className?: string;\n style?: CSSProperties;\n children?: ReactNode;\n}\n\n/**\n * Left or right side panel of an editor — typically holds layer lists,\n * inspector / properties, history, comments, etc. Static-width for v1.\n * (Resize handles arrive in a later iteration if needed.)\n */\nfunction DesignerPanel({\n side,\n variant = \"inline\",\n width = 240,\n bordered = true,\n floatingInset,\n open,\n onOpenChange,\n sheetTitle,\n sheetDescription,\n sheetSide = \"bottom\",\n sheetClassName,\n className,\n style,\n children,\n}: DesignerPanelProps) {\n if (variant === \"sheet\") {\n const sheetProps = {\n ...(open !== undefined ? { open } : {}),\n ...(onOpenChange ? { onOpenChange } : {}),\n };\n const resolvedSheetDescription = sheetDescription ?? \"Editor panel controls\";\n\n return (\n <Sheet {...sheetProps}>\n <SheetContent\n side={sheetSide}\n className={cn(\n \"flex max-h-[min(86svh,44rem)] flex-col overflow-hidden p-0\",\n sheetSide === \"bottom\" && \"rounded-t-2xl\",\n sheetClassName,\n )}\n >\n <SheetHeader\n className={cn(sheetTitle ? \"mb-0 border-b border-border px-4 py-3\" : \"sr-only\")}\n >\n <SheetTitle>{sheetTitle ?? `${side} panel`}</SheetTitle>\n <SheetDescription className={sheetDescription ? undefined : \"sr-only\"}>\n {resolvedSheetDescription}\n </SheetDescription>\n </SheetHeader>\n <div className=\"flex min-w-0 flex-1 flex-col overflow-x-hidden overflow-y-auto\">\n {children}\n </div>\n </SheetContent>\n </Sheet>\n );\n }\n\n const floatingInsets = resolveDesignerWorkspaceInsets(floatingInset, 16);\n const floatingStyle: CSSProperties | undefined =\n variant === \"floating\"\n ? {\n top: floatingInsets.top,\n bottom: floatingInsets.bottom,\n [side]: floatingInsets[side],\n width,\n maxWidth: \"calc(100% - 2rem)\",\n ...style,\n }\n : { width, maxWidth: \"100%\", ...style };\n\n return (\n <aside\n data-side={side}\n data-variant={variant}\n className={cn(\n \"flex min-w-0 max-w-full shrink-0 flex-col overflow-hidden bg-card\",\n variant === \"inline\" && bordered && (side === \"left\" ? \"border-r\" : \"border-l\"),\n variant === \"inline\" && bordered && \"border-border\",\n variant === \"floating\" && \"absolute z-20 rounded-2xl shadow-natural\",\n variant === \"floating\" && bordered && \"border border-border\",\n className,\n )}\n style={floatingStyle}\n >\n <div className=\"flex min-w-0 flex-1 flex-col overflow-x-hidden overflow-y-auto\">\n {children}\n </div>\n </aside>\n );\n}\n\nexport { DesignerPanel };\nexport type { DesignerPanelProps };\n","import { useState, type ReactNode } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"@hilum/ui\";\nimport { useShellContext } from \"../shell/ShellContext\";\n\ninterface DesignerPaneProps {\n /**\n * Predicate or list of allowed kinds. The pane renders only when matched.\n *\n * - `string[]`: render when at least one selected ID resolves to one of\n * these kinds (requires `ShellContext.resolveKind`).\n * - `(selectedIds: string[]) => boolean`: full predicate.\n * - omitted: always render.\n */\n showFor?: string[] | ((selectedIds: string[]) => boolean);\n collapsible?: boolean;\n defaultOpen?: boolean;\n className?: string;\n children: ReactNode;\n}\n\ninterface DesignerPaneTitleProps {\n className?: string;\n children: ReactNode;\n /** Right-aligned action / control. */\n action?: ReactNode;\n}\n\ninterface DesignerPaneContentProps {\n className?: string;\n children: ReactNode;\n}\n\n/**\n * Collapsible inspector section. Use inside a <DesignerPanel>.\n *\n * <DesignerPane showFor={[\"text\"]} collapsible>\n * <DesignerPaneTitle>Typography</DesignerPaneTitle>\n * <DesignerPaneContent>...</DesignerPaneContent>\n * </DesignerPane>\n */\nfunction DesignerPane({\n showFor,\n collapsible = false,\n defaultOpen = true,\n className,\n children,\n}: DesignerPaneProps) {\n const { selectedIds, resolveKind } = useShellContext();\n const [open, setOpen] = useState(defaultOpen);\n\n // Visibility check.\n let visible = true;\n if (typeof showFor === \"function\") {\n visible = showFor(selectedIds);\n } else if (Array.isArray(showFor)) {\n if (!resolveKind) {\n // No resolver: best effort — show only if any IDs are selected.\n visible = selectedIds.length > 0;\n } else {\n visible = selectedIds.some((id) => {\n const kind = resolveKind(id);\n return kind != null && showFor.includes(kind);\n });\n }\n }\n if (!visible) return null;\n\n return (\n <PaneContext.Provider value={{ open, toggle: () => setOpen((v) => !v), collapsible }}>\n <section\n className={cn(\n \"flex min-w-0 max-w-full flex-col overflow-x-hidden border-b border-border last:border-b-0\",\n className,\n )}\n >\n {children}\n </section>\n </PaneContext.Provider>\n );\n}\n\nfunction DesignerPaneTitle({ className, children, action }: DesignerPaneTitleProps) {\n const { open, toggle, collapsible } = usePaneContext();\n\n const Tag = collapsible ? \"button\" : \"div\";\n return (\n <Tag\n type={collapsible ? \"button\" : undefined}\n onClick={collapsible ? toggle : undefined}\n className={cn(\n \"flex min-h-10 w-full items-center justify-between gap-2 px-3 py-2 text-left\",\n \"caption-xs uppercase tracking-wider font-semibold text-muted-foreground\",\n collapsible && \"hover:text-foreground transition-colors\",\n className,\n )}\n >\n <span className=\"flex items-center gap-1.5\">\n {collapsible && (\n <ChevronDown\n size={12}\n className={cn(\"transition-transform duration-150\", !open && \"-rotate-90\")}\n />\n )}\n {children}\n </span>\n {action && <span className=\"ml-auto\">{action}</span>}\n </Tag>\n );\n}\n\nfunction DesignerPaneContent({ className, children }: DesignerPaneContentProps) {\n const { open } = usePaneContext();\n if (!open) return null;\n return (\n <div\n className={cn(\n \"flex min-w-0 max-w-full flex-col gap-2 overflow-x-hidden px-3 pb-3\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n// --- internal pane context (so title and content stay in sync) ---\n\nimport { createContext, useContext } from \"react\";\n\ninterface PaneCtx {\n open: boolean;\n toggle: () => void;\n collapsible: boolean;\n}\nconst PaneContext = createContext<PaneCtx>({ open: true, toggle: () => {}, collapsible: false });\nfunction usePaneContext() {\n return useContext(PaneContext);\n}\n\nexport { DesignerPane, DesignerPaneTitle, DesignerPaneContent };\nexport type { DesignerPaneProps, DesignerPaneTitleProps, DesignerPaneContentProps };\n","import type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"@hilum/ui\";\n\ninterface DesignerPropertyRowProps extends ComponentPropsWithoutRef<\"div\"> {\n /** Optional label for direct row usage. Compound usage can use DesignerPropertyLabel. */\n label?: ReactNode;\n /** htmlFor forwarded to the generated label when label is provided. */\n labelFor?: string;\n /** Class name for the generated controls container when label is provided. */\n controlsClassName?: string;\n children: ReactNode;\n}\n\ninterface DesignerPropertyLabelProps extends ComponentPropsWithoutRef<\"label\"> {\n children: ReactNode;\n}\n\ninterface DesignerPropertyControlsProps extends ComponentPropsWithoutRef<\"div\"> {\n children: ReactNode;\n}\n\ninterface DesignerPropertyGroupProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\"> {\n title?: ReactNode;\n children: ReactNode;\n}\n\nfunction DesignerPropertyRow({\n label,\n labelFor,\n controlsClassName,\n className,\n children,\n ...rest\n}: DesignerPropertyRowProps) {\n return (\n <div\n className={cn(\n \"flex w-full min-w-0 max-w-full flex-col items-stretch gap-1.5 py-1.5\",\n className,\n )}\n {...rest}\n >\n {label === undefined ? (\n children\n ) : (\n <>\n <DesignerPropertyLabel htmlFor={labelFor}>{label}</DesignerPropertyLabel>\n <DesignerPropertyControls className={controlsClassName}>\n {children}\n </DesignerPropertyControls>\n </>\n )}\n </div>\n );\n}\n\nfunction DesignerPropertyLabel({ className, children, ...rest }: DesignerPropertyLabelProps) {\n return (\n <label\n className={cn(\n \"caption w-full min-w-0 max-w-full select-none text-muted-foreground\",\n className,\n )}\n {...rest}\n >\n {children}\n </label>\n );\n}\n\nfunction DesignerPropertyControls({ className, children, ...rest }: DesignerPropertyControlsProps) {\n return (\n <div\n className={cn(\n \"flex w-full min-w-0 max-w-full flex-1 items-center gap-2 overflow-visible\",\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\nfunction DesignerPropertyGroup({\n title,\n className,\n children,\n ...rest\n}: DesignerPropertyGroupProps) {\n return (\n <div className={cn(\"flex min-w-0 max-w-full flex-col gap-3\", className)} {...rest}>\n {title && (\n <div className=\"caption-xs min-w-0 max-w-full select-none overflow-hidden text-ellipsis uppercase tracking-wider text-muted-foreground\">\n {title}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nexport {\n DesignerPropertyRow,\n DesignerPropertyLabel,\n DesignerPropertyControls,\n DesignerPropertyGroup,\n};\nexport type {\n DesignerPropertyRowProps,\n DesignerPropertyLabelProps,\n DesignerPropertyControlsProps,\n DesignerPropertyGroupProps,\n};\n","import type { ComponentType, CSSProperties, ReactNode } from \"react\";\nimport { cn, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@hilum/ui\";\n\n/* ============================================================== *\n * Toolbar — outer container *\n * ============================================================== */\n\ninterface DesignerToolbarProps {\n className?: string;\n /** Position. Default: 'floating' (centered, floating above content). */\n variant?: \"floating\" | \"inline\" | \"dock\";\n /**\n * Position floating chrome against the viewport or the nearest positioned\n * workspace ancestor. Default: 'viewport'.\n */\n boundary?: \"viewport\" | \"workspace\";\n /** Center against the full boundary or its configured workspace safe area. */\n center?: \"boundary\" | \"safe-area\";\n style?: CSSProperties;\n children: ReactNode;\n}\n\nfunction DesignerToolbar({\n className,\n variant = \"floating\",\n boundary = \"viewport\",\n center = \"boundary\",\n style,\n children,\n}: DesignerToolbarProps) {\n const positioned = boundary === \"workspace\" ? \"absolute\" : \"fixed\";\n const safeAreaStyle: CSSProperties | undefined =\n variant === \"floating\" && boundary === \"workspace\" && center === \"safe-area\"\n ? {\n left: \"calc(var(--designer-workspace-inset-left) + (100% - var(--designer-workspace-inset-left) - var(--designer-workspace-inset-right)) / 2)\",\n }\n : undefined;\n\n return (\n <TooltipProvider>\n <div\n role=\"toolbar\"\n className={cn(\n \"flex items-center gap-0.5 rounded-lg bg-card p-1 shadow-natural\",\n variant === \"floating\" && positioned,\n variant === \"floating\" && \"bottom-4 -translate-x-1/2 z-30\",\n variant === \"floating\" && center === \"boundary\" && \"left-1/2\",\n variant === \"dock\" && [\n positioned,\n \"inset-x-3 bottom-[max(0.75rem,env(safe-area-inset-bottom))] z-30\",\n \"overflow-x-auto overscroll-x-contain rounded-xl\",\n ],\n className,\n )}\n style={{ ...safeAreaStyle, ...style }}\n >\n {children}\n </div>\n </TooltipProvider>\n );\n}\n\n/* ============================================================== *\n * ToolbarGroup — visual group of buttons *\n * ============================================================== */\n\ninterface DesignerToolbarGroupProps {\n className?: string;\n children: ReactNode;\n}\n\nfunction DesignerToolbarGroup({ className, children }: DesignerToolbarGroupProps) {\n return <div className={cn(\"flex items-center gap-0.5\", className)}>{children}</div>;\n}\n\n/* ============================================================== *\n * ToolbarSeparator *\n * ============================================================== */\n\ninterface DesignerToolbarSeparatorProps {\n className?: string;\n}\n\nfunction DesignerToolbarSeparator({ className }: DesignerToolbarSeparatorProps) {\n return <div className={cn(\"mx-1 h-5 w-px bg-muted\", className)} role=\"separator\" />;\n}\n\n/* ============================================================== *\n * ToolbarButton — single tool / action *\n * ============================================================== */\n\ninterface DesignerToolbarButtonProps {\n label: string;\n icon?: ComponentType<{ size?: number; className?: string }>;\n onClick?: () => void;\n active?: boolean;\n disabled?: boolean;\n /** Optional keyboard shortcut shown in the tooltip (e.g. 'V', 'Cmd+Z'). */\n shortcut?: string;\n size?: \"default\" | \"touch\";\n className?: string;\n children?: ReactNode;\n}\n\nfunction DesignerToolbarButton({\n label,\n icon: Icon,\n onClick,\n active,\n disabled,\n shortcut,\n size = \"default\",\n className,\n children,\n}: DesignerToolbarButtonProps) {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-label={label}\n aria-pressed={active}\n className={cn(\n \"flex h-9 min-w-9 items-center justify-center gap-1 rounded-md px-2 caption transition-[background-color,color,opacity,scale] active:scale-[0.96]\",\n \"[@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:min-w-11\",\n size === \"touch\" && \"h-11 min-w-11\",\n active\n ? \"bg-foreground text-background\"\n : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n disabled && \"opacity-50 cursor-not-allowed\",\n className,\n )}\n >\n {Icon && <Icon size={16} />}\n {children}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n <span>{label}</span>\n {shortcut && <span className=\"ml-2 caption-xs text-muted-foreground\">{shortcut}</span>}\n </TooltipContent>\n </Tooltip>\n );\n}\n\nexport { DesignerToolbar, DesignerToolbarGroup, DesignerToolbarSeparator, DesignerToolbarButton };\nexport type {\n DesignerToolbarProps,\n DesignerToolbarGroupProps,\n DesignerToolbarSeparatorProps,\n DesignerToolbarButtonProps,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Link2, Unlink2 } from \"lucide-react\";\nimport { Button, InputNumber, cn } from \"@hilum/ui\";\n\ntype DesignerControlValue = number | null;\n\ninterface DesignerValueItem<K extends string> {\n key: K;\n label: React.ReactNode;\n ariaLabel?: string;\n min?: number;\n max?: number;\n step?: number;\n precision?: number;\n unit?: string;\n disabled?: boolean;\n}\n\ninterface DesignerValueControlBaseProps<K extends string> {\n label?: React.ReactNode;\n values: Record<K, DesignerControlValue>;\n items: readonly DesignerValueItem<K>[];\n onChange: (key: K, value: number) => void;\n onChangeAll?: (value: number) => void;\n onCommit?: () => void;\n linked?: boolean;\n onLinkedChange?: (linked: boolean) => void;\n unit?: string;\n min?: number;\n max?: number;\n step?: number;\n precision?: number;\n disabled?: boolean;\n readOnly?: boolean;\n mixedLabel?: string;\n hideSteppers?: boolean;\n className?: string;\n labelClassName?: string;\n inputClassName?: string;\n controlsClassName?: string;\n linkButtonClassName?: string;\n linkLabel?: string;\n unlinkLabel?: string;\n}\n\ninterface TwoValueControlProps<K extends string = string>\n extends DesignerValueControlBaseProps<K> {\n items: readonly [DesignerValueItem<K>, DesignerValueItem<K>];\n}\n\ninterface FourValueControlProps<K extends string = string>\n extends DesignerValueControlBaseProps<K> {\n items: readonly [\n DesignerValueItem<K>,\n DesignerValueItem<K>,\n DesignerValueItem<K>,\n DesignerValueItem<K>,\n ];\n layout?: \"grid\" | \"single-when-linked\";\n}\n\ntype SpacingSide = \"top\" | \"right\" | \"bottom\" | \"left\";\ntype CornerSide = \"topLeft\" | \"topRight\" | \"bottomLeft\" | \"bottomRight\";\n\ntype SpacingControlProps = Omit<\n FourValueControlProps<SpacingSide>,\n \"items\" | \"values\" | \"onChange\" | \"onChangeAll\"\n> & {\n values: Record<SpacingSide, DesignerControlValue>;\n onChange: (side: SpacingSide, value: number) => void;\n onChangeAll?: (value: number) => void;\n};\n\ntype CornerRadiusControlProps = Omit<\n FourValueControlProps<CornerSide>,\n \"items\" | \"values\" | \"onChange\" | \"onChangeAll\"\n> & {\n values: Record<CornerSide, DesignerControlValue>;\n onChange: (side: CornerSide, value: number) => void;\n onChangeAll?: (value: number) => void;\n};\n\nfunction getSharedValue<K extends string>(\n items: readonly DesignerValueItem<K>[],\n values: Record<K, DesignerControlValue>,\n) {\n const first = values[items[0].key];\n if (first === null) return null;\n return items.every((item) => values[item.key] === first) ? first : null;\n}\n\nfunction DesignerValueField<K extends string>({\n item,\n value,\n unit,\n min,\n max,\n step,\n precision,\n disabled,\n readOnly,\n mixedLabel,\n hideSteppers,\n inputClassName,\n onChange,\n onCommit,\n}: {\n item: DesignerValueItem<K>;\n value: DesignerControlValue;\n unit?: string | undefined;\n min?: number | undefined;\n max?: number | undefined;\n step?: number | undefined;\n precision?: number | undefined;\n disabled?: boolean | undefined;\n readOnly?: boolean | undefined;\n mixedLabel?: string | undefined;\n hideSteppers?: boolean | undefined;\n inputClassName?: string | undefined;\n onChange: (value: number) => void;\n onCommit?: (() => void) | undefined;\n}) {\n return (\n <div className=\"relative min-w-0\">\n <span className=\"caption-xs pointer-events-none absolute left-2 top-1/2 z-10 -translate-y-1/2 select-none font-semibold uppercase text-muted-foreground\">\n {item.label}\n </span>\n <InputNumber\n value={value}\n onChange={onChange}\n min={item.min ?? min}\n max={item.max ?? max}\n step={item.step ?? step}\n precision={item.precision ?? precision}\n unit={item.unit ?? unit}\n mixedLabel={mixedLabel}\n commitOnChange\n hideSteppers={hideSteppers}\n disabled={disabled || item.disabled}\n readOnly={readOnly}\n aria-label={item.ariaLabel}\n onBlur={onCommit}\n className={cn(\"h-9 w-full bg-muted/60\", inputClassName)}\n inputMode=\"decimal\"\n />\n </div>\n );\n}\n\nfunction DesignerValueControl<K extends string>({\n label,\n values,\n items,\n onChange,\n onChangeAll,\n onCommit,\n linked,\n onLinkedChange,\n unit,\n min = -Infinity,\n max = Infinity,\n step = 1,\n precision = 0,\n disabled = false,\n readOnly = false,\n mixedLabel = \"Mixed\",\n hideSteppers = true,\n className,\n labelClassName,\n inputClassName,\n controlsClassName,\n linkButtonClassName,\n linkLabel = \"Link values\",\n unlinkLabel = \"Unlink values\",\n singleWhenLinked = false,\n}: DesignerValueControlBaseProps<K> & { singleWhenLinked?: boolean }) {\n const hasLinkControl = typeof linked === \"boolean\" && Boolean(onLinkedChange);\n const sharedValue = getSharedValue(items, values);\n const showSingleInput = singleWhenLinked && linked;\n\n const handleChange = (key: K, value: number) => {\n if (linked) {\n if (onChangeAll) {\n onChangeAll(value);\n } else {\n items.forEach((item) => onChange(item.key, value));\n }\n return;\n }\n\n onChange(key, value);\n };\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-1.5\", className)}>\n {(label || hasLinkControl) && (\n <div className=\"flex min-w-0 items-center justify-between gap-2\">\n {label && (\n <div className={cn(\"caption select-none text-muted-foreground\", labelClassName)}>\n {label}\n </div>\n )}\n {hasLinkControl && (\n <Button\n type=\"button\"\n variant={linked ? \"secondary\" : \"ghost\"}\n size=\"icon-xs\"\n aria-label={linked ? unlinkLabel : linkLabel}\n title={linked ? unlinkLabel : linkLabel}\n aria-pressed={linked}\n disabled={disabled || readOnly}\n onClick={() => onLinkedChange?.(!linked)}\n className={linkButtonClassName}\n >\n {linked ? <Link2 size={12} /> : <Unlink2 size={12} />}\n </Button>\n )}\n </div>\n )}\n\n {showSingleInput ? (\n <DesignerValueField\n item={{ ...items[0], label: \"All\", ariaLabel: \"All values\" }}\n value={sharedValue}\n unit={unit}\n min={min}\n max={max}\n step={step}\n precision={precision}\n disabled={disabled}\n readOnly={readOnly}\n mixedLabel={mixedLabel}\n hideSteppers={hideSteppers}\n inputClassName={inputClassName}\n onChange={(value) => handleChange(items[0].key, value)}\n onCommit={onCommit}\n />\n ) : (\n <div\n className={cn(\n \"grid min-w-0 gap-2\",\n items.length === 2 ? \"grid-cols-2\" : \"grid-cols-2\",\n controlsClassName,\n )}\n >\n {items.map((item) => (\n <DesignerValueField\n key={item.key}\n item={item}\n value={values[item.key]}\n unit={unit}\n min={min}\n max={max}\n step={step}\n precision={precision}\n disabled={disabled}\n readOnly={readOnly}\n mixedLabel={mixedLabel}\n hideSteppers={hideSteppers}\n inputClassName={inputClassName}\n onChange={(value) => handleChange(item.key, value)}\n onCommit={onCommit}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction TwoValueControl<K extends string = string>(props: TwoValueControlProps<K>) {\n return <DesignerValueControl {...props} />;\n}\n\nfunction FourValueControl<K extends string = string>({\n layout = \"single-when-linked\",\n ...props\n}: FourValueControlProps<K>) {\n return <DesignerValueControl {...props} singleWhenLinked={layout === \"single-when-linked\"} />;\n}\n\nconst spacingItems = [\n { key: \"top\", label: \"T\", ariaLabel: \"Top\" },\n { key: \"right\", label: \"R\", ariaLabel: \"Right\" },\n { key: \"bottom\", label: \"B\", ariaLabel: \"Bottom\" },\n { key: \"left\", label: \"L\", ariaLabel: \"Left\" },\n] as const satisfies readonly [\n DesignerValueItem<SpacingSide>,\n DesignerValueItem<SpacingSide>,\n DesignerValueItem<SpacingSide>,\n DesignerValueItem<SpacingSide>,\n];\n\nconst cornerItems = [\n { key: \"topLeft\", label: \"TL\", ariaLabel: \"Top left radius\" },\n { key: \"topRight\", label: \"TR\", ariaLabel: \"Top right radius\" },\n { key: \"bottomLeft\", label: \"BL\", ariaLabel: \"Bottom left radius\" },\n { key: \"bottomRight\", label: \"BR\", ariaLabel: \"Bottom right radius\" },\n] as const satisfies readonly [\n DesignerValueItem<CornerSide>,\n DesignerValueItem<CornerSide>,\n DesignerValueItem<CornerSide>,\n DesignerValueItem<CornerSide>,\n];\n\nfunction SpacingControl(props: SpacingControlProps) {\n return <FourValueControl {...props} items={spacingItems} />;\n}\n\nfunction CornerRadiusControl(props: CornerRadiusControlProps) {\n return <FourValueControl {...props} items={cornerItems} min={props.min ?? 0} />;\n}\n\nexport {\n CornerRadiusControl,\n FourValueControl,\n SpacingControl,\n TwoValueControl,\n};\nexport type {\n CornerRadiusControlProps,\n CornerSide,\n DesignerControlValue,\n DesignerValueItem,\n FourValueControlProps,\n SpacingControlProps,\n SpacingSide,\n TwoValueControlProps,\n};\n","import { useCallback, useState } from \"react\";\n\ninterface HistoryState<T> {\n past: T[];\n present: T;\n future: T[];\n}\n\ninterface UseHistoryReturn<T> {\n state: T;\n /**\n * Record a new state. Use when the user makes a logical edit. Pushes the\n * current `state` into `past` and clears `future`. Pass `{ skipHistory: true }`\n * (via a separate setter) to overwrite without pushing — apps that need that\n * can set state directly via a wrapper.\n */\n setState: (next: T | ((prev: T) => T)) => void;\n /** Replace `state` without pushing onto the history stack. */\n replaceState: (next: T | ((prev: T) => T)) => void;\n undo: () => void;\n redo: () => void;\n reset: (next: T) => void;\n canUndo: boolean;\n canRedo: boolean;\n /** Number of past entries (undo depth). */\n pastSize: number;\n /** Number of future entries (redo depth). */\n futureSize: number;\n}\n\n/**\n * Generic, engine-agnostic undo/redo stack.\n *\n * @hilum/designer-canvas wires this with `useHistory<Layer[]>(layers)`.\n * A form-builder app could wire `useHistory<FormSchema>(schema)`.\n */\nexport function useHistory<T>(initial: T): UseHistoryReturn<T> {\n const [history, setHistory] = useState<HistoryState<T>>({\n past: [],\n present: initial,\n future: [],\n });\n\n const setState = useCallback((next: T | ((prev: T) => T)) => {\n setHistory((prev) => {\n const value = typeof next === \"function\" ? (next as (p: T) => T)(prev.present) : next;\n if (Object.is(value, prev.present)) return prev;\n return {\n past: [...prev.past, prev.present],\n present: value,\n future: [],\n };\n });\n }, []);\n\n const replaceState = useCallback((next: T | ((prev: T) => T)) => {\n setHistory((prev) => {\n const value = typeof next === \"function\" ? (next as (p: T) => T)(prev.present) : next;\n return { ...prev, present: value };\n });\n }, []);\n\n const undo = useCallback(() => {\n setHistory((prev) => {\n if (prev.past.length === 0) return prev;\n const past = prev.past.slice(0, -1);\n const previous = prev.past[prev.past.length - 1]!;\n return {\n past,\n present: previous,\n future: [prev.present, ...prev.future],\n };\n });\n }, []);\n\n const redo = useCallback(() => {\n setHistory((prev) => {\n if (prev.future.length === 0) return prev;\n const [next, ...rest] = prev.future;\n return {\n past: [...prev.past, prev.present],\n present: next!,\n future: rest,\n };\n });\n }, []);\n\n const reset = useCallback((next: T) => {\n setHistory({ past: [], present: next, future: [] });\n }, []);\n\n return {\n state: history.present,\n setState,\n replaceState,\n undo,\n redo,\n reset,\n canUndo: history.past.length > 0,\n canRedo: history.future.length > 0,\n pastSize: history.past.length,\n futureSize: history.future.length,\n };\n}\n","import { useEffect } from \"react\";\n\nexport interface KeybindingConfig {\n /** Lower-case key (e.g. 'z', 'arrowup', 'escape', '+', '-'). */\n key: string;\n ctrl?: boolean;\n /** Cmd on macOS. Use both `meta` and `ctrl: true` if you want both. */\n meta?: boolean;\n shift?: boolean;\n alt?: boolean;\n /**\n * Treat both ctrl and meta as the same modifier (for cross-platform\n * shortcuts like Cmd+Z / Ctrl+Z). Default: false. Set to true to match\n * either modifier.\n */\n mod?: boolean;\n action: (event: KeyboardEvent) => void;\n /** Don't run when target is an input / textarea / contenteditable. Default: true. */\n skipInputs?: boolean;\n /** Call event.preventDefault() before action. Default: true. */\n preventDefault?: boolean;\n}\n\ninterface UseKeybindingsOptions {\n /** Skip all bindings entirely. */\n disabled?: boolean;\n /** Element to attach the listener to. Default: window. */\n target?: Window | HTMLElement | null;\n}\n\n/**\n * Generic keyboard shortcut registry. Engine-agnostic — the package doesn't\n * know what an action does. Pass an array of bindings; the hook attaches\n * a single keydown listener and dispatches on match.\n *\n * @hilum/designer-canvas wires its standard editor shortcuts (Cmd+Z, V, T,\n * arrow nudge, etc.) on top of this hook.\n */\nexport function useKeybindings(\n bindings: KeybindingConfig[],\n { disabled, target }: UseKeybindingsOptions = {},\n) {\n useEffect(() => {\n if (disabled) return;\n const node = target ?? (typeof window !== \"undefined\" ? window : null);\n if (!node) return;\n\n const handler = (rawEvent: Event) => {\n const e = rawEvent as KeyboardEvent;\n\n const tgt = e.target as HTMLElement | null;\n const isInput =\n tgt instanceof HTMLInputElement ||\n tgt instanceof HTMLTextAreaElement ||\n tgt instanceof HTMLSelectElement ||\n tgt?.isContentEditable === true;\n\n const key = e.key.toLowerCase();\n\n for (const b of bindings) {\n if (b.key.toLowerCase() !== key) continue;\n if (b.skipInputs !== false && isInput) continue;\n\n const ctrlMatches = b.ctrl ? e.ctrlKey : !e.ctrlKey || b.mod;\n const metaMatches = b.meta ? e.metaKey : !e.metaKey || b.mod;\n const modMatches = b.mod ? e.ctrlKey || e.metaKey : true;\n const shiftMatches = b.shift ? e.shiftKey : !e.shiftKey;\n const altMatches = b.alt ? e.altKey : !e.altKey;\n\n if (!modMatches) continue;\n if (!b.mod && (!ctrlMatches || !metaMatches)) continue;\n if (!shiftMatches || !altMatches) continue;\n\n if (b.preventDefault !== false) e.preventDefault();\n b.action(e);\n return;\n }\n };\n\n (node as Window).addEventListener(\"keydown\", handler);\n return () => (node as Window).removeEventListener(\"keydown\", handler);\n }, [bindings, disabled, target]);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hilum/designer",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Engine-agnostic canvas-editor chrome — DesignerShell, Toolbar, Panel, Pane + generic useHistory and useKeybindings hooks",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"tailwindcss": "^4.2.0",
|
|
40
40
|
"tsup": "^8.3.0",
|
|
41
41
|
"typescript": "^5.7.0",
|
|
42
|
-
"@hilum/ui": "3.8.
|
|
42
|
+
"@hilum/ui": "3.8.3"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsup",
|