@pixerate/editor 0.272.0 → 0.272.1

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.
Files changed (41) hide show
  1. package/dist/agent/index.cjs +34 -32
  2. package/dist/agent/index.js +10 -8
  3. package/dist/chart/contract.d.cts +95 -0
  4. package/dist/chart/contract.d.ts +95 -0
  5. package/dist/chart/controller.d.cts +4 -0
  6. package/dist/chart/controller.d.ts +4 -0
  7. package/dist/chart/index.cjs +492 -26
  8. package/dist/chart/index.d.cts +1 -0
  9. package/dist/chart/index.d.ts +1 -0
  10. package/dist/chart/index.js +476 -10
  11. package/dist/chart/tools.d.cts +3 -0
  12. package/dist/chart/tools.d.ts +3 -0
  13. package/dist/chart-maps/index.cjs +4 -64
  14. package/dist/chart-maps/index.js +3 -63
  15. package/dist/{chunk-NMZQMPFZ.js → chunk-4LZQO5Y7.js} +2 -0
  16. package/dist/chunk-5UGRMVNE.js +328 -0
  17. package/dist/{chunk-X4FTNFIA.js → chunk-7MGPW2OV.js} +1 -1
  18. package/dist/{chunk-DGITFN73.cjs → chunk-BWJBZAUE.cjs} +8 -8
  19. package/dist/chunk-CHZYVNXZ.js +336 -0
  20. package/dist/chunk-DRMZ5R3S.cjs +67 -0
  21. package/dist/chunk-EI5GFTKG.js +67 -0
  22. package/dist/chunk-JV7DKLMX.js +1073 -0
  23. package/dist/chunk-MFBUQC67.cjs +328 -0
  24. package/dist/{chunk-IBXEQOGI.js → chunk-PYHB2EHE.js} +2 -324
  25. package/dist/chunk-QEUI6OGE.cjs +336 -0
  26. package/dist/{chunk-6ZSFRRJI.js → chunk-RSF6BT34.js} +1 -1
  27. package/dist/chunk-T2HUQBRC.cjs +1073 -0
  28. package/dist/{chunk-GSLOH2IN.cjs → chunk-VF6ODSYX.cjs} +2 -0
  29. package/dist/{chunk-NQUKTRKN.cjs → chunk-WZLNNGG3.cjs} +45 -45
  30. package/dist/{chunk-NRBGAEFI.cjs → chunk-Y3RUYOOW.cjs} +8 -330
  31. package/dist/commands/index.cjs +7 -323
  32. package/dist/commands/index.js +5 -321
  33. package/dist/extensions/index.cjs +4 -4
  34. package/dist/extensions/index.js +3 -3
  35. package/dist/index.cjs +9 -9
  36. package/dist/index.js +3 -3
  37. package/dist/persistence/index.cjs +24 -1042
  38. package/dist/persistence/index.js +22 -1040
  39. package/dist/tools/index.cjs +5 -3
  40. package/dist/tools/index.js +8 -6
  41. package/package.json +1 -1
@@ -1,4 +1,9 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+ var _chunkQEUI6OGEcjs = require('../chunk-QEUI6OGE.cjs');
6
+
2
7
 
3
8
 
4
9
 
@@ -50,327 +55,6 @@ var _chunkVCL7CB56cjs = require('../chunk-VCL7CB56.cjs');
50
55
  require('../chunk-K7ENM55P.cjs');
51
56
  require('../chunk-WOFXZ3XU.cjs');
52
57
 
