@pixerate/editor-svelte 0.104.0 → 0.106.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 +3 -1
- package/dist/canvas/createMermaidDiagram.svelte.d.ts +7 -1
- package/dist/canvas/createMermaidDiagram.svelte.js +7 -2
- package/dist/color/ColorPicker.svelte +546 -0
- package/dist/color/ColorPicker.svelte.d.ts +36 -0
- package/dist/color/DualColorPicker.svelte +296 -0
- package/dist/color/DualColorPicker.svelte.d.ts +34 -0
- package/dist/color/colorScheme.svelte.d.ts +19 -0
- package/dist/color/colorScheme.svelte.js +76 -0
- package/dist/color/index.d.ts +9 -0
- package/dist/color/index.js +5 -0
- package/dist/gradient/FillPicker.svelte +236 -0
- package/dist/gradient/FillPicker.svelte.d.ts +32 -0
- package/dist/gradient/GradientEditor.svelte +472 -0
- package/dist/gradient/GradientEditor.svelte.d.ts +23 -0
- package/dist/gradient/gradientController.svelte.d.ts +13 -0
- package/dist/gradient/gradientController.svelte.js +21 -0
- package/dist/gradient/index.d.ts +10 -0
- package/dist/gradient/index.js +5 -0
- package/dist/gradient/types.d.ts +2 -0
- package/dist/gradient/types.js +1 -0
- package/dist/parameters/ParameterColor.svelte +63 -64
- package/dist/persistence/editorAutosave.svelte.d.ts +17 -0
- package/dist/persistence/editorAutosave.svelte.js +40 -0
- package/dist/persistence/index.d.ts +1 -0
- package/dist/persistence/index.js +1 -0
- package/package.json +18 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { normalizeHexColor, parameterLabel, type ColorParameterField } from '@pixerate/editor/parameters';
|
|
3
|
+
import ColorPicker from '../color/ColorPicker.svelte';
|
|
3
4
|
import ParameterCommitInput from './ParameterCommitInput.svelte';
|
|
4
|
-
import { parameterInputClass
|
|
5
|
+
import { parameterInputClass } from './styles.js';
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
7
8
|
field: ColorParameterField;
|
|
@@ -19,44 +20,53 @@
|
|
|
19
20
|
const alpha = $derived(!!field.alpha);
|
|
20
21
|
const hex = $derived(normalizeHexColor(value, true) ?? '#000000ff');
|
|
21
22
|
const rgb = $derived(hex.slice(0, 7));
|
|
22
|
-
const a = $derived(hex.slice(7));
|
|
23
23
|
const shown = $derived(alpha ? hex : rgb);
|
|
24
24
|
const off = $derived(disabled || !!field.readOnly);
|
|
25
25
|
const name = $derived(parameterLabel(field));
|
|
26
26
|
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
let open = $state(false);
|
|
28
|
+
let containerEl = $state<HTMLDivElement | null>(null);
|
|
29
|
+
let buttonEl = $state<HTMLButtonElement | null>(null);
|
|
30
|
+
let popoverEl = $state<HTMLDivElement | null>(null);
|
|
31
|
+
|
|
32
|
+
$effect(() => {
|
|
33
|
+
if (!open) return;
|
|
34
|
+
function onPointerDown(e: PointerEvent) {
|
|
35
|
+
if (containerEl && !containerEl.contains(e.target as Node)) {
|
|
36
|
+
open = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function onKeyDown(e: KeyboardEvent) {
|
|
40
|
+
if (e.key === 'Escape') {
|
|
41
|
+
e.stopPropagation();
|
|
42
|
+
open = false;
|
|
43
|
+
buttonEl?.focus();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
window.addEventListener('pointerdown', onPointerDown, true);
|
|
47
|
+
window.addEventListener('keydown', onKeyDown, true);
|
|
48
|
+
return () => {
|
|
49
|
+
window.removeEventListener('pointerdown', onPointerDown, true);
|
|
50
|
+
window.removeEventListener('keydown', onKeyDown, true);
|
|
51
|
+
};
|
|
52
|
+
});
|
|
38
53
|
</script>
|
|
39
54
|
|
|
40
|
-
<!-- A colour picker with a hex box
|
|
41
|
-
<div class="space-y-1.5">
|
|
55
|
+
<!-- A colour picker with a hex box and a popup ColorPicker. -->
|
|
56
|
+
<div bind:this={containerEl} class="relative space-y-1.5">
|
|
42
57
|
<div class="flex items-center gap-2">
|
|
43
|
-
<
|
|
44
|
-
|
|
58
|
+
<button
|
|
59
|
+
bind:this={buttonEl}
|
|
60
|
+
type="button"
|
|
61
|
+
aria-label={name}
|
|
62
|
+
aria-expanded={open}
|
|
63
|
+
aria-haspopup="dialog"
|
|
64
|
+
disabled={off}
|
|
65
|
+
onclick={() => (open = !open)}
|
|
66
|
+
class="relative h-7 w-9 shrink-0 overflow-hidden rounded-md border border-input bg-[repeating-conic-gradient(#d4d4d8_0_25%,#fff_0_50%)] bg-[length:8px_8px] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50"
|
|
45
67
|
>
|
|
46
68
|
<span class="absolute inset-0" style:background={shown}></span>
|
|
47
|
-
|
|
48
|
-
type="color"
|
|
49
|
-
aria-label={name}
|
|
50
|
-
value={rgb}
|
|
51
|
-
disabled={off}
|
|
52
|
-
class="absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed"
|
|
53
|
-
oninput={(e) => {
|
|
54
|
-
start();
|
|
55
|
-
onchange(alpha ? `${e.currentTarget.value}${a}` : e.currentTarget.value);
|
|
56
|
-
}}
|
|
57
|
-
onblur={end}
|
|
58
|
-
/>
|
|
59
|
-
</span>
|
|
69
|
+
</button>
|
|
60
70
|
<ParameterCommitInput
|
|
61
71
|
{id}
|
|
62
72
|
aria-label="{name} hex"
|
|
@@ -70,40 +80,29 @@
|
|
|
70
80
|
}}
|
|
71
81
|
/>
|
|
72
82
|
</div>
|
|
73
|
-
{#if
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
type="button"
|
|
97
|
-
title={swatch}
|
|
98
|
-
aria-label="{name} {swatch}"
|
|
99
|
-
aria-pressed={swatch === shown}
|
|
100
|
-
disabled={off}
|
|
101
|
-
onclick={() => onchange(swatch)}
|
|
102
|
-
class="h-5 w-5 rounded border border-input aria-pressed:ring-1 aria-pressed:ring-primary"
|
|
103
|
-
style:background={swatch}
|
|
104
|
-
></button>
|
|
105
|
-
{/if}
|
|
106
|
-
{/each}
|
|
83
|
+
{#if open}
|
|
84
|
+
<div
|
|
85
|
+
bind:this={popoverEl}
|
|
86
|
+
role="dialog"
|
|
87
|
+
aria-label={name}
|
|
88
|
+
tabindex="-1"
|
|
89
|
+
onfocusout={(e) => {
|
|
90
|
+
if (popoverEl && !popoverEl.contains(e.relatedTarget as Node)) {
|
|
91
|
+
open = false;
|
|
92
|
+
}
|
|
93
|
+
}}
|
|
94
|
+
class="absolute left-0 top-full z-50 mt-1 w-64 rounded-lg border border-border bg-popover p-2 text-popover-foreground shadow-xl"
|
|
95
|
+
style="background: var(--popover, var(--background, #fff));"
|
|
96
|
+
>
|
|
97
|
+
<ColorPicker
|
|
98
|
+
value={shown}
|
|
99
|
+
{alpha}
|
|
100
|
+
swatches={field.swatches}
|
|
101
|
+
disabled={off}
|
|
102
|
+
{onchange}
|
|
103
|
+
{ongesturestart}
|
|
104
|
+
{ongestureend}
|
|
105
|
+
/>
|
|
107
106
|
</div>
|
|
108
107
|
{/if}
|
|
109
108
|
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type EditorDocument, type EditorDocumentFile, type LoadReport } from "@pixerate/editor/persistence";
|
|
2
|
+
import { type CreateAutosaveOptions, type SvelteAutosave } from "./autosave.svelte.js";
|
|
3
|
+
export interface CreateEditorAutosaveOptions extends Omit<CreateAutosaveOptions<EditorDocumentFile>, "key" | "getSnapshot" | "serialize" | "deserialize" | "history"> {
|
|
4
|
+
/** Snapshot key (default the document's `kind`). */
|
|
5
|
+
key?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SvelteEditorAutosave extends Omit<SvelteAutosave<EditorDocumentFile>, "restore"> {
|
|
8
|
+
/** Loads the recovered snapshot into the document and starts autosaving. */
|
|
9
|
+
restore(): LoadReport | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* `createAutosave` for any editor's `EditorDocument` (e.g.
|
|
13
|
+
* `createMermaidDiagram(...).editorDocument`): snapshots it as an
|
|
14
|
+
* `EditorDocumentFile` after each change, and `restore` loads a recovered
|
|
15
|
+
* snapshot straight into the editor. Status and recovery stay reactive.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createEditorAutosave(doc: EditorDocument, options: CreateEditorAutosaveOptions): SvelteEditorAutosave;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { parseEditorDocument, toEditorDocumentFile, } from "@pixerate/editor/persistence";
|
|
2
|
+
import { createAutosave } from "./autosave.svelte.js";
|
|
3
|
+
/**
|
|
4
|
+
* `createAutosave` for any editor's `EditorDocument` (e.g.
|
|
5
|
+
* `createMermaidDiagram(...).editorDocument`): snapshots it as an
|
|
6
|
+
* `EditorDocumentFile` after each change, and `restore` loads a recovered
|
|
7
|
+
* snapshot straight into the editor. Status and recovery stay reactive.
|
|
8
|
+
*/
|
|
9
|
+
export function createEditorAutosave(doc, options) {
|
|
10
|
+
const autosave = createAutosave({
|
|
11
|
+
...options,
|
|
12
|
+
key: options.key ?? doc.kind,
|
|
13
|
+
getSnapshot: () => toEditorDocumentFile(doc),
|
|
14
|
+
deserialize: (text) => parseEditorDocument(text, { kind: doc.kind }),
|
|
15
|
+
history: doc,
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
get status() {
|
|
19
|
+
return autosave.status;
|
|
20
|
+
},
|
|
21
|
+
get recovery() {
|
|
22
|
+
return autosave.recovery;
|
|
23
|
+
},
|
|
24
|
+
get pendingRecovery() {
|
|
25
|
+
return autosave.pendingRecovery;
|
|
26
|
+
},
|
|
27
|
+
restore() {
|
|
28
|
+
const snapshot = autosave.restore();
|
|
29
|
+
return snapshot ? doc.loadDocument(snapshot, { history: "reset" }) : undefined;
|
|
30
|
+
},
|
|
31
|
+
discard: () => autosave.discard(),
|
|
32
|
+
ready: () => autosave.ready(),
|
|
33
|
+
flushNow: () => autosave.flushNow(),
|
|
34
|
+
markClean: () => autosave.markClean(),
|
|
35
|
+
notifyChange: () => autosave.notifyChange(),
|
|
36
|
+
checked: autosave.checked,
|
|
37
|
+
controller: autosave.controller,
|
|
38
|
+
destroy: () => autosave.destroy(),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -2,4 +2,5 @@ import type { ComponentProps } from "svelte";
|
|
|
2
2
|
import type RecoveryPromptComponent from "./RecoveryPrompt.svelte";
|
|
3
3
|
export { default as RecoveryPrompt } from "./RecoveryPrompt.svelte";
|
|
4
4
|
export * from "./autosave.svelte.js";
|
|
5
|
+
export * from "./editorAutosave.svelte.js";
|
|
5
6
|
export type RecoveryPromptProps = ComponentProps<typeof RecoveryPromptComponent>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.106.0",
|
|
4
4
|
"description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
@@ -88,6 +88,16 @@
|
|
|
88
88
|
"svelte": "./dist/video-editor/index.js",
|
|
89
89
|
"default": "./dist/video-editor/index.js"
|
|
90
90
|
},
|
|
91
|
+
"./color": {
|
|
92
|
+
"types": "./dist/color/index.d.ts",
|
|
93
|
+
"svelte": "./dist/color/index.js",
|
|
94
|
+
"default": "./dist/color/index.js"
|
|
95
|
+
},
|
|
96
|
+
"./gradient": {
|
|
97
|
+
"types": "./dist/gradient/index.d.ts",
|
|
98
|
+
"svelte": "./dist/gradient/index.js",
|
|
99
|
+
"default": "./dist/gradient/index.js"
|
|
100
|
+
},
|
|
91
101
|
"./package.json": "./package.json"
|
|
92
102
|
},
|
|
93
103
|
"typesVersions": {
|
|
@@ -130,6 +140,12 @@
|
|
|
130
140
|
],
|
|
131
141
|
"video-editor": [
|
|
132
142
|
"./dist/video-editor/index.d.ts"
|
|
143
|
+
],
|
|
144
|
+
"color": [
|
|
145
|
+
"./dist/color/index.d.ts"
|
|
146
|
+
],
|
|
147
|
+
"gradient": [
|
|
148
|
+
"./dist/gradient/index.d.ts"
|
|
133
149
|
]
|
|
134
150
|
}
|
|
135
151
|
},
|
|
@@ -144,7 +160,7 @@
|
|
|
144
160
|
"@tiptap/extension-bubble-menu": "^2.27.3",
|
|
145
161
|
"@tiptap/extension-placeholder": "^2.27.3",
|
|
146
162
|
"@tiptap/starter-kit": "^2.27.3",
|
|
147
|
-
"@pixerate/editor": "0.
|
|
163
|
+
"@pixerate/editor": "0.147.0"
|
|
148
164
|
},
|
|
149
165
|
"peerDependencies": {
|
|
150
166
|
"@dagrejs/dagre": "^1.1.4",
|