@pixerate/editor-svelte 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/canvas/CanvasGuidesLayer.svelte +32 -2
- package/dist/canvas/CanvasGuidesLayer.svelte.d.ts +2 -0
- package/dist/canvas/CanvasGuidesLayer.svelte.d.ts.map +1 -1
- package/dist/canvas/ShapeNode.svelte +57 -0
- package/dist/canvas/ShapeNode.svelte.d.ts +21 -0
- package/dist/canvas/ShapeNode.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasArrange.svelte.d.ts +23 -1
- package/dist/canvas/createCanvasArrange.svelte.d.ts.map +1 -1
- package/dist/canvas/createCanvasArrange.svelte.js +19 -2
- package/dist/canvas/createCanvasMeasure.svelte.d.ts +53 -0
- package/dist/canvas/createCanvasMeasure.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasMeasure.svelte.js +80 -0
- package/dist/canvas/index.d.ts +4 -0
- package/dist/canvas/index.d.ts.map +1 -1
- package/dist/canvas/index.js +6 -0
- package/dist/commands/CommandPalette.svelte +129 -0
- package/dist/commands/CommandPalette.svelte.d.ts +13 -0
- package/dist/commands/CommandPalette.svelte.d.ts.map +1 -0
- package/dist/commands/commandShortcuts.svelte.d.ts +30 -0
- package/dist/commands/commandShortcuts.svelte.d.ts.map +1 -0
- package/dist/commands/commandShortcuts.svelte.js +37 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/palette.svelte.d.ts +34 -0
- package/dist/commands/palette.svelte.d.ts.map +1 -0
- package/dist/commands/palette.svelte.js +61 -0
- package/dist/history/createHistoryShortcuts.d.ts +1 -1
- package/dist/history/createHistoryShortcuts.d.ts.map +1 -1
- package/dist/history/createHistoryShortcuts.js +10 -32
- package/dist/history/history.svelte.d.ts +13 -4
- package/dist/history/history.svelte.d.ts.map +1 -1
- package/dist/history/history.svelte.js +10 -0
- package/dist/history/historyDirty.svelte.d.ts +31 -0
- package/dist/history/historyDirty.svelte.d.ts.map +1 -0
- package/dist/history/historyDirty.svelte.js +30 -0
- package/dist/history/index.d.ts +1 -0
- package/dist/history/index.d.ts.map +1 -1
- package/dist/history/index.js +1 -0
- package/dist/image-editor/ImageEditor.svelte +39 -0
- package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -1
- package/dist/image-editor/imageEditorState.svelte.d.ts +2 -0
- package/dist/image-editor/imageEditorState.svelte.d.ts.map +1 -1
- package/dist/image-editor/imageEditorState.svelte.js +4 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/review/ReviewToolbar.svelte +15 -0
- package/dist/review/ReviewToolbar.svelte.d.ts +4 -0
- package/dist/review/ReviewToolbar.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/FormulaBar.svelte +12 -1
- package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/SpreadsheetContextMenu.svelte +21 -2
- package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts +1 -1
- package/dist/spreadsheet/SpreadsheetContextMenu.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/SpreadsheetEditor.svelte +48 -6
- package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/SpreadsheetGroupRow.svelte +1 -1
- package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -1
- package/dist/spreadsheet/tableInteractions.d.ts.map +1 -1
- package/dist/spreadsheet/tableInteractions.js +2 -1
- package/package.json +10 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CommandRegistry, CommandResult, CommandSpec } from "@pixerate/editor/commands";
|
|
2
|
+
type MaybeGetter<T> = T | (() => T);
|
|
3
|
+
export interface CommandShortcutsOptions<TContext = any> {
|
|
4
|
+
/** Element or window to listen on (default: `window`). */
|
|
5
|
+
target?: Window | HTMLElement | null;
|
|
6
|
+
/** Active scopes, most specific first; a getter is read on every keydown. */
|
|
7
|
+
scopes?: MaybeGetter<string | readonly string[] | undefined>;
|
|
8
|
+
/** Context for the commands (default: the registry's); a getter is read on every keydown. */
|
|
9
|
+
context?: MaybeGetter<TContext | undefined>;
|
|
10
|
+
/** Fire even while typing in inputs / contenteditable (default: per binding). */
|
|
11
|
+
allowInEditable?: boolean;
|
|
12
|
+
/** Called after a shortcut ran a command. */
|
|
13
|
+
onRun?: (result: CommandResult) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Runs the registry's commands from their keyboard shortcuts (`registry.handleKeyDown`).
|
|
17
|
+
* Typing in inputs and editors is never hijacked, and disabled commands leave the event
|
|
18
|
+
* alone. Returns `{ destroy }`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createCommandShortcuts<TContext = any>(registry: CommandRegistry<TContext>, options?: CommandShortcutsOptions<TContext>): {
|
|
21
|
+
destroy: () => void;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Registers commands for the lifetime of the calling component (call it during
|
|
25
|
+
* component initialisation). Pass a getter to react to changes: when it returns a
|
|
26
|
+
* different array, the old commands are unregistered.
|
|
27
|
+
*/
|
|
28
|
+
export declare function useRegisterCommands<TContext = any>(registry: MaybeGetter<CommandRegistry<TContext> | null | undefined>, specs: MaybeGetter<readonly CommandSpec<TContext>[] | null | undefined>): void;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=commandShortcuts.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandShortcuts.svelte.d.ts","sourceRoot":"","sources":["../../src/commands/commandShortcuts.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7F,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAKpC,MAAM,WAAW,uBAAuB,CAAC,QAAQ,GAAG,GAAG;IACrD,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACrC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IAC7D,6FAA6F;IAC7F,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC5C,iFAAiF;IACjF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,GAAG,GAAG,EACnD,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,EACnC,OAAO,GAAE,uBAAuB,CAAC,QAAQ,CAAM,GAC9C;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAczB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,GAAG,GAAG,EAChD,QAAQ,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,EACnE,KAAK,EAAE,WAAW,CAAC,SAAS,WAAW,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GACtE,IAAI,CAON"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const read = (value) => typeof value === "function" ? value() : value;
|
|
2
|
+
/**
|
|
3
|
+
* Runs the registry's commands from their keyboard shortcuts (`registry.handleKeyDown`).
|
|
4
|
+
* Typing in inputs and editors is never hijacked, and disabled commands leave the event
|
|
5
|
+
* alone. Returns `{ destroy }`.
|
|
6
|
+
*/
|
|
7
|
+
export function createCommandShortcuts(registry, options = {}) {
|
|
8
|
+
const target = options.target ?? (typeof window !== "undefined" ? window : null);
|
|
9
|
+
if (!target)
|
|
10
|
+
return { destroy: () => { } };
|
|
11
|
+
const onKeyDown = (event) => {
|
|
12
|
+
const context = options.context === undefined ? undefined : read(options.context);
|
|
13
|
+
const result = registry.handleKeyDown(event, {
|
|
14
|
+
scopes: options.scopes === undefined ? undefined : read(options.scopes),
|
|
15
|
+
...(options.allowInEditable !== undefined ? { allowInEditable: options.allowInEditable } : {}),
|
|
16
|
+
...(context !== undefined ? { context } : {}),
|
|
17
|
+
});
|
|
18
|
+
if (result)
|
|
19
|
+
options.onRun?.(result);
|
|
20
|
+
};
|
|
21
|
+
target.addEventListener("keydown", onKeyDown);
|
|
22
|
+
return { destroy: () => target.removeEventListener("keydown", onKeyDown) };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Registers commands for the lifetime of the calling component (call it during
|
|
26
|
+
* component initialisation). Pass a getter to react to changes: when it returns a
|
|
27
|
+
* different array, the old commands are unregistered.
|
|
28
|
+
*/
|
|
29
|
+
export function useRegisterCommands(registry, specs) {
|
|
30
|
+
$effect(() => {
|
|
31
|
+
const currentRegistry = read(registry);
|
|
32
|
+
const currentSpecs = read(specs);
|
|
33
|
+
if (!currentRegistry || !currentSpecs || currentSpecs.length === 0)
|
|
34
|
+
return;
|
|
35
|
+
return currentRegistry.register(currentSpecs);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ComponentProps } from "svelte";
|
|
2
|
+
import type CommandPaletteComponent from "./CommandPalette.svelte";
|
|
3
|
+
export { default as CommandPalette } from "./CommandPalette.svelte";
|
|
4
|
+
export * from "./palette.svelte.js";
|
|
5
|
+
export * from "./commandShortcuts.svelte.js";
|
|
6
|
+
export type CommandPaletteProps = ComponentProps<typeof CommandPaletteComponent>;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,uBAAuB,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAE7C,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type CommandPaletteController, type CommandPaletteItem, type CommandPaletteOptions, type CommandRegistry, type CommandResult } from "@pixerate/editor/commands";
|
|
2
|
+
export interface CreateCommandPaletteOptions<TContext = any> extends CommandPaletteOptions<TContext> {
|
|
3
|
+
/** Chord that toggles the palette from anywhere, also while typing (e.g. `Mod+K`). */
|
|
4
|
+
hotkey?: string;
|
|
5
|
+
/** Element or window the hotkey listens on (default: `window`). */
|
|
6
|
+
hotkeyTarget?: Window | HTMLElement | null;
|
|
7
|
+
}
|
|
8
|
+
export interface SvelteCommandPalette {
|
|
9
|
+
readonly open: boolean;
|
|
10
|
+
readonly query: string;
|
|
11
|
+
readonly activeIndex: number;
|
|
12
|
+
readonly items: CommandPaletteItem[];
|
|
13
|
+
readonly recents: string[];
|
|
14
|
+
readonly lastResult: CommandResult | null;
|
|
15
|
+
readonly controller: CommandPaletteController;
|
|
16
|
+
setOpen(open: boolean): void;
|
|
17
|
+
toggle(): void;
|
|
18
|
+
setQuery(query: string): void;
|
|
19
|
+
setActiveIndex(index: number): void;
|
|
20
|
+
move(delta: number): void;
|
|
21
|
+
run(id: string): CommandResult | null;
|
|
22
|
+
runActive(): CommandResult | null;
|
|
23
|
+
handleKeyDown(event: KeyboardEvent): boolean;
|
|
24
|
+
/** Stops following the registry and removes the hotkey listener. */
|
|
25
|
+
destroy(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Reactive command palette state over a `CommandRegistry` (Svelte 5 runes): ranked rows
|
|
29
|
+
* with shortcuts and disabled reasons, active row and recents. Render it with
|
|
30
|
+
* `<CommandPalette palette={…} />` or your own markup. Call `destroy()` when done
|
|
31
|
+
* (e.g. in `onDestroy`).
|
|
32
|
+
*/
|
|
33
|
+
export declare function createCommandPalette<TContext = any>(registry: CommandRegistry<TContext>, options?: CreateCommandPaletteOptions<TContext>): SvelteCommandPalette;
|
|
34
|
+
//# sourceMappingURL=palette.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"palette.svelte.d.ts","sourceRoot":"","sources":["../../src/commands/palette.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAE1B,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,2BAA2B,CAAC,QAAQ,GAAG,GAAG,CAAE,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IAClG,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,wBAAwB,CAAC;IAC9C,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IACtC,SAAS,IAAI,aAAa,GAAG,IAAI,CAAC;IAClC,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;IAC7C,oEAAoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,GAAG,GAAG,EACjD,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,EACnC,OAAO,GAAE,2BAA2B,CAAC,QAAQ,CAAM,GAClD,oBAAoB,CAsDtB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createCommandPaletteController, matchPaletteHotkey, } from "@pixerate/editor/commands";
|
|
2
|
+
/**
|
|
3
|
+
* Reactive command palette state over a `CommandRegistry` (Svelte 5 runes): ranked rows
|
|
4
|
+
* with shortcuts and disabled reasons, active row and recents. Render it with
|
|
5
|
+
* `<CommandPalette palette={…} />` or your own markup. Call `destroy()` when done
|
|
6
|
+
* (e.g. in `onDestroy`).
|
|
7
|
+
*/
|
|
8
|
+
export function createCommandPalette(registry, options = {}) {
|
|
9
|
+
const controller = createCommandPaletteController(registry, options);
|
|
10
|
+
let state = $state.raw(controller.getState());
|
|
11
|
+
const unsubscribe = controller.subscribe((next) => {
|
|
12
|
+
state = next;
|
|
13
|
+
});
|
|
14
|
+
let removeHotkey = () => { };
|
|
15
|
+
const { hotkey } = options;
|
|
16
|
+
const target = options.hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
|
|
17
|
+
if (hotkey && target) {
|
|
18
|
+
const onKeyDown = (event) => {
|
|
19
|
+
const e = event;
|
|
20
|
+
if (e.defaultPrevented || !matchPaletteHotkey(e, hotkey, options.platform))
|
|
21
|
+
return;
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
controller.toggle();
|
|
24
|
+
};
|
|
25
|
+
target.addEventListener("keydown", onKeyDown);
|
|
26
|
+
removeHotkey = () => target.removeEventListener("keydown", onKeyDown);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
get open() {
|
|
30
|
+
return state.open;
|
|
31
|
+
},
|
|
32
|
+
get query() {
|
|
33
|
+
return state.query;
|
|
34
|
+
},
|
|
35
|
+
get activeIndex() {
|
|
36
|
+
return state.activeIndex;
|
|
37
|
+
},
|
|
38
|
+
get items() {
|
|
39
|
+
return state.items;
|
|
40
|
+
},
|
|
41
|
+
get recents() {
|
|
42
|
+
return state.recents;
|
|
43
|
+
},
|
|
44
|
+
get lastResult() {
|
|
45
|
+
return state.lastResult;
|
|
46
|
+
},
|
|
47
|
+
controller,
|
|
48
|
+
setOpen: controller.setOpen,
|
|
49
|
+
toggle: controller.toggle,
|
|
50
|
+
setQuery: controller.setQuery,
|
|
51
|
+
setActiveIndex: controller.setActiveIndex,
|
|
52
|
+
move: controller.move,
|
|
53
|
+
run: controller.run,
|
|
54
|
+
runActive: controller.runActive,
|
|
55
|
+
handleKeyDown: controller.handleKeyDown,
|
|
56
|
+
destroy() {
|
|
57
|
+
unsubscribe();
|
|
58
|
+
removeHotkey();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createHistoryShortcuts.d.ts","sourceRoot":"","sources":["../../src/history/createHistoryShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"createHistoryShortcuts.d.ts","sourceRoot":"","sources":["../../src/history/createHistoryShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,uBAA4B,GACpC;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAqCzB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { matchHistoryShortcut } from "@pixerate/editor/commands";
|
|
1
2
|
/**
|
|
2
3
|
* Attaches keyboard listeners for Undo (Mod+Z) and Redo (Mod+Shift+Z / Mod+Y).
|
|
3
4
|
* Returns an object with a `destroy()` function for lifecycle cleanup.
|
|
@@ -13,39 +14,16 @@ export function createHistoryShortcuts(manager, options = {}) {
|
|
|
13
14
|
}
|
|
14
15
|
const handleKeyDown = (event) => {
|
|
15
16
|
const e = event;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const targetEl = (e.target || document.activeElement);
|
|
23
|
-
if (targetEl && targetEl.tagName) {
|
|
24
|
-
const tagName = targetEl.tagName.toLowerCase();
|
|
25
|
-
const isInput = tagName === "input" || tagName === "textarea";
|
|
26
|
-
const isContentEditable = targetEl.isContentEditable ||
|
|
27
|
-
targetEl.getAttribute?.("contenteditable") === "true";
|
|
28
|
-
if (isInput || isContentEditable) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
17
|
+
// Default bindings from the command system: Mod+Z, Mod+Shift+Z and (off macOS) Mod+Y,
|
|
18
|
+
// matched by `event.code` with `Mod` = ⌘ on macOS and Ctrl elsewhere.
|
|
19
|
+
const action = matchHistoryShortcut(e, { allowInEditable: !ignoreEditableElements });
|
|
20
|
+
if (action === "undo" && manager.getState().canUndo) {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
manager.undo();
|
|
32
23
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (manager.getState().canUndo) {
|
|
37
|
-
e.preventDefault();
|
|
38
|
-
manager.undo();
|
|
39
|
-
}
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
// Redo: Mod+Shift+Z or (on non-Mac) Mod+Y
|
|
43
|
-
const isRedoKey = (key === "z" && e.shiftKey) || (!isMac && key === "y" && !e.shiftKey);
|
|
44
|
-
if (isRedoKey) {
|
|
45
|
-
if (manager.getState().canRedo) {
|
|
46
|
-
e.preventDefault();
|
|
47
|
-
manager.redo();
|
|
48
|
-
}
|
|
24
|
+
else if (action === "redo" && manager.getState().canRedo) {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
manager.redo();
|
|
49
27
|
}
|
|
50
28
|
};
|
|
51
29
|
eventTarget.addEventListener("keydown", handleKeyDown);
|
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
import { HistoryManager, HistoryState, Command, HistoryManagerOptions } from "@pixerate/editor/history";
|
|
1
|
+
import { HistoryManager, HistoryState, HistoryEntry, HistoryMark, MergedExecutionOptions, Command, HistoryManagerOptions } from "@pixerate/editor/history";
|
|
2
2
|
export interface SvelteHistory extends HistoryState {
|
|
3
3
|
readonly manager: HistoryManager;
|
|
4
|
+
/** History panel rows (undo steps, then redo steps). */
|
|
5
|
+
readonly entries: HistoryEntry[];
|
|
4
6
|
undo(): boolean;
|
|
5
7
|
redo(): boolean;
|
|
6
8
|
clear(): void;
|
|
7
9
|
execute(command: Command): void;
|
|
8
|
-
executeMerged(command: Command, options?:
|
|
9
|
-
windowMs?: number;
|
|
10
|
-
}): void;
|
|
10
|
+
executeMerged(command: Command, options?: MergedExecutionOptions): void;
|
|
11
11
|
batch(name: string, fn: () => void): void;
|
|
12
|
+
/** Undoes / redoes until the entry at `index` is current (`-1` = before all). */
|
|
13
|
+
goTo(index: number): number;
|
|
14
|
+
/** Captures the current point, e.g. when a drag starts. */
|
|
15
|
+
mark(): HistoryMark;
|
|
16
|
+
/** Takes back every step since `mark` without leaving redo (Escape-cancel). */
|
|
17
|
+
revertTo(mark: HistoryMark): number;
|
|
18
|
+
/** Joins every merged execute into one step until `endGesture`. */
|
|
19
|
+
beginGesture(key: string): void;
|
|
20
|
+
endGesture(): void;
|
|
12
21
|
subscribe(run: (value: HistoryState) => void): () => void;
|
|
13
22
|
}
|
|
14
23
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.svelte.d.ts","sourceRoot":"","sources":["../../src/history/history.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,OAAO,EAEP,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,IAAI,IAAI,OAAO,CAAC;IAChB,IAAI,IAAI,OAAO,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"history.svelte.d.ts","sourceRoot":"","sources":["../../src/history/history.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,OAAO,EAEP,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;IACjC,IAAI,IAAI,OAAO,CAAC;IAChB,IAAI,IAAI,OAAO,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACxE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,iFAAiF;IACjF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,2DAA2D;IAC3D,IAAI,IAAI,WAAW,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,mEAAmE;IACnE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,IAAI,IAAI,CAAC;IACnB,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC3D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,gBAAgB,CAAC,EAAE,cAAc,GAAG,qBAAqB,GACxD,aAAa,CAqDf"}
|
|
@@ -32,12 +32,22 @@ export function createHistory(managerOrOptions) {
|
|
|
32
32
|
get manager() {
|
|
33
33
|
return manager;
|
|
34
34
|
},
|
|
35
|
+
get entries() {
|
|
36
|
+
// Reading `state` makes the getter reactive; getEntries() is cached per change.
|
|
37
|
+
void state;
|
|
38
|
+
return manager.getEntries();
|
|
39
|
+
},
|
|
35
40
|
undo: () => manager.undo(),
|
|
36
41
|
redo: () => manager.redo(),
|
|
37
42
|
clear: () => manager.clear(),
|
|
38
43
|
execute: (cmd) => manager.execute(cmd),
|
|
39
44
|
executeMerged: (cmd, opts) => manager.executeMerged(cmd, opts),
|
|
40
45
|
batch: (name, fn) => manager.batch(name, fn),
|
|
46
|
+
goTo: (index) => manager.goTo(index),
|
|
47
|
+
mark: () => manager.mark(),
|
|
48
|
+
revertTo: (m) => manager.revertTo(m),
|
|
49
|
+
beginGesture: (key) => manager.beginGesture(key),
|
|
50
|
+
endGesture: () => manager.endGesture(),
|
|
41
51
|
subscribe: (run) => manager.subscribe(run),
|
|
42
52
|
};
|
|
43
53
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DirtyTracker, type DirtyTrackerOptions, type HistoryManager } from "@pixerate/editor/history";
|
|
2
|
+
export interface CreateHistoryDirtyOptions<T> extends DirtyTrackerOptions<T> {
|
|
3
|
+
/** The history whose changes re-check the document (a `createHistory().manager`). */
|
|
4
|
+
history: HistoryManager;
|
|
5
|
+
/** Reads the current document value. */
|
|
6
|
+
getValue: () => T;
|
|
7
|
+
/** Existing tracker to drive. */
|
|
8
|
+
tracker?: DirtyTracker<T>;
|
|
9
|
+
}
|
|
10
|
+
export interface SvelteHistoryDirty<T> {
|
|
11
|
+
/** Whether the document differs from the saved state (reactive). */
|
|
12
|
+
readonly isDirty: boolean;
|
|
13
|
+
/** Marks the current document as saved. */
|
|
14
|
+
markClean(): void;
|
|
15
|
+
/** Runs a load / restore without marking the document dirty (re-entrant). */
|
|
16
|
+
suppress<R>(fn: () => R): R;
|
|
17
|
+
/** Re-checks after a change made outside the history. */
|
|
18
|
+
refresh(): boolean;
|
|
19
|
+
readonly tracker: DirtyTracker<T>;
|
|
20
|
+
/** Stops following the history. */
|
|
21
|
+
destroy(): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Svelte 5 rune: dirty-vs-saved tracking bound to a HistoryManager. Undoing
|
|
25
|
+
* back to the saved state makes the document clean again, so a navigation
|
|
26
|
+
* guard fed with `isDirty` stops prompting.
|
|
27
|
+
*
|
|
28
|
+
* Usage: `createNavigationGuard({ isDirty: () => dirty.isDirty })`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createHistoryDirty<T>(options: CreateHistoryDirtyOptions<T>): SvelteHistoryDirty<T>;
|
|
31
|
+
//# sourceMappingURL=historyDirty.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historyDirty.svelte.d.ts","sourceRoot":"","sources":["../../src/history/historyDirty.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,yBAAyB,CAAC,CAAC,CAAE,SAAQ,mBAAmB,CAAC,CAAC,CAAC;IAC1E,qFAAqF;IACrF,OAAO,EAAE,cAAc,CAAC;IACxB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,iCAAiC;IACjC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2CAA2C;IAC3C,SAAS,IAAI,IAAI,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC;IACnB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,mCAAmC;IACnC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,GACpC,kBAAkB,CAAC,CAAC,CAAC,CAsBvB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { bindDirtyToHistory, } from "@pixerate/editor/history";
|
|
2
|
+
/**
|
|
3
|
+
* Svelte 5 rune: dirty-vs-saved tracking bound to a HistoryManager. Undoing
|
|
4
|
+
* back to the saved state makes the document clean again, so a navigation
|
|
5
|
+
* guard fed with `isDirty` stops prompting.
|
|
6
|
+
*
|
|
7
|
+
* Usage: `createNavigationGuard({ isDirty: () => dirty.isDirty })`.
|
|
8
|
+
*/
|
|
9
|
+
export function createHistoryDirty(options) {
|
|
10
|
+
const binding = bindDirtyToHistory(options);
|
|
11
|
+
let isDirty = $state(binding.dirty);
|
|
12
|
+
const unsubscribe = binding.subscribe((dirty) => {
|
|
13
|
+
isDirty = dirty;
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
get isDirty() {
|
|
17
|
+
return isDirty;
|
|
18
|
+
},
|
|
19
|
+
markClean: () => binding.markClean(),
|
|
20
|
+
suppress: (fn) => binding.suppress(fn),
|
|
21
|
+
refresh: () => binding.refresh(),
|
|
22
|
+
get tracker() {
|
|
23
|
+
return binding.tracker;
|
|
24
|
+
},
|
|
25
|
+
destroy() {
|
|
26
|
+
unsubscribe();
|
|
27
|
+
binding.destroy();
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
package/dist/history/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/history/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/history/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
|
package/dist/history/index.js
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
getCropCursor,
|
|
17
17
|
calculateCropDrag,
|
|
18
18
|
hitTestAnnotation,
|
|
19
|
+
normalizeProcessVersion,
|
|
20
|
+
LATEST_PROCESS_VERSION,
|
|
19
21
|
} from '@pixerate/editor/image-editor';
|
|
20
22
|
import { onDestroy, untrack } from 'svelte';
|
|
21
23
|
import { createReactiveImageEditor, type ReactiveImageEditor } from './imageEditorState.svelte.js';
|
|
@@ -47,6 +49,9 @@
|
|
|
47
49
|
const internalEditor = createReactiveImageEditor();
|
|
48
50
|
const editor = $derived(propEditor || internalEditor);
|
|
49
51
|
onDestroy(() => internalEditor.destroy());
|
|
52
|
+
const legacyProcess = $derived(
|
|
53
|
+
normalizeProcessVersion(editor.state.adjustments.process) < LATEST_PROCESS_VERSION
|
|
54
|
+
);
|
|
50
55
|
|
|
51
56
|
let canvasEl = $state<HTMLCanvasElement | null>(null);
|
|
52
57
|
let containerEl = $state<HTMLDivElement | null>(null);
|
|
@@ -961,6 +966,40 @@
|
|
|
961
966
|
/>
|
|
962
967
|
</div>
|
|
963
968
|
|
|
969
|
+
<!-- Tint (process 2 white balance) -->
|
|
970
|
+
<div>
|
|
971
|
+
<div class="flex justify-between text-slate-400 mb-1">
|
|
972
|
+
<span>Tint</span>
|
|
973
|
+
<span class="font-mono">{editor.state.adjustments.tint ?? 0}</span>
|
|
974
|
+
</div>
|
|
975
|
+
<input
|
|
976
|
+
type="range"
|
|
977
|
+
min="-100"
|
|
978
|
+
max="100"
|
|
979
|
+
aria-label="Tint"
|
|
980
|
+
disabled={legacyProcess}
|
|
981
|
+
value={editor.state.adjustments.tint ?? 0}
|
|
982
|
+
oninput={(e) => editor.setAdjustments({ tint: Number((e.target as HTMLInputElement).value) })}
|
|
983
|
+
class="w-full accent-indigo-500 disabled:opacity-40"
|
|
984
|
+
/>
|
|
985
|
+
</div>
|
|
986
|
+
|
|
987
|
+
{#if legacyProcess}
|
|
988
|
+
<div
|
|
989
|
+
class="flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200"
|
|
990
|
+
data-testid="image-editor-process-notice"
|
|
991
|
+
>
|
|
992
|
+
<span>Legacy rendering (process 1). Tint needs the current process.</span>
|
|
993
|
+
<button
|
|
994
|
+
type="button"
|
|
995
|
+
onclick={() => editor.upgradeProcess()}
|
|
996
|
+
class="shrink-0 rounded bg-amber-500/20 px-2 py-0.5 hover:bg-amber-500/30"
|
|
997
|
+
>
|
|
998
|
+
Update
|
|
999
|
+
</button>
|
|
1000
|
+
</div>
|
|
1001
|
+
{/if}
|
|
1002
|
+
|
|
964
1003
|
<!-- Blur -->
|
|
965
1004
|
<div>
|
|
966
1005
|
<div class="flex justify-between text-slate-400 mb-1">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/ImageEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAIR,aAAa,EAGb,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/ImageEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAIR,aAAa,EAGb,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AAWzC,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGjG,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAojCH,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -14,6 +14,8 @@ export declare function createReactiveImageEditor(options?: ImageEditorOptions):
|
|
|
14
14
|
flipVertical(): void;
|
|
15
15
|
setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory?: boolean): void;
|
|
16
16
|
resetAdjustments(): void;
|
|
17
|
+
/** Update to Current Process: re-render the adjustments with the latest process (one undo step). */
|
|
18
|
+
upgradeProcess(): boolean;
|
|
17
19
|
setDepthMask(partial: Partial<DepthMaskOptions>): void;
|
|
18
20
|
resetDepthMask(): void;
|
|
19
21
|
addAnnotation(ann: CreateAnnotationPayload): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageEditorState.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/imageEditorState.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAChB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB;;;;;kBA0BxD,eAAe;kBAGf,OAAO,GAAG,IAAI;2BAGL,WAAW;;oBAMlB,MAAM;yBAGD,MAAM;;;4BASH,OAAO,CAAC,gBAAgB,CAAC;;
|
|
1
|
+
{"version":3,"file":"imageEditorState.svelte.d.ts","sourceRoot":"","sources":["../../src/image-editor/imageEditorState.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAChB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB;;;;;kBA0BxD,eAAe;kBAGf,OAAO,GAAG,IAAI;2BAGL,WAAW;;oBAMlB,MAAM;yBAGD,MAAM;;;4BASH,OAAO,CAAC,gBAAgB,CAAC;;IAMjD,oGAAoG;;0BAI9E,OAAO,CAAC,gBAAgB,CAAC;;uBAM5B,uBAAuB;yBAGrB,MAAM,WAAW,OAAO,CAAC,UAAU,CAAC;yBAGpC,MAAM;;yBAMN,MAAM,GAAG,IAAI;;;;oBAYlB,MAAM;qBAGL,MAAM;;kBAMT,MAAM;gBAGR,UAAU;4BAGE,OAAO;mBAGhB,MAAM,GAAG,gBAAgB;qBAGvB,aAAa;kBAGhB,aAAa;;mBAMZ,0BAA0B;sBAGvB;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;yBAG5C;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE;2BAG7C,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;oCAGhC,MAAM;4CAGE,MAAM;IAG9C,8EAA8E;;EAKjF;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
|
|
@@ -53,6 +53,10 @@ export function createReactiveImageEditor(options = {}) {
|
|
|
53
53
|
resetAdjustments() {
|
|
54
54
|
controller.resetAdjustments();
|
|
55
55
|
},
|
|
56
|
+
/** Update to Current Process: re-render the adjustments with the latest process (one undo step). */
|
|
57
|
+
upgradeProcess() {
|
|
58
|
+
return controller.upgradeProcess();
|
|
59
|
+
},
|
|
56
60
|
setDepthMask(partial) {
|
|
57
61
|
controller.setDepthMask(partial);
|
|
58
62
|
},
|
package/dist/index.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ export * from "./history/index.js";
|
|
|
11
11
|
export * from "./fileImport.svelte.js";
|
|
12
12
|
export * from "./agentTools.svelte.js";
|
|
13
13
|
export * from "./outline.svelte.js";
|
|
14
|
-
export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, } from "@pixerate/editor";
|
|
15
|
-
export type { DirtyTrackerOptions, Command, HistoryState, HistoryManagerOptions, } from "@pixerate/editor";
|
|
14
|
+
export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, bindDirtyToHistory, withoutDirty, } from "@pixerate/editor";
|
|
15
|
+
export type { DirtyTrackerOptions, Command, HistoryState, HistoryManagerOptions, HistoryEntry, HistoryMark, MergedExecutionOptions, HistoryDirtyBinding, BindDirtyToHistoryOptions, } from "@pixerate/editor";
|
|
16
16
|
export type EditableTextNodeEditorProps = ComponentProps<typeof EditableTextNodeEditorComponent>;
|
|
17
17
|
export type BubbleMenuProps = ComponentProps<typeof BubbleMenuComponent>;
|
|
18
18
|
export type TemplateRendererProps = ComponentProps<typeof TemplateRendererComponent>;
|
|
@@ -28,4 +28,5 @@ export type { PromptValues, PromptDiagnostic, VariableFormField, } from "@pixera
|
|
|
28
28
|
export * from "./spreadsheet/index.js";
|
|
29
29
|
export * from "./image-editor/index.js";
|
|
30
30
|
export * from "./review/index.js";
|
|
31
|
+
export * from "./commands/index.js";
|
|
31
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,KAAK,+BAA+B,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,yBAAyB,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAE/D,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,KAAK,+BAA+B,MAAM,iCAAiC,CAAC;AACnF,OAAO,KAAK,mBAAmB,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,yBAAyB,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,qBAAqB,MAAM,uBAAuB,CAAC;AAE/D,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,mBAAmB,EACnB,OAAO,EACP,YAAY,EACZ,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,+BAA+B,CACvC,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAChD,OAAO,yBAAyB,CACjC,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE7E,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAEhE,YAAY,EACV,QAAQ,EACR,eAAe,EACf,KAAK,EACL,SAAS,EACT,aAAa,EACb,qBAAqB,EACrB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export * from "./history/index.js";
|
|
|
5
5
|
export * from "./fileImport.svelte.js";
|
|
6
6
|
export * from "./agentTools.svelte.js";
|
|
7
7
|
export * from "./outline.svelte.js";
|
|
8
|
-
export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, } from "@pixerate/editor";
|
|
8
|
+
export { DirtyTracker, createDirtyTracker, defaultIsEqual, HistoryManager, createHistoryManager, bindDirtyToHistory, withoutDirty, } from "@pixerate/editor";
|
|
9
9
|
export { default as EditableTextNodeEditor } from "./EditableTextNodeEditor.svelte";
|
|
10
10
|
export { default as BubbleMenu } from "./BubbleMenu.svelte";
|
|
11
11
|
export { default as TemplateRenderer } from "./TemplateRenderer.svelte";
|
|
@@ -14,3 +14,4 @@ export { default as OutlinePanel } from "./OutlinePanel.svelte";
|
|
|
14
14
|
export * from "./spreadsheet/index.js";
|
|
15
15
|
export * from "./image-editor/index.js";
|
|
16
16
|
export * from "./review/index.js";
|
|
17
|
+
export * from "./commands/index.js";
|
|
@@ -5,11 +5,17 @@
|
|
|
5
5
|
interface Props {
|
|
6
6
|
editor?: Editor | null;
|
|
7
7
|
class?: string;
|
|
8
|
+
/** Show the current change's author and description. Defaults to `true`. */
|
|
9
|
+
showDescription?: boolean;
|
|
10
|
+
/** Class of the description label. */
|
|
11
|
+
descriptionClass?: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
let {
|
|
11
15
|
editor = null,
|
|
12
16
|
class: className = "flex flex-wrap items-center gap-1 rounded-md border border-border bg-background p-1 text-sm",
|
|
17
|
+
showDescription = true,
|
|
18
|
+
descriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground",
|
|
13
19
|
}: Props = $props();
|
|
14
20
|
|
|
15
21
|
const buttonClass =
|
|
@@ -60,6 +66,15 @@
|
|
|
60
66
|
>
|
|
61
67
|
›
|
|
62
68
|
</button>
|
|
69
|
+
{#if showDescription && current}
|
|
70
|
+
<span
|
|
71
|
+
class={descriptionClass}
|
|
72
|
+
data-change-type={current.type}
|
|
73
|
+
title={`${current.author.name}: ${current.description}`}
|
|
74
|
+
>
|
|
75
|
+
{current.author.name ? `${current.author.name}: ` : ""}{current.description}
|
|
76
|
+
</span>
|
|
77
|
+
{/if}
|
|
63
78
|
<span class="mx-1 h-4 w-px bg-border" aria-hidden="true"></span>
|
|
64
79
|
<button
|
|
65
80
|
type="button"
|
|
@@ -2,6 +2,10 @@ import type { Editor } from "@tiptap/core";
|
|
|
2
2
|
interface Props {
|
|
3
3
|
editor?: Editor | null;
|
|
4
4
|
class?: string;
|
|
5
|
+
/** Show the current change's author and description. Defaults to `true`. */
|
|
6
|
+
showDescription?: boolean;
|
|
7
|
+
/** Class of the description label. */
|
|
8
|
+
descriptionClass?: string;
|
|
5
9
|
}
|
|
6
10
|
declare const ReviewToolbar: import("svelte").Component<Props, {}, "">;
|
|
7
11
|
type ReviewToolbar = ReturnType<typeof ReviewToolbar>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/review/ReviewToolbar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAIzC,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ReviewToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/review/ReviewToolbar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAIzC,UAAU,KAAK;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAiEH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -46,6 +46,15 @@
|
|
|
46
46
|
return value;
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
// A spilled cell shows its anchor's formula greyed out (it has no formula of its own).
|
|
50
|
+
let spillFormula = $derived.by(() => {
|
|
51
|
+
if (!sheetState || sheetState.editingCell || !sheetState.activeCell || effectiveValue) return '';
|
|
52
|
+
void sheetState.document;
|
|
53
|
+
const { row, col } = sheetState.activeCell;
|
|
54
|
+
const spill = sheetState.controller.getSpillAt(row, col);
|
|
55
|
+
return spill && (spill.anchor.row !== row || spill.anchor.col !== col) ? spill.formula : '';
|
|
56
|
+
});
|
|
57
|
+
|
|
49
58
|
function handleKeyDown(e: KeyboardEvent) {
|
|
50
59
|
// Keys typed here must not reach the grid's navigation handler.
|
|
51
60
|
e.stopPropagation();
|
|
@@ -101,7 +110,9 @@
|
|
|
101
110
|
placeholder="Enter a value or formula (e.g. =SUM(A1:A5))"
|
|
102
111
|
aria-label="Formula bar"
|
|
103
112
|
bind:this={inputEl}
|
|
104
|
-
|
|
113
|
+
data-spill-formula={spillFormula ? 'true' : undefined}
|
|
114
|
+
style={spillFormula ? 'color: var(--muted-foreground, #94a3b8);' : undefined}
|
|
115
|
+
value={effectiveValue || spillFormula}
|
|
105
116
|
oninput={handleInput}
|
|
106
117
|
onkeydown={handleKeyDown}
|
|
107
118
|
/>
|