@pixerate/editor-svelte 0.21.0 → 0.22.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.
Files changed (49) hide show
  1. package/README.md +2 -1
  2. package/dist/canvas/CanvasGuidesLayer.svelte +32 -2
  3. package/dist/canvas/CanvasGuidesLayer.svelte.d.ts +2 -0
  4. package/dist/canvas/CanvasGuidesLayer.svelte.d.ts.map +1 -1
  5. package/dist/canvas/createCanvasArrange.svelte.d.ts +16 -1
  6. package/dist/canvas/createCanvasArrange.svelte.d.ts.map +1 -1
  7. package/dist/canvas/createCanvasArrange.svelte.js +19 -2
  8. package/dist/canvas/createCanvasMeasure.svelte.d.ts +53 -0
  9. package/dist/canvas/createCanvasMeasure.svelte.d.ts.map +1 -0
  10. package/dist/canvas/createCanvasMeasure.svelte.js +80 -0
  11. package/dist/canvas/index.d.ts +2 -0
  12. package/dist/canvas/index.d.ts.map +1 -1
  13. package/dist/canvas/index.js +3 -0
  14. package/dist/commands/CommandPalette.svelte +129 -0
  15. package/dist/commands/CommandPalette.svelte.d.ts +13 -0
  16. package/dist/commands/CommandPalette.svelte.d.ts.map +1 -0
  17. package/dist/commands/commandShortcuts.svelte.d.ts +30 -0
  18. package/dist/commands/commandShortcuts.svelte.d.ts.map +1 -0
  19. package/dist/commands/commandShortcuts.svelte.js +37 -0
  20. package/dist/commands/index.d.ts +7 -0
  21. package/dist/commands/index.d.ts.map +1 -0
  22. package/dist/commands/index.js +3 -0
  23. package/dist/commands/palette.svelte.d.ts +34 -0
  24. package/dist/commands/palette.svelte.d.ts.map +1 -0
  25. package/dist/commands/palette.svelte.js +61 -0
  26. package/dist/history/createHistoryShortcuts.d.ts +1 -1
  27. package/dist/history/createHistoryShortcuts.d.ts.map +1 -1
  28. package/dist/history/createHistoryShortcuts.js +10 -32
  29. package/dist/history/history.svelte.d.ts +13 -4
  30. package/dist/history/history.svelte.d.ts.map +1 -1
  31. package/dist/history/history.svelte.js +10 -0
  32. package/dist/history/historyDirty.svelte.d.ts +31 -0
  33. package/dist/history/historyDirty.svelte.d.ts.map +1 -0
  34. package/dist/history/historyDirty.svelte.js +30 -0
  35. package/dist/history/index.d.ts +1 -0
  36. package/dist/history/index.d.ts.map +1 -1
  37. package/dist/history/index.js +1 -0
  38. package/dist/image-editor/ImageEditor.svelte +39 -0
  39. package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -1
  40. package/dist/image-editor/imageEditorState.svelte.d.ts +2 -0
  41. package/dist/image-editor/imageEditorState.svelte.d.ts.map +1 -1
  42. package/dist/image-editor/imageEditorState.svelte.js +4 -0
  43. package/dist/index.d.ts +3 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +2 -1
  46. package/dist/spreadsheet/SpreadsheetEditor.svelte +3 -2
  47. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -1
  48. package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -1
  49. package/package.json +10 -2
package/README.md CHANGED
@@ -73,9 +73,10 @@ Requires **Svelte 5** (the components use runes). Components ship as `.svelte` s
73
73
 
74
74
  | Import | Exports |
75
75
  | :--- | :--- |
76
- | `@pixerate/editor-svelte` | `EditableTextNodeEditor`, `BubbleMenu`, `TemplateRenderer`, `initiateEditor`, `createReactiveEditor`, `createHistory`, `createHistoryShortcuts`, `navigationGuard` (action), `createNavigationGuard`, `SpreadsheetEditor`, `FormulaBar`, `FormulaHints`, `createReactiveSpreadsheet`, `DirtyTracker` |
76
+ | `@pixerate/editor-svelte` | `EditableTextNodeEditor`, `BubbleMenu`, `TemplateRenderer`, `initiateEditor`, `createReactiveEditor`, `createHistory`, `createHistoryDirty`, `createHistoryShortcuts`, `navigationGuard` (action), `createNavigationGuard`, `SpreadsheetEditor`, `FormulaBar`, `FormulaHints`, `createReactiveSpreadsheet`, `DirtyTracker` |
77
77
  | `@pixerate/editor-svelte/spreadsheet` | `SpreadsheetEditor`, `FormulaBar`, `FormulaHints`, `SpreadsheetContextMenu`, `SpreadsheetGroupRow`, `createReactiveSpreadsheet` (also re-exported from the root entry) |
78
78
  | `@pixerate/editor-svelte/image-editor` | `ImageEditor`, `createReactiveImageEditor`: crop, rotate/flip, adjustments, annotations, depth masks, and `onInpaint` / `onRemoveBackground` AI hooks |
79
+ | `@pixerate/editor-svelte/commands` | `CommandPalette`, `createCommandPalette` (`hotkey: "Mod+K"`; call `destroy()` when done), `createCommandShortcuts`, `useRegisterCommands` over a `CommandRegistry` from `@pixerate/editor/commands` (also re-exported from the root entry) |
79
80
  | `@pixerate/editor-svelte/canvas` | Runes for `@xyflow/svelte`: `createCanvasGraph`, `createCanvasClipboard`, `createCanvasDocking`, `createCanvasShortcuts`, `createCanvasInteractions`, `createCanvasExplosion`, `createCanvasNodeSync`, `createCanvasMultiDrag`, `createStreamingCanvas`, `AgentPresenceLayer`, `FloatingHorizontalScrollbar`, plus layout helpers |
80
81
 
81
82
  Prop types are exported alongside each component, for example `EditableTextNodeEditorProps`, `BubbleMenuProps`, `ImageEditorProps` and `SpreadsheetEditorProps`.
@@ -10,6 +10,8 @@
10
10
  color?: string;
11
11
  /** Colour of equal-spacing guides. */
12
12
  spacingColor?: string;
13
+ /** Colour of measuring lines, their labels and extension lines. */
14
+ measureColor?: string;
13
15
  class?: string;
14
16
  }
15
17
 
@@ -18,6 +20,7 @@
18
20
  viewport = { x: 0, y: 0, zoom: 1 },
19
21
  color = '#f59e0b',
20
22
  spacingColor = '#ec4899',
23
+ measureColor = '#ef4444',
21
24
  class: className = ''
22
25
  }: Props = $props();
23
26
 
@@ -42,11 +45,38 @@
42
45
  y1={a.y}
43
46
  x2={b.x}
44
47
  y2={b.y}
45
- stroke={guide.kind === 'spacing' ? spacingColor : color}
48
+ stroke={guide.kind === 'measure' || guide.kind === 'extension'
49
+ ? measureColor
50
+ : guide.kind === 'spacing'
51
+ ? spacingColor
52
+ : color}
46
53
  stroke-width="1"
47
- stroke-dasharray={guide.kind === 'centre' ? '4 3' : undefined}
54
+ stroke-dasharray={guide.kind === 'centre' ? '4 3' : guide.kind === 'extension' ? '3 3' : undefined}
48
55
  shape-rendering="crispEdges"
49
56
  />
50
57
  {/each}
