@pixerate/editor-svelte 0.18.0 → 0.19.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 (75) hide show
  1. package/README.md +22 -1
  2. package/dist/EditableTextNodeEditor.svelte +19 -3
  3. package/dist/EditableTextNodeEditor.svelte.d.ts +5 -1
  4. package/dist/EditableTextNodeEditor.svelte.d.ts.map +1 -1
  5. package/dist/OutlinePanel.svelte +85 -0
  6. package/dist/OutlinePanel.svelte.d.ts +25 -0
  7. package/dist/OutlinePanel.svelte.d.ts.map +1 -0
  8. package/dist/TemplateRenderer.svelte +54 -7
  9. package/dist/TemplateRenderer.svelte.d.ts +8 -1
  10. package/dist/TemplateRenderer.svelte.d.ts.map +1 -1
  11. package/dist/VariableForm.svelte +86 -0
  12. package/dist/VariableForm.svelte.d.ts +21 -0
  13. package/dist/VariableForm.svelte.d.ts.map +1 -0
  14. package/dist/agentTools.svelte.d.ts +12 -0
  15. package/dist/agentTools.svelte.d.ts.map +1 -0
  16. package/dist/agentTools.svelte.js +17 -0
  17. package/dist/canvas/CanvasGuidesLayer.svelte +52 -0
  18. package/dist/canvas/CanvasGuidesLayer.svelte.d.ts +16 -0
  19. package/dist/canvas/CanvasGuidesLayer.svelte.d.ts.map +1 -0
  20. package/dist/canvas/createCanvasArrange.svelte.d.ts +63 -0
  21. package/dist/canvas/createCanvasArrange.svelte.d.ts.map +1 -0
  22. package/dist/canvas/createCanvasArrange.svelte.js +60 -0
  23. package/dist/canvas/createCanvasScenes.svelte.d.ts +51 -0
  24. package/dist/canvas/createCanvasScenes.svelte.d.ts.map +1 -0
  25. package/dist/canvas/createCanvasScenes.svelte.js +62 -0
  26. package/dist/canvas/index.d.ts +4 -0
  27. package/dist/canvas/index.d.ts.map +1 -1
  28. package/dist/canvas/index.js +5 -0
  29. package/dist/fileImport.svelte.d.ts +25 -0
  30. package/dist/fileImport.svelte.d.ts.map +1 -0
  31. package/dist/fileImport.svelte.js +40 -0
  32. package/dist/index.d.ts +11 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +6 -0
  35. package/dist/outline.svelte.d.ts +18 -0
  36. package/dist/outline.svelte.d.ts.map +1 -0
  37. package/dist/outline.svelte.js +27 -0
  38. package/dist/review/CommentButton.svelte +32 -0
  39. package/dist/review/CommentButton.svelte.d.ts +10 -0
  40. package/dist/review/CommentButton.svelte.d.ts.map +1 -0
  41. package/dist/review/CommentsPanel.svelte +226 -0
  42. package/dist/review/CommentsPanel.svelte.d.ts +18 -0
  43. package/dist/review/CommentsPanel.svelte.d.ts.map +1 -0
  44. package/dist/review/ReviewToolbar.svelte +86 -0
  45. package/dist/review/ReviewToolbar.svelte.d.ts +9 -0
  46. package/dist/review/ReviewToolbar.svelte.d.ts.map +1 -0
  47. package/dist/review/index.d.ts +12 -0
  48. package/dist/review/index.d.ts.map +1 -0
  49. package/dist/review/index.js +4 -0
  50. package/dist/review/review.svelte.d.ts +40 -0
  51. package/dist/review/review.svelte.d.ts.map +1 -0
  52. package/dist/review/review.svelte.js +104 -0
  53. package/dist/spreadsheet/FormulaBar.svelte +13 -5
  54. package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -1
  55. package/dist/spreadsheet/FormulaHints.svelte +149 -0
  56. package/dist/spreadsheet/FormulaHints.svelte.d.ts +14 -0
  57. package/dist/spreadsheet/FormulaHints.svelte.d.ts.map +1 -0
  58. package/dist/spreadsheet/SpreadsheetContextMenu.svelte +60 -0
  59. package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts +11 -0
  60. package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts.map +1 -0
  61. package/dist/spreadsheet/SpreadsheetEditor.svelte +172 -19
  62. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -1
  63. package/dist/spreadsheet/SpreadsheetGroupRow.svelte +55 -0
  64. package/dist/spreadsheet/SpreadsheetGroupRow.svelte.d.ts +14 -0
  65. package/dist/spreadsheet/SpreadsheetGroupRow.svelte.d.ts.map +1 -0
  66. package/dist/spreadsheet/index.d.ts +6 -0
  67. package/dist/spreadsheet/index.d.ts.map +1 -1
  68. package/dist/spreadsheet/index.js +4 -0
  69. package/dist/spreadsheet/spreadsheet.svelte.d.ts +42 -4
  70. package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -1
  71. package/dist/spreadsheet/spreadsheet.svelte.js +16 -2
  72. package/dist/spreadsheet/tableInteractions.d.ts +28 -0
  73. package/dist/spreadsheet/tableInteractions.d.ts.map +1 -0
  74. package/dist/spreadsheet/tableInteractions.js +61 -0
  75. package/package.json +2 -2
