@pixerate/editor-svelte 0.23.0 → 0.25.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 (147) hide show
  1. package/README.md +4 -2
  2. package/dist/ExportDocxButton.svelte +48 -0
  3. package/dist/ExportDocxButton.svelte.d.ts +13 -0
  4. package/dist/ExportDocxButton.svelte.d.ts.map +1 -0
  5. package/dist/StylesGallery.svelte +169 -0
  6. package/dist/StylesGallery.svelte.d.ts +27 -0
  7. package/dist/StylesGallery.svelte.d.ts.map +1 -0
  8. package/dist/canvas/AnimationTimeline.svelte +217 -0
  9. package/dist/canvas/AnimationTimeline.svelte.d.ts +20 -0
  10. package/dist/canvas/AnimationTimeline.svelte.d.ts.map +1 -0
  11. package/dist/canvas/CanvasComponentsPanel.svelte +73 -0
  12. package/dist/canvas/CanvasComponentsPanel.svelte.d.ts +13 -0
  13. package/dist/canvas/CanvasComponentsPanel.svelte.d.ts.map +1 -0
  14. package/dist/canvas/CanvasInstanceInspector.svelte +136 -0
  15. package/dist/canvas/CanvasInstanceInspector.svelte.d.ts +16 -0
  16. package/dist/canvas/CanvasInstanceInspector.svelte.d.ts.map +1 -0
  17. package/dist/canvas/TokenBindingPicker.svelte +93 -0
  18. package/dist/canvas/TokenBindingPicker.svelte.d.ts +20 -0
  19. package/dist/canvas/TokenBindingPicker.svelte.d.ts.map +1 -0
  20. package/dist/canvas/TokenModeSwitcher.svelte +55 -0
  21. package/dist/canvas/TokenModeSwitcher.svelte.d.ts +18 -0
  22. package/dist/canvas/TokenModeSwitcher.svelte.d.ts.map +1 -0
  23. package/dist/canvas/createCanvasAnimation.svelte.d.ts +98 -0
  24. package/dist/canvas/createCanvasAnimation.svelte.d.ts.map +1 -0
  25. package/dist/canvas/createCanvasAnimation.svelte.js +79 -0
  26. package/dist/canvas/createCanvasArrange.svelte.d.ts +4 -0
  27. package/dist/canvas/createCanvasArrange.svelte.d.ts.map +1 -1
  28. package/dist/canvas/createCanvasAutoLayout.svelte.d.ts.map +1 -1
  29. package/dist/canvas/createCanvasComponents.svelte.d.ts +68 -0
  30. package/dist/canvas/createCanvasComponents.svelte.d.ts.map +1 -0
  31. package/dist/canvas/createCanvasComponents.svelte.js +31 -0
  32. package/dist/canvas/createCanvasTokens.svelte.d.ts +31 -0
  33. package/dist/canvas/createCanvasTokens.svelte.d.ts.map +1 -0
  34. package/dist/canvas/createCanvasTokens.svelte.js +50 -0
  35. package/dist/canvas/index.d.ts +12 -0
  36. package/dist/canvas/index.d.ts.map +1 -1
  37. package/dist/canvas/index.js +16 -0
  38. package/dist/docxExport.svelte.d.ts +26 -0
  39. package/dist/docxExport.svelte.d.ts.map +1 -0
  40. package/dist/docxExport.svelte.js +36 -0
  41. package/dist/fileImport.svelte.d.ts +8 -1
  42. package/dist/fileImport.svelte.d.ts.map +1 -1
  43. package/dist/fileImport.svelte.js +11 -1
  44. package/dist/generation/AssetMentionChips.svelte +130 -0
  45. package/dist/generation/AssetMentionChips.svelte.d.ts +21 -0
  46. package/dist/generation/AssetMentionChips.svelte.d.ts.map +1 -0
  47. package/dist/generation/GenerationHistory.svelte +161 -0
  48. package/dist/generation/GenerationHistory.svelte.d.ts +28 -0
  49. package/dist/generation/GenerationHistory.svelte.d.ts.map +1 -0
  50. package/dist/generation/index.d.ts +7 -0
  51. package/dist/generation/index.d.ts.map +1 -1
  52. package/dist/generation/index.js +3 -0
  53. package/dist/generation/records.svelte.d.ts +18 -0
  54. package/dist/generation/records.svelte.d.ts.map +1 -0
  55. package/dist/generation/records.svelte.js +66 -0
  56. package/dist/image-editor/ImageEditor.svelte +72 -1
  57. package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -1
  58. package/dist/image-editor/RefineEdgePanel.svelte +180 -0
  59. package/dist/image-editor/RefineEdgePanel.svelte.d.ts +13 -0
  60. package/dist/image-editor/RefineEdgePanel.svelte.d.ts.map +1 -0
  61. package/dist/image-editor/SelectionOptionsBar.svelte +135 -0
  62. package/dist/image-editor/SelectionOptionsBar.svelte.d.ts +15 -0
  63. package/dist/image-editor/SelectionOptionsBar.svelte.d.ts.map +1 -0
  64. package/dist/image-editor/index.d.ts +6 -0
  65. package/dist/image-editor/index.d.ts.map +1 -1
  66. package/dist/image-editor/index.js +2 -0
  67. package/dist/index.d.ts +9 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +5 -0
  70. package/dist/paragraphStyles.svelte.d.ts +30 -0
  71. package/dist/paragraphStyles.svelte.d.ts.map +1 -0
  72. package/dist/paragraphStyles.svelte.js +44 -0
  73. package/dist/review/TrackedChangesList.svelte +67 -0
  74. package/dist/review/TrackedChangesList.svelte.d.ts +13 -0
  75. package/dist/review/TrackedChangesList.svelte.d.ts.map +1 -0
  76. package/dist/review/index.d.ts +3 -0
  77. package/dist/review/index.d.ts.map +1 -1
  78. package/dist/review/index.js +1 -0
  79. package/dist/review/review.svelte.d.ts +6 -0
  80. package/dist/review/review.svelte.d.ts.map +1 -1
  81. package/dist/review/review.svelte.js +3 -0
  82. package/dist/spreadsheet/FormulaBar.svelte +13 -4
  83. package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -1
  84. package/dist/spreadsheet/FormulaHints.svelte +7 -5
  85. package/dist/spreadsheet/FormulaHints.svelte.d.ts +3 -0
  86. package/dist/spreadsheet/FormulaHints.svelte.d.ts.map +1 -1
  87. package/dist/spreadsheet/NameManager.svelte +165 -0
  88. package/dist/spreadsheet/NameManager.svelte.d.ts +11 -0
  89. package/dist/spreadsheet/NameManager.svelte.d.ts.map +1 -0
  90. package/dist/spreadsheet/SheetTabs.svelte +161 -0
  91. package/dist/spreadsheet/SheetTabs.svelte.d.ts +10 -0
  92. package/dist/spreadsheet/SheetTabs.svelte.d.ts.map +1 -0
  93. package/dist/spreadsheet/SpreadsheetConditionalFormatPanel.svelte +184 -0
  94. package/dist/spreadsheet/SpreadsheetConditionalFormatPanel.svelte.d.ts +9 -0
  95. package/dist/spreadsheet/SpreadsheetConditionalFormatPanel.svelte.d.ts.map +1 -0
  96. package/dist/spreadsheet/SpreadsheetContextMenu.svelte +9 -4
  97. package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts +5 -1
  98. package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts.map +1 -1
  99. package/dist/spreadsheet/SpreadsheetDataValidationPanel.svelte +141 -0
  100. package/dist/spreadsheet/SpreadsheetDataValidationPanel.svelte.d.ts +9 -0
  101. package/dist/spreadsheet/SpreadsheetDataValidationPanel.svelte.d.ts.map +1 -0
  102. package/dist/spreadsheet/SpreadsheetEditor.svelte +273 -19
  103. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts +8 -0
  104. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -1
  105. package/dist/spreadsheet/SpreadsheetGroupRow.svelte +31 -3
  106. package/dist/spreadsheet/SpreadsheetGroupRow.svelte.d.ts +6 -0
  107. package/dist/spreadsheet/SpreadsheetGroupRow.svelte.d.ts.map +1 -1
  108. package/dist/spreadsheet/SpreadsheetValidationDialog.svelte +92 -0
  109. package/dist/spreadsheet/SpreadsheetValidationDialog.svelte.d.ts +9 -0
  110. package/dist/spreadsheet/SpreadsheetValidationDialog.svelte.d.ts.map +1 -0
  111. package/dist/spreadsheet/index.d.ts +10 -0
  112. package/dist/spreadsheet/index.d.ts.map +1 -1
  113. package/dist/spreadsheet/index.js +6 -0
  114. package/dist/spreadsheet/spreadsheet.svelte.d.ts +56 -3
  115. package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -1
  116. package/dist/spreadsheet/spreadsheet.svelte.js +105 -6
  117. package/dist/spreadsheet/viewport.svelte.d.ts +26 -0
  118. package/dist/spreadsheet/viewport.svelte.d.ts.map +1 -0
  119. package/dist/spreadsheet/viewport.svelte.js +93 -0
  120. package/dist/tables/InsertTableGrid.svelte +85 -0
  121. package/dist/tables/InsertTableGrid.svelte.d.ts +21 -0
  122. package/dist/tables/InsertTableGrid.svelte.d.ts.map +1 -0
  123. package/dist/tables/TableBubbleMenu.svelte +43 -0
  124. package/dist/tables/TableBubbleMenu.svelte.d.ts +18 -0
  125. package/dist/tables/TableBubbleMenu.svelte.d.ts.map +1 -0
  126. package/dist/tables/TableToolbar.svelte +81 -0
  127. package/dist/tables/TableToolbar.svelte.d.ts +19 -0
  128. package/dist/tables/TableToolbar.svelte.d.ts.map +1 -0
  129. package/dist/tables/index.d.ts +12 -0
  130. package/dist/tables/index.d.ts.map +1 -0
  131. package/dist/tables/index.js +4 -0
  132. package/dist/tables/tableMenu.svelte.d.ts +21 -0
  133. package/dist/tables/tableMenu.svelte.d.ts.map +1 -0
  134. package/dist/tables/tableMenu.svelte.js +27 -0
  135. package/dist/tokens/TokenSwatch.svelte +14 -0
  136. package/dist/tokens/TokenSwatch.svelte.d.ts +8 -0
  137. package/dist/tokens/TokenSwatch.svelte.d.ts.map +1 -0
  138. package/dist/tokens/TokensPanel.svelte +323 -0
  139. package/dist/tokens/TokensPanel.svelte.d.ts +14 -0
  140. package/dist/tokens/TokensPanel.svelte.d.ts.map +1 -0
  141. package/dist/tokens/createTokens.svelte.d.ts +31 -0
  142. package/dist/tokens/createTokens.svelte.d.ts.map +1 -0
  143. package/dist/tokens/createTokens.svelte.js +43 -0
  144. package/dist/tokens/index.d.ts +7 -0
  145. package/dist/tokens/index.d.ts.map +1 -0
  146. package/dist/tokens/index.js +3 -0
  147. package/package.json +10 -2