58
+ {#each guides as guide, i (i)}
59
+ {#if guide.label}
60
+ {@const mid = toScreen((guide.x1 + guide.x2) / 2, (guide.y1 + guide.y2) / 2)}
61
+ {@const vertical = guide.orientation === 'vertical'}
62
+ {@const width = guide.label.length * 6.5 + 8}
63
+ <!-- Labels sit beside vertical lines and below horizontal ones. -->
64
+ <g
65
+ class="pixerate-canvas-guides__label"
66
+ data-label={guide.label}
67
+ transform="translate({vertical ? mid.x + 4 : mid.x - width / 2} {vertical ? mid.y - 8 : mid.y + 4})"
68
+ >
69
+ <rect {width} height="16" rx="3" fill={measureColor} />
70
+ <text
71
+ x={width / 2}
72
+ y="11.5"
73
+ text-anchor="middle"
74
+ font-size="11"
75
+ font-family="system-ui, sans-serif"
76
+ fill="#fff">{guide.label}</text
77
+ >
78
+ </g>
79
+ {/if}
80
+ {/each}
51
81
  </svg>
52
82
  {/if}
@@ -8,6 +8,8 @@ interface Props {
8
8
  color?: string;
9
9
  /** Colour of equal-spacing guides. */
10
10
  spacingColor?: string;
11
+ /** Colour of measuring lines, their labels and extension lines. */
12
+ measureColor?: string;
11
13
  class?: string;
12
14
  }
13
15
  declare const CanvasGuidesLayer: import("svelte").Component<Props, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasGuidesLayer.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/CanvasGuidesLayer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGxE,UAAU,KAAK;IACd,kEAAkE;IAClE,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AA+BF,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"CanvasGuidesLayer.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/CanvasGuidesLayer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGxE,UAAU,KAAK;IACd,kEAAkE;IAClE,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAgDF,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
@@ -16,10 +16,21 @@ export interface CreateCanvasArrangeOptions<TNode extends CanvasNode = CanvasNod
16
16
  * Wire snapping to SvelteFlow with `onnodedragstart={() => arrange.beginDrag()}`,
17
17
  * `onnodedrag={({ nodes }) => arrange.drag(nodes.map((n) => n.id))}` and
18
18
  * `onnodedragstop={() => arrange.endDrag()}`, and render `arrange.guides` with
19
- * `<CanvasGuidesLayer>`.
19
+ * `<CanvasGuidesLayer>`. Snap resizes with `<NodeResizer {...arrange.resizerHandlers(id)} />`.
20
20
  */
21
21
  export declare function createCanvasArrange<TNode extends CanvasNode = CanvasNode>(options: CreateCanvasArrangeOptions<TNode>): {
22
22
  guides: GuideLine[];
23
+ /**
24
+ * Resize snapping for SvelteFlow's `<NodeResizer>` / `<NodeResizeControl>`:
25
+ * `<NodeResizer {...arrange.resizerHandlers(id)} />`. The resizer writes the raw size
26
+ * to the nodes after `onResize`, so snapping runs a microtask later and writes the
27
+ * snapped box back. Locked nodes snap back to their starting box.
28
+ */
29
+ resizerHandlers(id: string): {
30
+ onResizeStart: () => void;
31
+ onResize: () => void;
32
+ onResizeEnd: () => void;
33
+ };
23
34
  apply: (name: string, updates: import("@pixerate/editor/canvas").CanvasNodeUpdate[]) => import("@pixerate/editor/canvas").CanvasNodeUpdate[];
24
35
  align(edge: import("@pixerate/editor/canvas").AlignEdge, ids?: Iterable<string>, alignOptions?: import("@pixerate/editor/canvas").AlignNodesOptions): import("@pixerate/editor/canvas").CanvasNodeUpdate[];
25
36
  distribute(axis: import("@pixerate/editor/canvas").DistributeAxis, mode?: import("@pixerate/editor/canvas").DistributeMode, ids?: Iterable<string>, distributeOptions?: import("@pixerate/editor/canvas").DistributeNodesOptions): import("@pixerate/editor/canvas").CanvasNodeUpdate[];
@@ -44,6 +55,10 @@ export declare function createCanvasArrange<TNode extends CanvasNode = CanvasNod
44
55
  beginDrag(ids?: Iterable<string>): void;
45
56
  drag(ids?: Iterable<string>): import("@pixerate/editor/canvas").SnapNodeDragResult | null;
46
57
  snapPositionChanges<TChange extends import("@pixerate/editor/canvas").PositionChangeLike>(changes: TChange[]): TChange[];
58
+ beginResize(id: string): void;
59
+ resize(id: string, handle?: import("@pixerate/editor/canvas").ResizeHandle): import("@pixerate/editor/canvas").SnapNodeResizeResult | null;
60
+ endResize(): void;
61
+ snapResizeChanges<TChange extends import("@pixerate/editor/canvas").PositionChangeLike>(changes: TChange[]): TChange[];
47
62
  endDrag(): void;
48
63
  };
49
64
  export type CanvasArrange<TNode extends CanvasNode = CanvasNode> = ReturnType<typeof createCanvasArrange<TNode>>;
@@ -1 +1 @@
1
- {"version":3,"file":"createCanvasArrange.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasArrange.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACnC,KAAK,SAAS,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,KAAK,WAAW,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;AAEvD,MAAM,WAAW,0BAA0B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,CAChF,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,gBAAgB,CAAC;IACrE,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EACxE,OAAO,EAAE,0BAA0B,CAAC,KAAK,CAAC;;;;;;;sBA2D2rlD,CAAC;sBAAiE,CAAC;sBAAiE,CAAC;oBAA+D,CAAC;cAAyD,CAAC;gBAAiD,CAAC;;;;;;;;;0BAA8tC,CAAC;;;;;;EAxCrvoD;AAED,MAAM,MAAM,aAAa,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;AAEjH,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE;QAAE,SAAS,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,OAAO,CAAA;KAAE,CAAC;IACjE,uEAAuE;IACvE,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IAC1D,aAAa,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,6BAA6B,GAAG,MAAM,IAAI,CAqB/F"}
1
+ {"version":3,"file":"createCanvasArrange.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasArrange.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACnC,KAAK,SAAS,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,KAAK,WAAW,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC;AAEvD,MAAM,WAAW,0BAA0B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,CAChF,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,gBAAgB,CAAC;IACrE,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EACxE,OAAO,EAAE,0BAA0B,CAAC,KAAK,CAAC;;IAkBzC;;;;;OAKG;wBACiB,MAAM;;;;;;;;;;sBAoD+j/C,CAAC;sBAAiE,CAAC;sBAAiE,CAAC;oBAA+D,CAAC;cAAyD,CAAC;gBAAiD,CAAC;;;;;;;;;0BAA8tC,CAAC;;;;;;;;;;EAxC1miD;AAED,MAAM,MAAM,aAAa,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;AAEjH,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE;QAAE,SAAS,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,OAAO,CAAA;KAAE,CAAC;IACjE,uEAAuE;IACvE,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IAC1D,aAAa,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,6BAA6B,GAAG,MAAM,IAAI,CAqB/F"}
@@ -9,7 +9,7 @@ import { createCanvasArrangeController, matchArrangeShortcut } from '@pixerate/e
9
9
  * Wire snapping to SvelteFlow with `onnodedragstart={() => arrange.beginDrag()}`,
10
10
  * `onnodedrag={({ nodes }) => arrange.drag(nodes.map((n) => n.id))}` and
11
11
  * `onnodedragstop={() => arrange.endDrag()}`, and render `arrange.guides` with
12
- * `<CanvasGuidesLayer>`.
12
+ * `<CanvasGuidesLayer>`. Snap resizes with `<NodeResizer {...arrange.resizerHandlers(id)} />`.
13
13
  */
14
14
  export function createCanvasArrange(options) {
15
15
  let guides = $state.raw([]);
@@ -22,9 +22,26 @@ export function createCanvasArrange(options) {
22
22
  });
23
23
  return {
24
24
  ...controller,
25
- /** Guide segments (flow coordinates) for the active drag; empty otherwise. */
25
+ /** Guide segments (flow coordinates) for the active drag or resize; empty otherwise. */
26
26
  get guides() {
27
27
  return guides;
28
+ },
29
+ /**
30
+ * Resize snapping for SvelteFlow's `<NodeResizer>` / `<NodeResizeControl>`:
31
+ * `<NodeResizer {...arrange.resizerHandlers(id)} />`. The resizer writes the raw size
32
+ * to the nodes after `onResize`, so snapping runs a microtask later and writes the
33
+ * snapped box back. Locked nodes snap back to their starting box.
34
+ */
35
+ resizerHandlers(id) {
36
+ return {
37
+ onResizeStart: () => controller.beginResize(id),
38
+ onResize: () => {
39
+ queueMicrotask(() => controller.resize(id));
40
+ },
41
+ onResizeEnd: () => {
42
+ queueMicrotask(() => controller.endResize());
43
+ }
44
+ };
28
45
  }
29
46
  };
30
47
  }
@@ -0,0 +1,53 @@
1
+ import { type NodeRectOptions } from '@pixerate/editor/canvas';
2
+ import type { CanvasNode } from './types.js';
3
+ export interface CreateCanvasMeasureOptions<TNode extends CanvasNode = CanvasNode> {
4
+ getNodes: () => TNode[];
5
+ /** Ids measured from (default: nodes with `selected: true`). */
6
+ getSelectedIds?: () => string[];
7
+ /** Turns measuring off (default `true`). Read reactively. */
8
+ enabled?: boolean | (() => boolean);
9
+ /** Measure only while Alt / Option is held (default `true`); `false` always measures. */
10
+ requireModifier?: boolean;
11
+ rectOptions?: NodeRectOptions;
12
+ }
13
+ /**
14
+ * Headless Svelte 5 rune for Alt-hover distance measuring: hold Alt / Option and hover a
15
+ * node to see red distance lines with labels from the selection to it (or to the selection's
16
+ * parent when hovering the selection or empty space).
17
+ *
18
+ * Wire it with `$effect(() => measure.listen())`, `onnodepointerenter={measure.onnodepointerenter}`
19
+ * and `onnodepointerleave={measure.onnodepointerleave}` on `<SvelteFlow>`, and render
20
+ * `measure.guides` with `<CanvasGuidesLayer>` (concatenate with `arrange.guides` to share one).
21
+ */
22
+ export declare function createCanvasMeasure<TNode extends CanvasNode = CanvasNode>(options: CreateCanvasMeasureOptions<TNode>): {
23
+ /** Measuring lines (flow coordinates) for `<CanvasGuidesLayer>`. */
24
+ readonly guides: import("@pixerate/editor/canvas").MeasureGuide[];
25
+ /** The box measured to (outline it), or `null`. */
26
+ readonly target: import("@pixerate/editor/canvas").Rect | null;
27
+ /** Whether measuring is showing. */
28
+ readonly active: boolean;
29
+ readonly hoveredId: string | null;
30
+ setHovered(id: string | null): void;
31
+ /** Sets the modifier state by hand (e.g. from a toolbar toggle). */
32
+ setModifier(held: boolean): void;
33
+ onnodepointerenter: ({ node, event }: {
34
+ node: {
35
+ id: string;
36
+ };
37
+ event?: {
38
+ altKey?: boolean;
39
+ };
40
+ }) => void;
41
+ onnodepointerleave: ({ node }: {
42
+ node: {
43
+ id: string;
44
+ };
45
+ }) => void;
46
+ /**
47
+ * Tracks the Alt key on `target` (default `window`) and resets it when the window
48
+ * loses focus. Returns a cleanup function.
49
+ */
50
+ listen(target?: HTMLElement | Window | null): () => void;
51
+ };
52
+ export type CanvasMeasure = ReturnType<typeof createCanvasMeasure>;
53
+ //# sourceMappingURL=createCanvasMeasure.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasMeasure.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasMeasure.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,eAAe,EACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,0BAA0B,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU;IAChF,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;IACxB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAChC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACpC,yFAAyF;IACzF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,eAAe,CAAC;CAC9B;AAID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,0BAA0B,CAAC,KAAK,CAAC;IAcnH,oEAAoE;;IAIpE,mDAAmD;;IAInD,oCAAoC;;;mBAOrB,MAAM,GAAG,IAAI;IAG5B,oEAAoE;sBAClD,OAAO;0CAGa;QAAE,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,KAAK,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE;mCAI7D;QAAE,IAAI,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE;IAGvD;;;OAGG;oBACY,WAAW,GAAG,MAAM,GAAG,IAAI,GAAmD,MAAM,IAAI;EAmBxG;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { isMeasureModifierHeld, measureSelection } from '@pixerate/editor/canvas';
2
+ const EMPTY = { guides: [], target: null, selection: null };
3
+ /**
4
+ * Headless Svelte 5 rune for Alt-hover distance measuring: hold Alt / Option and hover a
5
+ * node to see red distance lines with labels from the selection to it (or to the selection's
6
+ * parent when hovering the selection or empty space).
7
+ *
8
+ * Wire it with `$effect(() => measure.listen())`, `onnodepointerenter={measure.onnodepointerenter}`
9
+ * and `onnodepointerleave={measure.onnodepointerleave}` on `<SvelteFlow>`, and render
10
+ * `measure.guides` with `<CanvasGuidesLayer>` (concatenate with `arrange.guides` to share one).
11
+ */
12
+ export function createCanvasMeasure(options) {
13
+ let hoveredId = $state(null);
14
+ let modifier = $state(false);
15
+ const enabled = () => (typeof options.enabled === 'function' ? options.enabled() : options.enabled !== false);
16
+ const active = $derived(enabled() && (options.requireModifier === false || modifier));
17
+ const result = $derived.by(() => {
18
+ if (!active)
19
+ return EMPTY;
20
+ const nodes = options.getNodes();
21
+ const ids = options.getSelectedIds?.() ?? nodes.filter((n) => n.selected).map((n) => n.id);
22
+ return measureSelection(nodes, ids, hoveredId, options.rectOptions);
23
+ });
24
+ return {
25
+ /** Measuring lines (flow coordinates) for `<CanvasGuidesLayer>`. */
26
+ get guides() {
27
+ return result.guides;
28
+ },
29
+ /** The box measured to (outline it), or `null`. */
30
+ get target() {
31
+ return result.target;
32
+ },
33
+ /** Whether measuring is showing. */
34
+ get active() {
35
+ return active;
36
+ },
37
+ get hoveredId() {
38
+ return hoveredId;
39
+ },
40
+ setHovered(id) {
41
+ hoveredId = id;
42
+ },
43
+ /** Sets the modifier state by hand (e.g. from a toolbar toggle). */
44
+ setModifier(held) {
45
+ modifier = held;
46
+ },
47
+ onnodepointerenter: ({ node, event }) => {
48
+ hoveredId = node.id;
49
+ if (event && typeof event.altKey === 'boolean')
50
+ modifier = event.altKey;
51
+ },
52
+ onnodepointerleave: ({ node }) => {
53
+ if (hoveredId === node.id)
54
+ hoveredId = null;
55
+ },
56
+ /**
57
+ * Tracks the Alt key on `target` (default `window`) and resets it when the window
58
+ * loses focus. Returns a cleanup function.
59
+ */
60
+ listen(target = typeof window !== 'undefined' ? window : null) {
61
+ if (!target)
62
+ return () => { };
63
+ const onKey = (event) => {
64
+ modifier = isMeasureModifierHeld(event);
65
+ };
66
+ const onBlur = () => {
67
+ modifier = false;
68
+ };
69
+ target.addEventListener('keydown', onKey);
70
+ target.addEventListener('keyup', onKey);
71
+ const win = typeof window !== 'undefined' ? window : null;
72
+ win?.addEventListener('blur', onBlur);
73
+ return () => {
74
+ target.removeEventListener('keydown', onKey);
75
+ target.removeEventListener('keyup', onKey);
76
+ win?.removeEventListener('blur', onBlur);
77
+ };
78
+ }
79
+ };
80
+ }
@@ -17,6 +17,8 @@ export { createStreamingCanvas, type CreateStreamingCanvasOptions } from './crea
17
17
  export { createCanvasArrange, createCanvasArrangeShortcuts, type CanvasArrange, type CreateCanvasArrangeOptions, type CanvasArrangeShortcutsOptions } from './createCanvasArrange.svelte.js';
18
18
  export { createCanvasScenes, type CanvasScenes, type CreateCanvasScenesOptions } from './createCanvasScenes.svelte.js';
19
19
  export { default as CanvasGuidesLayer } from './CanvasGuidesLayer.svelte';
20
+ export { createCanvasMeasure, type CanvasMeasure, type CreateCanvasMeasureOptions } from './createCanvasMeasure.svelte.js';
21
+ export { measureBetween, measureToLine, measureSelection, measureLabel, isMeasureModifierHeld, snapToGrid, snapResize, snapNodeResize, inferResizeHandle, resizeHandleAxes, getResizingNodeRect, RESIZE_HANDLES, fitCubics, fitCubicRun, fitPathData, fitFreehandPath, cubicsToPathData, cubicPointAt, isStraightCubic, type MeasureGuide, type MeasureSelectionResult, type MeasureSelectionOptions, type ResizeHandle, type SnapResizeOptions, type SnapResizeResult, type SnapNodeResizeOptions, type SnapNodeResizeResult, type CubicSegment, type FitCubicsOptions, type FitPathDataOptions } from '@pixerate/editor/canvas';
20
22
  export { alignNodes, distributeNodes, matchSize, reorderNodes, applyNodeUpdates, invertNodeUpdates, lockNodes, unlockNodes, toggleLockNodes, isLocked, getNodeSize, getNodeRect, getAbsolutePosition, readStyleSize, withStyleSize, computeSnapGuides, createGuideIndex, createNodeGuideIndex, snapNodeDrag, findConnectorSnap, nearestHandlePositions, handlePoint, positionToSide, sideToPosition, oppositePosition, CONNECTION_LINE_TYPES, CanvasScenesStore, createCanvasScenesStore, parseCanvasScenes, fitViewportToRect, fitViewportToNodes, matchArrangeShortcut, DEFAULT_ARRANGE_SHORTCUTS, type AlignEdge, type DistributeAxis, type DistributeMode, type SizeDimension, type ZOrderOperation, type CanvasNodeUpdate, type GuideLine, type GuideIndex, type SnapGuidesOptions, type SnapResult, type ConnectorSnap, type ConnectorSnapTarget, type CanvasConnectionLineType, type CanvasScene, type CanvasScenesState, type CanvasViewport, type CanvasArrangeAction, type ArrangeShortcutBinding } from '@pixerate/editor/canvas';
21
23
  export { default as ShapeNode } from './ShapeNode.svelte';
22
24
  export { combineShapeNodes, canCombineShapeNodes, applyShapeCombination, revertShapeCombination, shapeNodeToPolygon, isShapeNode, getNodeShape, SHAPE_DATA_KEY, SHAPE_NODE_TYPE, SHAPE_OPERATIONS, SHAPE_KINDS, isShapeDescription, shapeToPolygon, getShapeSvg, getShapeRenderData, parseSvgPath, flattenSvgPath, polygonToSvgPath, simplifyRing, polygonBoolean, unionPolygons, intersectPolygons, subtractPolygons, xorPolygons, dividePolygons, polygonArea, multiPolygonArea, multiPolygonBounds, ringSignedArea, pointInRings, pointInMultiPolygon, type ShapeOperation, type ShapeDescription, type ShapeKind, type ShapePaint, type ShapeSize, type ShapeRenderData, type RectShape, type EllipseShape, type RegularPolygonShape, type StarShape, type PathShape, type PathCommand, type FlattenOptions, type PolygonToPathOptions, type CombineShapeNodesOptions, type CombineShapeNodesResult, type CombineShapeNodesRefusal, type ShapeNodePolygonOptions, type MultiPolygon, type PolygonWithHoles, type PolygonRing, type PolygonFillRule, type PolygonOperand, type PolygonInput, type PolygonPiece, type PolygonBooleanOperation, type PolygonBooleanOptions } from '@pixerate/editor/canvas';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/canvas/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/canvas/index.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,9 @@ export { createStreamingCanvas } from './createStreamingCanvas.svelte.js';
34
34
  export { createCanvasArrange, createCanvasArrangeShortcuts } from './createCanvasArrange.svelte.js';
35
35
  export { createCanvasScenes } from './createCanvasScenes.svelte.js';
36
36
  export { default as CanvasGuidesLayer } from './CanvasGuidesLayer.svelte';
37
+ // Distance measuring (Alt-hover), resize / grid snapping and curve fitting
38
+ export { createCanvasMeasure } from './createCanvasMeasure.svelte.js';
39
+ export { measureBetween, measureToLine, measureSelection, measureLabel, isMeasureModifierHeld, snapToGrid, snapResize, snapNodeResize, inferResizeHandle, resizeHandleAxes, getResizingNodeRect, RESIZE_HANDLES, fitCubics, fitCubicRun, fitPathData, fitFreehandPath, cubicsToPathData, cubicPointAt, isStraightCubic } from '@pixerate/editor/canvas';
37
40
  export { alignNodes, distributeNodes, matchSize, reorderNodes, applyNodeUpdates, invertNodeUpdates, lockNodes, unlockNodes, toggleLockNodes, isLocked, getNodeSize, getNodeRect, getAbsolutePosition, readStyleSize, withStyleSize, computeSnapGuides, createGuideIndex, createNodeGuideIndex, snapNodeDrag, findConnectorSnap, nearestHandlePositions, handlePoint, positionToSide, sideToPosition, oppositePosition, CONNECTION_LINE_TYPES, CanvasScenesStore, createCanvasScenesStore, parseCanvasScenes, fitViewportToRect, fitViewportToNodes, matchArrangeShortcut, DEFAULT_ARRANGE_SHORTCUTS } from '@pixerate/editor/canvas';
38
41
  export { default as ShapeNode } from './ShapeNode.svelte';
39
42
  // Shape nodes and boolean operations (Unite / Intersect / Subtract / Exclude / Divide)
@@ -0,0 +1,129 @@
1
+ <script lang="ts" module>
2
+ // Ids only render while the palette is open (client side), so a counter is enough
3
+ // (`$props.id()` needs Svelte 5.20, newer than our peer range).
4
+ let nextId = 0;
5
+ </script>
6
+
7
+ <script lang="ts">
8
+ import type { CommandPaletteItem } from '@pixerate/editor/commands';
9
+ import type { SvelteCommandPalette } from './palette.svelte.js';
10
+
11
+ interface Props {
12
+ /** State from `createCommandPalette`. */
13
+ palette: SvelteCommandPalette;
14
+ placeholder?: string;
15
+ emptyMessage?: string;
16
+ /** Extra classes for the dialog panel. */
17
+ class?: string;
18
+ }
19
+
20
+ let {
21
+ palette,
22
+ placeholder = 'Type a command…',
23
+ emptyMessage = 'No matching commands',
24
+ class: className = ''
25
+ }: Props = $props();
26
+
27
+ const baseId = `command-palette-${++nextId}`;
28
+ const listId = `${baseId}-list`;
29
+ const optionId = (index: number) => `${baseId}-option-${index}`;
30
+
31
+ let inputEl = $state<HTMLInputElement | null>(null);
32
+ let listEl = $state<HTMLUListElement | null>(null);
33
+
34
+ $effect(() => {
35
+ if (palette.open) inputEl?.focus();
36
+ });
37
+
38
+ $effect(() => {
39
+ void palette.activeIndex;
40
+ if (!palette.open) return;
41
+ const active = listEl?.querySelector<HTMLElement>('[aria-selected="true"]');
42
+ active?.scrollIntoView?.({ block: 'nearest' });
43
+ });
44
+
45
+ const segments = (item: CommandPaletteItem) => {
46
+ const marked = new Set(item.labelIndices);
47
+ return Array.from(item.label).map((ch, i) => ({ ch, match: marked.has(i) }));
48
+ };
49
+ </script>
50
+
51
+ {#if palette.open}
52
+ <!-- Headless-styled command palette: Arrow keys move, Enter runs, Escape or a backdrop press closes. -->
53
+ <div
54
+ class="fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]"
55
+ data-command-palette-backdrop=""
56
+ role="presentation"
57
+ onmousedown={(e) => {
58
+ if (e.target === e.currentTarget) palette.setOpen(false);
59
+ }}
60
+ >
61
+ <div
62
+ role="dialog"
63
+ aria-modal="true"
64
+ aria-label="Command palette"
65
+ class="w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl {className}"
66
+ style="background: var(--popover, var(--background, #fff));"
67
+ >
68
+ <input
69
+ bind:this={inputEl}
70
+ type="text"
71
+ role="combobox"
72
+ aria-expanded="true"
73
+ aria-controls={listId}
74
+ aria-autocomplete="list"
75
+ aria-activedescendant={palette.items.length ? optionId(palette.activeIndex) : undefined}
76
+ aria-label="Search commands"
77
+ {placeholder}
78
+ value={palette.query}
79
+ oninput={(e) => palette.setQuery(e.currentTarget.value)}
80
+ onkeydown={(e) => {
81
+ if (palette.handleKeyDown(e)) e.stopPropagation();
82
+ }}
83
+ class="w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
84
+ />
85
+ {#if palette.items.length === 0}
86
+ <div class="px-3 py-6 text-center text-sm text-muted-foreground">{emptyMessage}</div>
87
+ {:else}
88
+ <ul bind:this={listEl} id={listId} role="listbox" aria-label="Commands" class="max-h-80 overflow-y-auto py-1">
89
+ {#each palette.items as item, index (item.id)}
90
+ <li
91
+ id={optionId(index)}
92
+ role="option"
93
+ aria-selected={index === palette.activeIndex}
94
+ aria-disabled={!item.enabled || undefined}
95
+ data-command-id={item.id}
96
+ data-recent={item.recent ? '' : undefined}
97
+ title={item.disabledReason}
98
+ onmousemove={() => index !== palette.activeIndex && palette.setActiveIndex(index)}
99
+ onmousedown={(e) => e.preventDefault()}
100
+ onclick={() => palette.run(item.id)}
101
+ onkeydown={() => {}}
102
+ class="flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm {index === palette.activeIndex
103
+ ? 'bg-muted'
104
+ : ''} {item.enabled ? '' : 'cursor-default opacity-50'}"
105
+ >
106
+ <span class="min-w-0 flex-1 truncate">
107
+ {#each segments(item) as segment, i (i)}{#if segment.match}<span
108
+ class="font-semibold text-foreground"
109
+ data-match="">{segment.ch}</span
110
+ >{:else}{segment.ch}{/if}{/each}
111
+ {#if item.disabledReason}
112
+ <span class="ml-2 text-xs text-muted-foreground" data-disabled-reason="">{item.disabledReason}</span>
113
+ {/if}
114
+ </span>
115
+ {#if item.group}
116
+ <span class="shrink-0 text-xs text-muted-foreground">{item.group}</span>
117
+ {/if}
118
+ {#if item.shortcut}
119
+ <kbd class="shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground"
120
+ >{item.shortcut}</kbd
121
+ >
122
+ {/if}
123
+ </li>
124
+ {/each}
125
+ </ul>
126
+ {/if}
127
+ </div>
128
+ </div>
129
+ {/if}
@@ -0,0 +1,13 @@
1
+ import type { SvelteCommandPalette } from './palette.svelte.js';
2
+ interface Props {
3
+ /** State from `createCommandPalette`. */
4
+ palette: SvelteCommandPalette;
5
+ placeholder?: string;
6
+ emptyMessage?: string;
7
+ /** Extra classes for the dialog panel. */
8
+ class?: string;
9
+ }
10
+ declare const CommandPalette: import("svelte").Component<Props, {}, "">;
11
+ type CommandPalette = ReturnType<typeof CommandPalette>;
12
+ export default CommandPalette;
13
+ //# sourceMappingURL=CommandPalette.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommandPalette.svelte.d.ts","sourceRoot":"","sources":["../../src/commands/CommandPalette.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,UAAU,KAAK;IACb,yCAAyC;IACzC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8EH,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { CommandRegistry, CommandResult, CommandSpec } from "@pixerate/editor/commands";
2
+ type MaybeGetter<T> = T | (() => T);
3
+ export interface CommandShortcutsOptions<TContext = any> {
4
+ /** Element or window to listen on (default: `window`). */
5
+ target?: Window | HTMLElement | null;
6
+ /** Active scopes, most specific first; a getter is read on every keydown. */
7
+ scopes?: MaybeGetter<string | readonly string[] | undefined>;
8
+ /** Context for the commands (default: the registry's); a getter is read on every keydown. */
9
+ context?: MaybeGetter<TContext | undefined>;
10
+ /** Fire even while typing in inputs / contenteditable (default: per binding). */
11
+ allowInEditable?: boolean;
12
+ /** Called after a shortcut ran a command. */
13
+ onRun?: (result: CommandResult) => void;
14
+ }
15
+ /**
16
+ * Runs the registry's commands from their keyboard shortcuts (`registry.handleKeyDown`).
17
+ * Typing in inputs and editors is never hijacked, and disabled commands leave the event
18
+ * alone. Returns `{ destroy }`.
19
+ */
20
+ export declare function createCommandShortcuts<TContext = any>(registry: CommandRegistry<TContext>, options?: CommandShortcutsOptions<TContext>): {
21
+ destroy: () => void;
22
+ };
23
+ /**
24
+ * Registers commands for the lifetime of the calling component (call it during
25
+ * component initialisation). Pass a getter to react to changes: when it returns a
26
+ * different array, the old commands are unregistered.
27
+ */
28
+ export declare function useRegisterCommands<TContext = any>(registry: MaybeGetter<CommandRegistry<TContext> | null | undefined>, specs: MaybeGetter<readonly CommandSpec<TContext>[] | null | undefined>): void;
29
+ export {};
30
+ //# sourceMappingURL=commandShortcuts.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commandShortcuts.svelte.d.ts","sourceRoot":"","sources":["../../src/commands/commandShortcuts.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7F,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAKpC,MAAM,WAAW,uBAAuB,CAAC,QAAQ,GAAG,GAAG;IACrD,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACrC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IAC7D,6FAA6F;IAC7F,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC5C,iFAAiF;IACjF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,GAAG,GAAG,EACnD,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,EACnC,OAAO,GAAE,uBAAuB,CAAC,QAAQ,CAAM,GAC9C;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAczB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,GAAG,GAAG,EAChD,QAAQ,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,EACnE,KAAK,EAAE,WAAW,CAAC,SAAS,WAAW,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACtE,IAAI,CAON"}
@@ -0,0 +1,37 @@
1
+ const read = (value) => typeof value === "function" ? value() : value;
2
+ /**
3
+ * Runs the registry's commands from their keyboard shortcuts (`registry.handleKeyDown`).
4
+ * Typing in inputs and editors is never hijacked, and disabled commands leave the event
5
+ * alone. Returns `{ destroy }`.
6
+ */
7
+ export function createCommandShortcuts(registry, options = {}) {
8
+ const target = options.target ?? (typeof window !== "undefined" ? window : null);
9
+ if (!target)
10
+ return { destroy: () => { } };
11
+ const onKeyDown = (event) => {
12
+ const context = options.context === undefined ? undefined : read(options.context);
13
+ const result = registry.handleKeyDown(event, {
14
+ scopes: options.scopes === undefined ? undefined : read(options.scopes),
15
+ ...(options.allowInEditable !== undefined ? { allowInEditable: options.allowInEditable } : {}),
16
+ ...(context !== undefined ? { context } : {}),
17
+ });
18
+ if (result)
19
+ options.onRun?.(result);
20
+ };
21
+ target.addEventListener("keydown", onKeyDown);
22
+ return { destroy: () => target.removeEventListener("keydown", onKeyDown) };
23
+ }
24
+ /**
25
+ * Registers commands for the lifetime of the calling component (call it during
26
+ * component initialisation). Pass a getter to react to changes: when it returns a
27
+ * different array, the old commands are unregistered.
28
+ */
29
+ export function useRegisterCommands(registry, specs) {
30
+ $effect(() => {
31
+ const currentRegistry = read(registry);
32
+ const currentSpecs = read(specs);
33
+ if (!currentRegistry || !currentSpecs || currentSpecs.length === 0)
34
+ return;
35
+ return currentRegistry.register(currentSpecs);
36
+ });
37
+ }
@@ -0,0 +1,7 @@
1
+ import type { ComponentProps } from "svelte";
2
+ import type CommandPaletteComponent from "./CommandPalette.svelte";
3
+ export { default as CommandPalette } from "./CommandPalette.svelte";
4
+ export * from "./palette.svelte.js";
5
+ export * from "./commandShortcuts.svelte.js";
6
+ export type CommandPaletteProps = ComponentProps<typeof CommandPaletteComponent>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,uBAAuB,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { default as CommandPalette } from "./CommandPalette.svelte";
2
+ export * from "./palette.svelte.js";
3
+ export * from "./commandShortcuts.svelte.js";
@@ -0,0 +1,34 @@
1
+ import { type CommandPaletteController, type CommandPaletteItem, type CommandPaletteOptions, type CommandRegistry, type CommandResult } from "@pixerate/editor/commands";
2
+ export interface CreateCommandPaletteOptions<TContext = any> extends CommandPaletteOptions<TContext> {
3
+ /** Chord that toggles the palette from anywhere, also while typing (e.g. `Mod+K`). */
4
+ hotkey?: string;
5
+ /** Element or window the hotkey listens on (default: `window`). */
6
+ hotkeyTarget?: Window | HTMLElement | null;
7
+ }
8
+ export interface SvelteCommandPalette {
9
+ readonly open: boolean;
10
+ readonly query: string;
11
+ readonly activeIndex: number;
12
+ readonly items: CommandPaletteItem[];
13
+ readonly recents: string[];
14
+ readonly lastResult: CommandResult | null;
15
+ readonly controller: CommandPaletteController;
16
+ setOpen(open: boolean): void;
17
+ toggle(): void;
18
+ setQuery(query: string): void;
19
+ setActiveIndex(index: number): void;
20
+ move(delta: number): void;
21
+ run(id: string): CommandResult | null;
22
+ runActive(): CommandResult | null;
23
+ handleKeyDown(event: KeyboardEvent): boolean;
24
+ /** Stops following the registry and removes the hotkey listener. */
25
+ destroy(): void;
26
+ }
27
+ /**
28
+ * Reactive command palette state over a `CommandRegistry` (Svelte 5 runes): ranked rows
29
+ * with shortcuts and disabled reasons, active row and recents. Render it with
30
+ * `<CommandPalette palette={…} />` or your own markup. Call `destroy()` when done
31
+ * (e.g. in `onDestroy`).
32
+ */
33
+ export declare function createCommandPalette<TContext = any>(registry: CommandRegistry<TContext>, options?: CreateCommandPaletteOptions<TContext>): SvelteCommandPalette;
34
+ //# sourceMappingURL=palette.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"palette.svelte.d.ts","sourceRoot":"","sources":["../../src/commands/palette.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAE1B,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,2BAA2B,CAAC,QAAQ,GAAG,GAAG,CAAE,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IAClG,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,wBAAwB,CAAC;IAC9C,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IACtC,SAAS,IAAI,aAAa,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;IAC7C,oEAAoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,GAAG,GAAG,EACjD,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,EACnC,OAAO,GAAE,2BAA2B,CAAC,QAAQ,CAAM,GAClD,oBAAoB,CAsDtB"}
@@ -0,0 +1,61 @@
1
+ import { createCommandPaletteController, matchPaletteHotkey, } from "@pixerate/editor/commands";
2
+ /**
3
+ * Reactive command palette state over a `CommandRegistry` (Svelte 5 runes): ranked rows
4
+ * with shortcuts and disabled reasons, active row and recents. Render it with
5
+ * `<CommandPalette palette={…} />` or your own markup. Call `destroy()` when done
6
+ * (e.g. in `onDestroy`).
7
+ */
8
+ export function createCommandPalette(registry, options = {}) {
9
+ const controller = createCommandPaletteController(registry, options);
10
+ let state = $state.raw(controller.getState());
11
+ const unsubscribe = controller.subscribe((next) => {
12
+ state = next;
13
+ });
14
+ let removeHotkey = () => { };
15
+ const { hotkey } = options;
16
+ const target = options.hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
17
+ if (hotkey && target) {
18
+ const onKeyDown = (event) => {
19
+ const e = event;
20
+ if (e.defaultPrevented || !matchPaletteHotkey(e, hotkey, options.platform))
21
+ return;
22
+ e.preventDefault();
23
+ controller.toggle();
24
+ };
25
+ target.addEventListener("keydown", onKeyDown);
26
+ removeHotkey = () => target.removeEventListener("keydown", onKeyDown);
27
+ }
28
+ return {
29
+ get open() {
30
+ return state.open;
31
+ },
32
+ get query() {
33
+ return state.query;
34
+ },
35
+ get activeIndex() {
36
+ return state.activeIndex;
37
+ },
38
+ get items() {
39
+ return state.items;
40
+ },
41
+ get recents() {
42
+ return state.recents;
43
+ },
44
+ get lastResult() {
45
+ return state.lastResult;
46
+ },
47
+ controller,
48
+ setOpen: controller.setOpen,
49
+ toggle: controller.toggle,
50
+ setQuery: controller.setQuery,
51
+ setActiveIndex: controller.setActiveIndex,
52
+ move: controller.move,
53
+ run: controller.run,
54
+ runActive: controller.runActive,
55
+ handleKeyDown: controller.handleKeyDown,
56
+ destroy() {
57
+ unsubscribe();
58
+ removeHotkey();
59
+ },
60
+ };
61
+ }
@@ -1,4 +1,4 @@
1
- import { HistoryManager } from "@pixerate/editor/history";
1
+ import type { HistoryManager } from "@pixerate/editor/history";
2
2
  export interface HistoryShortcutsOptions {
3
3
  /**
4
4
  * Whether keyboard shortcuts are enabled. Defaults to true.
@@ -1 +1 @@
1
- {"version":3,"file":"createHistoryShortcuts.d.ts","sourceRoot":"","sources":["../../src/history/createHistoryShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,uBAA4B,GACpC;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAqEzB"}
1
+ {"version":3,"file":"createHistoryShortcuts.d.ts","sourceRoot":"","sources":["../../src/history/createHistoryShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,uBAA4B,GACpC;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAqCzB"}
@@ -1,3 +1,4 @@
1
+ import { matchHistoryShortcut } from "@pixerate/editor/commands";
1
2
  /**
2
3
  * Attaches keyboard listeners for Undo (Mod+Z) and Redo (Mod+Shift+Z / Mod+Y).
3
4
  * Returns an object with a `destroy()` function for lifecycle cleanup.
@@ -13,39 +14,16 @@ export function createHistoryShortcuts(manager, options = {}) {
13
14
  }
14
15
  const handleKeyDown = (event) => {
15
16
  const e = event;
16
- const isMac = typeof navigator !== "undefined" &&
17
- /Mac|iPod|iPhone|iPad/.test(navigator.platform || navigator.userAgent);
18
- const modifier = isMac ? e.metaKey : e.ctrlKey;
19
- if (!modifier)
20
- return;
21
- if (ignoreEditableElements && typeof document !== "undefined") {
22
- const targetEl = (e.target || document.activeElement);
23
- if (targetEl && targetEl.tagName) {
24
- const tagName = targetEl.tagName.toLowerCase();
25
- const isInput = tagName === "input" || tagName === "textarea";
26
- const isContentEditable = targetEl.isContentEditable ||
27
- targetEl.getAttribute?.("contenteditable") === "true";
28
- if (isInput || isContentEditable) {
29
- return;
30
- }
31
- }
17
+ // Default bindings from the command system: Mod+Z, Mod+Shift+Z and (off macOS) Mod+Y,
18
+ // matched by `event.code` with `Mod` = ⌘ on macOS and Ctrl elsewhere.
19
+ const action = matchHistoryShortcut(e, { allowInEditable: !ignoreEditableElements });
20
+ if (action === "undo" && manager.getState().canUndo) {
21
+ e.preventDefault();
22
+ manager.undo();
32
23
  }
33
- const key = e.key?.toLowerCase();
34
- // Undo: Mod+Z (without Shift)
35
- if (key === "z" && !e.shiftKey) {
36
- if (manager.getState().canUndo) {
37
- e.preventDefault();
38
- manager.undo();
39
- }
40
- return;
41
- }
42
- // Redo: Mod+Shift+Z or (on non-Mac) Mod+Y
43
- const isRedoKey = (key === "z" && e.shiftKey) || (!isMac && key === "y" && !e.shiftKey);
44
- if (isRedoKey) {
45
- if (manager.getState().canRedo) {
46
- e.preventDefault();
47
- manager.redo();
48
- }
24
+ else if (action === "redo" && manager.getState().canRedo) {
25
+ e.preventDefault();
26
+ manager.redo();
49
27
  }
50
28
  };
51
29
  eventTarget.addEventListener("keydown", handleKeyDown);
@@ -1,14 +1,23 @@
1
- import { HistoryManager, HistoryState, Command, HistoryManagerOptions } from "@pixerate/editor/history";
1
+ import { HistoryManager, HistoryState, HistoryEntry, HistoryMark, MergedExecutionOptions, Command, HistoryManagerOptions } from "@pixerate/editor/history";
2
2
  export interface SvelteHistory extends HistoryState {
3
3
  readonly manager: HistoryManager;
4
+ /** History panel rows (undo steps, then redo steps). */
5
+ readonly entries: HistoryEntry[];
4
6
  undo(): boolean;
5
7
  redo(): boolean;
6
8
  clear(): void;
7
9
  execute(command: Command): void;
8
- executeMerged(command: Command, options?: {
9
- windowMs?: number;
10
- }): void;
10
+ executeMerged(command: Command, options?: MergedExecutionOptions): void;
11
11
  batch(name: string, fn: () => void): void;
12
+ /** Undoes / redoes until the entry at `index` is current (`-1` = before all). */
13
+ goTo(index: number): number;
14
+ /** Captures the current point, e.g. when a drag starts. */
15
+ mark(): HistoryMark;
16
+ /** Takes back every step since `mark` without leaving redo (Escape-cancel). */
17
+ revertTo(mark: HistoryMark): number;
18
+ /** Joins every merged execute into one step until `endGesture`. */
19
+ beginGesture(key: string): void;
20
+ endGesture(): void;
12
21
  subscribe(run: (value: HistoryState) => void): () => void;
13
22
  }
14
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"history.svelte.d.ts","sourceRoot":"","sources":["../../src/history/history.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,OAAO,EAEP,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,IAAI,IAAI,OAAO,CAAC;IAChB,IAAI,IAAI,OAAO,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC3D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,gBAAgB,CAAC,EAAE,cAAc,GAAG,qBAAqB,GACxD,aAAa,CA2Cf"}
1
+ {"version":3,"file":"history.svelte.d.ts","sourceRoot":"","sources":["../../src/history/history.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,OAAO,EAEP,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;IACjC,IAAI,IAAI,OAAO,CAAC;IAChB,IAAI,IAAI,OAAO,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACxE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,iFAAiF;IACjF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,2DAA2D;IAC3D,IAAI,IAAI,WAAW,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,mEAAmE;IACnE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,IAAI,IAAI,CAAC;IACnB,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC3D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,gBAAgB,CAAC,EAAE,cAAc,GAAG,qBAAqB,GACxD,aAAa,CAqDf"}
@@ -32,12 +32,22 @@ export function createHistory(managerOrOptions) {
32
32
  get manager() {
33
33
  return manager;
34
34
  },
35
+ get entries() {
36
+ // Reading `state` makes the getter reactive; getEntries() is cached per change.
37
+ void state;
38
+ return manager.getEntries();
39
+ },
35
40
  undo: () => manager.undo(),
36
41
  redo: () => manager.redo(),
37
42
  clear: () => manager.clear(),
38
43
  execute: (cmd) => manager.execute(cmd),
39
44
  executeMerged: (cmd, opts) => manager.executeMerged(cmd, opts),
40
45
  batch: (name, fn) => manager.batch(name, fn),
46
+ goTo: (index) => manager.goTo(index),
47
+ mark: () => manager.mark(),
48
+ revertTo: (m) => manager.revertTo(m),
49
+ beginGesture: (key) => manager.beginGesture(key),
50
+ endGesture: () => manager.endGesture(),
41
51
  subscribe: (run) => manager.subscribe(run),
42
52
  };
43
53
  }
@@ -0,0 +1,31 @@
1
+ import { DirtyTracker, type DirtyTrackerOptions, type HistoryManager } from "@pixerate/editor/history";
2
+ export interface CreateHistoryDirtyOptions<T> extends DirtyTrackerOptions<T> {
3
+ /** The history whose changes re-check the document (a `createHistory().manager`). */
4
+ history: HistoryManager;
5
+ /** Reads the current document value. */
6
+ getValue: () => T;
7
+ /** Existing tracker to drive. */
8
+ tracker?: DirtyTracker<T>;
9
+ }
10
+ export interface SvelteHistoryDirty<T> {
11
+ /** Whether the document differs from the saved state (reactive). */
12
+ readonly isDirty: boolean;
13
+ /** Marks the current document as saved. */
14
+ markClean(): void;
15
+ /** Runs a load / restore without marking the document dirty (re-entrant). */
16
+ suppress<R>(fn: () => R): R;
17
+ /** Re-checks after a change made outside the history. */
18
+ refresh(): boolean;
19
+ readonly tracker: DirtyTracker<T>;
20
+ /** Stops following the history. */
21
+ destroy(): void;
22
+ }
23
+ /**
24
+ * Svelte 5 rune: dirty-vs-saved tracking bound to a HistoryManager. Undoing
25
+ * back to the saved state makes the document clean again, so a navigation
26
+ * guard fed with `isDirty` stops prompting.
27
+ *
28
+ * Usage: `createNavigationGuard({ isDirty: () => dirty.isDirty })`.
29
+ */
30
+ export declare function createHistoryDirty<T>(options: CreateHistoryDirtyOptions<T>): SvelteHistoryDirty<T>;
31
+ //# sourceMappingURL=historyDirty.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historyDirty.svelte.d.ts","sourceRoot":"","sources":["../../src/history/historyDirty.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,yBAAyB,CAAC,CAAC,CAAE,SAAQ,mBAAmB,CAAC,CAAC,CAAC;IAC1E,qFAAqF;IACrF,OAAO,EAAE,cAAc,CAAC;IACxB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,iCAAiC;IACjC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2CAA2C;IAC3C,SAAS,IAAI,IAAI,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC;IACnB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,mCAAmC;IACnC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,GACpC,kBAAkB,CAAC,CAAC,CAAC,CAsBvB"}
@@ -0,0 +1,30 @@
1
+ import { bindDirtyToHistory, } from "@pixerate/editor/history";
2
+ /**
3
+ * Svelte 5 rune: dirty-vs-saved tracking bound to a HistoryManager. Undoing
4
+ * back to the saved state makes the document clean again, so a navigation
5
+ * guard fed with `isDirty` stops prompting.
6
+ *
7
+ * Usage: `createNavigationGuard({ isDirty: () => dirty.isDirty })`.
8
+ */
9
+ export function createHistoryDirty(options) {
10
+ const binding = bindDirtyToHistory(options);
11
+ let isDirty = $state(binding.dirty);
12
+ const unsubscribe = binding.subscribe((dirty) => {
13
+ isDirty = dirty;
14
+ });
15
+ return {
16
+ get isDirty() {
17
+ return isDirty;
18
+ },
19
+ markClean: () => binding.markClean(),
20
+ suppress: (fn) => binding.suppress(fn),
21
+ refresh: () => binding.refresh(),
22
+ get tracker() {
23
+ return binding.tracker;
24
+ },
25
+ destroy() {
26
+ unsubscribe();
27
+ binding.destroy();
28
+ },
29
+ };
30
+ }
@@ -1,3 +1,4 @@
1
1
  export * from "./history.svelte.js";
2
2
  export * from "./createHistoryShortcuts.js";
3
+ export * from "./historyDirty.svelte.js";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/history/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/history/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export * from "./history.svelte.js";
2
2
  export * from "./createHistoryShortcuts.js";
3
+ export * from "./historyDirty.svelte.js";
@@ -16,6 +16,8 @@
16
16
  getCropCursor,
17
17
  calculateCropDrag,
18
18
  hitTestAnnotation,
19
+ normalizeProcessVersion,
20
+ LATEST_PROCESS_VERSION,
19
21
  } from '@pixerate/editor/image-editor';
20
22
  import { onDestroy, untrack } from 'svelte';
21
23
  import { createReactiveImageEditor, type ReactiveImageEditor } from './imageEditorState.svelte.js';
@@ -47,6 +49,9 @@
47
49
  const internalEditor = createReactiveImageEditor();
48
50
  const editor = $derived(propEditor || internalEditor);
49
51
  onDestroy(() => internalEditor.destroy());
52
+ const legacyProcess = $derived(
53
+ normalizeProcessVersion(editor.state.adjustments.process) < LATEST_PROCESS_VERSION
54
+ );
50
55
 
51
56
  let canvasEl = $state<HTMLCanvasElement | null>(null);
52
57
  let containerEl = $state<HTMLDivElement | null>(null);
@@ -961,6 +966,40 @@
961
966
  />
962
967
  </div>
963
968
 
969
+ <!-- Tint (process 2 white balance) -->
970
+ <div>
971
+ <div class="flex justify-between text-slate-400 mb-1">
972
+ <span>Tint</span>
973
+ <span class="font-mono">{editor.state.adjustments.tint ?? 0}</span>
974
+ </div>
975
+ <input
976
+ type="range"
977
+ min="-100"
978
+ max="100"
979
+ aria-label="Tint"
980
+ disabled={legacyProcess}
981
+ value={editor.state.adjustments.tint ?? 0}
982
+ oninput={(e) => editor.setAdjustments({ tint: Number((e.target as HTMLInputElement).value) })}
983
+ class="w-full accent-indigo-500 disabled:opacity-40"
984
+ />
985
+ </div>
986
+
987
+ {#if legacyProcess}
988
+ <div
989
+ class="flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200"
990
+ data-testid="image-editor-process-notice"
991
+ >
992
+ <span>Legacy rendering (process 1). Tint needs the current process.</span>
993
+ <button
994
+ type="button"
995
+ onclick={() => editor.upgradeProcess()}
996
+ class="shrink-0 rounded bg-amber-500/20 px-2 py-0.5 hover:bg-amber-500/30"
997
+ >
998
+ Update
999
+ </button>
1000
+ </div>
1001
+ {/if}
1002
+
964
1003
  <!-- Blur -->
965
1004
  <div>
966
1005
  <div class="flex justify-between text-slate-400 mb-1">
@@ -1 +1 @@
1
- {"version":3,"file":"ImageEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/ImageEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAIR,aAAa,EAGb,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AASzC,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGjG,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AA+hCH,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ImageEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/ImageEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAIR,aAAa,EAGb,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AAWzC,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGjG,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAojCH,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -14,6 +14,8 @@ export declare function createReactiveImageEditor(options?: ImageEditorOptions):
14
14
  flipVertical(): void;
15
15
  setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory?: boolean): void;
16
16
  resetAdjustments(): void;
17
+ /** Update to Current Process: re-render the adjustments with the latest process (one undo step). */
18
+ upgradeProcess(): boolean;
17
19
  setDepthMask(partial: Partial<DepthMaskOptions>): void;
18
20
  resetDepthMask(): void;
19
21
  addAnnotation(ann: CreateAnnotationPayload): string;
@@ -1 +1 @@
1
- {"version":3,"file":"imageEditorState.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/imageEditorState.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAChB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB;;;;;kBA0BxD,eAAe;kBAGf,OAAO,GAAG,IAAI;2BAGL,WAAW;;oBAMlB,MAAM;yBAGD,MAAM;;;4BASH,OAAO,CAAC,gBAAgB,CAAC;;0BAM3B,OAAO,CAAC,gBAAgB,CAAC;;uBAM5B,uBAAuB;yBAGrB,MAAM,WAAW,OAAO,CAAC,UAAU,CAAC;yBAGpC,MAAM;;yBAMN,MAAM,GAAG,IAAI;;;;oBAYlB,MAAM;qBAGL,MAAM;;kBAMT,MAAM;gBAGR,UAAU;4BAGE,OAAO;mBAGhB,MAAM,GAAG,gBAAgB;qBAGvB,aAAa;kBAGhB,aAAa;;mBAMZ,0BAA0B;sBAGvB;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;yBAG5C;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;2BAG7C,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;oCAGhC,MAAM;4CAGE,MAAM;IAG9C,8EAA8E;;EAKjF;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
1
+ {"version":3,"file":"imageEditorState.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/imageEditorState.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAChB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB;;;;;kBA0BxD,eAAe;kBAGf,OAAO,GAAG,IAAI;2BAGL,WAAW;;oBAMlB,MAAM;yBAGD,MAAM;;;4BASH,OAAO,CAAC,gBAAgB,CAAC;;IAMjD,oGAAoG;;0BAI9E,OAAO,CAAC,gBAAgB,CAAC;;uBAM5B,uBAAuB;yBAGrB,MAAM,WAAW,OAAO,CAAC,UAAU,CAAC;yBAGpC,MAAM;;yBAMN,MAAM,GAAG,IAAI;;;;oBAYlB,MAAM;qBAGL,MAAM;;kBAMT,MAAM;gBAGR,UAAU;4BAGE,OAAO;mBAGhB,MAAM,GAAG,gBAAgB;qBAGvB,aAAa;kBAGhB,aAAa;;mBAMZ,0BAA0B;sBAGvB;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;yBAG5C;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;2BAG7C,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;oCAGhC,MAAM;4CAGE,MAAM;IAG9C,8EAA8E;;EAKjF;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -53,6 +53,10 @@ export function createReactiveImageEditor(options = {}) {
53
53
  resetAdjustments() {
54
54
  controller.resetAdjustments();
55
55
  },
56
+ /** Update to Current Process: re-render the adjustments with the latest process (one undo step). */
57
+ upgradeProcess() {
58
+ return controller.upgradeProcess();
59
+ },
56
60
  setDepthMask(partial) {
57
61
  controller.setDepthMask(partial);
58
62
  },
package/dist/index.d.ts CHANGED
@@ -11,8 +11,8 @@ export * from "./history/index.js";
11
11
  export * from "./fileImport.svelte.js";
12
12
  export * from "./agentTools.svelte.js";
13
13
  export * from "./outline.svelte.js";
14
- export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, } from "@pixerate/editor";
15
- export type { DirtyTrackerOptions, Command, HistoryState, HistoryManagerOptions, } from "@pixerate/editor";
14
+ export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, bindDirtyToHistory, withoutDirty, } from "@pixerate/editor";
15
+ export type { DirtyTrackerOptions, Command, HistoryState, HistoryManagerOptions, HistoryEntry, HistoryMark, MergedExecutionOptions, HistoryDirtyBinding, BindDirtyToHistoryOptions, } from "@pixerate/editor";
16
16
  export type EditableTextNodeEditorProps = ComponentProps<typeof EditableTextNodeEditorComponent>;
17
17
  export type BubbleMenuProps = ComponentProps<typeof BubbleMenuComponent>;
18
18
  export type TemplateRendererProps = ComponentProps<typeof TemplateRendererComponent>;
@@ -28,4 +28,5 @@ export type { PromptValues, PromptDiagnostic, VariableFormField, } from "@pixera
28
28
  export * from "./spreadsheet/index.js";
29
29
  export * from "./image-editor/index.js";
30
30
  export * from "./review/index.js";
31
+ export * from "./commands/index.js";
31
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,KAAK,+BAA+B,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,yBAAyB,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAE/D,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,mBAAmB,EACnB,OAAO,EACP,YAAY,EACZ,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAG1B,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,+BAA+B,CACvC,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAChD,OAAO,yBAAyB,CACjC,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE7E,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEhE,YAAY,EACV,QAAQ,EACR,eAAe,EACf,KAAK,EACL,SAAS,EACT,aAAa,EACb,qBAAqB,EACrB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,KAAK,+BAA+B,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,yBAAyB,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAE/D,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,mBAAmB,EACnB,OAAO,EACP,YAAY,EACZ,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,+BAA+B,CACvC,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAChD,OAAO,yBAAyB,CACjC,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE7E,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEhE,YAAY,EACV,QAAQ,EACR,eAAe,EACf,KAAK,EACL,SAAS,EACT,aAAa,EACb,qBAAqB,EACrB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ export * from "./history/index.js";
5
5
  export * from "./fileImport.svelte.js";
6
6
  export * from "./agentTools.svelte.js";
7
7
  export * from "./outline.svelte.js";
8
- export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, } from "@pixerate/editor";
8
+ export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, bindDirtyToHistory, withoutDirty, } from "@pixerate/editor";
9
9
  export { default as EditableTextNodeEditor } from "./EditableTextNodeEditor.svelte";
10
10
  export { default as BubbleMenu } from "./BubbleMenu.svelte";
11
11
  export { default as TemplateRenderer } from "./TemplateRenderer.svelte";
@@ -14,3 +14,4 @@ export { default as OutlinePanel } from "./OutlinePanel.svelte";
14
14
  export * from "./spreadsheet/index.js";
15
15
  export * from "./image-editor/index.js";
16
16
  export * from "./review/index.js";
17
+ export * from "./commands/index.js";
@@ -12,7 +12,8 @@
12
12
  type CellRange,
13
13
  type SpreadsheetMenuItem,
14
14
  type SpreadsheetViewColumn,
15
- type SpreadsheetViewRow
15
+ type SpreadsheetViewRow,
16
+ formatCellDisplay
16
17
  } from '@pixerate/editor/spreadsheet';
17
18
  import FormulaBar from './FormulaBar.svelte';
18
19
  import SpreadsheetContextMenu from './SpreadsheetContextMenu.svelte';
@@ -589,7 +590,7 @@
589
590
  class="truncate block max-w-full {cell.error ? 'text-destructive font-semibold' : ''}"
590
591
  title={cell.error ? (cell.errorMessage ?? cell.error) : undefined}
591
592
  >
592
- {cell.error || (cell.value ?? '')}
593
+ {formatCellDisplay(cell)}
593
594
  </span>
594
595
  {/if}
595
596
  {#if activeSpill && rangeContains(activeSpill.range, rIdx, cIdx)}
@@ -1 +1 @@
1
- {"version":3,"file":"SpreadsheetEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/SpreadsheetEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAMH,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,QAAQ,EAKd,MAAM,8BAA8B,CAAC;AAKxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIlE,UAAU,KAAK;IACb,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EACf,OAAO,CAAC,CAAC,QAAQ,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC,GACtD,OAAO,CAAC,CAAC;QAAE,GAAG,EAAE,cAAc,CAAC;QAAC,GAAG,EAAE,iBAAiB,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzD;AA+hBH,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"SpreadsheetEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/SpreadsheetEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAMH,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,QAAQ,EAMd,MAAM,8BAA8B,CAAC;AAKxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIlE,UAAU,KAAK;IACb,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EACf,OAAO,CAAC,CAAC,QAAQ,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC,GACtD,OAAO,CAAC,CAAC;QAAE,GAAG,EAAE,cAAc,CAAC;QAAC,GAAG,EAAE,iBAAiB,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzD;AA+hBH,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"spreadsheet.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/spreadsheet.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EAErB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,4BAAiC;;aAmL8zuB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA/G33uB,MAAM;;mBAMX,MAAM,SAAS,MAAM,GAAG,QAAQ;wBAG3B,MAAM,SAAS,MAAM,OAAO,MAAM;oBAItC,MAAM,OAAO,MAAM;uBAKhB,SAAS;uBAIT,MAAM,QAAQ,MAAM,eAAe,MAAM;wBAMxC,MAAM;;oBAWV,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;wBAK5B,MAAM,WAAW,OAAO,CAAC,iBAAiB,CAAC;wBAI3C,MAAM;qBAIT,MAAM,WAAW,OAAO,CAAC,cAAc,CAAC;qBAIxC,MAAM;0BAID,MAAM,SAAS,MAAM;8BAIjB,MAAM,gBAAgB,MAAM;2BAI/B,mBAAmB;;2BAanB,qBAAqB;6BAInB,MAAM,GAAG,SAAS;;wBAQvB,SAAS,GAAG,IAAI;wBAGhB,MAAM;;;EAc7B"}
1
+ {"version":3,"file":"spreadsheet.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/spreadsheet.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EAErB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,4BAAiC;;aAmLy20B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA/Gt60B,MAAM;;mBAMX,MAAM,SAAS,MAAM,GAAG,QAAQ;wBAG3B,MAAM,SAAS,MAAM,OAAO,MAAM;oBAItC,MAAM,OAAO,MAAM;uBAKhB,SAAS;uBAIT,MAAM,QAAQ,MAAM,eAAe,MAAM;wBAMxC,MAAM;;oBAWV,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;wBAK5B,MAAM,WAAW,OAAO,CAAC,iBAAiB,CAAC;wBAI3C,MAAM;qBAIT,MAAM,WAAW,OAAO,CAAC,cAAc,CAAC;qBAIxC,MAAM;0BAID,MAAM,SAAS,MAAM;8BAIjB,MAAM,gBAAgB,MAAM;2BAI/B,mBAAmB;;2BAanB,qBAAqB;6BAInB,MAAM,GAAG,SAAS;;wBAQvB,SAAS,GAAG,IAAI;wBAGhB,MAAM;;;EAc7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-svelte",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -33,6 +33,11 @@
33
33
  "svelte": "./dist/image-editor/index.js",
34
34
  "default": "./dist/image-editor/index.js"
35
35
  },
36
+ "./commands": {
37
+ "types": "./dist/commands/index.d.ts",
38
+ "svelte": "./dist/commands/index.js",
39
+ "default": "./dist/commands/index.js"
40
+ },
36
41
  "./package.json": "./package.json"
37
42
  },
38
43
  "typesVersions": {
@@ -45,6 +50,9 @@
45
50
  ],
46
51
  "image-editor": [
47
52
  "./dist/image-editor/index.d.ts"
53
+ ],
54
+ "commands": [
55
+ "./dist/commands/index.d.ts"
48
56
  ]
49
57
  }
50
58
  },
@@ -59,7 +67,7 @@
59
67
  "@tiptap/extension-bubble-menu": "^2.11.5",
60
68
  "@tiptap/extension-placeholder": "^2.11.5",
61
69
  "@tiptap/starter-kit": "^2.11.5",
62
- "@pixerate/editor": "0.22.0"
70
+ "@pixerate/editor": "0.23.0"
63
71
  },
64
72
  "peerDependencies": {
65
73
  "@dagrejs/dagre": "^1.1.4",