package/README.md CHANGED
@@ -35,6 +35,10 @@ Requires **Svelte 5** (the components use runes). Components ship as `.svelte` s
35
35
 
36
36
  `content` sets the initial document. Read later changes from the bound `editor` (for example in `onUpdate`), as above. The editor is preloaded with `createRichTextPreset()`. Pass `markdown`, `image`, `uploadImage`, `extensions` or `richTextOptions` to configure it.
37
37
 
38
+ `fileImport` imports dropped/pasted `.md`, `.html`, `.txt` and `.rtf` files at the drop position, and `richClipboard` copies lossless slices between editors (both opt-in). `createFileImport(() => editor)` returns reactive `isImporting` / `error` plus `openFilePicker()` and `importFiles()` for an import button.
39
+
40
+ `useAgentToolProvider(registry, () => editor && createRichTextToolProvider(editor, { id: "doc" }))` registers an agent tool provider (see `ToolRegistry` in `@pixerate/editor/agent`) for the component's lifetime. Call it during component initialisation.
41
+
38
42
  ## Read-only token renderer
39
43
 
40
44
  ```svelte
@@ -46,11 +50,28 @@ Requires **Svelte 5** (the components use runes). Components ship as `.svelte` s
46
50
  <TemplateRenderer content={"A photo of {subject} in {{golden_hour}}"} {templates} resolve />
47
51
  ```
48
52
 
53
+ ## Comments and tracked changes
54
+
55
+ ```svelte
56
+ <script lang="ts">
57
+ import { Comments, TrackChanges } from "@pixerate/editor";
58
+ import { EditableTextNodeEditor, CommentsPanel, ReviewToolbar } from "@pixerate/editor-svelte";
59
+ let editor = $state();
60
+ const extensions = [Comments.configure({ author: me }), TrackChanges.configure({ author: me })];
61
+ </script>
62
+
63
+ <ReviewToolbar {editor} />
64
+ <EditableTextNodeEditor bind:editor {extensions} />
65
+ <CommentsPanel {editor} />
66
+ ```
67
+
68
+ Put `<CommentButton {editor} />` inside a `BubbleMenu` to comment on the selection. `createComments(editorOrStore)` and `createTrackChanges(editor)` are rune (and Svelte store) adapters for custom UIs.
69
+
49
70
  ## More exports
50
71
 
51
72
  | Import | Exports |
52
73
  | :--- | :--- |
53
- | `@pixerate/editor-svelte` | `EditableTextNodeEditor`, `BubbleMenu`, `TemplateRenderer`, `initiateEditor`, `createReactiveEditor`, `createHistory`, `createHistoryShortcuts`, `navigationGuard` (action), `createNavigationGuard`, `SpreadsheetEditor`, `FormulaBar`, `createReactiveSpreadsheet`, `DirtyTracker` |
74
+ | `@pixerate/editor-svelte` | `EditableTextNodeEditor`, `BubbleMenu`, `TemplateRenderer`, `initiateEditor`, `createReactiveEditor`, `createHistory`, `createHistoryShortcuts`, `navigationGuard` (action), `createNavigationGuard`, `SpreadsheetEditor`, `FormulaBar`, `FormulaHints`, `createReactiveSpreadsheet`, `DirtyTracker` |
54
75
  | `@pixerate/editor-svelte/image-editor` | `ImageEditor`, `createReactiveImageEditor`: crop, rotate/flip, adjustments, annotations, depth masks, and `onInpaint` / `onRemoveBackground` AI hooks |
55
76
  | `@pixerate/editor-svelte/canvas` | Runes for `@xyflow/svelte`: `createCanvasGraph`, `createCanvasClipboard`, `createCanvasDocking`, `createCanvasShortcuts`, `createCanvasInteractions`, `createCanvasExplosion`, `createCanvasNodeSync`, `createCanvasMultiDrag`, `createStreamingCanvas`, `AgentPresenceLayer`, `FloatingHorizontalScrollbar`, plus layout helpers |
56
77
 
@@ -1,6 +1,12 @@
1
1
  <script lang="ts">
2
2
  import type { Editor, Content, Extensions, FocusPosition } from "@tiptap/core";
3
- import type { RichTextPresetOptions, MarkdownOptions, ImageOptions } from "@pixerate/editor";
3
+ import type {
4
+ RichTextPresetOptions,
5
+ MarkdownOptions,
6
+ ImageOptions,
7
+ FileImportOptions,
8
+ RichClipboardOptions,
9
+ } from "@pixerate/editor";
4
10
  import { onDestroy, onMount } from "svelte";