@@ -0,0 +1,135 @@
1
+ <script lang="ts">
2
+ import type {
3
+ ImageEditorController,
4
+ SelectionMask,
5
+ SelectionModifyOp,
6
+ SelectionToolOptions,
7
+ } from '@pixerate/editor/image-editor';
8
+ import {
9
+ SELECTION_MODES,
10
+ SELECTION_MODE_LABELS,
11
+ SELECTION_TOOLS,
12
+ describeSelection,
13
+ } from '@pixerate/editor/image-editor';
14
+ import { untrack } from 'svelte';
15
+
16
+ interface Props {
17
+ controller: ImageEditorController;
18
+ options: SelectionToolOptions;
19
+ onOptionsChange: (next: SelectionToolOptions) => void;
20
+ /** The current selection (`state.selection`). Omit to follow the controller. */
21
+ selection?: SelectionMask | null;
22
+ /** The Quick Mask view flag (`state.quickMask`). Omit to follow the controller. */
23
+ quickMask?: boolean;
24
+ class?: string;
25
+ }
26
+
27
+ let { controller, options, onOptionsChange, selection, quickMask, class: className = '' }: Props = $props();
28
+
29
+ let tick = $state(0);
30
+ $effect(() => {
31
+ const c = controller;
32
+ return untrack(() => c.subscribe(() => tick++));
33
+ });
34
+ const sel = $derived.by(() => {
35
+ void tick;
36
+ return selection === undefined ? controller.getSelection() : selection;
37
+ });
38
+ const qm = $derived.by(() => {
39
+ void tick;
40
+ return quickMask ?? Boolean(controller.getState().quickMask);
41
+ });
42
+
43
+ let radius = $state(2);
44
+
45
+ const MODIFY_OPS: { op: SelectionModifyOp; label: string }[] = [
46
+ { op: 'grow', label: 'Grow' },
47
+ { op: 'shrink', label: 'Shrink' },
48
+ { op: 'feather', label: 'Feather' },
49
+ { op: 'border', label: 'Border' },
50
+ { op: 'smooth', label: 'Smooth' },
51
+ ];
52
+
53
+ function set(patch: Partial<SelectionToolOptions>) {
54
+ onOptionsChange({ ...options, ...patch });
55
+ }
56
+
57
+ const btn = (on: boolean) =>
58
+ `px-2 py-1 rounded-md border text-[11px] transition-colors ${
59
+ on ? 'bg-indigo-600 border-indigo-500 text-white' : 'bg-slate-950 border-slate-800 text-slate-300 hover:text-white'
60
+ }`;
61
+ </script>
62
+
63
+ <div data-testid="selection-options-bar" class="flex flex-col gap-3 text-xs {className}">
64
+ <div role="group" aria-label="Selection tool" class="flex flex-wrap gap-1">
65
+ {#each SELECTION_TOOLS as t (t.id)}
66
+ <button type="button" aria-pressed={options.tool === t.id} class={btn(options.tool === t.id)} onclick={() => set({ tool: t.id })}>
67
+ {t.label}
68
+ </button>
69
+ {/each}
70
+ </div>
71
+ <div role="group" aria-label="Selection mode" class="flex flex-wrap gap-1">
72
+ {#each SELECTION_MODES as m (m)}
73
+ <button type="button" aria-pressed={options.mode === m} class={btn(options.mode === m)} onclick={() => set({ mode: m })}>
74
+ {SELECTION_MODE_LABELS[m]}
75
+ </button>
76
+ {/each}
77
+ </div>
78
+ {#if options.tool === 'wand'}
79
+ <div class="flex flex-col gap-2">
80
+ <label class="flex flex-col gap-1">
81
+ <span class="flex justify-between text-slate-400">
82
+ <span>Tolerance</span>
83
+ <span class="font-mono">{options.tolerance}</span>
84
+ </span>
85
+ <input
86
+ type="range"
87
+ min="0"
88
+ max="255"
89
+ step="1"
90
+ aria-label="Tolerance"
91
+ value={options.tolerance}
92
+ oninput={(e) => set({ tolerance: Number((e.currentTarget as HTMLInputElement).value) })}
93
+ class="w-full accent-indigo-500"
94
+ />
95
+ </label>
96
+ <label class="flex items-center gap-2 text-slate-300">
97
+ <input type="checkbox" checked={options.contiguous} onchange={(e) => set({ contiguous: (e.currentTarget as HTMLInputElement).checked })} />
98
+ Contiguous
99
+ </label>
100
+ <label class="flex items-center gap-2 text-slate-300">
101
+ <input type="checkbox" checked={options.sampleMerged} onchange={(e) => set({ sampleMerged: (e.currentTarget as HTMLInputElement).checked })} />
102
+ Sample adjusted image
103
+ </label>
104
+ </div>
105
+ {/if}
106
+ <label class="flex items-center gap-2 text-slate-300">
107
+ <input type="checkbox" checked={options.antiAlias} onchange={(e) => set({ antiAlias: (e.currentTarget as HTMLInputElement).checked })} />
108
+ Anti-alias
109
+ </label>
110
+ <div class="flex flex-wrap gap-1">
111
+ <button type="button" class={btn(false)} onclick={() => controller.selectAll()}>Select All</button>
112
+ <button type="button" class={btn(false)} disabled={!sel} onclick={() => controller.deselect()}>Deselect</button>
113
+ <button type="button" class={btn(false)} onclick={() => controller.invertSelection()}>Inverse</button>
114
+ <button type="button" aria-pressed={qm} class={btn(qm)} onclick={() => controller.setQuickMask(!qm)}>Quick Mask</button>
115
+ </div>
116
+ <div class="flex flex-wrap items-center gap-1">
117
+ <label class="flex items-center gap-1 text-slate-400">
118
+ Radius
119
+ <input
120
+ type="number"
121
+ min="0"
122
+ max="500"
123
+ step="1"
124
+ aria-label="Modify radius"
125
+ value={radius}
126
+ oninput={(e) => (radius = Math.max(0, Number((e.currentTarget as HTMLInputElement).value) || 0))}
127
+ class="w-14 bg-slate-950 border border-slate-800 rounded px-1 py-0.5 text-slate-200"
128
+ />
129
+ </label>
130
+ {#each MODIFY_OPS as m (m.op)}
131
+ <button type="button" class={btn(false)} disabled={!sel} onclick={() => controller.modifySelection(m.op, radius)}>{m.label}</button>
132
+ {/each}
133
+ </div>
134
+ <p data-testid="selection-status" class="text-slate-400">{describeSelection(sel)}</p>
135
+ </div>
@@ -0,0 +1,15 @@
1
+ import type { ImageEditorController, SelectionMask, SelectionToolOptions } from '@pixerate/editor/image-editor';
2
+ interface Props {
3
+ controller: ImageEditorController;
4
+ options: SelectionToolOptions;
5
+ onOptionsChange: (next: SelectionToolOptions) => void;
6
+ /** The current selection (`state.selection`). Omit to follow the controller. */
7
+ selection?: SelectionMask | null;
8
+ /** The Quick Mask view flag (`state.quickMask`). Omit to follow the controller. */
9
+ quickMask?: boolean;
10
+ class?: string;
11
+ }
12
+ declare const SelectionOptionsBar: import("svelte").Component<Props, {}, "">;
13
+ type SelectionOptionsBar = ReturnType<typeof SelectionOptionsBar>;
14
+ export default SelectionOptionsBar;
15
+ //# sourceMappingURL=SelectionOptionsBar.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionOptionsBar.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/SelectionOptionsBar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,qBAAqB,EACrB,aAAa,EAEb,oBAAoB,EACrB,MAAM,+BAA+B,CAAC;AAUvC,UAAU,KAAK;IACb,UAAU,EAAE,qBAAqB,CAAC;IAClC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,eAAe,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,gFAAgF;IAChF,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqGH,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -4,15 +4,21 @@ import type HistogramComponent from "./Histogram.svelte";
4
4
  import type AdjustmentLayersPanelComponent from "./AdjustmentLayersPanel.svelte";
5
5
  import type CurvesEditorComponent from "./CurvesEditor.svelte";
6
6
  import type ControlSliderComponent from "./ControlSlider.svelte";
7
+ import type SelectionOptionsBarComponent from "./SelectionOptionsBar.svelte";
8
+ import type RefineEdgePanelComponent from "./RefineEdgePanel.svelte";
7
9
  export { default as ImageEditor } from './ImageEditor.svelte';
8
10
  export { default as Histogram } from './Histogram.svelte';
9
11
  export { default as AdjustmentLayersPanel } from './AdjustmentLayersPanel.svelte';
10
12
  export { default as CurvesEditor } from './CurvesEditor.svelte';
11
13
  export { default as ControlSlider } from './ControlSlider.svelte';
14
+ export { default as SelectionOptionsBar } from './SelectionOptionsBar.svelte';
15
+ export { default as RefineEdgePanel } from './RefineEdgePanel.svelte';
12
16
  export * from './imageEditorState.svelte.js';
13
17
  export type ImageEditorProps = ComponentProps<typeof ImageEditorComponent>;
14
18
  export type HistogramProps = ComponentProps<typeof HistogramComponent>;
15
19
  export type AdjustmentLayersPanelProps = ComponentProps<typeof AdjustmentLayersPanelComponent>;
16
20
  export type CurvesEditorProps = ComponentProps<typeof CurvesEditorComponent>;
17
21
  export type ControlSliderProps = ComponentProps<typeof ControlSliderComponent>;
22
+ export type SelectionOptionsBarProps = ComponentProps<typeof SelectionOptionsBarComponent>;
23
+ export type RefineEdgePanelProps = ComponentProps<typeof RefineEdgePanelComponent>;
18
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,8BAA8B,MAAM,gCAAgC,CAAC;AACjF,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,cAAc,8BAA8B,CAAC;AAE7C,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACvE,MAAM,MAAM,0BAA0B,GAAG,cAAc,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAC/F,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image-editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,8BAA8B,MAAM,gCAAgC,CAAC;AACjF,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,4BAA4B,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,wBAAwB,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,cAAc,8BAA8B,CAAC;AAE7C,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC3E,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACvE,MAAM,MAAM,0BAA0B,GAAG,cAAc,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAC/F,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,wBAAwB,GAAG,cAAc,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAC3F,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -3,4 +3,6 @@ export { default as Histogram } from './Histogram.svelte';
3
3
  export { default as AdjustmentLayersPanel } from './AdjustmentLayersPanel.svelte';
4
4
  export { default as CurvesEditor } from './CurvesEditor.svelte';
5
5
  export { default as ControlSlider } from './ControlSlider.svelte';
6
+ export { default as SelectionOptionsBar } from './SelectionOptionsBar.svelte';
7
+ export { default as RefineEdgePanel } from './RefineEdgePanel.svelte';
6
8
  export * from './imageEditorState.svelte.js';
package/dist/index.d.ts CHANGED
@@ -5,11 +5,14 @@ import type TemplateRendererComponent from "./TemplateRenderer.svelte";
5
5
  import type VariableFormComponent from "./VariableForm.svelte";
6
6
  import type OutlinePanelComponent from "./OutlinePanel.svelte";
7
7
  import type MergePreviewComponent from "./MergePreview.svelte";
8
+ import type StylesGalleryComponent from "./StylesGallery.svelte";
9
+ import type ExportDocxButtonComponent from "./ExportDocxButton.svelte";
8
10
  export * from "./editor.svelte.js";
9
11
  export * from "./navigationGuard.js";
10
12
  export * from "./createNavigationGuard.svelte.js";
11
13
  export * from "./history/index.js";
12
14
  export * from "./fileImport.svelte.js";
15
+ export * from "./docxExport.svelte.js";
13
16
  export * from "./agentTools.svelte.js";
14
17
  export * from "./outline.svelte.js";
15
18
  export * from "./merge.svelte.js";
@@ -27,6 +30,11 @@ export type MergePreviewProps = ComponentProps<typeof MergePreviewComponent>;
27
30
  export { default as MergePreview } from "./MergePreview.svelte";
28
31
  export type OutlinePanelProps = ComponentProps<typeof OutlinePanelComponent>;
29
32
  export { default as OutlinePanel } from "./OutlinePanel.svelte";
33
+ export * from "./paragraphStyles.svelte.js";
34
+ export type StylesGalleryProps = ComponentProps<typeof StylesGalleryComponent>;
35
+ export { default as StylesGallery } from "./StylesGallery.svelte";
36
+ export type ExportDocxButtonProps = ComponentProps<typeof ExportDocxButtonComponent>;
37
+ export { default as ExportDocxButton } from "./ExportDocxButton.svelte";
30
38
  export type { Template, TemplateVersion, Token, TokenType, ColorGradient, RichTextPresetOptions, ImageOptions, } from "@pixerate/editor";
31
39
  export type { PromptValues, PromptDiagnostic, VariableFormField, MergeDataSource, MergeRecord, MergeRecordsResult, MergeOutput, } from "@pixerate/editor";
32
40
  export * from "./spreadsheet/index.js";
@@ -36,4 +44,5 @@ export * from "./commands/index.js";
36
44
  export * from "./persistence/index.js";
37
45
  export * from "./generation/index.js";
38
46
  export * from "./find-replace/index.js";
47
+ export * from "./tables/index.js";
39
48
  //# 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;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;AACpC,cAAc,mBAAmB,CAAC;AAElC,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;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,EACjB,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export * from "./navigationGuard.js";
3
3
  export * from "./createNavigationGuard.svelte.js";
4
4
  export * from "./history/index.js";
5
5
  export * from "./fileImport.svelte.js";
6
+ export * from "./docxExport.svelte.js";
6
7
  export * from "./agentTools.svelte.js";
7
8
  export * from "./outline.svelte.js";
8
9
  export * from "./merge.svelte.js";
@@ -13,6 +14,9 @@ export { default as TemplateRenderer } from "./TemplateRenderer.svelte";
13
14
  export { default as VariableForm } from "./VariableForm.svelte";
14
15
  export { default as MergePreview } from "./MergePreview.svelte";
15
16
  export { default as OutlinePanel } from "./OutlinePanel.svelte";
17
+ export * from "./paragraphStyles.svelte.js";
18
+ export { default as StylesGallery } from "./StylesGallery.svelte";
19
+ export { default as ExportDocxButton } from "./ExportDocxButton.svelte";
16
20
  export * from "./spreadsheet/index.js";
17
21
  export * from "./image-editor/index.js";
18
22
  export * from "./review/index.js";
@@ -20,3 +24,4 @@ export * from "./commands/index.js";
20
24
  export * from "./persistence/index.js";
21
25
  export * from "./generation/index.js";
22
26
  export * from "./find-replace/index.js";
27
+ export * from "./tables/index.js";
@@ -0,0 +1,30 @@
1
+ import type { Editor } from "@tiptap/core";
2
+ import { type CreateStyleFromSelectionOptions, type ParagraphStylesSnapshot, type StyleDefinition, type StyleRegistry } from "@pixerate/editor";
3
+ export type { ParagraphStylesSnapshot, StyleDefinition } from "@pixerate/editor";
4
+ export interface SvelteParagraphStyles {
5
+ /** Snapshot: gallery, styles, character styles, current style id, version. */
6
+ readonly current: ParagraphStylesSnapshot;
7
+ readonly registry: StyleRegistry | null;
8
+ /** The style of the block at the selection. */
9
+ readonly currentStyle: StyleDefinition | null;
10
+ /** Applies a paragraph style to the selected blocks. */
11
+ apply(id: string): boolean;
12
+ /** Resets the selected blocks to Normal. */
13
+ clear(): boolean;
14
+ /** Updates a style (default: the current one) to the formatting at the selection. */
15
+ updateFromSelection(id?: string): boolean;
16
+ /** Creates (and applies) a style from the formatting at the selection; returns its id. */
17
+ createFromSelection(name: string, options?: CreateStyleFromSelectionOptions): string | null;
18
+ /** Applies a character style to the selection. */
19
+ applyCharacterStyle(id: string): boolean;
20
+ destroy(): void;
21
+ }
22
+ /**
23
+ * Reactive paragraph styles for Svelte 5 (the counterpart of React's
24
+ * `useParagraphStyles`): the gallery, all styles and the style at the
25
+ * selection, with commands. `current` is replaced only when the styles or
26
+ * the current style change. Call `destroy()` when done (or create it inside
27
+ * a component's `$effect`).
28
+ */
29
+ export declare function createParagraphStyles(editor: Editor | null | undefined): SvelteParagraphStyles;
30
+ //# sourceMappingURL=paragraphStyles.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paragraphStyles.svelte.d.ts","sourceRoot":"","sources":["../src/paragraphStyles.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,KAAK,+BAA+B,EACpC,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjF,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9C,wDAAwD;IACxD,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC;IACjB,qFAAqF;IACrF,mBAAmB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1C,0FAA0F;IAC1F,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,+BAA+B,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5F,kDAAkD;IAClD,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,qBAAqB,CAmC9F"}
@@ -0,0 +1,44 @@
1
+ import { createParagraphStylesStore, getStyleRegistry, } from "@pixerate/editor";
2
+ /**
3
+ * Reactive paragraph styles for Svelte 5 (the counterpart of React's
4
+ * `useParagraphStyles`): the gallery, all styles and the style at the
5
+ * selection, with commands. `current` is replaced only when the styles or
6
+ * the current style change. Call `destroy()` when done (or create it inside
7
+ * a component's `$effect`).
8
+ */
9
+ export function createParagraphStyles(editor) {
10
+ const store = createParagraphStylesStore(editor);
11
+ const registry = getStyleRegistry(editor);
12
+ let current = $state.raw(store.getSnapshot());
13
+ const unsubscribe = store.subscribe(() => {
14
+ current = store.getSnapshot();
15
+ });
16
+ const live = () => (editor && !editor.isDestroyed ? editor : null);
17
+ return {
18
+ get current() {
19
+ return current;
20
+ },
21
+ get registry() {
22
+ return registry;
23
+ },
24
+ get currentStyle() {
25
+ return (current.currentStyleId && registry?.get(current.currentStyleId)) || null;
26
+ },
27
+ apply: (id) => !!live()?.chain().focus().setParagraphStyle(id).run(),
28
+ clear: () => !!live()?.chain().focus().clearParagraphStyle().run(),
29
+ updateFromSelection: (id) => !!live()?.chain().focus().updateParagraphStyleFromSelection(id).run(),
30
+ createFromSelection: (name, options) => {
31
+ const e = live();
32
+ if (!e || !registry)
33
+ return null;
34
+ const id = options?.id ?? registry.newId(name.trim());
35
+ const ok = e.chain().focus().createParagraphStyleFromSelection(name, { ...options, id }).run();
36
+ return ok ? id : null;
37
+ },
38
+ applyCharacterStyle: (id) => !!live()?.chain().focus().setCharacterStyle(id).run(),
39
+ destroy() {
40
+ unsubscribe();
41
+ store.destroy();
42
+ },
43
+ };
44
+ }
@@ -0,0 +1,67 @@
1
+ <script lang="ts">
2
+ import type { Editor } from "@tiptap/core";
3
+ import { trackedChangeLabel } from "@pixerate/editor";
4
+ import { createTrackChanges, type SvelteTrackChanges } from "./review.svelte.js";
5
+
6
+ interface Props {
7
+ editor?: Editor | null;
8
+ class?: string;
9
+ itemClass?: string;
10
+ activeItemClass?: string;
11
+ /** Text shown when there are no changes. */
12
+ emptyState?: string;
13
+ }
14
+
15
+ let {
16
+ editor = null,
17
+ class: className = "flex flex-col gap-1 text-sm",
18
+ itemClass = "flex items-center gap-2 rounded px-2 py-1 hover:bg-muted/50",
19
+ activeItemClass = "bg-primary/10",
20
+ emptyState = "No tracked changes.",
21
+ }: Props = $props();
22
+
23
+ const buttonClass =
24
+ "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
25
+
26
+ let review = $state.raw<SvelteTrackChanges>(createTrackChanges(null));
27
+
28
+ $effect(() => {
29
+ const r = createTrackChanges(editor);
30
+ review = r;
31
+ return () => r.destroy();
32
+ });
33
+ </script>
34
+
35
+ {#if review.changes.length === 0}
36
+ <div class={className} data-tracked-changes-list="">
37
+ <div class="pixerate-changes-empty text-xs text-muted-foreground">{emptyState}</div>
38
+ </div>
39
+ {:else}
40
+ <ul class={className} role="list" aria-label="Tracked changes" data-tracked-changes-list="">
41
+ {#each review.changes as change (`${change.type}:${change.id}`)}
42
+ <li
43
+ class={change.id === review.currentChangeId ? `${itemClass} ${activeItemClass}` : itemClass}
44
+ data-change-type={change.type}
45
+ data-change-id={change.id}
46
+ >
47
+ <button
48
+ type="button"
49
+ class="min-w-0 flex-1 truncate text-left text-xs"
50
+ title={`${change.author.name}: ${change.description}`}
51
+ onclick={() => review.select(change.id)}
52
+ >
53
+ <span class="font-medium">{trackedChangeLabel(change)}</span>{change.author.name
54
+ ? ` · ${change.author.name}`
55
+ : ""}
56
+ <span class="block truncate text-muted-foreground">{change.description}</span>
57
+ </button>
58
+ <button type="button" class={buttonClass} onclick={() => review.accept(change.id)}>
59
+ Accept
60
+ </button>
61
+ <button type="button" class={buttonClass} onclick={() => review.reject(change.id)}>
62
+ Reject
63
+ </button>
64
+ </li>
65
+ {/each}
66
+ </ul>
67
+ {/if}
@@ -0,0 +1,13 @@
1
+ import type { Editor } from "@tiptap/core";
2
+ interface Props {
3
+ editor?: Editor | null;
4
+ class?: string;
5
+ itemClass?: string;
6
+ activeItemClass?: string;
7
+ /** Text shown when there are no changes. */
8
+ emptyState?: string;
9
+ }
10
+ declare const TrackedChangesList: import("svelte").Component<Props, {}, "">;
11
+ type TrackedChangesList = ReturnType<typeof TrackedChangesList>;
12
+ export default TrackedChangesList;
13
+ //# sourceMappingURL=TrackedChangesList.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrackedChangesList.svelte.d.ts","sourceRoot":"","sources":["../../src/review/TrackedChangesList.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAKzC,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAsDH,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -2,6 +2,9 @@ import type { ComponentProps } from "svelte";
2
2
  import type CommentsPanelComponent from "./CommentsPanel.svelte";
3
3
  import type ReviewToolbarComponent from "./ReviewToolbar.svelte";
4
4
  import type CommentButtonComponent from "./CommentButton.svelte";
5
+ import type TrackedChangesListComponent from "./TrackedChangesList.svelte";
6
+ export { default as TrackedChangesList } from "./TrackedChangesList.svelte";
7
+ export type TrackedChangesListProps = ComponentProps<typeof TrackedChangesListComponent>;
5
8
  export { default as CommentsPanel } from "./CommentsPanel.svelte";
6
9
  export { default as ReviewToolbar } from "./ReviewToolbar.svelte";
7
10
  export { default as CommentButton } from "./CommentButton.svelte";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAE5C,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,sBAAsB,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,2BAA2B,MAAM,6BAA6B,CAAC;AAE3E,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC,OAAO,2BAA2B,CAAC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAE5C,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/E,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ export { default as TrackedChangesList } from "./TrackedChangesList.svelte";
1
2
  export { default as CommentsPanel } from "./CommentsPanel.svelte";
2
3
  export { default as ReviewToolbar } from "./ReviewToolbar.svelte";
3
4
  export { default as CommentButton } from "./CommentButton.svelte";
@@ -29,6 +29,12 @@ export interface SvelteTrackChanges extends TrackChangesSnapshot {
29
29
  rejectAll(): void;
30
30
  next(): void;
31
31
  previous(): void;
32
+ /** Selects a change in the editor. */
33
+ select(id: string): void;
34
+ /** Accepts a tracked move (both ends). */
35
+ acceptMove(id: string): void;
36
+ /** Rejects a tracked move (both ends). */
37
+ rejectMove(id: string): void;
32
38
  subscribe(run: (value: TrackChangesSnapshot) => void): () => void;
33
39
  destroy(): void;
34
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"review.svelte.d.ts","sourceRoot":"","sources":["../../src/review/review.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,uBAAuB,EAAE,oBAGZ,CAAC;AAE3B,eAAO,MAAM,4BAA4B,EAAE,oBAKjB,CAAC;AAE3B,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAMpE;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,GAC/C,YAAY,GAAG,IAAI,CAErB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,CA4B/F;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,IAAI,IAAI,CAAC;IAClB,SAAS,IAAI,IAAI,CAAC;IAClB,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,IAAI,IAAI,CAAC;IACjB,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB,CA+CxF"}
1
+ {"version":3,"file":"review.svelte.d.ts","sourceRoot":"","sources":["../../src/review/review.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,uBAAuB,EAAE,oBAGZ,CAAC;AAE3B,eAAO,MAAM,4BAA4B,EAAE,oBAKjB,CAAC;AAE3B,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAMpE;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,GAC/C,YAAY,GAAG,IAAI,CAErB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,CA4B/F;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,IAAI,IAAI,CAAC;IAClB,SAAS,IAAI,IAAI,CAAC;IAClB,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,IAAI,IAAI,CAAC;IACjB,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB,CAkDxF"}
@@ -92,6 +92,9 @@ export function createTrackChanges(editor) {
92
92
  rejectAll: () => run((e) => e.commands.rejectAllChanges()),
93
93
  next: () => run((e) => e.chain().focus().selectNextChange().run()),
94
94
  previous: () => run((e) => e.chain().focus().selectPreviousChange().run()),
95
+ select: (id) => run((e) => e.chain().focus().selectChange(id).run()),
96
+ acceptMove: (id) => run((e) => e.commands.acceptMove(id)),
97
+ rejectMove: (id) => run((e) => e.commands.rejectMove(id)),
95
98
  subscribe(runFn) {
96
99
  if (!store) {
97
100
  runFn(EMPTY_TRACK_CHANGES_SNAPSHOT);
@@ -46,6 +46,13 @@
46
46
  return value;
47
47
  });
48
48
 
49
+ // Defined names for formula autocomplete.
50
+ let nameSuggestions = $derived.by(() => {
51
+ if (!sheetState) return [];
52
+ void sheetState.document;
53
+ return sheetState.controller.getNameSuggestions();
54
+ });
55
+
49
56
  // A spilled cell shows its anchor's formula greyed out (it has no formula of its own).
50
57
  let spillFormula = $derived.by(() => {
51
58
  if (!sheetState || sheetState.editingCell || !sheetState.activeCell || effectiveValue) return '';
@@ -63,10 +70,12 @@
63
70
  if (sheetState && sheetState.activeCell) {
64
71
  const row = sheetState.document.rows[sheetState.activeCell.row];
65
72
  const col = sheetState.document.columns[sheetState.activeCell.col];
66
- if (row && col) {
67
- sheetState.setCellValue(row.id, col.id, effectiveValue);
73
+ // Committed with data validation: invalid input waits for the alert.
74
+ if (sheetState.editingCell) {
75
+ sheetState.commitEditing(effectiveValue);
76
+ } else if (row && col) {
77
+ sheetState.commitCellInput(row.id, col.id, effectiveValue);
68
78
  }
69
- sheetState.commitEditing();
70
79
  }
71
80
  onCommit?.(effectiveValue);
72
81
  } else if (e.key === 'Escape') {
@@ -116,5 +125,5 @@
116
125
  oninput={handleInput}
117
126
  onkeydown={handleKeyDown}
118
127
  />
119
- <FormulaHints input={inputEl} value={effectiveValue} onAccept={setValue} />
128
+ <FormulaHints input={inputEl} value={effectiveValue} onAccept={setValue} names={nameSuggestions} />
120
129
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"FormulaBar.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/FormulaBar.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,UAAU,KAAK;IACb,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;IAC1D,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwGH,QAAA,MAAM,UAAU,gDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"FormulaBar.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/FormulaBar.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,UAAU,KAAK;IACb,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;IAC1D,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiHH,QAAA,MAAM,UAAU,gDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { tick } from 'svelte';
3
- import { applyFormulaSuggestion, getFormulaHints } from '@pixerate/editor/spreadsheet';
3
+ import { applyFormulaSuggestion, getFormulaHints, type FormulaNameSuggestionSource } from '@pixerate/editor/spreadsheet';
4
4
 
5
5
  interface Props {
6
6
  /** The input being edited (a cell editor or the formula bar). */
@@ -11,9 +11,11 @@
11
11
  onAccept?: (value: string) => void;
12
12
  /** Maximum number of function suggestions (default 8). */
13
13
  limit?: number;
14
+ /** Defined names to suggest too (e.g. `controller.getNameSuggestions()`). */
15
+ names?: readonly FormulaNameSuggestionSource[];
14
16
  }
15
17
 
16
- let { input = null, value = '', onAccept, limit = 8 }: Props = $props();
18
+ let { input = null, value = '', onAccept, limit = 8, names }: Props = $props();
17
19
 
18
20
  let caret = $state<number | null>(null);
19
21
  let focused = $state(false);
@@ -21,7 +23,7 @@
21
23
  let dismissed = $state(false);
22
24
  let position = $state<{ top: number; left: number; width: number } | null>(null);
23
25
 
24
- let hints = $derived(getFormulaHints(value, caret ?? value.length, { limit }));
26
+ let hints = $derived(getFormulaHints(value, caret ?? value.length, { limit, names }));
25
27
  let suggestions = $derived(dismissed ? [] : hints.suggestions);
26
28
  let selectedIndex = $derived(Math.max(0, Math.min(selected, suggestions.length - 1)));
27
29
  let visible = $derived(
@@ -31,7 +33,7 @@
31
33
  async function accept(index: number) {
32
34
  const suggestion = suggestions[index];
33
35
  if (!suggestion || !input) return;
34
- const next = applyFormulaSuggestion(value, caret ?? value.length, suggestion.name);
36
+ const next = applyFormulaSuggestion(value, caret ?? value.length, suggestion);
35
37
  caret = next.caret;
36
38
  selected = 0;
37
39
  onAccept?.(next.value);
@@ -127,7 +129,7 @@
127
129
  {/if}
128
130
  {#if suggestions.length > 0}
129
131
  <ul role="listbox" aria-label="Formula suggestions" class="max-h-64 overflow-auto m-0 list-none p-0 py-1">
130
- {#each suggestions as s, i (s.name)}
132
+ {#each suggestions as s, i (`${s.kind ?? "fn"}:${s.name}`)}
131
133
  <li
132
134
  role="option"
133
135
  aria-selected={i === selectedIndex}
@@ -1,3 +1,4 @@
1
+ import { type FormulaNameSuggestionSource } from '@pixerate/editor/spreadsheet';
1
2
  interface Props {
2
3
  /** The input being edited (a cell editor or the formula bar). */
3
4
  input?: HTMLInputElement | null;
@@ -7,6 +8,8 @@ interface Props {
7
8
  onAccept?: (value: string) => void;
8
9
  /** Maximum number of function suggestions (default 8). */
9
10
  limit?: number;
11
+ /** Defined names to suggest too (e.g. `controller.getNameSuggestions()`). */
12
+ names?: readonly FormulaNameSuggestionSource[];
10
13
  }
11
14
  declare const FormulaHints: import("svelte").Component<Props, {}, "">;
12
15
  type FormulaHints = ReturnType<typeof FormulaHints>;
@@ -1 +1 @@
1
- {"version":3,"file":"FormulaHints.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/FormulaHints.svelte.ts"],"names":[],"mappings":"AAOE,UAAU,KAAK;IACb,iEAAiE;IACjE,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAoIH,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"FormulaHints.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/FormulaHints.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2C,KAAK,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAGvH,UAAU,KAAK;IACb,iEAAiE;IACjE,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAChD;AAoIH,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}