53
- // src/commands/paletteController.ts
54
- function createCommandPaletteController(registry, options = {}) {
55
- const listeners = /* @__PURE__ */ new Set();
56
- let open = false;
57
- let query = "";
58
- let activeIndex = 0;
59
- let recents = [..._nullishCoalesce(options.recents, () => ( []))];
60
- let lastResult = null;
61
- let state;
62
- const context = () => {
63
- const c = options.context;
64
- if (c === void 0) return registry.context;
65
- return typeof c === "function" ? c() : c;
66
- };
67
- const scope = () => typeof options.scope === "function" ? options.scope() : options.scope;
68
- function computeItems() {
69
- if (!open) return [];
70
- const entries = registry.list({ scope: scope(), context: context() });
71
- const platform = _nullishCoalesce(options.platform, () => ( registry.shortcuts.platform));
72
- return _chunkKIJIONZFcjs.rankCommands.call(void 0, query, entries, {
73
- recents,
74
- recentLimit: options.recentLimit,
75
- limit: _nullishCoalesce(options.limit, () => ( 50))
76
- }).map((ranked) => ({
77
- ...ranked,
78
- id: ranked.entry.id,
79
- label: ranked.entry.label,
80
- ...ranked.entry.group !== void 0 ? { group: ranked.entry.group } : {},
81
- ...ranked.entry.shortcuts[0] ? { shortcut: _chunkQJVOJUTDcjs.formatShortcut.call(void 0, ranked.entry.shortcuts[0], platform) } : {},
82
- enabled: ranked.entry.enabled,
83
- ...ranked.entry.disabledReason ? { disabledReason: ranked.entry.disabledReason } : {}
84
- }));
85
- }
86
- function update() {
87
- const items = computeItems();
88
- activeIndex = items.length === 0 ? 0 : Math.min(Math.max(activeIndex, 0), items.length - 1);
89
- state = { open, query, activeIndex, items, recents, lastResult };
90
- for (const listener of Array.from(listeners)) listener(state);
91
- }
92
- state = { open, query, activeIndex, items: [], recents, lastResult };
93
- let unsubscribeRegistry = null;
94
- const onRegistryChange = () => {
95
- if (open) update();
96
- };
97
- const controller = {
98
- getState: () => state,
99
- subscribe(listener) {
100
- listeners.add(listener);
101
- unsubscribeRegistry ??= registry.subscribe(onRegistryChange);
102
- if (open) update();
103
- return () => {
104
- listeners.delete(listener);
105
- if (listeners.size === 0) {
106
- _optionalChain([unsubscribeRegistry, 'optionalCall', _ => _()]);
107
- unsubscribeRegistry = null;
108
- }
109
- };
110
- },
111
- setOpen(next) {
112
- if (next === open) return;
113
- open = next;
114
- query = "";
115
- activeIndex = 0;
116
- update();
117
- },
118
- toggle() {
119
- controller.setOpen(!open);
120
- },
121
- setQuery(next) {
122
- if (next === query) return;
123
- query = next;
124
- activeIndex = 0;
125
- update();
126
- },
127
- setActiveIndex(index) {
128
- activeIndex = index;
129
- update();
130
- },
131
- /** Moves the active row by `delta`, wrapping around. */
132
- move(delta) {
133
- const n = state.items.length;
134
- if (n === 0) return;
135
- activeIndex = ((activeIndex + delta) % n + n) % n;
136
- update();
137
- },
138
- /** Runs a command by id, closes the palette and records it as recent. Disabled commands do nothing. */
139
- run(id) {
140
- if (!registry.isEnabled(id, void 0, context()).enabled) return null;
141
- open = false;
142
- query = "";
143
- activeIndex = 0;
144
- recents = _chunkKIJIONZFcjs.pushRecent.call(void 0, recents, id, _nullishCoalesce(options.recentLimit, () => ( _chunkKIJIONZFcjs.DEFAULT_RECENT_LIMIT)));
145
- _optionalChain([options, 'access', _2 => _2.onRecentsChange, 'optionalCall', _3 => _3(recents)]);
146
- const result = registry.execute(id, void 0, context());
147
- lastResult = result;
148
- update();
149
- _optionalChain([options, 'access', _4 => _4.onRun, 'optionalCall', _5 => _5(result)]);
150
- return result;
151
- },
152
- runActive() {
153
- const item = state.items[state.activeIndex];
154
- return item ? controller.run(item.id) : null;
155
- },
156
- /**
157
- * Keyboard handling for the palette input: ArrowUp/ArrowDown (wrap), Home/End,
158
- * Enter (run the active row) and Escape (close). Returns whether it handled the key.
159
- */
160
- handleKeyDown(event) {
161
- if (!open) return false;
162
- switch (event.key) {
163
- case "ArrowDown":
164
- controller.move(1);
165
- break;
166
- case "ArrowUp":
167
- controller.move(-1);
168
- break;
169
- case "Home":
170
- controller.setActiveIndex(0);
171
- break;
172
- case "End":
173
- controller.setActiveIndex(state.items.length - 1);
174
- break;
175
- case "Enter":
176
- controller.runActive();
177
- break;
178
- case "Escape":
179
- controller.setOpen(false);
180
- break;
181
- default:
182
- return false;
183
- }
184
- _optionalChain([event, 'access', _6 => _6.preventDefault, 'optionalCall', _7 => _7()]);
185
- return true;
186
- },
187
- /** Re-reads commands and enablement. */
188
- refresh() {
189
- update();
190
- },
191
- destroy() {
192
- _optionalChain([unsubscribeRegistry, 'optionalCall', _8 => _8()]);
193
- unsubscribeRegistry = null;
194
- listeners.clear();
195
- }
196
- };
197
- return controller;
198
- }
199
- function matchPaletteHotkey(event, hotkey, platform) {
200
- const map = new (0, _chunkQJVOJUTDcjs.ShortcutMap)([{ command: "palette", chord: hotkey, allowInEditable: true }], platform ? { platform } : {});
201
- return map.resolve(event) !== null;
202
- }
203
-
204
- // src/commands/animation.ts
205
- var EASING_DESCRIPTION = "Easing preset (linear, ease, ease-in, ease-out, ease-in-out, ease-in-back, ease-out-back, spring, hold) or a CSS cubic-bezier(x1, y1, x2, y2).";
206
- var VALUES = {
207
- type: "object",
208
- description: 'Property \u2192 value, e.g. {"x": 200, "opacity": 0.5, "fill": "#ff0000"}. Properties: x, y, width, height, rotation (degrees), scale, opacity (0\u20131), fill, stroke, strokeWidth, cornerRadius, motionPath (0\u20131).',
209
- additionalProperties: { type: ["number", "string"] }
210
- };
211
- function createCanvasAnimationCommands(controller, options = {}) {
212
- const prefix = _nullishCoalesce(options.prefix, () => ( "canvas.animation."));
213
- const group = _nullishCoalesce(options.group, () => ( "Animation"));
214
- const scope = options.scope === null ? void 0 : _nullishCoalesce(options.scope, () => ( "canvas"));
215
- const base = { group, ...scope ? { scope } : {} };
216
- const hasSelection = () => controller.getState().selection.length > 0 ? true : "Select keyframes first.";
217
- return [
218
- {
219
- ...base,
220
- id: `${prefix}togglePlay`,
221
- label: "Play / Pause Animation",
222
- keywords: ["play", "pause", "preview", "timeline"],
223
- description: "Plays or pauses the canvas animation from the playhead.",
224
- run: () => {
225
- controller.toggle();
226
- return { playing: controller.getState().playing, time: controller.getState().time };
227
- }
228
- },
229
- {
230
- ...base,
231
- id: `${prefix}play`,
232
- label: "Play Animation",
233
- keywords: ["preview", "timeline"],
234
- enabled: () => controller.getState().playing ? "Already playing." : true,
235
- run: () => controller.play()
236
- },
237
- {
238
- ...base,
239
- id: `${prefix}pause`,
240
- label: "Pause Animation",
241
- enabled: () => controller.getState().playing ? true : "Not playing.",
242
- run: () => controller.pause()
243
- },
244
- {
245
- ...base,
246
- id: `${prefix}stop`,
247
- label: "Stop Animation",
248
- keywords: ["rewind", "reset"],
249
- description: "Stops playback and returns to the start.",
250
- run: () => controller.stop()
251
- },
252
- {
253
- ...base,
254
- id: `${prefix}seek`,
255
- label: "Go to Time\u2026",
256
- keywords: ["playhead", "scrub", "time"],
257
- description: "Moves the playhead.",
258
- params: {
259
- type: "object",
260
- properties: { time: { type: "number", minimum: 0, description: "Time in milliseconds." } },
261
- required: ["time"]
262
- },
263
- run: (_ctx, params) => {
264
- controller.seek(params.time);
265
- return { time: controller.getState().time };
266
- }
267
- },
268
- {
269
- ...base,
270
- id: `${prefix}addKeyframe`,
271
- label: "Add Keyframe at Playhead",
272
- keywords: ["key", "animate", "record"],
273
- description: "Keys the selected nodes (or `ids`) at the playhead (or `time`): their animated properties, `properties`, or position.",
274
- params: {
275
- type: "object",
276
- properties: {
277
- ids: { type: "array", items: { type: "string" }, description: "Node ids (default: selected nodes)." },
278
- properties: { type: "array", items: { type: "string" }, description: "Properties to key (default: animated ones, or x and y)." },
279
- time: { type: "number", minimum: 0, description: "Time in ms (default: the playhead)." }
280
- }
281
- },
282
- run: (_ctx, params) => controller.addKeyframe(_optionalChain([params, 'optionalAccess', _9 => _9.ids]), _optionalChain([params, 'optionalAccess', _10 => _10.properties]), _optionalChain([params, 'optionalAccess', _11 => _11.time]))
283
- },
284
- {
285
- ...base,
286
- id: `${prefix}deleteKeyframes`,
287
- label: "Delete Keyframes",
288
- keywords: ["remove", "clear"],
289
- enabled: hasSelection,
290
- run: () => controller.deleteKeyframes()
291
- },
292
- {
293
- ...base,
294
- id: `${prefix}setEasing`,
295
- label: "Set Keyframe Easing\u2026",
296
- keywords: ["interpolation", "ease", "bezier", "spring", "hold", "curve"],
297
- description: "Sets the easing of the segments leaving the selected keyframes.",
298
- params: {
299
- type: "object",
300
- properties: { easing: { type: "string", description: EASING_DESCRIPTION } },
301
- required: ["easing"]
302
- },
303
- enabled: hasSelection,
304
- run: (_ctx, params) => controller.setEasing(params.easing)
305
- },
306
- {
307
- ...base,
308
- id: `${prefix}toggleRecord`,
309
- label: "Toggle Record Mode",
310
- keywords: ["auto key", "record", "keyframe"],
311
- description: "In record mode, changing a property at the playhead keys it.",
312
- run: () => {
313
- controller.toggleRecording();
314
- return { recording: controller.getState().recording };
315
- }
316
- },
317
- {
318
- ...base,
319
- id: `${prefix}nextKeyframe`,
320
- label: "Next Keyframe",
321
- keywords: ["jump", "navigate"],
322
- run: () => controller.nextKeyframe()
323
- },
324
- {
325
- ...base,
326
- id: `${prefix}previousKeyframe`,
327
- label: "Previous Keyframe",
328
- keywords: ["jump", "navigate"],
329
- run: () => controller.previousKeyframe()
330
- },
331
- {
332
- ...base,
333
- id: `${prefix}animateNode`,
334
- label: "Animate Node\u2026",
335
- keywords: ["tween", "transition", "move", "fade"],
336
- description: "Animates a node from `from` (default: its current values) to `to` over `duration` ms, starting at `delay` ms.",
337
- params: {
338
- type: "object",
339
- properties: {
340
- nodeId: { type: "string", description: "Node to animate." },
341
- to: VALUES,
342
- from: VALUES,
343
- duration: { type: "number", exclusiveMinimum: 0, description: "Duration in ms (default 1000)." },
344
- delay: { type: "number", minimum: 0, description: "Start time in ms (default 0)." },
345
- easing: { type: "string", description: EASING_DESCRIPTION }
346
- },
347
- required: ["nodeId", "to"]
348
- },
349
- run: (_ctx, params) => controller.animateNode(params.nodeId, {
350
- to: params.to,
351
- ...params.from ? { from: params.from } : {},
352
- ...params.duration !== void 0 ? { duration: params.duration } : {},
353
- ...params.delay !== void 0 ? { delay: params.delay } : {},
354
- ...params.easing !== void 0 ? { easing: params.easing } : {}
355
- })
356
- },
357
- {
358
- ...base,
359
- id: `${prefix}exportCss`,
360
- label: "Export Animation as CSS",
361
- keywords: ["keyframes", "css", "web animations"],
362
- description: "Returns CSS @keyframes for a node's animation.",
363
- readOnly: true,
364
- params: {
365
- type: "object",
366
- properties: { nodeId: { type: "string" } },
367
- required: ["nodeId"]
368
- },
369
- run: (_ctx, params) => controller.exportCss(params.nodeId)
370
- }
371
- ];
372
- }
373
-
374
58
 