5
11
  import { initiateEditor } from "./editor.svelte.js";
6
12
 
@@ -23,6 +29,10 @@
23
29
  image?: ImageOptions | boolean;
24
30
  uploadImage?: (file: File) => Promise<string> | string;
25
31
  onUploadError?: (error: Error, file: File) => void;
32
+ /** Import .md, .html, .txt and .rtf files dropped or pasted into the editor (opt-in). */
33
+ fileImport?: FileImportOptions | boolean;
34
+ /** Copy/paste lossless ProseMirror slices between editors (opt-in). */
35
+ richClipboard?: RichClipboardOptions | boolean;
26
36
  }
27
37
 
28
38
  let {
@@ -44,6 +54,8 @@
44
54
  image = undefined,
45
55
  uploadImage = undefined,
46
56
  onUploadError = undefined,
57
+ fileImport = undefined,
58
+ richClipboard = undefined,
47
59
  }: EditorProps = $props();
48
60
 
49
61
  let element = $state<HTMLElement>();
@@ -75,12 +87,16 @@
75
87
  },
76
88
  }
77
89
  : {}),
90
+ ...(fileImport !== undefined ? { fileImport } : {}),
91
+ ...(richClipboard !== undefined ? { richClipboard } : {}),
78
92
  ...richTextOptions,
79
93
  },
80
94
  editable,
81
95
  autofocus,
82
- onCreate,
83
- onUpdate,
96
+ // TipTap registers these as event listeners; passing `undefined`
97
+ // overrides its no-op defaults and makes `emit` throw.
98
+ ...(onCreate ? { onCreate } : {}),
99
+ ...(onUpdate ? { onUpdate } : {}),
84
100
  onFocus() {
85
101
  if (onFocus) onFocus();
86
102
  },
@@ -1,5 +1,5 @@
1
1
  import type { Editor, Content, Extensions, FocusPosition } from "@tiptap/core";
