@pixerate/editor-svelte 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/StylesGallery.svelte +169 -0
- package/dist/StylesGallery.svelte.d.ts +27 -0
- package/dist/StylesGallery.svelte.d.ts.map +1 -0
- package/dist/canvas/TokenBindingPicker.svelte +93 -0
- package/dist/canvas/TokenBindingPicker.svelte.d.ts +20 -0
- package/dist/canvas/TokenBindingPicker.svelte.d.ts.map +1 -0
- package/dist/canvas/TokenModeSwitcher.svelte +55 -0
- package/dist/canvas/TokenModeSwitcher.svelte.d.ts +18 -0
- package/dist/canvas/TokenModeSwitcher.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasArrange.svelte.d.ts +4 -0
- package/dist/canvas/createCanvasArrange.svelte.d.ts.map +1 -1
- package/dist/canvas/createCanvasAutoLayout.svelte.d.ts.map +1 -1
- package/dist/canvas/createCanvasTokens.svelte.d.ts +31 -0
- package/dist/canvas/createCanvasTokens.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasTokens.svelte.js +50 -0
- package/dist/canvas/index.d.ts +5 -0
- package/dist/canvas/index.d.ts.map +1 -1
- package/dist/canvas/index.js +7 -0
- package/dist/fileImport.svelte.d.ts +8 -1
- package/dist/fileImport.svelte.d.ts.map +1 -1
- package/dist/fileImport.svelte.js +11 -1
- package/dist/generation/AssetMentionChips.svelte +130 -0
- package/dist/generation/AssetMentionChips.svelte.d.ts +21 -0
- package/dist/generation/AssetMentionChips.svelte.d.ts.map +1 -0
- package/dist/generation/GenerationHistory.svelte +161 -0
- package/dist/generation/GenerationHistory.svelte.d.ts +28 -0
- package/dist/generation/GenerationHistory.svelte.d.ts.map +1 -0
- package/dist/generation/index.d.ts +7 -0
- package/dist/generation/index.d.ts.map +1 -1
- package/dist/generation/index.js +3 -0
- package/dist/generation/records.svelte.d.ts +18 -0
- package/dist/generation/records.svelte.d.ts.map +1 -0
- package/dist/generation/records.svelte.js +66 -0
- package/dist/image-editor/ImageEditor.svelte +72 -1
- package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -1
- package/dist/image-editor/RefineEdgePanel.svelte +180 -0
- package/dist/image-editor/RefineEdgePanel.svelte.d.ts +13 -0
- package/dist/image-editor/RefineEdgePanel.svelte.d.ts.map +1 -0
- package/dist/image-editor/SelectionOptionsBar.svelte +135 -0
- package/dist/image-editor/SelectionOptionsBar.svelte.d.ts +15 -0
- package/dist/image-editor/SelectionOptionsBar.svelte.d.ts.map +1 -0
- package/dist/image-editor/index.d.ts +6 -0
- package/dist/image-editor/index.d.ts.map +1 -1
- package/dist/image-editor/index.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/paragraphStyles.svelte.d.ts +30 -0
- package/dist/paragraphStyles.svelte.d.ts.map +1 -0
- package/dist/paragraphStyles.svelte.js +44 -0
- package/dist/review/TrackedChangesList.svelte +67 -0
- package/dist/review/TrackedChangesList.svelte.d.ts +13 -0
- package/dist/review/TrackedChangesList.svelte.d.ts.map +1 -0
- package/dist/review/index.d.ts +3 -0
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +1 -0
- package/dist/review/review.svelte.d.ts +6 -0
- package/dist/review/review.svelte.d.ts.map +1 -1
- package/dist/review/review.svelte.js +3 -0
- package/dist/spreadsheet/FormulaBar.svelte +13 -4
- package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/FormulaHints.svelte +7 -5
- package/dist/spreadsheet/FormulaHints.svelte.d.ts +3 -0
- package/dist/spreadsheet/FormulaHints.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/NameManager.svelte +165 -0
- package/dist/spreadsheet/NameManager.svelte.d.ts +11 -0
- package/dist/spreadsheet/NameManager.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/SheetTabs.svelte +161 -0
- package/dist/spreadsheet/SheetTabs.svelte.d.ts +10 -0
- package/dist/spreadsheet/SheetTabs.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/SpreadsheetConditionalFormatPanel.svelte +184 -0
- package/dist/spreadsheet/SpreadsheetConditionalFormatPanel.svelte.d.ts +9 -0
- package/dist/spreadsheet/SpreadsheetConditionalFormatPanel.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/SpreadsheetContextMenu.svelte +9 -4
- package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts +5 -1
- package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/SpreadsheetDataValidationPanel.svelte +141 -0
- package/dist/spreadsheet/SpreadsheetDataValidationPanel.svelte.d.ts +9 -0
- package/dist/spreadsheet/SpreadsheetDataValidationPanel.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/SpreadsheetEditor.svelte +197 -13
- package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts +2 -0
- package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/SpreadsheetValidationDialog.svelte +92 -0
- package/dist/spreadsheet/SpreadsheetValidationDialog.svelte.d.ts +9 -0
- package/dist/spreadsheet/SpreadsheetValidationDialog.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/index.d.ts +9 -0
- package/dist/spreadsheet/index.d.ts.map +1 -1
- package/dist/spreadsheet/index.js +5 -0
- package/dist/spreadsheet/spreadsheet.svelte.d.ts +55 -2
- package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/spreadsheet.svelte.js +105 -6
- package/dist/tokens/TokenSwatch.svelte +14 -0
- package/dist/tokens/TokenSwatch.svelte.d.ts +8 -0
- package/dist/tokens/TokenSwatch.svelte.d.ts.map +1 -0
- package/dist/tokens/TokensPanel.svelte +323 -0
- package/dist/tokens/TokensPanel.svelte.d.ts +14 -0
- package/dist/tokens/TokensPanel.svelte.d.ts.map +1 -0
- package/dist/tokens/createTokens.svelte.d.ts +31 -0
- package/dist/tokens/createTokens.svelte.d.ts.map +1 -0
- package/dist/tokens/createTokens.svelte.js +43 -0
- package/dist/tokens/index.d.ts +7 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +3 -0
- package/package.json +10 -2
|
@@ -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,
|
|
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
|
-
|
|
67
|
-
|
|
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;
|
|
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
|
|
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":"
|
|
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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getNameManagerRows, parseFormula, type SpreadsheetNameRow } from '@pixerate/editor/spreadsheet';
|
|
3
|
+
import type { createReactiveSpreadsheet } from './spreadsheet.svelte.js';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
sheetState: ReturnType<typeof createReactiveSpreadsheet>;
|
|
7
|
+
readOnly?: boolean;
|
|
8
|
+
onClose?: () => void;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { sheetState, readOnly = false, onClose, class: className = '' }: Props = $props();
|
|
13
|
+
|
|
14
|
+
interface Draft {
|
|
15
|
+
/** The name being edited (null for a new one). */
|
|
16
|
+
original: { name: string; sheetId?: string } | null;
|
|
17
|
+
name: string;
|
|
18
|
+
refersTo: string;
|
|
19
|
+
/** Sheet id, or '' for workbook scope. */
|
|
20
|
+
scope: string;
|
|
21
|
+
comment: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const EMPTY_DRAFT: Draft = { original: null, name: '', refersTo: '=', scope: '', comment: '' };
|
|
25
|
+
|
|
26
|
+
let draft = $state<Draft>({ ...EMPTY_DRAFT });
|
|
27
|
+
let error = $state<string | null>(null);
|
|
28
|
+
|
|
29
|
+
const rows = $derived.by(() => {
|
|
30
|
+
void sheetState.document;
|
|
31
|
+
void sheetState.names;
|
|
32
|
+
return getNameManagerRows(sheetState.controller);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
function edit(row: SpreadsheetNameRow) {
|
|
36
|
+
error = null;
|
|
37
|
+
draft = {
|
|
38
|
+
original: { name: row.name, sheetId: row.sheetId },
|
|
39
|
+
name: row.name,
|
|
40
|
+
refersTo: row.refersTo,
|
|
41
|
+
scope: row.sheetId ?? '',
|
|
42
|
+
comment: row.comment ?? ''
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function save(e: SubmitEvent) {
|
|
47
|
+
e.preventDefault();
|
|
48
|
+
const scope = draft.scope ? { sheet: draft.scope } : {};
|
|
49
|
+
try {
|
|
50
|
+
// Check before changing anything, so a failed edit keeps the old name.
|
|
51
|
+
const invalid = sheetState.controller.validateDefinedName(draft.name.trim());
|
|
52
|
+
if (invalid) throw new Error(invalid);
|
|
53
|
+
const formula = draft.refersTo.trim().startsWith('=') ? draft.refersTo.trim() : `=${draft.refersTo.trim()}`;
|
|
54
|
+
try {
|
|
55
|
+
parseFormula(formula);
|
|
56
|
+
} catch (err: any) {
|
|
57
|
+
throw new Error(`There's a problem with this formula: ${err?.message ?? formula}`);
|
|
58
|
+
}
|
|
59
|
+
const original = draft.original;
|
|
60
|
+
if (original) {
|
|
61
|
+
const originalScope = original.sheetId ? { sheet: original.sheetId } : {};
|
|
62
|
+
if ((original.sheetId ?? '') !== draft.scope) {
|
|
63
|
+
sheetState.deleteName(original.name, originalScope);
|
|
64
|
+
} else if (original.name !== draft.name.trim()) {
|
|
65
|
+
sheetState.renameName(original.name, draft.name.trim(), originalScope);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
sheetState.defineName(draft.name.trim(), draft.refersTo, { ...scope, comment: draft.comment || undefined });
|
|
69
|
+
draft = { ...EMPTY_DRAFT };
|
|
70
|
+
error = null;
|
|
71
|
+
} catch (err: any) {
|
|
72
|
+
error = err?.message ?? String(err);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function remove(row: SpreadsheetNameRow) {
|
|
77
|
+
sheetState.deleteName(row.name, row.sheetId ? { sheet: row.sheetId } : {});
|
|
78
|
+
if (draft.original?.name === row.name && (draft.original.sheetId ?? '') === (row.sheetId ?? '')) draft = { ...EMPTY_DRAFT };
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<!--
|
|
83
|
+
A simple Name Manager: lists defined names (name, current value, formula,
|
|
84
|
+
scope) and adds, edits, renames and deletes them. Renaming a name rewrites
|
|
85
|
+
the formulas that use it; deleting one leaves them showing #NAME?.
|
|
86
|
+
-->
|
|
87
|
+
<section aria-label="Name Manager" class="flex flex-col gap-2 text-xs {className}" data-name-manager="">
|
|
88
|
+
<div class="flex items-center justify-between">
|
|
89
|
+
<h3 class="m-0 text-sm font-semibold">Name Manager</h3>
|
|
90
|
+
{#if onClose}
|
|
91
|
+
<button type="button" aria-label="Close Name Manager" class="rounded px-2 hover:bg-muted" onclick={onClose}>×</button>
|
|
92
|
+
{/if}
|
|
93
|
+
</div>
|
|
94
|
+
<table class="w-full border-collapse">
|
|
95
|
+
<thead>
|
|
96
|
+
<tr class="text-left text-muted-foreground">
|
|
97
|
+
<th class="px-1 font-medium">Name</th>
|
|
98
|
+
<th class="px-1 font-medium">Value</th>
|
|
99
|
+
<th class="px-1 font-medium">Refers to</th>
|
|
100
|
+
<th class="px-1 font-medium">Scope</th>
|
|
101
|
+
{#if !readOnly}<th class="px-1"></th>{/if}
|
|
102
|
+
</tr>
|
|
103
|
+
</thead>
|
|
104
|
+
<tbody>
|
|
105
|
+
{#if rows.length === 0}
|
|
106
|
+
<tr><td colspan="5" class="px-1 py-2 text-muted-foreground">No names yet.</td></tr>
|
|
107
|
+
{/if}
|
|
108
|
+
{#each rows as row (`${row.sheetId ?? ''}!${row.name}`)}
|
|
109
|
+
<tr data-name={row.name} class="border-t border-border" title={row.comment}>
|
|
110
|
+
<td class="px-1 py-0.5 font-mono font-semibold">{row.name}</td>
|
|
111
|
+
<td class="px-1 py-0.5">{row.value}</td>
|
|
112
|
+
<td class="px-1 py-0.5 font-mono">{row.refersTo}</td>
|
|
113
|
+
<td class="px-1 py-0.5">{row.scopeLabel}</td>
|
|
114
|
+
{#if !readOnly}
|
|
115
|
+
<td class="whitespace-nowrap px-1 py-0.5 text-right">
|
|
116
|
+
<button type="button" aria-label="Edit {row.name}" class="rounded px-1 hover:bg-muted" onclick={() => edit(row)}>Edit</button>
|
|
117
|
+
<button type="button" aria-label="Delete {row.name}" class="rounded px-1 text-destructive hover:bg-muted" onclick={() => remove(row)}>
|
|
118
|
+
Delete
|
|
119
|
+
</button>
|
|
120
|
+
</td>
|
|
121
|
+
{/if}
|
|
122
|
+
</tr>
|
|
123
|
+
{/each}
|
|
124
|
+
</tbody>
|
|
125
|
+
</table>
|
|
126
|
+
{#if !readOnly}
|
|
127
|
+
<form
|
|
128
|
+
class="grid grid-cols-[auto_1fr] items-center gap-x-2 gap-y-1"
|
|
129
|
+
onsubmit={save}
|
|
130
|
+
aria-label={draft.original ? `Edit name ${draft.original.name}` : 'New name'}
|
|
131
|
+
>
|
|
132
|
+
<label for="pixerate-name-manager-name">Name</label>
|
|
133
|
+
<input id="pixerate-name-manager-name" class="rounded border border-border bg-background px-1 py-0.5" bind:value={draft.name} />
|
|
134
|
+
<label for="pixerate-name-manager-refers">Refers to</label>
|
|
135
|
+
<input id="pixerate-name-manager-refers" class="rounded border border-border bg-background px-1 py-0.5 font-mono" bind:value={draft.refersTo} />
|
|
136
|
+
<label for="pixerate-name-manager-scope">Scope</label>
|
|
137
|
+
<select id="pixerate-name-manager-scope" class="rounded border border-border bg-background px-1 py-0.5" bind:value={draft.scope}>
|
|
138
|
+
<option value="">Workbook</option>
|
|
139
|
+
{#each sheetState.sheets as sheet (sheet.id)}
|
|
140
|
+
<option value={sheet.id}>{sheet.name}</option>
|
|
141
|
+
{/each}
|
|
142
|
+
</select>
|
|
143
|
+
<label for="pixerate-name-manager-comment">Comment</label>
|
|
144
|
+
<input id="pixerate-name-manager-comment" class="rounded border border-border bg-background px-1 py-0.5" bind:value={draft.comment} />
|
|
145
|
+
<div class="col-span-2 flex gap-2">
|
|
146
|
+
<button type="submit" class="rounded bg-primary px-2 py-0.5 text-primary-foreground">{draft.original ? 'Save' : 'Add name'}</button>
|
|
147
|
+
{#if draft.original}
|
|
148
|
+
<button
|
|
149
|
+
type="button"
|
|
150
|
+
class="rounded px-2 py-0.5 hover:bg-muted"
|
|
151
|
+
onclick={() => {
|
|
152
|
+
draft = { ...EMPTY_DRAFT };
|
|
153
|
+
error = null;
|
|
154
|
+
}}
|
|
155
|
+
>
|
|
156
|
+
Cancel
|
|
157
|
+
</button>
|
|
158
|
+
{/if}
|
|
159
|
+
</div>
|
|
160
|
+
</form>
|
|
161
|
+
{/if}
|
|
162
|
+
{#if error}
|
|
163
|
+
<div role="alert" class="text-destructive">{error}</div>
|
|
164
|
+
{/if}
|
|
165
|
+
</section>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { createReactiveSpreadsheet } from './spreadsheet.svelte.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
sheetState: ReturnType<typeof createReactiveSpreadsheet>;
|
|
4
|
+
readOnly?: boolean;
|
|
5
|
+
onClose?: () => void;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const NameManager: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type NameManager = ReturnType<typeof NameManager>;
|
|
10
|
+
export default NameManager;
|
|
11
|
+
//# sourceMappingURL=NameManager.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NameManager.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/NameManager.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGvE,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwJH,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getSheetTabMenuItems, sheetDropIndex, type SpreadsheetMenuItem } from '@pixerate/editor/spreadsheet';
|
|
3
|
+
import type { createReactiveSpreadsheet } from './spreadsheet.svelte.js';
|
|
4
|
+
import SpreadsheetContextMenu from './SpreadsheetContextMenu.svelte';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
sheetState: ReturnType<typeof createReactiveSpreadsheet>;
|
|
8
|
+
readOnly?: boolean;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { sheetState, readOnly = false, class: className = '' }: Props = $props();
|
|
13
|
+
|
|
14
|
+
let renaming = $state<{ id: string; draft: string } | null>(null);
|
|
15
|
+
let error = $state<string | null>(null);
|
|
16
|
+
let menu = $state<{ x: number; y: number; items: SpreadsheetMenuItem[] } | null>(null);
|
|
17
|
+
let dragFrom: number | null = null;
|
|
18
|
+
let dropTarget = $state<{ index: number; after: boolean } | null>(null);
|
|
19
|
+
let renameInput = $state<HTMLInputElement | null>(null);
|
|
20
|
+
|
|
21
|
+
// Focus and select the name when the rename field opens.
|
|
22
|
+
$effect(() => {
|
|
23
|
+
if (!renameInput) return;
|
|
24
|
+
renameInput.focus();
|
|
25
|
+
renameInput.select();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function commitRename(cancelOnError: boolean) {
|
|
29
|
+
if (!renaming) return;
|
|
30
|
+
const current = renaming;
|
|
31
|
+
const sheet = sheetState.sheets.find((s) => s.id === current.id);
|
|
32
|
+
const name = current.draft.trim();
|
|
33
|
+
if (!sheet || !name || name === sheet.name) {
|
|
34
|
+
renaming = null;
|
|
35
|
+
error = null;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
sheetState.renameSheet(current.id, name);
|
|
40
|
+
renaming = null;
|
|
41
|
+
error = null;
|
|
42
|
+
} catch (err: any) {
|
|
43
|
+
error = err?.message ?? String(err);
|
|
44
|
+
if (cancelOnError) renaming = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function dropAfter(e: DragEvent): boolean {
|
|
49
|
+
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
50
|
+
return e.clientX > rect.left + rect.width / 2;
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<!--
|
|
55
|
+
The workbook's sheet tabs: click to switch, double-click to rename, drag to
|
|
56
|
+
reorder, right-click for insert / rename / duplicate / move / delete
|
|
57
|
+
(delete asks to confirm), and a `+` button to add a sheet.
|
|
58
|
+
-->
|
|
59
|
+
<div class="flex flex-col {className}" data-sheet-tabs="">
|
|
60
|
+
<div role="tablist" aria-label="Sheets" class="flex items-center gap-0.5 overflow-x-auto border-t border-border bg-muted px-1 py-1 text-xs">
|
|
61
|
+
{#each sheetState.sheets as sheet, index (sheet.id)}
|
|
62
|
+
{#if renaming?.id === sheet.id}
|
|
63
|
+
<input
|
|
64
|
+
bind:this={renameInput}
|
|
65
|
+
aria-label="Sheet name"
|
|
66
|
+
class="w-32 rounded border border-primary bg-background px-2 py-0.5 text-xs outline-none"
|
|
67
|
+
value={renaming.draft}
|
|
68
|
+
oninput={(e) => {
|
|
69
|
+
if (renaming) renaming = { id: renaming.id, draft: e.currentTarget.value };
|
|
70
|
+
}}
|
|
71
|
+
onkeydown={(e) => {
|
|
72
|
+
e.stopPropagation();
|
|
73
|
+
if (e.key === 'Enter') commitRename(false);
|
|
74
|
+
else if (e.key === 'Escape') {
|
|
75
|
+
renaming = null;
|
|
76
|
+
error = null;
|
|
77
|
+
}
|
|
78
|
+
}}
|
|
79
|
+
onblur={() => commitRename(true)}
|
|
80
|
+
/>
|
|
81
|
+
{:else}
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
role="tab"
|
|
85
|
+
aria-selected={sheet.active}
|
|
86
|
+
data-sheet-id={sheet.id}
|
|
87
|
+
draggable={!readOnly}
|
|
88
|
+
title={readOnly ? sheet.name : `${sheet.name} — double-click to rename, drag to move`}
|
|
89
|
+
class="whitespace-nowrap rounded px-3 py-0.5 {sheet.active
|
|
90
|
+
? 'bg-background font-semibold text-foreground shadow-sm'
|
|
91
|
+
: 'text-muted-foreground hover:bg-background/60'} {dropTarget?.index === index
|
|
92
|
+
? dropTarget.after
|
|
93
|
+
? 'border-r-2 border-primary'
|
|
94
|
+
: 'border-l-2 border-primary'
|
|
95
|
+
: ''}"
|
|
96
|
+
onclick={() => sheetState.setActiveSheet(sheet.id)}
|
|
97
|
+
ondblclick={() => {
|
|
98
|
+
if (readOnly) return;
|
|
99
|
+
error = null;
|
|
100
|
+
renaming = { id: sheet.id, draft: sheet.name };
|
|
101
|
+
}}
|
|
102
|
+
oncontextmenu={(e) => {
|
|
103
|
+
if (readOnly) return;
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
menu = {
|
|
106
|
+
x: e.clientX,
|
|
107
|
+
y: e.clientY,
|
|
108
|
+
items: getSheetTabMenuItems(sheetState.controller, sheet.id, { onError: (message) => (error = message) })
|
|
109
|
+
};
|
|
110
|
+
}}
|
|
111
|
+
ondragstart={(e) => {
|
|
112
|
+
dragFrom = index;
|
|
113
|
+
e.dataTransfer?.setData('text/plain', sheet.id);
|
|
114
|
+
if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';
|
|
115
|
+
}}
|
|
116
|
+
ondragover={(e) => {
|
|
117
|
+
if (dragFrom === null) return;
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
const after = dropAfter(e);
|
|
120
|
+
if (dropTarget?.index !== index || dropTarget.after !== after) dropTarget = { index, after };
|
|
121
|
+
}}
|
|
122
|
+
ondragleave={() => (dropTarget = null)}
|
|
123
|
+
ondrop={(e) => {
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
const from = dragFrom;
|
|
126
|
+
dragFrom = null;
|
|
127
|
+
dropTarget = null;
|
|
128
|
+
if (from === null) return;
|
|
129
|
+
sheetState.moveSheet(sheetState.sheets[from].id, sheetDropIndex(from, index, dropAfter(e)));
|
|
130
|
+
}}
|
|
131
|
+
ondragend={() => {
|
|
132
|
+
dragFrom = null;
|
|
133
|
+
dropTarget = null;
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{sheet.name}
|
|
137
|
+
</button>
|
|
138
|
+
{/if}
|
|
139
|
+
{/each}
|
|
140
|
+
{#if !readOnly}
|
|
141
|
+
<button
|
|
142
|
+
type="button"
|
|
143
|
+
aria-label="Add sheet"
|
|
144
|
+
title="Add sheet"
|
|
145
|
+
class="rounded px-2 py-0.5 text-muted-foreground hover:bg-background/60"
|
|
146
|
+
onclick={() => {
|
|
147
|
+
error = null;
|
|
148
|
+
sheetState.addSheet();
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
+
|
|
152
|
+
</button>
|
|
153
|
+
{/if}
|
|
154
|
+
</div>
|
|
155
|
+
{#if error}
|
|
156
|
+
<div role="alert" class="px-2 py-1 text-xs text-destructive">{error}</div>
|
|
157
|
+
{/if}
|
|
158
|
+
{#if menu}
|
|
159
|
+
<SpreadsheetContextMenu items={menu.items} x={menu.x} y={menu.y} ariaLabel="Sheet actions" onClose={() => (menu = null)} />
|
|
160
|
+
{/if}
|
|
161
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { createReactiveSpreadsheet } from './spreadsheet.svelte.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
sheetState: ReturnType<typeof createReactiveSpreadsheet>;
|
|
4
|
+
readOnly?: boolean;
|
|
5
|
+
class?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const SheetTabs: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type SheetTabs = ReturnType<typeof SheetTabs>;
|
|
9
|
+
export default SheetTabs;
|
|
10
|
+
//# sourceMappingURL=SheetTabs.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SheetTabs.svelte.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/SheetTabs.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8HH,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|