375
59
 
376
60
 
@@ -413,4 +97,4 @@ function createCanvasAnimationCommands(controller, options = {}) {
413
97
 
414
98
 
415
99
 
416
- exports.CommandRegistry = _chunkKIJIONZFcjs.CommandRegistry; exports.CommandRegistryError = _chunkKIJIONZFcjs.CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS = _chunkQEVLRLUNcjs.DEFAULT_HISTORY_SHORTCUTS; exports.DEFAULT_RECENT_LIMIT = _chunkKIJIONZFcjs.DEFAULT_RECENT_LIMIT; exports.PLATFORMS = _chunkQJVOJUTDcjs.PLATFORMS; exports.ShortcutMap = _chunkQJVOJUTDcjs.ShortcutMap; exports.chordToString = _chunkQJVOJUTDcjs.chordToString; exports.codeFromKey = _chunkQJVOJUTDcjs.codeFromKey; exports.codeToKeyText = _chunkQJVOJUTDcjs.codeToKeyText; exports.createArrangeCommands = _chunkQEVLRLUNcjs.createArrangeCommands; exports.createCanvasAnimationCommands = createCanvasAnimationCommands; exports.createCommandPaletteController = createCommandPaletteController; exports.createCommandRegistry = _chunkKIJIONZFcjs.createCommandRegistry; exports.createCommandToolProvider = _chunkKIJIONZFcjs.createCommandToolProvider; exports.createComponentCommands = _chunkQEVLRLUNcjs.createComponentCommands; exports.createDrawCommands = _chunkQEVLRLUNcjs.createDrawCommands; exports.createFormatCommands = _chunkVCL7CB56cjs.createFormatCommands; exports.createHistoryCommands = _chunkQEVLRLUNcjs.createHistoryCommands; exports.createShapeCommands = _chunkQEVLRLUNcjs.createShapeCommands; exports.createSpreadsheetCommands = _chunkQEVLRLUNcjs.createSpreadsheetCommands; exports.defineCommand = _chunkKIJIONZFcjs.defineCommand; exports.detectPlatform = _chunkQJVOJUTDcjs.detectPlatform; exports.effectiveChord = _chunkQJVOJUTDcjs.effectiveChord; exports.effectiveChordKey = _chunkQJVOJUTDcjs.effectiveChordKey; exports.eventCode = _chunkQJVOJUTDcjs.eventCode; exports.exactBonus = _chunkKIJIONZFcjs.exactBonus; exports.formatCommandsFor = _chunkVCL7CB56cjs.formatCommandsFor; exports.formatShortcut = _chunkQJVOJUTDcjs.formatShortcut; exports.fuzzyMatch = _chunkKIJIONZFcjs.fuzzyMatch; exports.fuzzyScore = _chunkKIJIONZFcjs.fuzzyScore; exports.hasVariantCommands = _chunkQEVLRLUNcjs.hasVariantCommands; exports.isEditableEventTarget = _chunkQJVOJUTDcjs.isEditableEventTarget; exports.keyToCode = _chunkQJVOJUTDcjs.keyToCode; exports.matchHistoryShortcut = _chunkQEVLRLUNcjs.matchHistoryShortcut; exports.matchPaletteHotkey = matchPaletteHotkey; exports.normalizeChord = _chunkQJVOJUTDcjs.normalizeChord; exports.parseChord = _chunkQJVOJUTDcjs.parseChord; exports.planFreehandPlayback = _chunkQEVLRLUNcjs.planFreehandPlayback; exports.pushRecent = _chunkKIJIONZFcjs.pushRecent; exports.rankCommands = _chunkKIJIONZFcjs.rankCommands; exports.shortcutCode = _chunkQJVOJUTDcjs.shortcutCode; exports.toShortcutBindings = _chunkQJVOJUTDcjs.toShortcutBindings;
100
+ exports.CommandRegistry = _chunkKIJIONZFcjs.CommandRegistry; exports.CommandRegistryError = _chunkKIJIONZFcjs.CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS = _chunkQEVLRLUNcjs.DEFAULT_HISTORY_SHORTCUTS; exports.DEFAULT_RECENT_LIMIT = _chunkKIJIONZFcjs.DEFAULT_RECENT_LIMIT; exports.PLATFORMS = _chunkQJVOJUTDcjs.PLATFORMS; exports.ShortcutMap = _chunkQJVOJUTDcjs.ShortcutMap; exports.chordToString = _chunkQJVOJUTDcjs.chordToString; exports.codeFromKey = _chunkQJVOJUTDcjs.codeFromKey; exports.codeToKeyText = _chunkQJVOJUTDcjs.codeToKeyText; exports.createArrangeCommands = _chunkQEVLRLUNcjs.createArrangeCommands; exports.createCanvasAnimationCommands = _chunkQEUI6OGEcjs.createCanvasAnimationCommands; exports.createCommandPaletteController = _chunkQEUI6OGEcjs.createCommandPaletteController; exports.createCommandRegistry = _chunkKIJIONZFcjs.createCommandRegistry; exports.createCommandToolProvider = _chunkKIJIONZFcjs.createCommandToolProvider; exports.createComponentCommands = _chunkQEVLRLUNcjs.createComponentCommands; exports.createDrawCommands = _chunkQEVLRLUNcjs.createDrawCommands; exports.createFormatCommands = _chunkVCL7CB56cjs.createFormatCommands; exports.createHistoryCommands = _chunkQEVLRLUNcjs.createHistoryCommands; exports.createShapeCommands = _chunkQEVLRLUNcjs.createShapeCommands; exports.createSpreadsheetCommands = _chunkQEVLRLUNcjs.createSpreadsheetCommands; exports.defineCommand = _chunkKIJIONZFcjs.defineCommand; exports.detectPlatform = _chunkQJVOJUTDcjs.detectPlatform; exports.effectiveChord = _chunkQJVOJUTDcjs.effectiveChord; exports.effectiveChordKey = _chunkQJVOJUTDcjs.effectiveChordKey; exports.eventCode = _chunkQJVOJUTDcjs.eventCode; exports.exactBonus = _chunkKIJIONZFcjs.exactBonus; exports.formatCommandsFor = _chunkVCL7CB56cjs.formatCommandsFor; exports.formatShortcut = _chunkQJVOJUTDcjs.formatShortcut; exports.fuzzyMatch = _chunkKIJIONZFcjs.fuzzyMatch; exports.fuzzyScore = _chunkKIJIONZFcjs.fuzzyScore; exports.hasVariantCommands = _chunkQEVLRLUNcjs.hasVariantCommands; exports.isEditableEventTarget = _chunkQJVOJUTDcjs.isEditableEventTarget; exports.keyToCode = _chunkQJVOJUTDcjs.keyToCode; exports.matchHistoryShortcut = _chunkQEVLRLUNcjs.matchHistoryShortcut; exports.matchPaletteHotkey = _chunkQEUI6OGEcjs.matchPaletteHotkey; exports.normalizeChord = _chunkQJVOJUTDcjs.normalizeChord; exports.parseChord = _chunkQJVOJUTDcjs.parseChord; exports.planFreehandPlayback = _chunkQEVLRLUNcjs.planFreehandPlayback; exports.pushRecent = _chunkKIJIONZFcjs.pushRecent; exports.rankCommands = _chunkKIJIONZFcjs.rankCommands; exports.shortcutCode = _chunkQJVOJUTDcjs.shortcutCode; exports.toShortcutBindings = _chunkQJVOJUTDcjs.toShortcutBindings;
@@ -1,3 +1,8 @@
1
+ import {
2
+ createCanvasAnimationCommands,
3
+ createCommandPaletteController,
4
+ matchPaletteHotkey
5
+ } from "../chunk-CHZYVNXZ.js";
1
6
  import {
2
7
  CommandRegistry,
3
8
  CommandRegistryError,
@@ -49,327 +54,6 @@ import {
49
54
  } from "../chunk-NZ3CTY7K.js";
50
55
  import "../chunk-IVSWRVB4.js";
51
56
  import "../chunk-V2ZCJRDM.js";
52
-
53
- // src/commands/paletteController.ts
54
- function createCommandPaletteController(registry, options = {}) {
55
- const listeners = /* @__PURE__ */ new Set();
56
- let open = false;
57
- let query = "";
58
- let activeIndex = 0;
59
- let recents = [...options.recents ?? []];
60
- let lastResult = null;
61
- let state;
62
- const context = () => {
63
- const c = options.context;
64
- if (c === void 0) return registry.context;
65
- return typeof c === "function" ? c() : c;
66
- };
67
- const scope = () => typeof options.scope === "function" ? options.scope() : options.scope;
68
- function computeItems() {
69
- if (!open) return [];
70
- const entries = registry.list({ scope: scope(), context: context() });
71
- const platform = options.platform ?? registry.shortcuts.platform;
72
- return rankCommands(query, entries, {
73
- recents,
74
- recentLimit: options.recentLimit,
75
- limit: options.limit ?? 50
76
- }).map((ranked) => ({
77
- ...ranked,
78
- id: ranked.entry.id,
79
- label: ranked.entry.label,
80
- ...ranked.entry.group !== void 0 ? { group: ranked.entry.group } : {},
81
- ...ranked.entry.shortcuts[0] ? { shortcut: formatShortcut(ranked.entry.shortcuts[0], platform) } : {},
82
- enabled: ranked.entry.enabled,
83
- ...ranked.entry.disabledReason ? { disabledReason: ranked.entry.disabledReason } : {}
84
- }));
85
- }
86
- function update() {
87
- const items = computeItems();
88
- activeIndex = items.length === 0 ? 0 : Math.min(Math.max(activeIndex, 0), items.length - 1);
89
- state = { open, query, activeIndex, items, recents, lastResult };
90
- for (const listener of Array.from(listeners)) listener(state);
91
- }
92
- state = { open, query, activeIndex, items: [], recents, lastResult };
93
- let unsubscribeRegistry = null;
94
- const onRegistryChange = () => {
95
- if (open) update();
96
- };
97
- const controller = {
98
- getState: () => state,
99
- subscribe(listener) {
100
- listeners.add(listener);
101
- unsubscribeRegistry ??= registry.subscribe(onRegistryChange);
102
- if (open) update();
103
- return () => {
104
- listeners.delete(listener);
105
- if (listeners.size === 0) {
106
- unsubscribeRegistry?.();
107
- unsubscribeRegistry = null;
108
- }
109
- };
110
- },
111
- setOpen(next) {
112
- if (next === open) return;
113
- open = next;
114
- query = "";
115
- activeIndex = 0;
116
- update();
117
- },
118
- toggle() {
119
- controller.setOpen(!open);
120
- },
121
- setQuery(next) {
122
- if (next === query) return;
123
- query = next;
124
- activeIndex = 0;
125
- update();
126
- },
127
- setActiveIndex(index) {
128
- activeIndex = index;
129
- update();
130
- },
131
- /** Moves the active row by `delta`, wrapping around. */
132
- move(delta) {
133
- const n = state.items.length;
134
- if (n === 0) return;
135
- activeIndex = ((activeIndex + delta) % n + n) % n;
136
- update();
137
- },
138
- /** Runs a command by id, closes the palette and records it as recent. Disabled commands do nothing. */
139
- run(id) {
140
- if (!registry.isEnabled(id, void 0, context()).enabled) return null;
141
- open = false;
142
- query = "";
143
- activeIndex = 0;
144
- recents = pushRecent(recents, id, options.recentLimit ?? DEFAULT_RECENT_LIMIT);
145
- options.onRecentsChange?.(recents);
146
- const result = registry.execute(id, void 0, context());
147
- lastResult = result;
148
- update();
149
- options.onRun?.(result);
150
- return result;
151
- },
152
- runActive() {
153
- const item = state.items[state.activeIndex];
154
- return item ? controller.run(item.id) : null;
155
- },
156
- /**
157
- * Keyboard handling for the palette input: ArrowUp/ArrowDown (wrap), Home/End,
158
- * Enter (run the active row) and Escape (close). Returns whether it handled the key.
159
- */
160
- handleKeyDown(event) {
161
- if (!open) return false;
162
- switch (event.key) {
163
- case "ArrowDown":
164
- controller.move(1);
165
- break;
166
- case "ArrowUp":
167
- controller.move(-1);
168
- break;
169
- case "Home":
170
- controller.setActiveIndex(0);
171
- break;
172
- case "End":
173
- controller.setActiveIndex(state.items.length - 1);
174
- break;
175
- case "Enter":
176
- controller.runActive();
177
- break;
178
- case "Escape":
179
- controller.setOpen(false);
180
- break;
181
- default:
182
- return false;
183
- }
184
- event.preventDefault?.();
185
- return true;
186
- },
187
- /** Re-reads commands and enablement. */
188
- refresh() {
189
- update();
190
- },
191
- destroy() {
192
- unsubscribeRegistry?.();
193
- unsubscribeRegistry = null;
194
- listeners.clear();
195
- }
196
- };
197
- return controller;
198
- }
199
- function matchPaletteHotkey(event, hotkey, platform) {
200
- const map = new ShortcutMap([{ command: "palette", chord: hotkey, allowInEditable: true }], platform ? { platform } : {});
201
- return map.resolve(event) !== null;
202
- }
203
-
204
- // src/commands/animation.ts
205
- var EASING_DESCRIPTION = "Easing preset (linear, ease, ease-in, ease-out, ease-in-out, ease-in-back, ease-out-back, spring, hold) or a CSS cubic-bezier(x1, y1, x2, y2).";
206
- var VALUES = {
207
- type: "object",
208
- description: 'Property \u2192 value, e.g. {"x": 200, "opacity": 0.5, "fill": "#ff0000"}. Properties: x, y, width, height, rotation (degrees), scale, opacity (0\u20131), fill, stroke, strokeWidth, cornerRadius, motionPath (0\u20131).',
209
- additionalProperties: { type: ["number", "string"] }
210
- };
211
- function createCanvasAnimationCommands(controller, options = {}) {
212
- const prefix = options.prefix ?? "canvas.animation.";
213
- const group = options.group ?? "Animation";
214
- const scope = options.scope === null ? void 0 : options.scope ?? "canvas";
215
- const base = { group, ...scope ? { scope } : {} };
216
- const hasSelection = () => controller.getState().selection.length > 0 ? true : "Select keyframes first.";
217
- return [
218
- {
219
- ...base,
220
- id: `${prefix}togglePlay`,
221
- label: "Play / Pause Animation",
222
- keywords: ["play", "pause", "preview", "timeline"],
223
- description: "Plays or pauses the canvas animation from the playhead.",
224
- run: () => {
225
- controller.toggle();
226
- return { playing: controller.getState().playing, time: controller.getState().time };
227
- }
228
- },
229
- {
230
- ...base,
231
- id: `${prefix}play`,
232
- label: "Play Animation",
233
- keywords: ["preview", "timeline"],
234
- enabled: () => controller.getState().playing ? "Already playing." : true,
235
- run: () => controller.play()
236
- },
237
- {
238
- ...base,
239
- id: `${prefix}pause`,
240
- label: "Pause Animation",
241
- enabled: () => controller.getState().playing ? true : "Not playing.",
242
- run: () => controller.pause()
243
- },
244
- {
245
- ...base,
246
- id: `${prefix}stop`,
247
- label: "Stop Animation",
248
- keywords: ["rewind", "reset"],
249
- description: "Stops playback and returns to the start.",
250
- run: () => controller.stop()
251
- },
252
- {
253
- ...base,
254
- id: `${prefix}seek`,
255
- label: "Go to Time\u2026",
256
- keywords: ["playhead", "scrub", "time"],
257
- description: "Moves the playhead.",
258
- params: {
259
- type: "object",
260
- properties: { time: { type: "number", minimum: 0, description: "Time in milliseconds." } },
261
- required: ["time"]
262
- },
263
- run: (_ctx, params) => {
264
- controller.seek(params.time);
265
- return { time: controller.getState().time };
266
- }
267
- },
268
- {
269
- ...base,
270
- id: `${prefix}addKeyframe`,
271
- label: "Add Keyframe at Playhead",
272
- keywords: ["key", "animate", "record"],
273
- description: "Keys the selected nodes (or `ids`) at the playhead (or `time`): their animated properties, `properties`, or position.",
274
- params: {
275
- type: "object",
276
- properties: {
277
- ids: { type: "array", items: { type: "string" }, description: "Node ids (default: selected nodes)." },
278
- properties: { type: "array", items: { type: "string" }, description: "Properties to key (default: animated ones, or x and y)." },
279
- time: { type: "number", minimum: 0, description: "Time in ms (default: the playhead)." }
280
- }
281
- },
282
- run: (_ctx, params) => controller.addKeyframe(params?.ids, params?.properties, params?.time)
283
- },
284
- {
285
- ...base,
286
- id: `${prefix}deleteKeyframes`,
287
- label: "Delete Keyframes",
288
- keywords: ["remove", "clear"],
289
- enabled: hasSelection,
290
- run: () => controller.deleteKeyframes()
291
- },
292
- {
293
- ...base,
294
- id: `${prefix}setEasing`,
295
- label: "Set Keyframe Easing\u2026",
296
- keywords: ["interpolation", "ease", "bezier", "spring", "hold", "curve"],
297
- description: "Sets the easing of the segments leaving the selected keyframes.",
298
- params: {
299
- type: "object",
300
- properties: { easing: { type: "string", description: EASING_DESCRIPTION } },
301
- required: ["easing"]
302
- },
303
- enabled: hasSelection,
304
- run: (_ctx, params) => controller.setEasing(params.easing)
305
- },
306
- {
307
- ...base,
308
- id: `${prefix}toggleRecord`,
309
- label: "Toggle Record Mode",
310
- keywords: ["auto key", "record", "keyframe"],
311
- description: "In record mode, changing a property at the playhead keys it.",
312
- run: () => {
313
- controller.toggleRecording();
314
- return { recording: controller.getState().recording };
315
- }
316
- },
317
- {
318
- ...base,
319
- id: `${prefix}nextKeyframe`,
320
- label: "Next Keyframe",
321
- keywords: ["jump", "navigate"],
322
- run: () => controller.nextKeyframe()
323
- },
324
- {
325
- ...base,
326
- id: `${prefix}previousKeyframe`,
327
- label: "Previous Keyframe",
328
- keywords: ["jump", "navigate"],
329
- run: () => controller.previousKeyframe()
330
- },
331
- {
332
- ...base,
333
- id: `${prefix}animateNode`,
334
- label: "Animate Node\u2026",
335
- keywords: ["tween", "transition", "move", "fade"],
336
- description: "Animates a node from `from` (default: its current values) to `to` over `duration` ms, starting at `delay` ms.",
337
- params: {
338
- type: "object",
339
- properties: {
340
- nodeId: { type: "string", description: "Node to animate." },
341
- to: VALUES,
342
- from: VALUES,
343
- duration: { type: "number", exclusiveMinimum: 0, description: "Duration in ms (default 1000)." },
344
- delay: { type: "number", minimum: 0, description: "Start time in ms (default 0)." },
345
- easing: { type: "string", description: EASING_DESCRIPTION }
346
- },
347
- required: ["nodeId", "to"]
348
- },
349
- run: (_ctx, params) => controller.animateNode(params.nodeId, {
350
- to: params.to,
351
- ...params.from ? { from: params.from } : {},
352
- ...params.duration !== void 0 ? { duration: params.duration } : {},
353
- ...params.delay !== void 0 ? { delay: params.delay } : {},
354
- ...params.easing !== void 0 ? { easing: params.easing } : {}
355
- })
356
- },
357
- {
358
- ...base,
359
- id: `${prefix}exportCss`,
360
- label: "Export Animation as CSS",
361
- keywords: ["keyframes", "css", "web animations"],
362
- description: "Returns CSS @keyframes for a node's animation.",
363
- readOnly: true,
364
- params: {
365
- type: "object",
366
- properties: { nodeId: { type: "string" } },
367
- required: ["nodeId"]
368
- },
369
- run: (_ctx, params) => controller.exportCss(params.nodeId)
370
- }
371
- ];
372
- }
373
57
  export {
374
58
  CommandRegistry,
375
59
  CommandRegistryError,