2
- import type { RichTextPresetOptions, MarkdownOptions, ImageOptions } from "@pixerate/editor";
2
+ import type { RichTextPresetOptions, MarkdownOptions, ImageOptions, FileImportOptions, RichClipboardOptions } from "@pixerate/editor";
3
3
  interface EditorProps {
4
4
  class?: string;
5
5
  editorClass?: string;
@@ -19,6 +19,10 @@ interface EditorProps {
19
19
  image?: ImageOptions | boolean;
20
20
  uploadImage?: (file: File) => Promise<string> | string;
21
21
  onUploadError?: (error: Error, file: File) => void;
22
+ /** Import .md, .html, .txt and .rtf files dropped or pasted into the editor (opt-in). */
23
+ fileImport?: FileImportOptions | boolean;
24
+ /** Copy/paste lossless ProseMirror slices between editors (opt-in). */
25
+ richClipboard?: RichClipboardOptions | boolean;
22
26
  }
23
27
  declare const EditableTextNodeEditor: import("svelte").Component<EditorProps, {}, "editor">;
24
28
  type EditableTextNodeEditor = ReturnType<typeof EditableTextNodeEditor>;
@@ -1 +1 @@
1
- {"version":3,"file":"EditableTextNodeEditor.svelte.d.ts","sourceRoot":"","sources":["../src/EditableTextNodeEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAK3F,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IACrC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACpD;AA8FH,QAAA,MAAM,sBAAsB,uDAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"EditableTextNodeEditor.svelte.d.ts","sourceRoot":"","sources":["../src/EditableTextNodeEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EACR,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAK1B,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IACrC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IAC/B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnD,yFAAyF;IACzF,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;IACzC,uEAAuE;IACvE,aAAa,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC;CAChD;AAoGH,QAAA,MAAM,sBAAsB,uDAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,85 @@
1
+ <script lang="ts">
2
+ import type { Editor } from "@tiptap/core";
3
+ import type { Snippet } from "svelte";
4
+ import { navigateToHeading, type OutlineHeading } from "@pixerate/editor";
5
+ import { createOutline } from "./outline.svelte.js";
6
+
7
+ interface Props {
8
+ editor?: Editor | null;
9
+ /** Heading shown above the list. Pass `null` to hide it. */
10
+ title?: string | null;
11
+ /** Text shown when the document has no headings. */
12
+ emptyText?: string;
13
+ /** Deepest heading level listed. Defaults to 6. */
14
+ maxLevel?: number;
15
+ /** Whether clicking an entry focuses the editor. Defaults to `true`. */
16
+ focusOnNavigate?: boolean;
17
+ class?: string;
18
+ itemClass?: string;
19
+ activeItemClass?: string;
20
+ /** Called after navigating to a heading. */
21
+ onNavigate?: (heading: OutlineHeading) => void;
22
+ /** Custom empty state, rendered instead of `emptyText`. */
23
+ empty?: Snippet;
24
+ }
25
+
26
+ let {
27
+ editor = null,
28
+ title = "Outline",
29
+ emptyText = "Add headings to see the outline.",
30
+ maxLevel = 6,
31
+ focusOnNavigate = true,
32
+ class: className = "flex flex-col gap-1 text-sm",
33
+ itemClass = "w-full truncate rounded px-2 py-1 text-left hover:bg-black/5",
34
+ activeItemClass = "font-semibold bg-black/5",
35
+ onNavigate,
36
+ empty,
37
+ }: Props = $props();
38
+
39
+ let outline = $state.raw<ReturnType<typeof createOutline> | null>(null);
40
+
41
+ $effect(() => {
42
+ const instance = createOutline(editor);
43
+ outline = instance;
44
+ return () => instance.destroy();
45
+ });
46
+
47
+ const snapshot = $derived(outline?.current ?? { headings: [], tree: [], activeId: null });
48
+ const visible = $derived(snapshot.headings.filter((h) => h.level <= maxLevel));
49
+
50
+ function navigate(heading: OutlineHeading) {
51
+ if (!editor) return;
52
+ if (navigateToHeading(editor, heading, { focus: focusOnNavigate })) {
53
+ onNavigate?.(heading);
54
+ }
55
+ }
56
+ </script>
57
+
58
+ <nav class={className} aria-label="Document outline" data-outline-panel="">
59
+ {#if title != null}
60
+ <div class="pixerate-outline-title">{title}</div>
61
+ {/if}
62
+ {#if visible.length === 0}
63
+ <div class="pixerate-outline-empty">
64
+ {#if empty}{@render empty()}{:else}{emptyText}{/if}
65
+ </div>
66
+ {:else}
67
+ <ul role="list" style="list-style: none; margin: 0; padding: 0;">
68
+ {#each visible as heading (heading.id)}
69
+ {@const active = heading.id === snapshot.activeId}
70
+ <li data-level={heading.level}>
71
+ <button
72
+ type="button"
73
+ class={active ? `${itemClass} ${activeItemClass}` : itemClass}
74
+ style="padding-left: {0.5 + heading.depth * 0.75}rem"
75
+ aria-current={active ? "location" : undefined}
76
+ data-heading-id={heading.id}
77
+ onclick={() => navigate(heading)}
78
+ >
79
+ {heading.text || "Untitled"}
80
+ </button>
81
+ </li>
82
+ {/each}
83
+ </ul>
84
+ {/if}
85
+ </nav>
@@ -0,0 +1,25 @@
1
+ import type { Editor } from "@tiptap/core";
2
+ import type { Snippet } from "svelte";
3
+ import { type OutlineHeading } from "@pixerate/editor";
4
+ interface Props {
5
+ editor?: Editor | null;
6
+ /** Heading shown above the list. Pass `null` to hide it. */
7
+ title?: string | null;
8
+ /** Text shown when the document has no headings. */
9
+ emptyText?: string;
10
+ /** Deepest heading level listed. Defaults to 6. */
11
+ maxLevel?: number;
12
+ /** Whether clicking an entry focuses the editor. Defaults to `true`. */
13
+ focusOnNavigate?: boolean;
14
+ class?: string;
15
+ itemClass?: string;
16
+ activeItemClass?: string;
17
+ /** Called after navigating to a heading. */
18
+ onNavigate?: (heading: OutlineHeading) => void;
19
+ /** Custom empty state, rendered instead of `emptyText`. */
20
+ empty?: Snippet;
21
+ }
22
+ declare const OutlinePanel: import("svelte").Component<Props, {}, "">;
23
+ type OutlinePanel = ReturnType<typeof OutlinePanel>;
24
+ export default OutlinePanel;
25
+ //# sourceMappingURL=OutlinePanel.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OutlinePanel.svelte.d.ts","sourceRoot":"","sources":["../src/OutlinePanel.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIxE,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,2DAA2D;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAgEH,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -1,9 +1,10 @@
1
1
  <script lang="ts">
2
2
  import {
3
- tokenizePrompt,
3
+ evaluatePromptTokens,
4
4
  resolveTemplates,
5
5
  type Template,
6
6
  type ColorGradient,
7
+ type PromptValues,
7
8
  } from "@pixerate/editor";
8
9
 
9
10
  interface Props {
@@ -11,6 +12,13 @@
11
12
  templates?: Template[];
12
13
  templateColorMap?: Map<string, ColorGradient>;
13
14
  resolve?: boolean;
15
+ /** Template version bindings used when `resolve` is set. */
16
+ bindings?: Record<string, string>;
17
+ /**
18
+ * Variable values. When set, variables show their value (or default),
19
+ * sections whose condition fails are hidden, and section tags are dropped.
20
+ */
21
+ values?: PromptValues;
14
22
  class?: string;
15
23
  onTemplateClick?: (templateName: string) => void;
16
24
  onVariableClick?: (variableName: string) => void;
@@ -21,18 +29,41 @@
21
29
  templates = [],
22
30
  templateColorMap,
23
31
  resolve = false,
32
+ bindings,
33
+ values,
24
34
  class: className = "font-mono text-sm leading-relaxed whitespace-pre-wrap break-words",
25
35
  onTemplateClick,
26
36
  onVariableClick,
27
37
  }: Props = $props();
28
38
 
39
+ const CONDITIONAL_PREFIX = { if: "?", unless: "!", end: "/" } as const;
40
+
29
41
  let displayText = $derived(
30
42
  resolve && templates.length > 0
31
- ? resolveTemplates(content, templates)
43
+ ? resolveTemplates(content, templates, { bindings })
32
44
  : content
33
45
  );
34
46
 
35
- let tokens = $derived(tokenizePrompt(displayText));
47
+ let tokens = $derived(evaluatePromptTokens(displayText, values));
48
+
49
+ function variableDetails(token: (typeof tokens)[number]): string {
50
+ return [
51
+ `Variable: ${token.value}`,
52
+ token.description,
53
+ token.defaultValue !== undefined
54
+ ? `Default: ${token.defaultValue || "(empty)"}`
55
+ : undefined,
56
+ ]
57
+ .filter(Boolean)
58
+ .join("\n");
59
+ }
60
+
61
+ function conditionalTitle(token: (typeof tokens)[number]): string {
62
+ if (token.conditional === "end") return `End of section: ${token.value}`;
63
+ return token.conditional === "if"
64
+ ? `Shown when "${token.value}" has a value`
65
+ : `Shown when "${token.value}" is empty`;
66
+ }
36
67
  </script>
37
68
 
38
69
  <div class={className}>
@@ -48,15 +79,31 @@
48
79
  >
49
80
  {`{{${token.value}}}`}
50
81
  </span>
82
+ {:else if token.type === "variable" && token.resolvedValue !== undefined}
83
+ <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions -->
84
+ <span
85
+ onclick={() => onVariableClick?.(token.value)}
86
+ data-variable={token.value}
87
+ data-value-source={token.valueSource}
88
+ class={token.valueSource === "value"
89
+ ? "inline px-1 mx-0.5 rounded-md bg-emerald-400/15 text-emerald-700 border-b border-emerald-400/60 cursor-pointer"
90
+ : "inline px-1 mx-0.5 rounded-md bg-violet-400/10 text-violet-600 italic border-b border-dashed border-violet-400/60 cursor-pointer"}
91
+ title={variableDetails(token)}
92
+ >{token.resolvedValue}</span>
51
93
  {:else if token.type === "variable"}
52
94
  <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions -->
53
95
  <span
54
96
  onclick={() => onVariableClick?.(token.value)}
97
+ data-variable={token.value}
55
98
  class="inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-violet-400/40 bg-violet-400/15 text-violet-600 hover:brightness-110 cursor-pointer transition-all"
56
- title={`Variable: ${token.value}`}
57
- >
58
- {`{${token.value}}`}
59
- </span>
99
+ title={variableDetails(token)}
100
+ >{`{${token.value}`}{#if token.defaultValue !== undefined}<span class="opacity-60">{`|${token.defaultValue}`}</span>{/if}{"}"}</span>
101
+ {:else if token.type === "conditional" && token.conditional}
102
+ <span
103
+ data-conditional={token.conditional}
104
+ class="inline-flex items-center px-1 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-amber-400/40 bg-amber-400/15 text-amber-700"
105
+ title={conditionalTitle(token)}
106
+ >{`{${CONDITIONAL_PREFIX[token.conditional]}${token.value}}`}</span>
60
107
  {:else if token.type === "instruction"}
61
108
  <span
62
109
  class="inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs italic font-medium rounded-md border border-rose-400/40 bg-rose-400/15 text-rose-600"
@@ -1,9 +1,16 @@
1
- import { type Template, type ColorGradient } from "@pixerate/editor";
1
+ import { type Template, type ColorGradient, type PromptValues } from "@pixerate/editor";
2
2
  interface Props {
3
3
  content: string;
4
4
  templates?: Template[];
5
5
  templateColorMap?: Map<string, ColorGradient>;
6
6
  resolve?: boolean;
7
+ /** Template version bindings used when `resolve` is set. */
8
+ bindings?: Record<string, string>;
9
+ /**
10
+ * Variable values. When set, variables show their value (or default),
11
+ * sections whose condition fails are hidden, and section tags are dropped.
12
+ */
13
+ values?: PromptValues;
7
14
  class?: string;
8
15
  onTemplateClick?: (templateName: string) => void;
9
16
  onVariableClick?: (variableName: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/TemplateRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAGH,KAAK,QAAQ,EACb,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAG1B,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAiDH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"TemplateRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/TemplateRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAGH,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAG1B,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AA6EH,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,86 @@
1
+ <!--
2
+ Inputs are nested in their labels, which associates them without ids
3
+ (`$props.id()` needs Svelte 5.20, newer than our peer range).
4
+ -->
5
+ <script lang="ts">
6
+ import {
7
+ compactVariableValues,
8
+ getVariableFormFields,
9
+ type PromptValues,
10
+ type Template,
11
+ } from "@pixerate/editor";
12
+
13
+ interface Props {
14
+ /** Prompt whose variables become form fields. */
15
+ content: string;
16
+ /** Templates searched recursively for further variables. */
17
+ templates?: Template[];
18
+ /** Template version bindings. */
19
+ bindings?: Record<string, string>;
20
+ /** Entered text per variable. Bindable. */
21
+ values?: Record<string, string>;
22
+ /**
23
+ * Called on every edit with the values to resolve with (blank fields
24
+ * dropped so defaults apply) and the raw entered text.
25
+ */
26
+ onChange?: (values: PromptValues, entered: Record<string, string>) => void;
27
+ class?: string;
28
+ }
29
+
30
+ let {
31
+ content,
32
+ templates,
33
+ bindings,
34
+ values = $bindable({}),
35
+ onChange,
36
+ class: className = "flex flex-col gap-3 text-sm",
37
+ }: Props = $props();
38
+
39
+ let fields = $derived(getVariableFormFields(content, { templates, bindings }));
40
+
41
+ function update(name: string, value: string) {
42
+ const next = { ...values, [name]: value };
43
+ values = next;
44
+ onChange?.(compactVariableValues(next), next);
45
+ }
46
+ </script>
47
+
48
+ {#if fields.length > 0}
49
+ <form class={className} onsubmit={(event) => event.preventDefault()}>
50
+ {#each fields as field (field.name)}
51
+ {#if field.conditionOnly}
52
+ <label
53
+ class="flex items-center gap-2"
54
+ data-variable-field={field.name}
55
+ >
56
+ <input
57
+ name={field.name}
58
+ type="checkbox"
59
+ checked={(values[field.name] ?? "") !== ""}
60
+ onchange={(event) =>
61
+ update(field.name, event.currentTarget.checked ? "true" : "")}
62
+ />
63
+ <span>{field.label}</span>
64
+ </label>
65
+ {:else}
66
+ <label
67
+ class="flex flex-col gap-1"
68
+ data-variable-field={field.name}
69
+ >
70
+ <span class="font-medium"
71
+ >{field.label}{#if field.required}<span class="text-rose-500" aria-hidden="true">{" *"}</span>{/if}</span
72
+ >
73
+ <input
74
+ name={field.name}
75
+ type="text"
76
+ value={values[field.name] ?? ""}
77
+ placeholder={field.placeholder}
78
+ aria-required={field.required || undefined}
79
+ oninput={(event) => update(field.name, event.currentTarget.value)}
80
+ class="px-2 py-1 rounded-md border border-violet-400/40 bg-transparent"
81
+ />
82
+ </label>
83
+ {/if}
84
+ {/each}
85
+ </form>
86
+ {/if}
@@ -0,0 +1,21 @@
1
+ import { type PromptValues, type Template } from "@pixerate/editor";
2
+ interface Props {
3
+ /** Prompt whose variables become form fields. */
4
+ content: string;
5
+ /** Templates searched recursively for further variables. */
6
+ templates?: Template[];
7
+ /** Template version bindings. */
8
+ bindings?: Record<string, string>;
9
+ /** Entered text per variable. Bindable. */
10
+ values?: Record<string, string>;
11
+ /**
12
+ * Called on every edit with the values to resolve with (blank fields
13
+ * dropped so defaults apply) and the raw entered text.
14
+ */
15
+ onChange?: (values: PromptValues, entered: Record<string, string>) => void;
16
+ class?: string;
17
+ }
18
+ declare const VariableForm: import("svelte").Component<Props, {}, "values">;
19
+ type VariableForm = ReturnType<typeof VariableForm>;
20
+ export default VariableForm;
21
+ //# sourceMappingURL=VariableForm.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableForm.svelte.d.ts","sourceRoot":"","sources":["../src/VariableForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAGH,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAC;AAG1B,UAAU,KAAK;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6CH,QAAA,MAAM,YAAY,iDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { AgentToolProvider, ToolRegistry } from "@pixerate/editor/agent";
2
+ type MaybeGetter<T> = T | (() => T);
3
+ /**
4
+ * Registers a tool provider with a `ToolRegistry` for the lifetime of the
5
+ * calling component (call it during component initialisation) and
6
+ * unregisters it on destroy. Pass getters to react to changes, e.g.
7
+ * `useAgentToolProvider(registry, () => editor && createRichTextToolProvider(editor, { id }))`:
8
+ * when the getter returns a different provider, the old one is unregistered.
9
+ */
10
+ export declare function useAgentToolProvider(registry: MaybeGetter<ToolRegistry | null | undefined>, provider: MaybeGetter<AgentToolProvider | null | undefined>): void;
11
+ export {};
12
+ //# sourceMappingURL=agentTools.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentTools.svelte.d.ts","sourceRoot":"","sources":["../src/agentTools.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE9E,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAKpC;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,CAAC,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC,EACtD,QAAQ,EAAE,WAAW,CAAC,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAC,GAC1D,IAAI,CAON"}
@@ -0,0 +1,17 @@
1
+ const read = (value) => typeof value === "function" ? value() : value;
2
+ /**
3
+ * Registers a tool provider with a `ToolRegistry` for the lifetime of the
4
+ * calling component (call it during component initialisation) and
5
+ * unregisters it on destroy. Pass getters to react to changes, e.g.
6
+ * `useAgentToolProvider(registry, () => editor && createRichTextToolProvider(editor, { id }))`:
7
+ * when the getter returns a different provider, the old one is unregistered.
8
+ */
9
+ export function useAgentToolProvider(registry, provider) {
10
+ $effect(() => {
11
+ const currentRegistry = read(registry);
12
+ const currentProvider = read(provider);
13
+ if (!currentRegistry || !currentProvider)
14
+ return;
15
+ return currentRegistry.register(currentProvider);
16
+ });
17
+ }
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import type { CanvasViewport, GuideLine } from '@pixerate/editor/canvas';
3
+
4
+ interface Props {
5
+ /** Guide segments in flow coordinates (e.g. `arrange.guides`). */
6
+ guides: GuideLine[];
7
+ /** Current viewport (`useSvelteFlow().getViewport()` or the `viewport` binding). */
8
+ viewport?: CanvasViewport;
9
+ /** Colour of edge and centre guides. */
10
+ color?: string;
11
+ /** Colour of equal-spacing guides. */
12
+ spacingColor?: string;
13
+ class?: string;
14
+ }
15
+
16
+ let {
17
+ guides = [],
18
+ viewport = { x: 0, y: 0, zoom: 1 },
19
+ color = '#f59e0b',
20
+ spacingColor = '#ec4899',
21
+ class: className = ''
22
+ }: Props = $props();
23
+
24
+ const toScreen = (x: number, y: number) => ({
25
+ x: x * viewport.zoom + viewport.x,
26
+ y: y * viewport.zoom + viewport.y
27
+ });
28
+ </script>
29
+
30
+ {#if guides.length > 0}
31
+ <svg
32
+ class="pixerate-canvas-guides {className}"
33
+ style="position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; z-index: 10;"
34
+ aria-hidden="true"
35
+ >
36
+ {#each guides as guide, i (i)}
37
+ {@const a = toScreen(guide.x1, guide.y1)}
38
+ {@const b = toScreen(guide.x2, guide.y2)}
39
+ <line
40
+ data-kind={guide.kind}
41
+ x1={a.x}
42
+ y1={a.y}
43
+ x2={b.x}
44
+ y2={b.y}
45
+ stroke={guide.kind === 'spacing' ? spacingColor : color}
46
+ stroke-width="1"
47
+ stroke-dasharray={guide.kind === 'centre' ? '4 3' : undefined}
48
+ shape-rendering="crispEdges"
49
+ />
50
+ {/each}
51
+ </svg>
52
+ {/if}
@@ -0,0 +1,16 @@
1
+ import type { CanvasViewport, GuideLine } from '@pixerate/editor/canvas';
2
+ interface Props {
3
+ /** Guide segments in flow coordinates (e.g. `arrange.guides`). */
4
+ guides: GuideLine[];
5
+ /** Current viewport (`useSvelteFlow().getViewport()` or the `viewport` binding). */
6
+ viewport?: CanvasViewport;
7
+ /** Colour of edge and centre guides. */
8
+ color?: string;
9
+ /** Colour of equal-spacing guides. */
10
+ spacingColor?: string;
11
+ class?: string;
12
+ }
13
+ declare const CanvasGuidesLayer: import("svelte").Component<Props, {}, "">;
14
+ type CanvasGuidesLayer = ReturnType<typeof CanvasGuidesLayer>;
15
+ export default CanvasGuidesLayer;
16
+ //# sourceMappingURL=CanvasGuidesLayer.svelte.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,63 @@
1
+ import { type ArrangeShortcutBinding, type CanvasArrangeAction, type CanvasArrangeControllerOptions, type GuideLine } from '@pixerate/editor/canvas';
2
+ import type { CanvasNode } from './types.js';
3
+ type CoreOptions = CanvasArrangeControllerOptions<any>;
4
+ export interface CreateCanvasArrangeOptions<TNode extends CanvasNode = CanvasNode> extends Omit<CoreOptions, 'getNodes' | 'setNodes' | 'onGuidesChange'> {
5
+ getNodes: () => TNode[];
6
+ setNodes: (nodes: TNode[]) => void;
7
+ onGuidesChange?: (guides: GuideLine[]) => void;
8
+ }
9
+ /**
10
+ * Headless Svelte 5 rune for Freeform-style arrangement: align, distribute, make same size,
11
+ * lock / unlock, layer order and smart guides with snap-to-shape while dragging.
12
+ *
13
+ * Actions act on `getSelectedIds()` (default: selected nodes) when called without ids and
14
+ * are recorded as single undoable steps when a `HistoryManager` is passed as `history`.
15
+ *
16
+ * Wire snapping to SvelteFlow with `onnodedragstart={() => arrange.beginDrag()}`,
17
+ * `onnodedrag={({ nodes }) => arrange.drag(nodes.map((n) => n.id))}` and
18
+ * `onnodedragstop={() => arrange.endDrag()}`, and render `arrange.guides` with
19
+ * `<CanvasGuidesLayer>`.
20
+ */
21
+ export declare function createCanvasArrange<TNode extends CanvasNode = CanvasNode>(options: CreateCanvasArrangeOptions<TNode>): {
22
+ guides: GuideLine[];
23
+ apply: (name: string, updates: import("@pixerate/editor/canvas").CanvasNodeUpdate[]) => import("@pixerate/editor/canvas").CanvasNodeUpdate[];
24
+ align(edge: import("@pixerate/editor/canvas").AlignEdge, ids?: Iterable<string>, alignOptions?: import("@pixerate/editor/canvas").AlignNodesOptions): import("@pixerate/editor/canvas").CanvasNodeUpdate[];
25
+ 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[];
26
+ matchSize(dimension: import("@pixerate/editor/canvas").SizeDimension, ids?: Iterable<string>, sizeOptions?: import("@pixerate/editor/canvas").MatchSizeOptions): import("@pixerate/editor/canvas").CanvasNodeUpdate[];
27
+ reorder(operation: import("@pixerate/editor/canvas").ZOrderOperation, ids?: Iterable<string>): import("@pixerate/editor/canvas").CanvasNodeUpdate[];
28
+ bringForward: (ids?: Iterable<string>) => import("@pixerate/editor/canvas").CanvasNodeUpdate[];
29
+ sendBackward: (ids?: Iterable<string>) => import("@pixerate/editor/canvas").CanvasNodeUpdate[];
30
+ bringToFront: (ids?: Iterable<string>) => import("@pixerate/editor/canvas").CanvasNodeUpdate[];
31
+ sendToBack: (ids?: Iterable<string>) => import("@pixerate/editor/canvas").CanvasNodeUpdate[];
32
+ lock: (ids?: Iterable<string>) => string[];
33
+ unlock: (ids?: Iterable<string>) => string[];
34
+ toggleLock(ids?: Iterable<string>): string[];
35
+ isLocked: (id: string) => boolean;
36
+ runAction(action: CanvasArrangeAction): boolean;
37
+ beginDrag(ids?: Iterable<string>): void;
38
+ drag(ids?: Iterable<string>): import("@pixerate/editor/canvas").SnapNodeDragResult | null;
39
+ snapPositionChanges<TChange extends import("@pixerate/editor/canvas").PositionChangeLike>(changes: TChange[]): TChange[];
40
+ endDrag(): void;
41
+ };
42
+ export type CanvasArrange<TNode extends CanvasNode = CanvasNode> = ReturnType<typeof createCanvasArrange<TNode>>;
43
+ export interface CanvasArrangeShortcutsOptions {
44
+ arrange: {
45
+ runAction: (action: CanvasArrangeAction) => boolean;
46
+ };
47
+ /** Scenes controller for PageDown / PageUp (next / previous scene). */
48
+ scenes?: {
49
+ next: () => unknown;
50
+ previous: () => unknown;
51
+ };
52
+ targetElement?: HTMLElement | Window;
53
+ bindings?: readonly ArrangeShortcutBinding[];
54
+ }
55
+ /**
56
+ * Attaches the arrange keyboard shortcuts (see `DEFAULT_ARRANGE_SHORTCUTS`). Shortcuts are
57
+ * ignored while typing in inputs, textareas, contenteditable or ProseMirror editors.
58
+ *
59
+ * @returns A cleanup function removing the listener.
60
+ */
61
+ export declare function createCanvasArrangeShortcuts(options: CanvasArrangeShortcutsOptions): () => void;
62
+ export {};
63
+ //# sourceMappingURL=createCanvasArrange.svelte.d.ts.map