|
4 | 4 | import LayoutCol from "/src/components/layout/LayoutCol.svelte"; |
5 | 5 | import LayoutRow from "/src/components/layout/LayoutRow.svelte"; |
6 | 6 | import WidgetLayout from "/src/components/widgets/WidgetLayout.svelte"; |
7 | | - import type { ColorPickerStore } from "/src/stores/color-picker"; |
| 7 | + import type { ColorPickerCallbacks, ColorPickerStore } from "/src/stores/color-picker"; |
8 | 8 | import type { EditorWrapper, FillChoice, MenuDirection } from "/wrapper/pkg/graphite_wasm_wrapper"; |
9 | 9 |
|
10 | 10 | const dispatch = createEventDispatcher<{ colorOrGradient: FillChoice; startHistoryTransaction: undefined; commitHistoryTransaction: undefined }>(); |
|
27 | 27 | // Open/close lifecycle: when `open` flips, register/clear the global callbacks (so events route to *this* instance) |
28 | 28 | // and tell the Rust handler to (re)initialize its state from the current `colorOrGradient`. |
29 | 29 | let lastOpen = false; |
| 30 | + // Identity used by `clearCallbacks` to skip stale clears when another picker has already taken over the store's callbacks |
| 31 | + let installedCallbacks: ColorPickerCallbacks | undefined; |
30 | 32 | $: handleOpenChange(open); |
31 | 33 |
|
32 | 34 | function handleOpenChange(isOpen: boolean) { |
33 | 35 | if (isOpen && !lastOpen) { |
34 | | - colorPickerStore.setCallbacks({ |
| 36 | + installedCallbacks = { |
35 | 37 | onColorChanged: (value) => dispatch("colorOrGradient", value), |
36 | 38 | onStartTransaction: () => dispatch("startHistoryTransaction"), |
37 | 39 | onCommitTransaction: () => dispatch("commitHistoryTransaction"), |
38 | | - }); |
| 40 | + }; |
| 41 | + colorPickerStore.setCallbacks(installedCallbacks); |
39 | 42 | editor.openColorPicker(colorOrGradient, allowNone, disabled); |
40 | 43 | // Auto-select the hex color code text input. Deferred so the layout has time to render after the picker opens. |
41 | 44 | setTimeout(() => { |
42 | 45 | const hexInput = self?.div()?.querySelector(".text-input input"); |
43 | 46 | if (hexInput instanceof HTMLInputElement) hexInput.select(); |
44 | 47 | }, 0); |
45 | 48 | } else if (!isOpen && lastOpen) { |
46 | | - colorPickerStore.clearCallbacks(); |
| 49 | + if (installedCallbacks) colorPickerStore.clearCallbacks(installedCallbacks); |
| 50 | + installedCallbacks = undefined; |
47 | 51 | editor.closeColorPicker(); |
48 | 52 | } |
49 | 53 | lastOpen = isOpen; |
|
55 | 59 |
|
56 | 60 | onDestroy(() => { |
57 | 61 | if (!lastOpen) return; |
58 | | - colorPickerStore.clearCallbacks(); |
| 62 | + if (installedCallbacks) colorPickerStore.clearCallbacks(installedCallbacks); |
| 63 | + installedCallbacks = undefined; |
59 | 64 | editor.closeColorPicker(); |
60 | 65 | }); |
61 | 66 | </script> |
|
0 commit comments