@tangle-network/agent-app 0.27.2 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DesignCanvas-AOIVN3SJ.js +12 -0
- package/dist/DesignCanvasEditor-IB2FMBBD.js +13 -0
- package/dist/InviteAcceptPage-EUOGZO2X.js +7 -0
- package/dist/MembersPanel-4CGUQRPF.js +8 -0
- package/dist/MembersPanel-4CGUQRPF.js.map +1 -0
- package/dist/{TimelineEditor-JDG54OBP.js → TimelineEditor-Z7C6BFP5.js} +2 -2
- package/dist/TimelineEditor-Z7C6BFP5.js.map +1 -0
- package/dist/access-ChAHG4Tp.d.ts +539 -0
- package/dist/{apply-Cp8c3K9D.d.ts → apply-Gk4raT2j.d.ts} +3 -1
- package/dist/{chunk-AFDROJ64.js → chunk-2QI7XV2T.js} +1 -1
- package/dist/chunk-2QI7XV2T.js.map +1 -0
- package/dist/chunk-3G334FVA.js +162 -0
- package/dist/chunk-3G334FVA.js.map +1 -0
- package/dist/chunk-3SVAA3MA.js +41 -0
- package/dist/chunk-3SVAA3MA.js.map +1 -0
- package/dist/{chunk-LUE4HO5C.js → chunk-4IQMTTNE.js} +10 -10
- package/dist/chunk-4IQMTTNE.js.map +1 -0
- package/dist/chunk-535V6BH6.js +128 -0
- package/dist/chunk-535V6BH6.js.map +1 -0
- package/dist/chunk-63CE7FEZ.js +63 -0
- package/dist/chunk-63CE7FEZ.js.map +1 -0
- package/dist/{chunk-5RT6KY4G.js → chunk-GQRL6VNU.js} +1 -1
- package/dist/chunk-GQRL6VNU.js.map +1 -0
- package/dist/{chunk-SCG5JJ4C.js → chunk-HFC4BTWJ.js} +32 -4
- package/dist/chunk-HFC4BTWJ.js.map +1 -0
- package/dist/{chunk-7QCIYDGC.js → chunk-IOREXWLM.js} +2 -2
- package/dist/{chunk-6UOE5CTA.js → chunk-JT6HHO5P.js} +5 -10
- package/dist/chunk-JT6HHO5P.js.map +1 -0
- package/dist/{chunk-JZAJE3JL.js → chunk-M2EBUDZ7.js} +19 -5
- package/dist/chunk-M2EBUDZ7.js.map +1 -0
- package/dist/{chunk-HABVCJJT.js → chunk-N4ZFKQ5C.js} +271 -404
- package/dist/chunk-N4ZFKQ5C.js.map +1 -0
- package/dist/chunk-S5CAJX6O.js +14 -0
- package/dist/chunk-S5CAJX6O.js.map +1 -0
- package/dist/{chunk-RJ2ZHK5D.js → chunk-S6WS2B32.js} +132 -7
- package/dist/chunk-S6WS2B32.js.map +1 -0
- package/dist/chunk-SQV7NUEM.js +136 -0
- package/dist/chunk-SQV7NUEM.js.map +1 -0
- package/dist/chunk-UAKFCMWK.js +1 -0
- package/dist/chunk-UAKFCMWK.js.map +1 -0
- package/dist/chunk-V5XZKHCL.js +296 -0
- package/dist/chunk-V5XZKHCL.js.map +1 -0
- package/dist/chunk-XWJXZ6WE.js +604 -0
- package/dist/chunk-XWJXZ6WE.js.map +1 -0
- package/dist/chunk-Y2SZVW35.js +125 -0
- package/dist/chunk-Y2SZVW35.js.map +1 -0
- package/dist/{chunk-27LQXQSS.js → chunk-YEWTVDDT.js} +224 -767
- package/dist/chunk-YEWTVDDT.js.map +1 -0
- package/dist/{chunk-UDXMR3AD.js → chunk-YNALYIQ3.js} +56 -18
- package/dist/chunk-YNALYIQ3.js.map +1 -0
- package/dist/command-stack-CkjelfK_.d.ts +267 -0
- package/dist/design-canvas/drizzle.d.ts +2 -2
- package/dist/design-canvas/index.d.ts +7 -6
- package/dist/design-canvas/index.js +3 -2
- package/dist/design-canvas-react/engine.d.ts +349 -0
- package/dist/design-canvas-react/engine.js +86 -0
- package/dist/design-canvas-react/engine.js.map +1 -0
- package/dist/design-canvas-react/index.d.ts +69 -649
- package/dist/design-canvas-react/index.js +84 -173
- package/dist/design-canvas-react/index.js.map +1 -1
- package/dist/design-canvas-react/lazy.d.ts +6 -0
- package/dist/design-canvas-react/lazy.js +9 -0
- package/dist/design-canvas-react/lazy.js.map +1 -0
- package/dist/{export-presets-Dl5Aa5xj.d.ts → export-presets-DAsU5Wal.d.ts} +2 -143
- package/dist/flow-types-Cb_AblZs.d.ts +25 -0
- package/dist/index.d.ts +11 -8
- package/dist/index.js +21 -8
- package/dist/lazy-BHHqS8-j.d.ts +72 -0
- package/dist/missions/index.d.ts +12 -0
- package/dist/missions/index.js +1 -1
- package/dist/{model-BHLN208Z.d.ts → model-BBwyOuWG.d.ts} +3 -1
- package/dist/operations-DLIvvD00.d.ts +144 -0
- package/dist/platform/index.js +1 -1
- package/dist/roles-CLtYKHHl.d.ts +49 -0
- package/dist/runtime/index.d.ts +33 -33
- package/dist/runtime/index.js +1 -1
- package/dist/sequences/index.d.ts +1 -1
- package/dist/sequences/index.js +2 -1
- package/dist/sequences-react/index.d.ts +15 -1
- package/dist/sequences-react/index.js +2 -2
- package/dist/{store-CUStmtdH.d.ts → store-CFyxgTlD.d.ts} +1 -1
- package/dist/teams/drizzle.d.ts +42 -0
- package/dist/teams/drizzle.js +194 -0
- package/dist/teams/drizzle.js.map +1 -0
- package/dist/teams/index.d.ts +44 -0
- package/dist/teams/index.js +39 -0
- package/dist/teams/index.js.map +1 -0
- package/dist/teams/members-api.d.ts +152 -0
- package/dist/teams/members-api.js +261 -0
- package/dist/teams/members-api.js.map +1 -0
- package/dist/teams-react/index.d.ts +81 -0
- package/dist/teams-react/index.js +12 -0
- package/dist/teams-react/index.js.map +1 -0
- package/dist/teams-react/lazy.d.ts +9 -0
- package/dist/teams-react/lazy.js +13 -0
- package/dist/teams-react/lazy.js.map +1 -0
- package/dist/theme/index.d.ts +80 -0
- package/dist/theme/index.js +14 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/tailwind-preset.d.ts +65 -0
- package/dist/theme/tailwind-preset.js +33 -0
- package/dist/theme/tailwind-preset.js.map +1 -0
- package/dist/theme/tokens.css +95 -0
- package/dist/trace/index.d.ts +2 -18
- package/dist/trace/index.js +2 -2
- package/dist/web/index.d.ts +25 -2
- package/dist/web/index.js +3 -1
- package/dist/web-react/index.d.ts +71 -31
- package/dist/web-react/index.js +625 -486
- package/dist/web-react/index.js.map +1 -1
- package/package.json +53 -3
- package/dist/DesignCanvas-73IUJJUP.js +0 -10
- package/dist/DesignCanvasEditor-6F2UTOSW.js +0 -9
- package/dist/chunk-27LQXQSS.js.map +0 -1
- package/dist/chunk-5RT6KY4G.js.map +0 -1
- package/dist/chunk-6UOE5CTA.js.map +0 -1
- package/dist/chunk-AFDROJ64.js.map +0 -1
- package/dist/chunk-HABVCJJT.js.map +0 -1
- package/dist/chunk-JZAJE3JL.js.map +0 -1
- package/dist/chunk-LUE4HO5C.js.map +0 -1
- package/dist/chunk-RJ2ZHK5D.js.map +0 -1
- package/dist/chunk-SCG5JJ4C.js.map +0 -1
- package/dist/chunk-UDXMR3AD.js.map +0 -1
- /package/dist/{DesignCanvas-73IUJJUP.js.map → DesignCanvas-AOIVN3SJ.js.map} +0 -0
- /package/dist/{DesignCanvasEditor-6F2UTOSW.js.map → DesignCanvasEditor-IB2FMBBD.js.map} +0 -0
- /package/dist/{TimelineEditor-JDG54OBP.js.map → InviteAcceptPage-EUOGZO2X.js.map} +0 -0
- /package/dist/{chunk-7QCIYDGC.js.map → chunk-IOREXWLM.js.map} +0 -0
|
@@ -1,564 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addPageCommand,
|
|
3
|
+
bindSlotCommand,
|
|
4
|
+
createSceneCommandStack,
|
|
5
|
+
deleteElementCommand,
|
|
6
|
+
deletePageCommand,
|
|
7
|
+
duplicatePageCommand,
|
|
8
|
+
groupElementsCommand,
|
|
9
|
+
multiSetAttrsCommand,
|
|
10
|
+
reorderElementCommand,
|
|
11
|
+
reorderPageCommand,
|
|
12
|
+
setAttrsCommand,
|
|
13
|
+
setPageGuidesCommand,
|
|
14
|
+
setPagePropsCommand,
|
|
15
|
+
ungroupElementCommand
|
|
16
|
+
} from "./chunk-XWJXZ6WE.js";
|
|
1
17
|
import {
|
|
2
18
|
SIZE_PRESETS,
|
|
3
|
-
applySceneOperation,
|
|
4
|
-
applySceneOperations,
|
|
5
19
|
findElement,
|
|
6
20
|
matchPreset,
|
|
7
|
-
requireElement,
|
|
8
21
|
requirePage
|
|
9
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-M2EBUDZ7.js";
|
|
10
23
|
|
|
11
24
|
// src/design-canvas-react/components/DesignCanvas.tsx
|
|
12
25
|
import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef as useRef5, useState as useState5, useSyncExternalStore } from "react";
|
|
13
26
|
|
|
14
|
-
// src/design-canvas-react/engine/command-stack.ts
|
|
15
|
-
var SCENE_COMMAND_HISTORY_LIMIT = 200;
|
|
16
|
-
function createSceneCommandStack(document2, activePageId) {
|
|
17
|
-
let state = {
|
|
18
|
-
document: document2,
|
|
19
|
-
activePageId,
|
|
20
|
-
selectedElementIds: [],
|
|
21
|
-
zoom: 1,
|
|
22
|
-
panX: 0,
|
|
23
|
-
panY: 0,
|
|
24
|
-
gridEnabled: false,
|
|
25
|
-
gridSize: 10,
|
|
26
|
-
snapEnabled: true,
|
|
27
|
-
showRulers: true,
|
|
28
|
-
showBleed: false
|
|
29
|
-
};
|
|
30
|
-
const undoStack = [];
|
|
31
|
-
const redoStack = [];
|
|
32
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
33
|
-
const notify = () => {
|
|
34
|
-
for (const listener of [...listeners]) listener();
|
|
35
|
-
};
|
|
36
|
-
return {
|
|
37
|
-
execute(command) {
|
|
38
|
-
state = command.execute(state);
|
|
39
|
-
undoStack.push(command);
|
|
40
|
-
if (undoStack.length > SCENE_COMMAND_HISTORY_LIMIT) {
|
|
41
|
-
undoStack.splice(0, undoStack.length - SCENE_COMMAND_HISTORY_LIMIT);
|
|
42
|
-
}
|
|
43
|
-
redoStack.length = 0;
|
|
44
|
-
notify();
|
|
45
|
-
},
|
|
46
|
-
// Both transforms run BEFORE the stacks move: a throwing transform (e.g.
|
|
47
|
-
// missing element after reset()) leaves history and state exactly as they
|
|
48
|
-
// were. The entry is never silently destroyed — the caller can retry after
|
|
49
|
-
// the next server refresh restores the target.
|
|
50
|
-
undo() {
|
|
51
|
-
const command = undoStack[undoStack.length - 1];
|
|
52
|
-
if (!command) throw new Error("nothing to undo \u2014 guard with canUndo() before calling undo()");
|
|
53
|
-
state = command.undo(state);
|
|
54
|
-
undoStack.pop();
|
|
55
|
-
redoStack.push(command);
|
|
56
|
-
notify();
|
|
57
|
-
return command;
|
|
58
|
-
},
|
|
59
|
-
redo() {
|
|
60
|
-
const command = redoStack[redoStack.length - 1];
|
|
61
|
-
if (!command) throw new Error("nothing to redo \u2014 guard with canRedo() before calling redo()");
|
|
62
|
-
state = command.execute(state);
|
|
63
|
-
redoStack.pop();
|
|
64
|
-
undoStack.push(command);
|
|
65
|
-
notify();
|
|
66
|
-
return command;
|
|
67
|
-
},
|
|
68
|
-
canUndo() {
|
|
69
|
-
return undoStack.length > 0;
|
|
70
|
-
},
|
|
71
|
-
canRedo() {
|
|
72
|
-
return redoStack.length > 0;
|
|
73
|
-
},
|
|
74
|
-
subscribe(listener) {
|
|
75
|
-
listeners.add(listener);
|
|
76
|
-
return () => {
|
|
77
|
-
listeners.delete(listener);
|
|
78
|
-
};
|
|
79
|
-
},
|
|
80
|
-
getState() {
|
|
81
|
-
return state;
|
|
82
|
-
},
|
|
83
|
-
setView(patch) {
|
|
84
|
-
state = { ...state, ...patch };
|
|
85
|
-
notify();
|
|
86
|
-
},
|
|
87
|
-
rollback(command) {
|
|
88
|
-
const idx = undoStack.lastIndexOf(command);
|
|
89
|
-
if (idx === -1) return;
|
|
90
|
-
state = command.undo(state);
|
|
91
|
-
undoStack.splice(idx, 1);
|
|
92
|
-
redoStack.length = 0;
|
|
93
|
-
notify();
|
|
94
|
-
},
|
|
95
|
-
/** Rebase onto a server-refreshed document. History survives; selection
|
|
96
|
-
* drops ids the refresh removed so view state never dangles. */
|
|
97
|
-
reset(newDocument) {
|
|
98
|
-
const liveElementIds = /* @__PURE__ */ new Set();
|
|
99
|
-
for (const page of newDocument.pages) {
|
|
100
|
-
collectElementIds(page.elements, liveElementIds);
|
|
101
|
-
}
|
|
102
|
-
const activePageExists = newDocument.pages.some((p) => p.id === state.activePageId);
|
|
103
|
-
const activePageId2 = activePageExists ? state.activePageId : newDocument.pages[0]?.id ?? state.activePageId;
|
|
104
|
-
state = {
|
|
105
|
-
...state,
|
|
106
|
-
document: newDocument,
|
|
107
|
-
activePageId: activePageId2,
|
|
108
|
-
selectedElementIds: state.selectedElementIds.filter((id) => liveElementIds.has(id))
|
|
109
|
-
};
|
|
110
|
-
notify();
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
function collectElementIds(elements, ids) {
|
|
115
|
-
for (const el of elements) {
|
|
116
|
-
ids.add(el.id);
|
|
117
|
-
if (el.kind === "group" && Array.isArray(el.children)) {
|
|
118
|
-
collectElementIds(el.children, ids);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// src/design-canvas-react/engine/commands.ts
|
|
124
|
-
function applyOps(state, ops) {
|
|
125
|
-
return { ...state, document: applySceneOperations(state.document, ops) };
|
|
126
|
-
}
|
|
127
|
-
function applyOp(state, op) {
|
|
128
|
-
return { ...state, document: applySceneOperation(state.document, op) };
|
|
129
|
-
}
|
|
130
|
-
function addElementCommand(input) {
|
|
131
|
-
const addOp = {
|
|
132
|
-
type: "add_element",
|
|
133
|
-
pageId: input.pageId,
|
|
134
|
-
element: structuredClone(input.element),
|
|
135
|
-
...input.index !== void 0 ? { index: input.index } : {},
|
|
136
|
-
...input.parentGroupId !== void 0 ? { parentGroupId: input.parentGroupId } : {}
|
|
137
|
-
};
|
|
138
|
-
const deleteOp = {
|
|
139
|
-
type: "delete_element",
|
|
140
|
-
pageId: input.pageId,
|
|
141
|
-
elementId: input.element.id
|
|
142
|
-
};
|
|
143
|
-
return {
|
|
144
|
-
label: `Add ${input.element.kind}`,
|
|
145
|
-
execute: (state) => applyOp(state, addOp),
|
|
146
|
-
undo: (state) => applyOp(state, deleteOp),
|
|
147
|
-
operations: () => [structuredClone(addOp)],
|
|
148
|
-
inverseOperations: () => [structuredClone(deleteOp)]
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
function setAttrsCommand(input) {
|
|
152
|
-
const forwardOp = {
|
|
153
|
-
type: "set_attrs",
|
|
154
|
-
pageId: input.pageId,
|
|
155
|
-
elementId: input.elementId,
|
|
156
|
-
attrs: structuredClone(input.attrs)
|
|
157
|
-
};
|
|
158
|
-
const inverseOp = {
|
|
159
|
-
type: "set_attrs",
|
|
160
|
-
pageId: input.pageId,
|
|
161
|
-
elementId: input.elementId,
|
|
162
|
-
attrs: structuredClone(input.priorAttrs)
|
|
163
|
-
};
|
|
164
|
-
return {
|
|
165
|
-
label: "Edit element",
|
|
166
|
-
execute: (state) => applyOp(state, forwardOp),
|
|
167
|
-
undo: (state) => applyOp(state, inverseOp),
|
|
168
|
-
operations: () => [structuredClone(forwardOp)],
|
|
169
|
-
inverseOperations: () => [structuredClone(inverseOp)]
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
function multiSetAttrsCommand(entries) {
|
|
173
|
-
if (entries.length === 0) throw new Error("multiSetAttrsCommand: entries must not be empty");
|
|
174
|
-
const forwardOps = entries.map((e) => ({
|
|
175
|
-
type: "set_attrs",
|
|
176
|
-
pageId: e.pageId,
|
|
177
|
-
elementId: e.elementId,
|
|
178
|
-
attrs: structuredClone(e.attrs)
|
|
179
|
-
}));
|
|
180
|
-
const inverseOps = entries.map((e) => ({
|
|
181
|
-
type: "set_attrs",
|
|
182
|
-
pageId: e.pageId,
|
|
183
|
-
elementId: e.elementId,
|
|
184
|
-
attrs: structuredClone(e.priorAttrs)
|
|
185
|
-
}));
|
|
186
|
-
return {
|
|
187
|
-
label: `Edit ${entries.length} elements`,
|
|
188
|
-
execute: (state) => applyOps(state, forwardOps),
|
|
189
|
-
undo: (state) => applyOps(state, inverseOps),
|
|
190
|
-
operations: () => structuredClone(forwardOps),
|
|
191
|
-
inverseOperations: () => structuredClone(inverseOps)
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
function reorderElementCommand(input) {
|
|
195
|
-
let capturedFromIndex = null;
|
|
196
|
-
const forwardOp = {
|
|
197
|
-
type: "reorder_element",
|
|
198
|
-
pageId: input.pageId,
|
|
199
|
-
elementId: input.elementId,
|
|
200
|
-
toIndex: input.toIndex
|
|
201
|
-
};
|
|
202
|
-
return {
|
|
203
|
-
label: "Reorder element",
|
|
204
|
-
execute: (state) => {
|
|
205
|
-
if (capturedFromIndex === null) {
|
|
206
|
-
const page = requirePage(state.document, input.pageId);
|
|
207
|
-
const { index } = requireElement(page, input.elementId);
|
|
208
|
-
capturedFromIndex = index;
|
|
209
|
-
}
|
|
210
|
-
return applyOp(state, forwardOp);
|
|
211
|
-
},
|
|
212
|
-
undo: (state) => {
|
|
213
|
-
if (capturedFromIndex === null) {
|
|
214
|
-
throw new Error("reorderElementCommand: undo called before execute");
|
|
215
|
-
}
|
|
216
|
-
return applyOp(state, {
|
|
217
|
-
type: "reorder_element",
|
|
218
|
-
pageId: input.pageId,
|
|
219
|
-
elementId: input.elementId,
|
|
220
|
-
toIndex: capturedFromIndex
|
|
221
|
-
});
|
|
222
|
-
},
|
|
223
|
-
operations: () => [structuredClone(forwardOp)],
|
|
224
|
-
inverseOperations: () => {
|
|
225
|
-
if (capturedFromIndex === null) {
|
|
226
|
-
throw new Error("reorderElementCommand: inverseOperations called before execute");
|
|
227
|
-
}
|
|
228
|
-
return [{
|
|
229
|
-
type: "reorder_element",
|
|
230
|
-
pageId: input.pageId,
|
|
231
|
-
elementId: input.elementId,
|
|
232
|
-
toIndex: capturedFromIndex
|
|
233
|
-
}];
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
function deleteElementCommand(input) {
|
|
238
|
-
const page = requirePage(input.document, input.pageId);
|
|
239
|
-
const { element, owner, index } = requireElement(page, input.elementId);
|
|
240
|
-
const snapshot = structuredClone(element);
|
|
241
|
-
const parentGroupId = findParentGroupId(page, owner);
|
|
242
|
-
const deleteOp = {
|
|
243
|
-
type: "delete_element",
|
|
244
|
-
pageId: input.pageId,
|
|
245
|
-
elementId: input.elementId
|
|
246
|
-
};
|
|
247
|
-
const addOp = {
|
|
248
|
-
type: "add_element",
|
|
249
|
-
pageId: input.pageId,
|
|
250
|
-
element: snapshot,
|
|
251
|
-
index,
|
|
252
|
-
...parentGroupId !== void 0 ? { parentGroupId } : {}
|
|
253
|
-
};
|
|
254
|
-
return {
|
|
255
|
-
label: `Delete ${element.kind}`,
|
|
256
|
-
execute: (state) => {
|
|
257
|
-
const next = applyOp(state, deleteOp);
|
|
258
|
-
return {
|
|
259
|
-
...next,
|
|
260
|
-
selectedElementIds: next.selectedElementIds.filter((id) => id !== input.elementId)
|
|
261
|
-
};
|
|
262
|
-
},
|
|
263
|
-
undo: (state) => applyOp(state, addOp),
|
|
264
|
-
operations: () => [structuredClone(deleteOp)],
|
|
265
|
-
inverseOperations: () => [structuredClone(addOp)]
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
function findParentGroupId(page, owner) {
|
|
269
|
-
if (owner === page.elements) return void 0;
|
|
270
|
-
return findGroupWithChildren(page.elements, owner);
|
|
271
|
-
}
|
|
272
|
-
function findGroupWithChildren(elements, target) {
|
|
273
|
-
for (const el of elements) {
|
|
274
|
-
if (el.kind === "group") {
|
|
275
|
-
if (el.children === target) return el.id;
|
|
276
|
-
const found = findGroupWithChildren(el.children, target);
|
|
277
|
-
if (found !== void 0) return found;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return void 0;
|
|
281
|
-
}
|
|
282
|
-
function groupElementsCommand(input) {
|
|
283
|
-
if (input.elementIds.length < 2) {
|
|
284
|
-
throw new Error("groupElementsCommand: requires \u2265 2 elementIds");
|
|
285
|
-
}
|
|
286
|
-
const groupOp = {
|
|
287
|
-
type: "group_elements",
|
|
288
|
-
pageId: input.pageId,
|
|
289
|
-
elementIds: input.elementIds.slice(),
|
|
290
|
-
groupId: input.groupId,
|
|
291
|
-
...input.name !== void 0 ? { name: input.name } : {}
|
|
292
|
-
};
|
|
293
|
-
const ungroupOp = {
|
|
294
|
-
type: "ungroup_element",
|
|
295
|
-
pageId: input.pageId,
|
|
296
|
-
groupId: input.groupId
|
|
297
|
-
};
|
|
298
|
-
return {
|
|
299
|
-
label: `Group ${input.elementIds.length} elements`,
|
|
300
|
-
execute: (state) => {
|
|
301
|
-
const next = applyOp(state, groupOp);
|
|
302
|
-
return {
|
|
303
|
-
...next,
|
|
304
|
-
selectedElementIds: [input.groupId]
|
|
305
|
-
};
|
|
306
|
-
},
|
|
307
|
-
undo: (state) => {
|
|
308
|
-
const next = applyOp(state, ungroupOp);
|
|
309
|
-
return { ...next, selectedElementIds: input.elementIds.slice() };
|
|
310
|
-
},
|
|
311
|
-
operations: () => [structuredClone(groupOp)],
|
|
312
|
-
inverseOperations: () => [structuredClone(ungroupOp)]
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
function ungroupElementCommand(input) {
|
|
316
|
-
const page = requirePage(input.document, input.pageId);
|
|
317
|
-
const { element } = requireElement(page, input.groupId);
|
|
318
|
-
if (element.kind !== "group") {
|
|
319
|
-
throw new Error(`ungroupElementCommand: element ${input.groupId} is kind ${element.kind}, not group`);
|
|
320
|
-
}
|
|
321
|
-
const childIds = element.children.map((c) => c.id);
|
|
322
|
-
const ungroupOp = {
|
|
323
|
-
type: "ungroup_element",
|
|
324
|
-
pageId: input.pageId,
|
|
325
|
-
groupId: input.groupId
|
|
326
|
-
};
|
|
327
|
-
const regroupOp = {
|
|
328
|
-
type: "group_elements",
|
|
329
|
-
pageId: input.pageId,
|
|
330
|
-
elementIds: childIds,
|
|
331
|
-
groupId: input.groupId,
|
|
332
|
-
name: element.name
|
|
333
|
-
};
|
|
334
|
-
return {
|
|
335
|
-
label: `Ungroup`,
|
|
336
|
-
execute: (state) => {
|
|
337
|
-
const next = applyOp(state, ungroupOp);
|
|
338
|
-
return { ...next, selectedElementIds: childIds.slice() };
|
|
339
|
-
},
|
|
340
|
-
undo: (state) => {
|
|
341
|
-
const next = applyOp(state, regroupOp);
|
|
342
|
-
return { ...next, selectedElementIds: [input.groupId] };
|
|
343
|
-
},
|
|
344
|
-
operations: () => [structuredClone(ungroupOp)],
|
|
345
|
-
inverseOperations: () => [structuredClone(regroupOp)]
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
function addPageCommand(input) {
|
|
349
|
-
const addOp = {
|
|
350
|
-
type: "add_page",
|
|
351
|
-
pageId: input.pageId,
|
|
352
|
-
...input.options !== void 0 ? { options: input.options } : {},
|
|
353
|
-
...input.index !== void 0 ? { index: input.index } : {}
|
|
354
|
-
};
|
|
355
|
-
const deleteOp = { type: "delete_page", pageId: input.pageId };
|
|
356
|
-
return {
|
|
357
|
-
label: "Add page",
|
|
358
|
-
execute: (state) => {
|
|
359
|
-
const next = applyOp(state, addOp);
|
|
360
|
-
return { ...next, activePageId: input.pageId };
|
|
361
|
-
},
|
|
362
|
-
undo: (state) => {
|
|
363
|
-
const next = applyOp(state, deleteOp);
|
|
364
|
-
const activeExists = next.document.pages.some((p) => p.id === next.activePageId);
|
|
365
|
-
return activeExists ? next : { ...next, activePageId: next.document.pages[0].id };
|
|
366
|
-
},
|
|
367
|
-
operations: () => [structuredClone(addOp)],
|
|
368
|
-
inverseOperations: () => [structuredClone(deleteOp)]
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
function duplicatePageCommand(input) {
|
|
372
|
-
requirePage(input.document, input.sourcePageId);
|
|
373
|
-
const dupOp = {
|
|
374
|
-
type: "duplicate_page",
|
|
375
|
-
sourcePageId: input.sourcePageId,
|
|
376
|
-
pageId: input.pageId
|
|
377
|
-
};
|
|
378
|
-
const deleteOp = { type: "delete_page", pageId: input.pageId };
|
|
379
|
-
return {
|
|
380
|
-
label: "Duplicate page",
|
|
381
|
-
execute: (state) => {
|
|
382
|
-
const next = applyOp(state, dupOp);
|
|
383
|
-
return { ...next, activePageId: input.pageId };
|
|
384
|
-
},
|
|
385
|
-
undo: (state) => {
|
|
386
|
-
const next = applyOp(state, deleteOp);
|
|
387
|
-
const activeExists = next.document.pages.some((p) => p.id === next.activePageId);
|
|
388
|
-
return activeExists ? next : { ...next, activePageId: input.sourcePageId };
|
|
389
|
-
},
|
|
390
|
-
operations: () => [structuredClone(dupOp)],
|
|
391
|
-
inverseOperations: () => [structuredClone(deleteOp)]
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
function deletePageCommand(input) {
|
|
395
|
-
if (input.document.pages.length <= 1) {
|
|
396
|
-
throw new Error("deletePageCommand: cannot delete the last page");
|
|
397
|
-
}
|
|
398
|
-
const page = requirePage(input.document, input.pageId);
|
|
399
|
-
const currentIndex = input.document.pages.findIndex((p) => p.id === input.pageId);
|
|
400
|
-
const snapshot = structuredClone(page);
|
|
401
|
-
const deleteOp = { type: "delete_page", pageId: input.pageId };
|
|
402
|
-
function buildRestoreOps() {
|
|
403
|
-
const ops = [
|
|
404
|
-
{
|
|
405
|
-
type: "add_page",
|
|
406
|
-
pageId: snapshot.id,
|
|
407
|
-
options: {
|
|
408
|
-
name: snapshot.name,
|
|
409
|
-
width: snapshot.width,
|
|
410
|
-
height: snapshot.height,
|
|
411
|
-
background: snapshot.background
|
|
412
|
-
},
|
|
413
|
-
index: currentIndex
|
|
414
|
-
}
|
|
415
|
-
];
|
|
416
|
-
if (snapshot.bleed) {
|
|
417
|
-
ops.push({ type: "set_page_props", pageId: snapshot.id, bleed: snapshot.bleed });
|
|
418
|
-
}
|
|
419
|
-
if (snapshot.guides.vertical.length > 0 || snapshot.guides.horizontal.length > 0) {
|
|
420
|
-
ops.push({ type: "set_page_guides", pageId: snapshot.id, guides: snapshot.guides });
|
|
421
|
-
}
|
|
422
|
-
for (let i = 0; i < snapshot.elements.length; i++) {
|
|
423
|
-
ops.push({
|
|
424
|
-
type: "add_element",
|
|
425
|
-
pageId: snapshot.id,
|
|
426
|
-
element: structuredClone(snapshot.elements[i]),
|
|
427
|
-
index: i
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
return ops;
|
|
431
|
-
}
|
|
432
|
-
return {
|
|
433
|
-
label: "Delete page",
|
|
434
|
-
execute: (state) => {
|
|
435
|
-
const next = applyOp(state, deleteOp);
|
|
436
|
-
const activeExists = next.document.pages.some((p) => p.id === next.activePageId);
|
|
437
|
-
if (activeExists) return next;
|
|
438
|
-
const fallbackIndex = Math.min(currentIndex, next.document.pages.length - 1);
|
|
439
|
-
return { ...next, activePageId: next.document.pages[fallbackIndex].id };
|
|
440
|
-
},
|
|
441
|
-
undo: (state) => {
|
|
442
|
-
const next = applyOps(state, buildRestoreOps());
|
|
443
|
-
return { ...next, activePageId: input.pageId };
|
|
444
|
-
},
|
|
445
|
-
operations: () => [structuredClone(deleteOp)],
|
|
446
|
-
inverseOperations: () => buildRestoreOps()
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
function reorderPageCommand(input) {
|
|
450
|
-
let capturedFromIndex = null;
|
|
451
|
-
const forwardOp = {
|
|
452
|
-
type: "reorder_page",
|
|
453
|
-
pageId: input.pageId,
|
|
454
|
-
toIndex: input.toIndex
|
|
455
|
-
};
|
|
456
|
-
return {
|
|
457
|
-
label: "Reorder page",
|
|
458
|
-
execute: (state) => {
|
|
459
|
-
if (capturedFromIndex === null) {
|
|
460
|
-
capturedFromIndex = state.document.pages.findIndex((p) => p.id === input.pageId);
|
|
461
|
-
if (capturedFromIndex === -1) throw new Error(`reorderPageCommand: page ${input.pageId} not found`);
|
|
462
|
-
}
|
|
463
|
-
return applyOp(state, forwardOp);
|
|
464
|
-
},
|
|
465
|
-
undo: (state) => {
|
|
466
|
-
if (capturedFromIndex === null) throw new Error("reorderPageCommand: undo called before execute");
|
|
467
|
-
return applyOp(state, {
|
|
468
|
-
type: "reorder_page",
|
|
469
|
-
pageId: input.pageId,
|
|
470
|
-
toIndex: capturedFromIndex
|
|
471
|
-
});
|
|
472
|
-
},
|
|
473
|
-
operations: () => [structuredClone(forwardOp)],
|
|
474
|
-
inverseOperations: () => {
|
|
475
|
-
if (capturedFromIndex === null) throw new Error("reorderPageCommand: inverseOperations called before execute");
|
|
476
|
-
return [{ type: "reorder_page", pageId: input.pageId, toIndex: capturedFromIndex }];
|
|
477
|
-
}
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
function setPagePropsCommand(input) {
|
|
481
|
-
const page = requirePage(input.document, input.pageId);
|
|
482
|
-
const prior = {
|
|
483
|
-
type: "set_page_props",
|
|
484
|
-
pageId: input.pageId,
|
|
485
|
-
...input.props.name !== void 0 ? { name: page.name } : {},
|
|
486
|
-
...input.props.width !== void 0 ? { width: page.width } : {},
|
|
487
|
-
...input.props.height !== void 0 ? { height: page.height } : {},
|
|
488
|
-
...input.props.background !== void 0 ? { background: page.background } : {},
|
|
489
|
-
...input.props.bleed !== void 0 ? { bleed: page.bleed } : {}
|
|
490
|
-
};
|
|
491
|
-
const forwardOp = {
|
|
492
|
-
type: "set_page_props",
|
|
493
|
-
pageId: input.pageId,
|
|
494
|
-
...input.props
|
|
495
|
-
};
|
|
496
|
-
return {
|
|
497
|
-
label: "Edit page",
|
|
498
|
-
execute: (state) => applyOp(state, forwardOp),
|
|
499
|
-
undo: (state) => applyOp(state, prior),
|
|
500
|
-
operations: () => [structuredClone(forwardOp)],
|
|
501
|
-
inverseOperations: () => [structuredClone(prior)]
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
function setPageGuidesCommand(input) {
|
|
505
|
-
const page = requirePage(input.document, input.pageId);
|
|
506
|
-
const priorGuides = structuredClone(page.guides);
|
|
507
|
-
const forwardOp = {
|
|
508
|
-
type: "set_page_guides",
|
|
509
|
-
pageId: input.pageId,
|
|
510
|
-
guides: structuredClone(input.guides)
|
|
511
|
-
};
|
|
512
|
-
const inverseOp = {
|
|
513
|
-
type: "set_page_guides",
|
|
514
|
-
pageId: input.pageId,
|
|
515
|
-
guides: priorGuides
|
|
516
|
-
};
|
|
517
|
-
return {
|
|
518
|
-
label: "Edit guides",
|
|
519
|
-
execute: (state) => applyOp(state, forwardOp),
|
|
520
|
-
undo: (state) => applyOp(state, inverseOp),
|
|
521
|
-
operations: () => [structuredClone(forwardOp)],
|
|
522
|
-
inverseOperations: () => [structuredClone(inverseOp)]
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
function bindSlotCommand(input) {
|
|
526
|
-
const page = requirePage(input.document, input.pageId);
|
|
527
|
-
const { element } = requireElement(page, input.elementId);
|
|
528
|
-
const priorSlot = element.slot ?? null;
|
|
529
|
-
const forwardOp = {
|
|
530
|
-
type: "bind_slot",
|
|
531
|
-
pageId: input.pageId,
|
|
532
|
-
elementId: input.elementId,
|
|
533
|
-
slot: input.slot
|
|
534
|
-
};
|
|
535
|
-
const inverseOp = {
|
|
536
|
-
type: "bind_slot",
|
|
537
|
-
pageId: input.pageId,
|
|
538
|
-
elementId: input.elementId,
|
|
539
|
-
slot: priorSlot
|
|
540
|
-
};
|
|
541
|
-
return {
|
|
542
|
-
label: input.slot === null ? "Unbind slot" : `Bind slot "${input.slot}"`,
|
|
543
|
-
execute: (state) => applyOp(state, forwardOp),
|
|
544
|
-
undo: (state) => applyOp(state, inverseOp),
|
|
545
|
-
operations: () => [structuredClone(forwardOp)],
|
|
546
|
-
inverseOperations: () => [structuredClone(inverseOp)]
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
function setDocumentTitleCommand(input) {
|
|
550
|
-
const priorTitle = input.document.title;
|
|
551
|
-
const forwardOp = { type: "set_document_title", title: input.title };
|
|
552
|
-
const inverseOp = { type: "set_document_title", title: priorTitle };
|
|
553
|
-
return {
|
|
554
|
-
label: `Rename document`,
|
|
555
|
-
execute: (state) => applyOp(state, forwardOp),
|
|
556
|
-
undo: (state) => applyOp(state, inverseOp),
|
|
557
|
-
operations: () => [structuredClone(forwardOp)],
|
|
558
|
-
inverseOperations: () => [structuredClone(inverseOp)]
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
|
|
562
27
|
// src/design-canvas-react/components/ruler-math.ts
|
|
563
28
|
var TICK_STEP_CANDIDATES_PX = [1, 2, 5, 10, 25, 50, 100, 250, 500, 1e3, 2500, 5e3];
|
|
564
29
|
function selectTickStep(input) {
|
|
@@ -796,7 +261,6 @@ var BoldGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M6 4h8a4 4 0 0 1 0 8H6z
|
|
|
796
261
|
var ItalicGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M11 4h6M7 20h6M14 4 8 20" }));
|
|
797
262
|
var PlusGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M12 5v14M5 12h14" }));
|
|
798
263
|
var ChevronDownGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }));
|
|
799
|
-
var ChevronRightGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m9 18 6-6-6-6" }));
|
|
800
264
|
var RectGlyph = glyph(/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }));
|
|
801
265
|
var EllipseGlyph = glyph(/* @__PURE__ */ jsx2("ellipse", { cx: "12", cy: "12", rx: "10", ry: "7" }));
|
|
802
266
|
var LineGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M5 19 19 5" }));
|
|
@@ -820,12 +284,6 @@ var SlotGlyph = glyph(
|
|
|
820
284
|
/* @__PURE__ */ jsx2("path", { d: "M12 1v4M12 19v4M4.2 4.2l2.8 2.8M17 17l2.8 2.8M1 12h4M19 12h4M4.2 19.8l2.8-2.8M17 7 19.8 4.2" })
|
|
821
285
|
] })
|
|
822
286
|
);
|
|
823
|
-
var FitGlyph = glyph(
|
|
824
|
-
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
825
|
-
/* @__PURE__ */ jsx2("path", { d: "M3 3h4v4H3zM17 3h4v4h-4zM3 17h4v4H3zM17 17h4v4h-4z" }),
|
|
826
|
-
/* @__PURE__ */ jsx2("path", { d: "M7 5h10M5 7v10M19 7v10M7 19h10" })
|
|
827
|
-
] })
|
|
828
|
-
);
|
|
829
287
|
var PageGlyph = glyph(
|
|
830
288
|
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
831
289
|
/* @__PURE__ */ jsx2("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
@@ -874,11 +332,24 @@ var ShapesGlyph = glyph(
|
|
|
874
332
|
] })
|
|
875
333
|
);
|
|
876
334
|
|
|
335
|
+
// src/design-canvas-react/components/icon-button.tsx
|
|
336
|
+
import { forwardRef } from "react";
|
|
337
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
338
|
+
var BTN_BASE = "items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-1 focus-visible:ring-offset-[var(--bg-input)] disabled:cursor-default disabled:opacity-40";
|
|
339
|
+
var BTN_ACTIVE_EXTRA = " border-[var(--brand-primary)] text-[var(--brand-primary)] hover:text-[var(--brand-primary)]";
|
|
340
|
+
var BTN = `flex h-7 w-7 ${BTN_BASE}`;
|
|
341
|
+
var BTN_ACTIVE = BTN + BTN_ACTIVE_EXTRA;
|
|
342
|
+
var BTN_SM = `flex h-6 w-6 ${BTN_BASE}`;
|
|
343
|
+
var BTN_SM_ACTIVE = BTN_SM + BTN_ACTIVE_EXTRA;
|
|
344
|
+
var IconButton = forwardRef(function IconButton2({ active = false, size = "md", className = "", type = "button", ...rest }, ref) {
|
|
345
|
+
const base = size === "sm" ? active ? BTN_SM_ACTIVE : BTN_SM : active ? BTN_ACTIVE : BTN;
|
|
346
|
+
return /* @__PURE__ */ jsx3("button", { ref, type, className: className ? `${base} ${className}` : base, ...rest });
|
|
347
|
+
});
|
|
348
|
+
|
|
877
349
|
// src/design-canvas-react/components/PagesStrip.tsx
|
|
878
|
-
import { jsx as
|
|
350
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
879
351
|
var THUMBNAIL_W = 80;
|
|
880
352
|
var THUMBNAIL_H = 56;
|
|
881
|
-
var BTN = "flex h-6 w-6 items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] disabled:cursor-default disabled:opacity-40";
|
|
882
353
|
function PagesStrip({
|
|
883
354
|
pages,
|
|
884
355
|
activePageId,
|
|
@@ -929,10 +400,6 @@ function PagesStrip({
|
|
|
929
400
|
return /* @__PURE__ */ jsxs3(
|
|
930
401
|
"div",
|
|
931
402
|
{
|
|
932
|
-
role: "button",
|
|
933
|
-
tabIndex: 0,
|
|
934
|
-
"aria-label": `Page ${index + 1}: ${page.name}${isActive ? " (active)" : ""}`,
|
|
935
|
-
"aria-pressed": isActive,
|
|
936
403
|
draggable: canWrite,
|
|
937
404
|
onDragStart: () => {
|
|
938
405
|
dragIndexRef.current = index;
|
|
@@ -955,38 +422,43 @@ function PagesStrip({
|
|
|
955
422
|
dragIndexRef.current = null;
|
|
956
423
|
setDragOverIndex(null);
|
|
957
424
|
},
|
|
958
|
-
onClick: () => onSelectPage(page.id),
|
|
959
|
-
onKeyDown: (event) => {
|
|
960
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
961
|
-
event.preventDefault();
|
|
962
|
-
onSelectPage(page.id);
|
|
963
|
-
}
|
|
964
|
-
},
|
|
965
425
|
className: [
|
|
966
|
-
"group relative flex shrink-0
|
|
426
|
+
"group relative flex shrink-0 flex-col items-center gap-1 rounded p-1 transition",
|
|
967
427
|
isActive ? "ring-2 ring-[var(--brand-primary)]" : "hover:bg-[var(--border-default)]/40",
|
|
968
428
|
dragOverIndex === index ? "ring-1 ring-[var(--brand-primary)]/60" : ""
|
|
969
429
|
].join(" "),
|
|
970
430
|
children: [
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
"
|
|
431
|
+
/* @__PURE__ */ jsxs3(
|
|
432
|
+
"button",
|
|
973
433
|
{
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
434
|
+
type: "button",
|
|
435
|
+
"aria-label": `Page ${index + 1}: ${page.name}${isActive ? " (active)" : ""}`,
|
|
436
|
+
"aria-pressed": isActive,
|
|
437
|
+
onClick: () => onSelectPage(page.id),
|
|
438
|
+
className: "flex cursor-pointer flex-col items-center gap-1 rounded focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
|
|
439
|
+
children: [
|
|
440
|
+
/* @__PURE__ */ jsx4(
|
|
441
|
+
"div",
|
|
442
|
+
{
|
|
443
|
+
className: "overflow-hidden rounded border border-[var(--border-default)] bg-[hsl(var(--card))]",
|
|
444
|
+
style: { width: THUMBNAIL_W, height: THUMBNAIL_H },
|
|
445
|
+
children: thumbUrl ? /* @__PURE__ */ jsx4(
|
|
446
|
+
"img",
|
|
447
|
+
{
|
|
448
|
+
src: thumbUrl,
|
|
449
|
+
alt: page.name,
|
|
450
|
+
className: "h-full w-full object-cover",
|
|
451
|
+
draggable: false
|
|
452
|
+
}
|
|
453
|
+
) : /* @__PURE__ */ jsx4("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx4(PageGlyph, { className: "h-5 w-5 text-[var(--text-muted)]" }) })
|
|
454
|
+
}
|
|
455
|
+
),
|
|
456
|
+
/* @__PURE__ */ jsx4("span", { className: "max-w-[80px] truncate text-[10px] text-[var(--text-secondary)]", children: page.name })
|
|
457
|
+
]
|
|
985
458
|
}
|
|
986
459
|
),
|
|
987
|
-
/* @__PURE__ */ jsx3("span", { className: "max-w-[80px] truncate text-[10px] text-[var(--text-secondary)]", children: page.name }),
|
|
988
460
|
canWrite && canManagePages ? /* @__PURE__ */ jsxs3("div", { className: "pointer-events-none absolute -top-1 right-0 flex gap-0.5 opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100", children: [
|
|
989
|
-
/* @__PURE__ */
|
|
461
|
+
/* @__PURE__ */ jsx4(
|
|
990
462
|
"button",
|
|
991
463
|
{
|
|
992
464
|
type: "button",
|
|
@@ -995,11 +467,11 @@ function PagesStrip({
|
|
|
995
467
|
event.stopPropagation();
|
|
996
468
|
onDuplicatePage(page.id);
|
|
997
469
|
},
|
|
998
|
-
className:
|
|
999
|
-
children: /* @__PURE__ */
|
|
470
|
+
className: BTN_SM,
|
|
471
|
+
children: /* @__PURE__ */ jsx4(DuplicateGlyph, { className: "h-3 w-3" })
|
|
1000
472
|
}
|
|
1001
473
|
),
|
|
1002
|
-
/* @__PURE__ */
|
|
474
|
+
/* @__PURE__ */ jsx4(
|
|
1003
475
|
"button",
|
|
1004
476
|
{
|
|
1005
477
|
type: "button",
|
|
@@ -1009,8 +481,8 @@ function PagesStrip({
|
|
|
1009
481
|
event.stopPropagation();
|
|
1010
482
|
if (pages.length > 1) onDeletePage(page.id);
|
|
1011
483
|
},
|
|
1012
|
-
className:
|
|
1013
|
-
children: /* @__PURE__ */
|
|
484
|
+
className: BTN_SM,
|
|
485
|
+
children: /* @__PURE__ */ jsx4(TrashGlyph, { className: "h-3 w-3 text-[var(--text-danger)]" })
|
|
1014
486
|
}
|
|
1015
487
|
)
|
|
1016
488
|
] }) : null
|
|
@@ -1025,10 +497,10 @@ function PagesStrip({
|
|
|
1025
497
|
type: "button",
|
|
1026
498
|
"aria-label": "Add page",
|
|
1027
499
|
onClick: onAddPage,
|
|
1028
|
-
className: "flex h-[72px] w-[80px] shrink-0 flex-col items-center justify-center gap-1 rounded border border-dashed border-[var(--border-default)] text-[var(--text-muted)] transition hover:border-[var(--brand-primary)] hover:text-[var(--brand-primary)]",
|
|
500
|
+
className: "flex h-[72px] w-[80px] shrink-0 flex-col items-center justify-center gap-1 rounded border border-dashed border-[var(--border-default)] text-[var(--text-muted)] transition hover:border-[var(--brand-primary)] hover:text-[var(--brand-primary)] focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
|
|
1029
501
|
children: [
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
502
|
+
/* @__PURE__ */ jsx4(PlusGlyph, { className: "h-4 w-4" }),
|
|
503
|
+
/* @__PURE__ */ jsx4("span", { className: "text-[10px]", children: "Add page" })
|
|
1032
504
|
]
|
|
1033
505
|
}
|
|
1034
506
|
) : null
|
|
@@ -1039,20 +511,20 @@ function PagesStrip({
|
|
|
1039
511
|
|
|
1040
512
|
// src/design-canvas-react/components/Rulers.tsx
|
|
1041
513
|
import { useRef as useRef2, useState as useState2 } from "react";
|
|
1042
|
-
import { Fragment as Fragment3, jsx as
|
|
514
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1043
515
|
var RULER_SIZE_PX = 20;
|
|
1044
516
|
var DELETE_THRESHOLD_PX = RULER_SIZE_PX + 4;
|
|
1045
517
|
function Rulers({ pageWidth, pageHeight, zoom, scrollLeft, scrollTop, showRulers, guides, onGuidesChange }) {
|
|
1046
518
|
if (!showRulers) return null;
|
|
1047
519
|
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1048
|
-
/* @__PURE__ */
|
|
520
|
+
/* @__PURE__ */ jsx5(
|
|
1049
521
|
"div",
|
|
1050
522
|
{
|
|
1051
523
|
className: "absolute top-0 left-0 z-20 shrink-0 border-b border-r border-[var(--border-default)] bg-[var(--bg-input)]",
|
|
1052
524
|
style: { width: RULER_SIZE_PX, height: RULER_SIZE_PX }
|
|
1053
525
|
}
|
|
1054
526
|
),
|
|
1055
|
-
/* @__PURE__ */
|
|
527
|
+
/* @__PURE__ */ jsx5(
|
|
1056
528
|
HorizontalRuler,
|
|
1057
529
|
{
|
|
1058
530
|
pageWidth,
|
|
@@ -1062,7 +534,7 @@ function Rulers({ pageWidth, pageHeight, zoom, scrollLeft, scrollTop, showRulers
|
|
|
1062
534
|
onGuidesChange
|
|
1063
535
|
}
|
|
1064
536
|
),
|
|
1065
|
-
/* @__PURE__ */
|
|
537
|
+
/* @__PURE__ */ jsx5(
|
|
1066
538
|
VerticalRuler,
|
|
1067
539
|
{
|
|
1068
540
|
pageHeight,
|
|
@@ -1150,18 +622,18 @@ function HorizontalRuler({ pageWidth, zoom, scrollLeft, guides, onGuidesChange }
|
|
|
1150
622
|
children: [
|
|
1151
623
|
ticks.map((tick) => {
|
|
1152
624
|
const screenX = tick.position * zoom - scrollLeft * zoom;
|
|
1153
|
-
return /* @__PURE__ */
|
|
625
|
+
return /* @__PURE__ */ jsx5(
|
|
1154
626
|
"div",
|
|
1155
627
|
{
|
|
1156
628
|
className: `absolute bottom-0 w-px bg-[var(--border-default)] ${tick.label !== null ? "top-1.5" : "top-[14px]"}`,
|
|
1157
629
|
style: { left: screenX },
|
|
1158
|
-
children: tick.label !== null ? /* @__PURE__ */
|
|
630
|
+
children: tick.label !== null ? /* @__PURE__ */ jsx5("span", { className: "absolute -top-1 left-0.5 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]", children: tick.label }) : null
|
|
1159
631
|
},
|
|
1160
632
|
tick.position
|
|
1161
633
|
);
|
|
1162
634
|
}),
|
|
1163
|
-
pointerX !== null ? /* @__PURE__ */
|
|
1164
|
-
dragGuideX !== null ? /* @__PURE__ */
|
|
635
|
+
pointerX !== null ? /* @__PURE__ */ jsx5("div", { className: "pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]/60", style: { left: pointerX } }) : null,
|
|
636
|
+
dragGuideX !== null ? /* @__PURE__ */ jsx5(
|
|
1165
637
|
"div",
|
|
1166
638
|
{
|
|
1167
639
|
className: "pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]",
|
|
@@ -1244,12 +716,12 @@ function VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange })
|
|
|
1244
716
|
children: [
|
|
1245
717
|
ticks.map((tick) => {
|
|
1246
718
|
const screenY = tick.position * zoom - scrollTop * zoom;
|
|
1247
|
-
return /* @__PURE__ */
|
|
719
|
+
return /* @__PURE__ */ jsx5(
|
|
1248
720
|
"div",
|
|
1249
721
|
{
|
|
1250
722
|
className: `absolute right-0 h-px bg-[var(--border-default)] ${tick.label !== null ? "left-1.5" : "left-[14px]"}`,
|
|
1251
723
|
style: { top: screenY },
|
|
1252
|
-
children: tick.label !== null ? /* @__PURE__ */
|
|
724
|
+
children: tick.label !== null ? /* @__PURE__ */ jsx5(
|
|
1253
725
|
"span",
|
|
1254
726
|
{
|
|
1255
727
|
className: "absolute top-0.5 left-0 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]",
|
|
@@ -1261,8 +733,8 @@ function VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange })
|
|
|
1261
733
|
tick.position
|
|
1262
734
|
);
|
|
1263
735
|
}),
|
|
1264
|
-
pointerY !== null ? /* @__PURE__ */
|
|
1265
|
-
dragGuideY !== null ? /* @__PURE__ */
|
|
736
|
+
pointerY !== null ? /* @__PURE__ */ jsx5("div", { className: "pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]/60", style: { top: pointerY } }) : null,
|
|
737
|
+
dragGuideY !== null ? /* @__PURE__ */ jsx5(
|
|
1266
738
|
"div",
|
|
1267
739
|
{
|
|
1268
740
|
className: "pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]",
|
|
@@ -1276,7 +748,7 @@ function VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange })
|
|
|
1276
748
|
|
|
1277
749
|
// src/design-canvas-react/components/Toolbar.tsx
|
|
1278
750
|
import { useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
|
|
1279
|
-
import { Fragment as Fragment4, jsx as
|
|
751
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1280
752
|
var FONT_FAMILIES = [
|
|
1281
753
|
"Inter",
|
|
1282
754
|
"Arial",
|
|
@@ -1291,9 +763,7 @@ var FONT_FAMILIES = [
|
|
|
1291
763
|
"Brush Script MT",
|
|
1292
764
|
"Impact"
|
|
1293
765
|
];
|
|
1294
|
-
var
|
|
1295
|
-
var BTN_ACTIVE = `${BTN2} border-[var(--brand-primary)] text-[var(--brand-primary)] hover:text-[var(--brand-primary)]`;
|
|
1296
|
-
var SEP = /* @__PURE__ */ jsx5("div", { className: "mx-1 h-5 w-px shrink-0 bg-[var(--border-default)]" });
|
|
766
|
+
var SEP = /* @__PURE__ */ jsx6("div", { className: "mx-1 h-5 w-px shrink-0 bg-[var(--border-default)]" });
|
|
1297
767
|
var POPOVER_PANEL = "absolute top-full left-0 z-50 mt-1 flex flex-col rounded border border-[var(--border-default)] bg-[var(--bg-input)] shadow-lg";
|
|
1298
768
|
function Popover({
|
|
1299
769
|
open,
|
|
@@ -1338,8 +808,8 @@ function NumberInput({
|
|
|
1338
808
|
setRaw(null);
|
|
1339
809
|
}
|
|
1340
810
|
return /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
|
|
1341
|
-
/* @__PURE__ */
|
|
1342
|
-
/* @__PURE__ */
|
|
811
|
+
/* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: label }),
|
|
812
|
+
/* @__PURE__ */ jsx6(
|
|
1343
813
|
"input",
|
|
1344
814
|
{
|
|
1345
815
|
type: "number",
|
|
@@ -1368,8 +838,8 @@ function SelectControl({
|
|
|
1368
838
|
const [open, setOpen] = useState3(false);
|
|
1369
839
|
const current = options.find((o) => o.value === value);
|
|
1370
840
|
return /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
|
|
1371
|
-
/* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
841
|
+
/* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: label }),
|
|
842
|
+
/* @__PURE__ */ jsx6(
|
|
1373
843
|
Popover,
|
|
1374
844
|
{
|
|
1375
845
|
open,
|
|
@@ -1384,12 +854,12 @@ function SelectControl({
|
|
|
1384
854
|
onClick: () => setOpen((v) => !v),
|
|
1385
855
|
className: `${buttonClassName} flex items-center justify-between gap-1 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-2 py-0.5 text-left text-[12px] text-[var(--text-primary)] outline-none hover:border-[var(--brand-primary)] disabled:cursor-default disabled:opacity-40`,
|
|
1386
856
|
children: [
|
|
1387
|
-
/* @__PURE__ */
|
|
1388
|
-
/* @__PURE__ */
|
|
857
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children: current?.label ?? value }),
|
|
858
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[8px] text-[var(--text-muted)]", children: "\u25BE" })
|
|
1389
859
|
]
|
|
1390
860
|
}
|
|
1391
861
|
),
|
|
1392
|
-
children: /* @__PURE__ */
|
|
862
|
+
children: /* @__PURE__ */ jsx6("div", { role: "listbox", className: `${POPOVER_PANEL} max-h-64 w-44 overflow-y-auto py-1`, children: options.map((opt) => /* @__PURE__ */ jsx6(
|
|
1393
863
|
"button",
|
|
1394
864
|
{
|
|
1395
865
|
type: "button",
|
|
@@ -1418,8 +888,8 @@ function FontPicker({
|
|
|
1418
888
|
const families = FONT_FAMILIES.includes(value) ? [...FONT_FAMILIES] : [value, ...FONT_FAMILIES];
|
|
1419
889
|
const filtered = families.filter((f) => f.toLowerCase().includes(query.trim().toLowerCase()));
|
|
1420
890
|
return /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
|
|
1421
|
-
/* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
891
|
+
/* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: "Font" }),
|
|
892
|
+
/* @__PURE__ */ jsx6(
|
|
1423
893
|
Popover,
|
|
1424
894
|
{
|
|
1425
895
|
open,
|
|
@@ -1439,13 +909,13 @@ function FontPicker({
|
|
|
1439
909
|
className: "flex w-28 items-center justify-between gap-1 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-2 py-0.5 text-left text-[12px] text-[var(--text-primary)] outline-none hover:border-[var(--brand-primary)] disabled:cursor-default disabled:opacity-40",
|
|
1440
910
|
style: { fontFamily: value },
|
|
1441
911
|
children: [
|
|
1442
|
-
/* @__PURE__ */
|
|
1443
|
-
/* @__PURE__ */
|
|
912
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children: value }),
|
|
913
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[8px] text-[var(--text-muted)]", children: "\u25BE" })
|
|
1444
914
|
]
|
|
1445
915
|
}
|
|
1446
916
|
),
|
|
1447
917
|
children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-52`, children: [
|
|
1448
|
-
/* @__PURE__ */
|
|
918
|
+
/* @__PURE__ */ jsx6(
|
|
1449
919
|
"input",
|
|
1450
920
|
{
|
|
1451
921
|
autoFocus: true,
|
|
@@ -1456,7 +926,7 @@ function FontPicker({
|
|
|
1456
926
|
className: "m-1 rounded border border-[var(--border-default)] bg-transparent px-2 py-1 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]"
|
|
1457
927
|
}
|
|
1458
928
|
),
|
|
1459
|
-
/* @__PURE__ */
|
|
929
|
+
/* @__PURE__ */ jsx6("div", { role: "listbox", className: "max-h-60 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx6("div", { className: "px-3 py-2 text-[11px] text-[var(--text-muted)]", children: "No matches" }) : filtered.map((family) => /* @__PURE__ */ jsx6(
|
|
1460
930
|
"button",
|
|
1461
931
|
{
|
|
1462
932
|
type: "button",
|
|
@@ -1482,13 +952,13 @@ function ColorSwatch({ label, value, onCommit, disabled }) {
|
|
|
1482
952
|
const [open, setOpen] = useState3(false);
|
|
1483
953
|
const normalized = value.startsWith("#") ? value : "#ffffff";
|
|
1484
954
|
return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
1485
|
-
/* @__PURE__ */
|
|
1486
|
-
/* @__PURE__ */
|
|
955
|
+
/* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: label }),
|
|
956
|
+
/* @__PURE__ */ jsx6(
|
|
1487
957
|
Popover,
|
|
1488
958
|
{
|
|
1489
959
|
open,
|
|
1490
960
|
onClose: () => setOpen(false),
|
|
1491
|
-
trigger: /* @__PURE__ */
|
|
961
|
+
trigger: /* @__PURE__ */ jsx6(
|
|
1492
962
|
"button",
|
|
1493
963
|
{
|
|
1494
964
|
type: "button",
|
|
@@ -1500,7 +970,7 @@ function ColorSwatch({ label, value, onCommit, disabled }) {
|
|
|
1500
970
|
}
|
|
1501
971
|
),
|
|
1502
972
|
children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-40 gap-2 p-2`, children: [
|
|
1503
|
-
/* @__PURE__ */
|
|
973
|
+
/* @__PURE__ */ jsx6(
|
|
1504
974
|
"input",
|
|
1505
975
|
{
|
|
1506
976
|
type: "color",
|
|
@@ -1510,7 +980,7 @@ function ColorSwatch({ label, value, onCommit, disabled }) {
|
|
|
1510
980
|
className: "h-8 w-full cursor-pointer rounded border border-[var(--border-default)] p-0.5"
|
|
1511
981
|
}
|
|
1512
982
|
),
|
|
1513
|
-
/* @__PURE__ */
|
|
983
|
+
/* @__PURE__ */ jsx6(
|
|
1514
984
|
"input",
|
|
1515
985
|
{
|
|
1516
986
|
type: "text",
|
|
@@ -1568,19 +1038,19 @@ function Toolbar({
|
|
|
1568
1038
|
const review = mode === "review";
|
|
1569
1039
|
return /* @__PURE__ */ jsxs5("div", { className: "flex min-h-11 shrink-0 flex-wrap items-center gap-x-2 gap-y-1 border-b border-[var(--border-default)] bg-[var(--bg-input)] px-3 py-1", children: [
|
|
1570
1040
|
/* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1571
|
-
/* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1041
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Undo", disabled: !canUndo || !canWrite, onClick: onUndo, className: BTN, children: /* @__PURE__ */ jsx6(UndoGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1042
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Redo", disabled: !canRedo || !canWrite, onClick: onRedo, className: BTN, children: /* @__PURE__ */ jsx6(RedoGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1573
1043
|
!review ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1574
1044
|
SEP,
|
|
1575
|
-
/* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
1577
|
-
/* @__PURE__ */
|
|
1578
|
-
/* @__PURE__ */
|
|
1045
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle rulers", "aria-pressed": showRulers, onClick: onToggleRulers, className: showRulers ? BTN_ACTIVE : BTN, children: /* @__PURE__ */ jsx6(RulerGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1046
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle grid", "aria-pressed": gridEnabled, onClick: onToggleGrid, className: gridEnabled ? BTN_ACTIVE : BTN, children: /* @__PURE__ */ jsx6(GridGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1047
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle snap", "aria-pressed": snapEnabled, onClick: onToggleSnap, className: snapEnabled ? BTN_ACTIVE : BTN, children: /* @__PURE__ */ jsx6(MagnetGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1048
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle bleed overlay", "aria-pressed": showBleed, onClick: onToggleBleed, className: showBleed ? BTN_ACTIVE : BTN, disabled: !page.bleed, children: /* @__PURE__ */ jsx6(BleedGlyph, { className: "h-3.5 w-3.5" }) })
|
|
1579
1049
|
] }) : null
|
|
1580
1050
|
] }),
|
|
1581
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: hasSelection ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1582
1052
|
SEP,
|
|
1583
|
-
/* @__PURE__ */
|
|
1053
|
+
/* @__PURE__ */ jsx6(
|
|
1584
1054
|
SelectionControls,
|
|
1585
1055
|
{
|
|
1586
1056
|
elements: selectedElements,
|
|
@@ -1604,7 +1074,7 @@ function Toolbar({
|
|
|
1604
1074
|
)
|
|
1605
1075
|
] }) : !review ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1606
1076
|
SEP,
|
|
1607
|
-
/* @__PURE__ */
|
|
1077
|
+
/* @__PURE__ */ jsx6(
|
|
1608
1078
|
PagePropsControls,
|
|
1609
1079
|
{
|
|
1610
1080
|
page,
|
|
@@ -1637,12 +1107,12 @@ function SelectionControls({
|
|
|
1637
1107
|
const [slotInput, setSlotInput] = useState3("");
|
|
1638
1108
|
const firstEl = elements[0];
|
|
1639
1109
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1640
|
-
allSameKind && firstKind === "text" && single ? /* @__PURE__ */
|
|
1641
|
-
allSameKind && firstKind === "rect" && single ? /* @__PURE__ */
|
|
1642
|
-
allSameKind && firstKind === "ellipse" && single ? /* @__PURE__ */
|
|
1643
|
-
allSameKind && firstKind === "image" && single ? /* @__PURE__ */
|
|
1110
|
+
allSameKind && firstKind === "text" && single ? /* @__PURE__ */ jsx6(TextControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs) }) : null,
|
|
1111
|
+
allSameKind && firstKind === "rect" && single ? /* @__PURE__ */ jsx6(ShapeControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs), showCornerRadius: true }) : null,
|
|
1112
|
+
allSameKind && firstKind === "ellipse" && single ? /* @__PURE__ */ jsx6(ShapeControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs), showCornerRadius: false }) : null,
|
|
1113
|
+
allSameKind && firstKind === "image" && single ? /* @__PURE__ */ jsx6(ImageControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs) }) : null,
|
|
1644
1114
|
SEP,
|
|
1645
|
-
/* @__PURE__ */
|
|
1115
|
+
/* @__PURE__ */ jsx6(
|
|
1646
1116
|
NumberInput,
|
|
1647
1117
|
{
|
|
1648
1118
|
label: "Opacity",
|
|
@@ -1652,7 +1122,7 @@ function SelectionControls({
|
|
|
1652
1122
|
className: "w-14"
|
|
1653
1123
|
}
|
|
1654
1124
|
),
|
|
1655
|
-
/* @__PURE__ */
|
|
1125
|
+
/* @__PURE__ */ jsx6(
|
|
1656
1126
|
NumberInput,
|
|
1657
1127
|
{
|
|
1658
1128
|
label: "Rotation",
|
|
@@ -1664,44 +1134,48 @@ function SelectionControls({
|
|
|
1664
1134
|
review ? null : /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1665
1135
|
SEP,
|
|
1666
1136
|
single ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1667
|
-
/* @__PURE__ */
|
|
1668
|
-
/* @__PURE__ */
|
|
1137
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Bring to front", disabled: !canWrite, onClick: () => reorderSingle("front"), className: BTN, children: /* @__PURE__ */ jsx6(BringFrontGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1138
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Send to back", disabled: !canWrite, onClick: () => reorderSingle("back"), className: BTN, children: /* @__PURE__ */ jsx6(SendBackGlyph, { className: "h-3.5 w-3.5" }) }),
|
|
1669
1139
|
SEP
|
|
1670
1140
|
] }) : null,
|
|
1671
|
-
groupable ? /* @__PURE__ */
|
|
1672
|
-
isGroup ? /* @__PURE__ */
|
|
1673
|
-
single ? /* @__PURE__ */
|
|
1141
|
+
groupable ? /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Group elements", disabled: !canWrite, onClick: onGroup, className: BTN, children: /* @__PURE__ */ jsx6(GroupGlyph, { className: "h-3.5 w-3.5" }) }) : null,
|
|
1142
|
+
isGroup ? /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Ungroup", disabled: !canWrite, onClick: onUngroup, className: BTN, children: /* @__PURE__ */ jsx6(UngroupGlyph, { className: "h-3.5 w-3.5" }) }) : null,
|
|
1143
|
+
single ? /* @__PURE__ */ jsx6(
|
|
1674
1144
|
"button",
|
|
1675
1145
|
{
|
|
1676
1146
|
type: "button",
|
|
1677
1147
|
"aria-label": single.locked ? "Unlock element" : "Lock element",
|
|
1148
|
+
"aria-pressed": !!single.locked,
|
|
1678
1149
|
disabled: !canWrite,
|
|
1679
1150
|
onClick: () => patchAll({ locked: !single.locked }),
|
|
1680
|
-
className: single.locked ? BTN_ACTIVE :
|
|
1681
|
-
children: single.locked ? /* @__PURE__ */
|
|
1151
|
+
className: single.locked ? BTN_ACTIVE : BTN,
|
|
1152
|
+
children: single.locked ? /* @__PURE__ */ jsx6(LockGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx6(UnlockGlyph, { className: "h-3.5 w-3.5" })
|
|
1682
1153
|
}
|
|
1683
1154
|
) : null,
|
|
1684
|
-
single && onBindSlot ? /* @__PURE__ */
|
|
1155
|
+
single && onBindSlot ? /* @__PURE__ */ jsx6(
|
|
1685
1156
|
Popover,
|
|
1686
1157
|
{
|
|
1687
1158
|
open: slotPopoverOpen,
|
|
1688
1159
|
onClose: () => setSlotPopoverOpen(false),
|
|
1689
|
-
trigger: /* @__PURE__ */
|
|
1160
|
+
trigger: /* @__PURE__ */ jsx6(
|
|
1690
1161
|
"button",
|
|
1691
1162
|
{
|
|
1692
1163
|
type: "button",
|
|
1693
1164
|
"aria-label": currentSlot ? `Slot: ${currentSlot}` : "Bind slot",
|
|
1165
|
+
"aria-pressed": !!currentSlot,
|
|
1166
|
+
"aria-haspopup": "dialog",
|
|
1167
|
+
"aria-expanded": slotPopoverOpen,
|
|
1694
1168
|
onClick: () => {
|
|
1695
1169
|
setSlotInput(currentSlot ?? "");
|
|
1696
1170
|
setSlotPopoverOpen((v) => !v);
|
|
1697
1171
|
},
|
|
1698
|
-
className: currentSlot ? BTN_ACTIVE :
|
|
1172
|
+
className: currentSlot ? BTN_ACTIVE : BTN,
|
|
1699
1173
|
title: currentSlot ? `Slot: ${currentSlot}` : "Bind slot",
|
|
1700
|
-
children: /* @__PURE__ */
|
|
1174
|
+
children: /* @__PURE__ */ jsx6(SlotGlyph, { className: "h-3.5 w-3.5" })
|
|
1701
1175
|
}
|
|
1702
1176
|
),
|
|
1703
1177
|
children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-48 gap-2 p-2`, children: [
|
|
1704
|
-
/* @__PURE__ */
|
|
1178
|
+
/* @__PURE__ */ jsx6(
|
|
1705
1179
|
"input",
|
|
1706
1180
|
{
|
|
1707
1181
|
autoFocus: true,
|
|
@@ -1712,7 +1186,7 @@ function SelectionControls({
|
|
|
1712
1186
|
}
|
|
1713
1187
|
),
|
|
1714
1188
|
/* @__PURE__ */ jsxs5("div", { className: "flex gap-2", children: [
|
|
1715
|
-
/* @__PURE__ */
|
|
1189
|
+
/* @__PURE__ */ jsx6(
|
|
1716
1190
|
"button",
|
|
1717
1191
|
{
|
|
1718
1192
|
type: "button",
|
|
@@ -1724,7 +1198,7 @@ function SelectionControls({
|
|
|
1724
1198
|
children: slotInput.trim() ? "Bind" : "Unbind"
|
|
1725
1199
|
}
|
|
1726
1200
|
),
|
|
1727
|
-
/* @__PURE__ */
|
|
1201
|
+
/* @__PURE__ */ jsx6(
|
|
1728
1202
|
"button",
|
|
1729
1203
|
{
|
|
1730
1204
|
type: "button",
|
|
@@ -1738,66 +1212,70 @@ function SelectionControls({
|
|
|
1738
1212
|
}
|
|
1739
1213
|
) : null,
|
|
1740
1214
|
SEP,
|
|
1741
|
-
/* @__PURE__ */
|
|
1215
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Delete selection", disabled: !canWrite, onClick: onDelete, className: BTN, children: /* @__PURE__ */ jsx6(TrashGlyph, { className: "h-3.5 w-3.5 text-[var(--text-danger)]" }) })
|
|
1742
1216
|
] })
|
|
1743
1217
|
] });
|
|
1744
1218
|
}
|
|
1745
1219
|
function TextControls({ element, canWrite, onPatch }) {
|
|
1746
1220
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1747
|
-
/* @__PURE__ */
|
|
1748
|
-
/* @__PURE__ */
|
|
1749
|
-
/* @__PURE__ */
|
|
1221
|
+
/* @__PURE__ */ jsx6(FontPicker, { value: element.fontFamily, disabled: !canWrite, onChange: (fontFamily) => onPatch({ fontFamily }) }),
|
|
1222
|
+
/* @__PURE__ */ jsx6(NumberInput, { label: "Size", value: element.fontSize, min: 1, onCommit: (v) => onPatch({ fontSize: v }), className: "w-12" }),
|
|
1223
|
+
/* @__PURE__ */ jsx6(
|
|
1750
1224
|
"button",
|
|
1751
1225
|
{
|
|
1752
1226
|
type: "button",
|
|
1753
1227
|
"aria-label": "Bold",
|
|
1228
|
+
"aria-pressed": !!element.fontStyle?.includes("bold"),
|
|
1754
1229
|
disabled: !canWrite,
|
|
1755
1230
|
onClick: () => onPatch({ fontStyle: element.fontStyle === "bold" || element.fontStyle === "bold italic" ? element.fontStyle === "bold italic" ? "italic" : "normal" : element.fontStyle === "italic" ? "bold italic" : "bold" }),
|
|
1756
|
-
className: element.fontStyle?.includes("bold") ? BTN_ACTIVE :
|
|
1757
|
-
children: /* @__PURE__ */
|
|
1231
|
+
className: element.fontStyle?.includes("bold") ? BTN_ACTIVE : BTN,
|
|
1232
|
+
children: /* @__PURE__ */ jsx6(BoldGlyph, { className: "h-3.5 w-3.5" })
|
|
1758
1233
|
}
|
|
1759
1234
|
),
|
|
1760
|
-
/* @__PURE__ */
|
|
1235
|
+
/* @__PURE__ */ jsx6(
|
|
1761
1236
|
"button",
|
|
1762
1237
|
{
|
|
1763
1238
|
type: "button",
|
|
1764
1239
|
"aria-label": "Italic",
|
|
1240
|
+
"aria-pressed": !!element.fontStyle?.includes("italic"),
|
|
1765
1241
|
disabled: !canWrite,
|
|
1766
1242
|
onClick: () => onPatch({ fontStyle: element.fontStyle === "italic" || element.fontStyle === "bold italic" ? element.fontStyle === "bold italic" ? "bold" : "normal" : element.fontStyle === "bold" ? "bold italic" : "italic" }),
|
|
1767
|
-
className: element.fontStyle?.includes("italic") ? BTN_ACTIVE :
|
|
1768
|
-
children: /* @__PURE__ */
|
|
1243
|
+
className: element.fontStyle?.includes("italic") ? BTN_ACTIVE : BTN,
|
|
1244
|
+
children: /* @__PURE__ */ jsx6(ItalicGlyph, { className: "h-3.5 w-3.5" })
|
|
1769
1245
|
}
|
|
1770
1246
|
),
|
|
1771
|
-
["left", "center", "right"].map((align) => /* @__PURE__ */
|
|
1247
|
+
/* @__PURE__ */ jsx6("div", { role: "radiogroup", "aria-label": "Text alignment", className: "flex items-center gap-2", children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsx6(
|
|
1772
1248
|
"button",
|
|
1773
1249
|
{
|
|
1774
1250
|
type: "button",
|
|
1251
|
+
role: "radio",
|
|
1775
1252
|
"aria-label": `Align ${align}`,
|
|
1253
|
+
"aria-checked": element.align === align,
|
|
1776
1254
|
disabled: !canWrite,
|
|
1777
1255
|
onClick: () => onPatch({ align }),
|
|
1778
|
-
className: element.align === align ? BTN_ACTIVE :
|
|
1779
|
-
children: align === "left" ? /* @__PURE__ */
|
|
1256
|
+
className: element.align === align ? BTN_ACTIVE : BTN,
|
|
1257
|
+
children: align === "left" ? /* @__PURE__ */ jsx6(AlignLeftGlyph, { className: "h-3.5 w-3.5" }) : align === "center" ? /* @__PURE__ */ jsx6(AlignCenterGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx6(AlignRightGlyph, { className: "h-3.5 w-3.5" })
|
|
1780
1258
|
},
|
|
1781
1259
|
align
|
|
1782
|
-
)),
|
|
1783
|
-
/* @__PURE__ */
|
|
1784
|
-
/* @__PURE__ */
|
|
1785
|
-
/* @__PURE__ */
|
|
1260
|
+
)) }),
|
|
1261
|
+
/* @__PURE__ */ jsx6(NumberInput, { label: "Line H", value: element.lineHeight, step: 0.1, min: 0.5, onCommit: (v) => onPatch({ lineHeight: v }), className: "w-12" }),
|
|
1262
|
+
/* @__PURE__ */ jsx6(NumberInput, { label: "Spacing", value: element.letterSpacing, step: 0.5, onCommit: (v) => onPatch({ letterSpacing: v }), className: "w-14" }),
|
|
1263
|
+
/* @__PURE__ */ jsx6(ColorSwatch, { label: "Fill", value: element.fill, onCommit: (v) => onPatch({ fill: v }), disabled: !canWrite })
|
|
1786
1264
|
] });
|
|
1787
1265
|
}
|
|
1788
1266
|
function ShapeControls({ element, canWrite, onPatch, showCornerRadius }) {
|
|
1789
1267
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1790
|
-
/* @__PURE__ */
|
|
1791
|
-
/* @__PURE__ */
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
showCornerRadius && "cornerRadius" in element ? /* @__PURE__ */
|
|
1268
|
+
/* @__PURE__ */ jsx6(ColorSwatch, { label: "Fill", value: element.fill, onCommit: (v) => onPatch({ fill: v }), disabled: !canWrite }),
|
|
1269
|
+
/* @__PURE__ */ jsx6(ColorSwatch, { label: "Stroke", value: element.stroke ?? "#000000", onCommit: (v) => onPatch({ stroke: v }), disabled: !canWrite }),
|
|
1270
|
+
/* @__PURE__ */ jsx6(NumberInput, { label: "Stroke W", value: element.strokeWidth ?? 0, min: 0, onCommit: (v) => onPatch({ strokeWidth: v }), className: "w-14" }),
|
|
1271
|
+
showCornerRadius && "cornerRadius" in element ? /* @__PURE__ */ jsx6(NumberInput, { label: "Corner R", value: element.cornerRadius ?? 0, min: 0, onCommit: (v) => onPatch({ cornerRadius: v }), className: "w-14" }) : null
|
|
1794
1272
|
] });
|
|
1795
1273
|
}
|
|
1796
1274
|
function ImageControls({ element, canWrite, onPatch }) {
|
|
1797
1275
|
const [swapOpen, setSwapOpen] = useState3(false);
|
|
1798
1276
|
const [swapUrl, setSwapUrl] = useState3("");
|
|
1799
1277
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1800
|
-
/* @__PURE__ */
|
|
1278
|
+
/* @__PURE__ */ jsx6(
|
|
1801
1279
|
SelectControl,
|
|
1802
1280
|
{
|
|
1803
1281
|
label: "Fit",
|
|
@@ -1812,12 +1290,12 @@ function ImageControls({ element, canWrite, onPatch }) {
|
|
|
1812
1290
|
]
|
|
1813
1291
|
}
|
|
1814
1292
|
),
|
|
1815
|
-
/* @__PURE__ */
|
|
1293
|
+
/* @__PURE__ */ jsx6(
|
|
1816
1294
|
Popover,
|
|
1817
1295
|
{
|
|
1818
1296
|
open: swapOpen,
|
|
1819
1297
|
onClose: () => setSwapOpen(false),
|
|
1820
|
-
trigger: /* @__PURE__ */
|
|
1298
|
+
trigger: /* @__PURE__ */ jsx6(
|
|
1821
1299
|
"button",
|
|
1822
1300
|
{
|
|
1823
1301
|
type: "button",
|
|
@@ -1827,13 +1305,13 @@ function ImageControls({ element, canWrite, onPatch }) {
|
|
|
1827
1305
|
setSwapUrl(element.src);
|
|
1828
1306
|
setSwapOpen((v) => !v);
|
|
1829
1307
|
},
|
|
1830
|
-
className:
|
|
1308
|
+
className: BTN,
|
|
1831
1309
|
title: "Replace image",
|
|
1832
|
-
children: /* @__PURE__ */
|
|
1310
|
+
children: /* @__PURE__ */ jsx6(SwapGlyph, { className: "h-3.5 w-3.5" })
|
|
1833
1311
|
}
|
|
1834
1312
|
),
|
|
1835
1313
|
children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-64 gap-2 p-2`, children: [
|
|
1836
|
-
/* @__PURE__ */
|
|
1314
|
+
/* @__PURE__ */ jsx6(
|
|
1837
1315
|
"input",
|
|
1838
1316
|
{
|
|
1839
1317
|
autoFocus: true,
|
|
@@ -1845,7 +1323,7 @@ function ImageControls({ element, canWrite, onPatch }) {
|
|
|
1845
1323
|
}
|
|
1846
1324
|
),
|
|
1847
1325
|
/* @__PURE__ */ jsxs5("div", { className: "flex gap-2", children: [
|
|
1848
|
-
/* @__PURE__ */
|
|
1326
|
+
/* @__PURE__ */ jsx6(
|
|
1849
1327
|
"button",
|
|
1850
1328
|
{
|
|
1851
1329
|
type: "button",
|
|
@@ -1858,7 +1336,7 @@ function ImageControls({ element, canWrite, onPatch }) {
|
|
|
1858
1336
|
children: "Replace"
|
|
1859
1337
|
}
|
|
1860
1338
|
),
|
|
1861
|
-
/* @__PURE__ */
|
|
1339
|
+
/* @__PURE__ */ jsx6(
|
|
1862
1340
|
"button",
|
|
1863
1341
|
{
|
|
1864
1342
|
type: "button",
|
|
@@ -1888,7 +1366,7 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
|
|
|
1888
1366
|
...SIZE_PRESETS.map((p) => ({ value: p.id, label: p.label }))
|
|
1889
1367
|
];
|
|
1890
1368
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1891
|
-
/* @__PURE__ */
|
|
1369
|
+
/* @__PURE__ */ jsx6(
|
|
1892
1370
|
"input",
|
|
1893
1371
|
{
|
|
1894
1372
|
type: "text",
|
|
@@ -1900,7 +1378,7 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
|
|
|
1900
1378
|
}
|
|
1901
1379
|
),
|
|
1902
1380
|
SEP,
|
|
1903
|
-
/* @__PURE__ */
|
|
1381
|
+
/* @__PURE__ */ jsx6(
|
|
1904
1382
|
SelectControl,
|
|
1905
1383
|
{
|
|
1906
1384
|
label: "Preset",
|
|
@@ -1914,8 +1392,8 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
|
|
|
1914
1392
|
}
|
|
1915
1393
|
),
|
|
1916
1394
|
/* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1395
|
+
/* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: "W" }),
|
|
1396
|
+
/* @__PURE__ */ jsx6(
|
|
1919
1397
|
"input",
|
|
1920
1398
|
{
|
|
1921
1399
|
type: "number",
|
|
@@ -1932,10 +1410,10 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
|
|
|
1932
1410
|
}
|
|
1933
1411
|
)
|
|
1934
1412
|
] }),
|
|
1935
|
-
/* @__PURE__ */
|
|
1413
|
+
/* @__PURE__ */ jsx6("span", { className: "text-[var(--text-muted)]", children: "\xD7" }),
|
|
1936
1414
|
/* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
|
|
1937
|
-
/* @__PURE__ */
|
|
1938
|
-
/* @__PURE__ */
|
|
1415
|
+
/* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: "H" }),
|
|
1416
|
+
/* @__PURE__ */ jsx6(
|
|
1939
1417
|
"input",
|
|
1940
1418
|
{
|
|
1941
1419
|
type: "number",
|
|
@@ -1953,9 +1431,9 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
|
|
|
1953
1431
|
)
|
|
1954
1432
|
] }),
|
|
1955
1433
|
SEP,
|
|
1956
|
-
/* @__PURE__ */
|
|
1434
|
+
/* @__PURE__ */ jsx6(ColorSwatch, { label: "BG", value: page.background, onCommit: (v) => onSetPageProps({ background: v }), disabled: !canWrite }),
|
|
1957
1435
|
SEP,
|
|
1958
|
-
/* @__PURE__ */
|
|
1436
|
+
/* @__PURE__ */ jsx6(BleedControls, { page, canWrite, onSetPageProps })
|
|
1959
1437
|
] });
|
|
1960
1438
|
}
|
|
1961
1439
|
function BleedControls({ page, canWrite, onSetPageProps }) {
|
|
@@ -1965,20 +1443,20 @@ function BleedControls({ page, canWrite, onSetPageProps }) {
|
|
|
1965
1443
|
onSetPageProps({ bleed: { ...current, [side]: value } });
|
|
1966
1444
|
}
|
|
1967
1445
|
if (!bleed) {
|
|
1968
|
-
return /* @__PURE__ */
|
|
1446
|
+
return /* @__PURE__ */ jsx6(
|
|
1969
1447
|
"button",
|
|
1970
1448
|
{
|
|
1971
1449
|
type: "button",
|
|
1972
1450
|
disabled: !canWrite,
|
|
1973
1451
|
onClick: () => onSetPageProps({ bleed: { top: 3, right: 3, bottom: 3, left: 3 } }),
|
|
1974
|
-
className:
|
|
1452
|
+
className: BTN,
|
|
1975
1453
|
title: "Enable bleed",
|
|
1976
|
-
children: /* @__PURE__ */
|
|
1454
|
+
children: /* @__PURE__ */ jsx6(BleedGlyph, { className: "h-3.5 w-3.5" })
|
|
1977
1455
|
}
|
|
1978
1456
|
);
|
|
1979
1457
|
}
|
|
1980
1458
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1981
|
-
["top", "right", "bottom", "left"].map((side) => /* @__PURE__ */
|
|
1459
|
+
["top", "right", "bottom", "left"].map((side) => /* @__PURE__ */ jsx6(
|
|
1982
1460
|
NumberInput,
|
|
1983
1461
|
{
|
|
1984
1462
|
label: `Bleed ${side[0].toUpperCase()}`,
|
|
@@ -1989,13 +1467,13 @@ function BleedControls({ page, canWrite, onSetPageProps }) {
|
|
|
1989
1467
|
},
|
|
1990
1468
|
side
|
|
1991
1469
|
)),
|
|
1992
|
-
/* @__PURE__ */
|
|
1470
|
+
/* @__PURE__ */ jsx6(
|
|
1993
1471
|
"button",
|
|
1994
1472
|
{
|
|
1995
1473
|
type: "button",
|
|
1996
1474
|
disabled: !canWrite,
|
|
1997
1475
|
onClick: () => onSetPageProps({ bleed: null }),
|
|
1998
|
-
className:
|
|
1476
|
+
className: BTN,
|
|
1999
1477
|
title: "Remove bleed",
|
|
2000
1478
|
children: "\xD7"
|
|
2001
1479
|
}
|
|
@@ -2004,11 +1482,10 @@ function BleedControls({ page, canWrite, onSetPageProps }) {
|
|
|
2004
1482
|
}
|
|
2005
1483
|
|
|
2006
1484
|
// src/design-canvas-react/components/ZoomControls.tsx
|
|
2007
|
-
import { jsx as
|
|
1485
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2008
1486
|
var STEP = 0.1;
|
|
2009
1487
|
var MIN = 0.05;
|
|
2010
1488
|
var MAX = 32;
|
|
2011
|
-
var BTN3 = "flex h-6 w-6 items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] disabled:cursor-default disabled:opacity-40";
|
|
2012
1489
|
function ZoomControls({ zoom, onZoom, onFit }) {
|
|
2013
1490
|
function zoomOut() {
|
|
2014
1491
|
onZoom(Math.max(MIN, parseFloat((zoom - STEP).toFixed(4))));
|
|
@@ -2020,26 +1497,26 @@ function ZoomControls({ zoom, onZoom, onFit }) {
|
|
|
2020
1497
|
onZoom(1);
|
|
2021
1498
|
}
|
|
2022
1499
|
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 px-2", children: [
|
|
2023
|
-
/* @__PURE__ */
|
|
1500
|
+
/* @__PURE__ */ jsx7(
|
|
2024
1501
|
"button",
|
|
2025
1502
|
{
|
|
2026
1503
|
type: "button",
|
|
2027
1504
|
"aria-label": "Fit page to viewport",
|
|
2028
1505
|
onClick: onFit,
|
|
2029
|
-
className:
|
|
1506
|
+
className: BTN_SM,
|
|
2030
1507
|
title: "Fit page (F)",
|
|
2031
|
-
children: /* @__PURE__ */
|
|
1508
|
+
children: /* @__PURE__ */ jsx7(ZoomFitGlyph, { className: "h-3.5 w-3.5" })
|
|
2032
1509
|
}
|
|
2033
1510
|
),
|
|
2034
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsx7(
|
|
2035
1512
|
"button",
|
|
2036
1513
|
{
|
|
2037
1514
|
type: "button",
|
|
2038
1515
|
"aria-label": "Zoom out",
|
|
2039
1516
|
onClick: zoomOut,
|
|
2040
1517
|
disabled: zoom <= MIN,
|
|
2041
|
-
className:
|
|
2042
|
-
children: /* @__PURE__ */
|
|
1518
|
+
className: BTN_SM,
|
|
1519
|
+
children: /* @__PURE__ */ jsx7("span", { className: "text-base leading-none", children: "\u2212" })
|
|
2043
1520
|
}
|
|
2044
1521
|
),
|
|
2045
1522
|
/* @__PURE__ */ jsxs6(
|
|
@@ -2048,7 +1525,7 @@ function ZoomControls({ zoom, onZoom, onFit }) {
|
|
|
2048
1525
|
type: "button",
|
|
2049
1526
|
"aria-label": "Reset to 100%",
|
|
2050
1527
|
onClick: resetHundred,
|
|
2051
|
-
className: "rounded px-1.5 py-0.5 font-mono text-[11px] tabular-nums text-[var(--text-secondary)] transition hover:bg-[var(--border-default)] hover:text-[var(--text-primary)]",
|
|
1528
|
+
className: "rounded px-1.5 py-0.5 font-mono text-[11px] tabular-nums text-[var(--text-secondary)] transition hover:bg-[var(--border-default)] hover:text-[var(--text-primary)] focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
|
|
2052
1529
|
title: "Reset to 100%",
|
|
2053
1530
|
children: [
|
|
2054
1531
|
Math.round(zoom * 100),
|
|
@@ -2056,15 +1533,15 @@ function ZoomControls({ zoom, onZoom, onFit }) {
|
|
|
2056
1533
|
]
|
|
2057
1534
|
}
|
|
2058
1535
|
),
|
|
2059
|
-
/* @__PURE__ */
|
|
1536
|
+
/* @__PURE__ */ jsx7(
|
|
2060
1537
|
"button",
|
|
2061
1538
|
{
|
|
2062
1539
|
type: "button",
|
|
2063
1540
|
"aria-label": "Zoom in",
|
|
2064
1541
|
onClick: zoomIn,
|
|
2065
1542
|
disabled: zoom >= MAX,
|
|
2066
|
-
className:
|
|
2067
|
-
children: /* @__PURE__ */
|
|
1543
|
+
className: BTN_SM,
|
|
1544
|
+
children: /* @__PURE__ */ jsx7("span", { className: "text-sm leading-none", children: "+" })
|
|
2068
1545
|
}
|
|
2069
1546
|
)
|
|
2070
1547
|
] });
|
|
@@ -2072,7 +1549,7 @@ function ZoomControls({ zoom, onZoom, onFit }) {
|
|
|
2072
1549
|
|
|
2073
1550
|
// src/design-canvas-react/components/ExportControl.tsx
|
|
2074
1551
|
import { useRef as useRef4, useState as useState4 } from "react";
|
|
2075
|
-
import { jsx as
|
|
1552
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2076
1553
|
var FORMATS = [
|
|
2077
1554
|
{ id: "png", label: "PNG" },
|
|
2078
1555
|
{ id: "jpeg", label: "JPEG" }
|
|
@@ -2106,9 +1583,9 @@ function ExportControl({ defaults, onExport, className }) {
|
|
|
2106
1583
|
},
|
|
2107
1584
|
className: "flex h-8 items-center gap-1.5 rounded-md border border-[var(--border-default)] px-2.5 text-xs font-medium text-[var(--text-primary)] transition-colors hover:border-[var(--brand-primary)]/40",
|
|
2108
1585
|
children: [
|
|
2109
|
-
/* @__PURE__ */
|
|
1586
|
+
/* @__PURE__ */ jsx8(ExportGlyph, { className: "h-3.5 w-3.5" }),
|
|
2110
1587
|
"Export",
|
|
2111
|
-
/* @__PURE__ */
|
|
1588
|
+
/* @__PURE__ */ jsx8(ChevronDownGlyph, { className: "h-3 w-3 text-[var(--text-muted)]" })
|
|
2112
1589
|
]
|
|
2113
1590
|
}
|
|
2114
1591
|
),
|
|
@@ -2125,8 +1602,8 @@ function ExportControl({ defaults, onExport, className }) {
|
|
|
2125
1602
|
className: "absolute right-0 top-full z-50 mt-1 flex w-52 flex-col gap-3 rounded-md border border-[var(--border-default)] bg-[var(--bg-input)] p-3 shadow-lg",
|
|
2126
1603
|
children: [
|
|
2127
1604
|
/* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1.5", children: [
|
|
2128
|
-
/* @__PURE__ */
|
|
2129
|
-
/* @__PURE__ */
|
|
1605
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[11px] font-medium text-[var(--text-muted)]", children: "Format" }),
|
|
1606
|
+
/* @__PURE__ */ jsx8("div", { className: "flex gap-1.5", children: FORMATS.map((f) => /* @__PURE__ */ jsx8(
|
|
2130
1607
|
"button",
|
|
2131
1608
|
{
|
|
2132
1609
|
type: "button",
|
|
@@ -2139,8 +1616,8 @@ function ExportControl({ defaults, onExport, className }) {
|
|
|
2139
1616
|
)) })
|
|
2140
1617
|
] }),
|
|
2141
1618
|
/* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1.5", children: [
|
|
2142
|
-
/* @__PURE__ */
|
|
2143
|
-
/* @__PURE__ */
|
|
1619
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[11px] font-medium text-[var(--text-muted)]", children: "Scale" }),
|
|
1620
|
+
/* @__PURE__ */ jsx8("div", { className: "flex gap-1.5", children: SCALES.map((s) => /* @__PURE__ */ jsx8(
|
|
2144
1621
|
"button",
|
|
2145
1622
|
{
|
|
2146
1623
|
type: "button",
|
|
@@ -2152,7 +1629,7 @@ function ExportControl({ defaults, onExport, className }) {
|
|
|
2152
1629
|
s.value
|
|
2153
1630
|
)) })
|
|
2154
1631
|
] }),
|
|
2155
|
-
/* @__PURE__ */
|
|
1632
|
+
/* @__PURE__ */ jsx8(
|
|
2156
1633
|
"button",
|
|
2157
1634
|
{
|
|
2158
1635
|
type: "button",
|
|
@@ -2169,7 +1646,7 @@ function ExportControl({ defaults, onExport, className }) {
|
|
|
2169
1646
|
}
|
|
2170
1647
|
|
|
2171
1648
|
// src/design-canvas-react/components/DesignCanvas.tsx
|
|
2172
|
-
import { jsx as
|
|
1649
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2173
1650
|
function mintId() {
|
|
2174
1651
|
const uuid = globalThis.crypto && "randomUUID" in globalThis.crypto ? globalThis.crypto.randomUUID() : null;
|
|
2175
1652
|
return `local-${uuid ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`;
|
|
@@ -2214,6 +1691,7 @@ function DesignCanvas({
|
|
|
2214
1691
|
className,
|
|
2215
1692
|
fitOnMount,
|
|
2216
1693
|
onReady,
|
|
1694
|
+
render,
|
|
2217
1695
|
renderWorkspace,
|
|
2218
1696
|
renderThumbnail
|
|
2219
1697
|
}) {
|
|
@@ -2396,12 +1874,7 @@ function DesignCanvas({
|
|
|
2396
1874
|
void onApplyOperations(command.inverseOperations()).then((result) => {
|
|
2397
1875
|
if (result.document) stack.reset(result.document);
|
|
2398
1876
|
}).catch((error) => {
|
|
2399
|
-
|
|
2400
|
-
try {
|
|
2401
|
-
stack.redo();
|
|
2402
|
-
} catch {
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
1877
|
+
stack.reexecute(command);
|
|
2405
1878
|
setCommitError(error instanceof Error ? error.message : String(error));
|
|
2406
1879
|
});
|
|
2407
1880
|
}, [stack, canWrite, onApplyOperations]);
|
|
@@ -2417,12 +1890,7 @@ function DesignCanvas({
|
|
|
2417
1890
|
void onApplyOperations(command.operations()).then((result) => {
|
|
2418
1891
|
if (result.document) stack.reset(result.document);
|
|
2419
1892
|
}).catch((error) => {
|
|
2420
|
-
|
|
2421
|
-
try {
|
|
2422
|
-
stack.undo();
|
|
2423
|
-
} catch {
|
|
2424
|
-
}
|
|
2425
|
-
}
|
|
1893
|
+
stack.reundo(command);
|
|
2426
1894
|
setCommitError(error instanceof Error ? error.message : String(error));
|
|
2427
1895
|
});
|
|
2428
1896
|
}, [stack, canWrite, onApplyOperations]);
|
|
@@ -2466,7 +1934,7 @@ function DesignCanvas({
|
|
|
2466
1934
|
}, [activePage, editorState.selectedElementIds]);
|
|
2467
1935
|
const review = mode === "review";
|
|
2468
1936
|
if (!activePage) {
|
|
2469
|
-
return /* @__PURE__ */
|
|
1937
|
+
return /* @__PURE__ */ jsx9("div", { className: `flex h-full items-center justify-center bg-[var(--bg-input)] text-[var(--text-muted)] ${className ?? ""}`, children: "No pages in document" });
|
|
2470
1938
|
}
|
|
2471
1939
|
const bleedScreen = editorState.showBleed && activePage.bleed ? {
|
|
2472
1940
|
top: activePage.bleed.top * editorState.zoom,
|
|
@@ -2475,10 +1943,10 @@ function DesignCanvas({
|
|
|
2475
1943
|
left: activePage.bleed.left * editorState.zoom
|
|
2476
1944
|
} : null;
|
|
2477
1945
|
return /* @__PURE__ */ jsxs8("div", { className: `flex h-full min-h-0 bg-[var(--bg-input)] text-[var(--text-primary)] ${className ?? ""}`, children: [
|
|
2478
|
-
renderSidePanel && !review ? /* @__PURE__ */
|
|
1946
|
+
renderSidePanel && !review ? /* @__PURE__ */ jsx9("aside", { className: "flex w-64 shrink-0 flex-col overflow-hidden border-r border-[var(--border-default)]", children: renderSidePanel() }) : null,
|
|
2479
1947
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
2480
1948
|
/* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-stretch", children: [
|
|
2481
|
-
/* @__PURE__ */
|
|
1949
|
+
/* @__PURE__ */ jsx9("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx9(
|
|
2482
1950
|
Toolbar,
|
|
2483
1951
|
{
|
|
2484
1952
|
page: activePage,
|
|
@@ -2507,7 +1975,7 @@ function DesignCanvas({
|
|
|
2507
1975
|
onBindSlot: handleBindSlot
|
|
2508
1976
|
}
|
|
2509
1977
|
) }),
|
|
2510
|
-
onExport ? /* @__PURE__ */
|
|
1978
|
+
onExport ? /* @__PURE__ */ jsx9("div", { className: "flex shrink-0 items-center border-b border-l border-[var(--border-default)] bg-[var(--bg-input)] px-2", children: /* @__PURE__ */ jsx9(
|
|
2511
1979
|
ExportControl,
|
|
2512
1980
|
{
|
|
2513
1981
|
defaults: exportDefaults,
|
|
@@ -2518,11 +1986,11 @@ function DesignCanvas({
|
|
|
2518
1986
|
commitError ? /* @__PURE__ */ jsxs8(
|
|
2519
1987
|
"div",
|
|
2520
1988
|
{
|
|
2521
|
-
className: "flex shrink-0 items-center justify-between gap-3 border-b border-
|
|
1989
|
+
className: "flex shrink-0 items-center justify-between gap-3 border-b border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-3 py-1.5 text-xs text-[var(--text-danger)]",
|
|
2522
1990
|
role: "alert",
|
|
2523
1991
|
children: [
|
|
2524
|
-
/* @__PURE__ */
|
|
2525
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsx9("span", { className: "min-w-0 truncate", children: commitError }),
|
|
1993
|
+
/* @__PURE__ */ jsx9(
|
|
2526
1994
|
"button",
|
|
2527
1995
|
{
|
|
2528
1996
|
type: "button",
|
|
@@ -2535,7 +2003,7 @@ function DesignCanvas({
|
|
|
2535
2003
|
}
|
|
2536
2004
|
) : null,
|
|
2537
2005
|
/* @__PURE__ */ jsxs8("div", { className: "relative min-h-0 flex-1", children: [
|
|
2538
|
-
/* @__PURE__ */
|
|
2006
|
+
/* @__PURE__ */ jsx9(
|
|
2539
2007
|
Rulers,
|
|
2540
2008
|
{
|
|
2541
2009
|
pageWidth: activePage.width,
|
|
@@ -2548,12 +2016,12 @@ function DesignCanvas({
|
|
|
2548
2016
|
onGuidesChange: handleSetPageGuides
|
|
2549
2017
|
}
|
|
2550
2018
|
),
|
|
2551
|
-
bleedScreen && activePage.bleed ? /* @__PURE__ */
|
|
2019
|
+
bleedScreen && activePage.bleed ? /* @__PURE__ */ jsx9(
|
|
2552
2020
|
"div",
|
|
2553
2021
|
{
|
|
2554
2022
|
className: "pointer-events-none absolute inset-0 z-10 overflow-hidden",
|
|
2555
2023
|
"aria-hidden": true,
|
|
2556
|
-
children: /* @__PURE__ */
|
|
2024
|
+
children: /* @__PURE__ */ jsx9(
|
|
2557
2025
|
"div",
|
|
2558
2026
|
{
|
|
2559
2027
|
style: {
|
|
@@ -2561,7 +2029,7 @@ function DesignCanvas({
|
|
|
2561
2029
|
left: editorState.panX,
|
|
2562
2030
|
top: editorState.panY
|
|
2563
2031
|
},
|
|
2564
|
-
children: /* @__PURE__ */
|
|
2032
|
+
children: /* @__PURE__ */ jsx9(
|
|
2565
2033
|
BleedTrimOverlay,
|
|
2566
2034
|
{
|
|
2567
2035
|
pageWidthPx: activePage.width * editorState.zoom,
|
|
@@ -2591,13 +2059,14 @@ function DesignCanvas({
|
|
|
2591
2059
|
onExportRef: exportRef,
|
|
2592
2060
|
fitOnMount,
|
|
2593
2061
|
onReady,
|
|
2062
|
+
render,
|
|
2594
2063
|
onZoomChange: setZoom,
|
|
2595
2064
|
onPanChange: setPan,
|
|
2596
2065
|
onSelectElements: setSelectedElements
|
|
2597
2066
|
})
|
|
2598
2067
|
] }),
|
|
2599
2068
|
/* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-stretch border-t border-[var(--border-default)]", children: [
|
|
2600
|
-
/* @__PURE__ */
|
|
2069
|
+
/* @__PURE__ */ jsx9("div", { className: "min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx9(
|
|
2601
2070
|
PagesStrip,
|
|
2602
2071
|
{
|
|
2603
2072
|
pages: editorState.document.pages,
|
|
@@ -2612,7 +2081,7 @@ function DesignCanvas({
|
|
|
2612
2081
|
onReorderPage: handleReorderPage
|
|
2613
2082
|
}
|
|
2614
2083
|
) }),
|
|
2615
|
-
/* @__PURE__ */
|
|
2084
|
+
/* @__PURE__ */ jsx9("div", { className: "flex shrink-0 items-center border-l border-[var(--border-default)]", children: /* @__PURE__ */ jsx9(
|
|
2616
2085
|
ZoomControls,
|
|
2617
2086
|
{
|
|
2618
2087
|
zoom: editorState.zoom,
|
|
@@ -2622,29 +2091,12 @@ function DesignCanvas({
|
|
|
2622
2091
|
) })
|
|
2623
2092
|
] })
|
|
2624
2093
|
] }),
|
|
2625
|
-
renderAgentPanel ? /* @__PURE__ */
|
|
2094
|
+
renderAgentPanel ? /* @__PURE__ */ jsx9("aside", { className: "flex w-80 shrink-0 flex-col overflow-hidden border-l border-[var(--border-default)]", children: renderAgentPanel({ selectedElements, activePageId: editorState.activePageId }) }) : null
|
|
2626
2095
|
] });
|
|
2627
2096
|
}
|
|
2628
2097
|
var DesignCanvas_default = DesignCanvas;
|
|
2629
2098
|
|
|
2630
2099
|
export {
|
|
2631
|
-
SCENE_COMMAND_HISTORY_LIMIT,
|
|
2632
|
-
createSceneCommandStack,
|
|
2633
|
-
addElementCommand,
|
|
2634
|
-
setAttrsCommand,
|
|
2635
|
-
multiSetAttrsCommand,
|
|
2636
|
-
reorderElementCommand,
|
|
2637
|
-
deleteElementCommand,
|
|
2638
|
-
groupElementsCommand,
|
|
2639
|
-
ungroupElementCommand,
|
|
2640
|
-
addPageCommand,
|
|
2641
|
-
duplicatePageCommand,
|
|
2642
|
-
deletePageCommand,
|
|
2643
|
-
reorderPageCommand,
|
|
2644
|
-
setPagePropsCommand,
|
|
2645
|
-
setPageGuidesCommand,
|
|
2646
|
-
bindSlotCommand,
|
|
2647
|
-
setDocumentTitleCommand,
|
|
2648
2100
|
selectTickStep,
|
|
2649
2101
|
buildRulerTicks,
|
|
2650
2102
|
formatRulerLabel,
|
|
@@ -2662,6 +2114,11 @@ export {
|
|
|
2662
2114
|
VideoGlyph,
|
|
2663
2115
|
SlotGlyph,
|
|
2664
2116
|
ShapesGlyph,
|
|
2117
|
+
BTN,
|
|
2118
|
+
BTN_ACTIVE,
|
|
2119
|
+
BTN_SM,
|
|
2120
|
+
BTN_SM_ACTIVE,
|
|
2121
|
+
IconButton,
|
|
2665
2122
|
PagesStrip,
|
|
2666
2123
|
Rulers,
|
|
2667
2124
|
Toolbar,
|
|
@@ -2670,4 +2127,4 @@ export {
|
|
|
2670
2127
|
DesignCanvas,
|
|
2671
2128
|
DesignCanvas_default
|
|
2672
2129
|
};
|
|
2673
|
-
//# sourceMappingURL=chunk-
|
|
2130
|
+
//# sourceMappingURL=chunk-YEWTVDDT.js.map
|