@pixerate/editor-svelte 0.128.4 → 0.129.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 (47) hide show
  1. package/dist/effects/EffectParameters.svelte +48 -5
  2. package/dist/effects/EffectParameters.svelte.d.ts +3 -0
  3. package/dist/image-editor/AdjustmentLayersPanel.svelte +3 -14
  4. package/dist/image-editor/BrushOptionsBar.svelte +4 -15
  5. package/dist/image-editor/ImageEditor.svelte +2 -5
  6. package/dist/image-editor/ImageEffectControls.svelte +9 -2
  7. package/dist/image-editor/ImageEffectControls.svelte.d.ts +3 -0
  8. package/dist/image-editor/ImageProviderEffectsPanel.svelte +10 -5
  9. package/dist/image-editor/ImageProviderEffectsPanel.svelte.d.ts +3 -0
  10. package/dist/image-editor/LayerEffectsPanel.svelte +2 -1
  11. package/dist/image-editor/ShapeOptionsBar.svelte +4 -17
  12. package/dist/image-editor/TypeOptionsBar.svelte +3 -2
  13. package/dist/image-editor/controls/ImageColor.svelte +21 -0
  14. package/dist/image-editor/controls/ImageColor.svelte.d.ts +4 -0
  15. package/dist/image-editor/controls/ImageParameterColor.svelte +9 -0
  16. package/dist/image-editor/controls/ImageParameterColor.svelte.d.ts +4 -0
  17. package/dist/image-editor/controls/ImageParameterSelect.svelte +11 -0
  18. package/dist/image-editor/controls/ImageParameterSelect.svelte.d.ts +4 -0
  19. package/dist/image-editor/controls/ImageParameterSlider.svelte +9 -0
  20. package/dist/image-editor/controls/ImageParameterSlider.svelte.d.ts +4 -0
  21. package/dist/image-editor/controls/controls.d.ts +17 -0
  22. package/dist/image-editor/controls/parameterControls.d.ts +4 -0
  23. package/dist/image-editor/controls/parameterControls.js +11 -0
  24. package/dist/image-editor/index.d.ts +2 -1
  25. package/dist/image-editor/index.js +1 -0
  26. package/dist/parameters/ParameterColor.svelte +59 -51
  27. package/dist/parameters/ParameterColor.svelte.d.ts +2 -0
  28. package/dist/parameters/ParameterCommitInput.svelte +33 -4
  29. package/dist/parameters/ParameterFieldControl.svelte +7 -5
  30. package/dist/parameters/ParameterFieldControl.svelte.d.ts +2 -0
  31. package/dist/parameters/ParameterNumberInput.svelte +41 -17
  32. package/dist/parameters/ParameterNumberInput.svelte.d.ts +2 -0
  33. package/dist/parameters/ParameterSelect.svelte +25 -6
  34. package/dist/parameters/ParameterSelect.svelte.d.ts +2 -0
  35. package/dist/parameters/ParameterSlider.svelte +48 -20
  36. package/dist/parameters/ParameterSlider.svelte.d.ts +2 -0
  37. package/dist/parameters/ParameterVector.svelte +6 -3
  38. package/dist/parameters/ParameterVector.svelte.d.ts +2 -0
  39. package/dist/parameters/ParametersPanel.svelte +54 -18
  40. package/dist/parameters/ParametersPanel.svelte.d.ts +3 -0
  41. package/dist/parameters/controls.d.ts +89 -0
  42. package/dist/parameters/controls.js +19 -0
  43. package/dist/parameters/index.d.ts +1 -0
  44. package/dist/parameters/index.js +1 -0
  45. package/dist/parameters/styles.d.ts +6 -0
  46. package/dist/parameters/styles.js +7 -0
  47. package/package.json +2 -2
@@ -20,7 +20,14 @@
20
20
  } from '@pixerate/editor/parameters';
21
21
  import KeyframeDiamond from './KeyframeDiamond.svelte';
22
22
  import ParameterFieldControl from './ParameterFieldControl.svelte';
23
- import { parameterButtonClass, parameterInputClass } from './styles.js';
23
+ import {
24
+ parameterButtonClass,
25
+ parameterButtonStyle,
26
+ parameterInputClass,
27
+ parameterInputStyle,
28
+ parameterSelectStyle
29
+ } from './styles.js';
30
+ import { getParameterComponents, resolveParameterComponents, type ParameterComponents } from './controls.js';
24
31
 
25
32
  interface Props {
26
33
  controller: ParametersController;
@@ -36,6 +43,8 @@
36
43
  showFieldReset?: boolean;
37
44
  /** Turns a picked file into a URL for image fields. */
38
45
  resolveFile?: (file: File) => string | Promise<string>;
46
+ /** Custom host components for inputs, sliders, and selects. */
47
+ components?: ParameterComponents;
39
48
  /** Shown when the schema has no fields. */
40
49
  emptyMessage?: string;
41
50
  /** Prefix for the panel's element ids. */
@@ -68,9 +77,13 @@
68
77
  children,
69
78
  playback,
70
79
  playbackId = 'parameters',
71
- onplaybackreveal
80
+ onplaybackreveal,
81
+ components
72
82
  }: Props = $props();
73
83
 
84
+ const parameterContext = getParameterComponents();
85
+ const CustomPresetSelect = $derived(resolveParameterComponents(components, parameterContext).select);
86
+
74
87
  // Agent playback: the cursor visits the controls a call changes.
75
88
  let root: HTMLDivElement | undefined = $state();
76
89
  const ambientPlayback = getAgentPlayback();
@@ -140,6 +153,7 @@
140
153
  value={view.values[field.id]}
141
154
  id={inputId}
142
155
  {resolveFile}
156
+ {components}
143
157
  onchange={(v) => controller.setValue(field.id, v)}
144
158
  ongesturestart={() => controller.beginGesture(field.id)}
145
159
  ongestureend={() => controller.endGesture()}
@@ -200,6 +214,7 @@
200
214
  <button
201
215
  type="button"
202
216
  class={parameterButtonClass}
217
+ style={parameterButtonStyle}
203
218
  disabled={!view.canUndo}
204
219
  title={view.canUndo ? `Undo ${view.undoLabel}` : 'Nothing to undo'}
205
220
  onclick={() => controller.undo()}>Undo</button
@@ -207,12 +222,13 @@
207
222
  <button
208
223
  type="button"
209
224
  class={parameterButtonClass}
225
+ style={parameterButtonStyle}
210
226
  disabled={!view.canRedo}
211
227
  title={view.canRedo ? `Redo ${view.redoLabel}` : 'Nothing to redo'}
212
228
  onclick={() => controller.redo()}>Redo</button
213
229
  >
214
- <button type="button" class={parameterButtonClass} disabled={!view.modified} onclick={() => controller.reset()}>Reset</button>
215
- <button type="button" class={parameterButtonClass} onclick={() => controller.randomize()}>Randomize</button>
230
+ <button type="button" class={parameterButtonClass} style={parameterButtonStyle} disabled={!view.modified} onclick={() => controller.reset()}>Reset</button>
231
+ <button type="button" class={parameterButtonClass} style={parameterButtonStyle} onclick={() => controller.randomize()}>Randomize</button>
216
232
  </div>
217
233
  {/if}
218
234
  </div>
@@ -221,22 +237,42 @@
221
237
  {#if showPresets}
222
238
  <div class="space-y-1.5" data-parameter-presets="">
223
239
  <div class="flex items-center gap-1.5">
224
- <select
225
- aria-label="Preset"
226
- class={parameterInputClass}
227
- value={view.activePreset ?? ''}
228
- onchange={(e) => e.currentTarget.value && controller.applyPreset(e.currentTarget.value)}
229
- >
230
- <option value="">{view.presets.length ? 'Presets…' : 'No presets'}</option>
231
- {#each view.presets as p (p.name)}
232
- <option value={p.name} title={p.description}>{p.name}</option>
233
- {/each}
234
- </select>
235
- <button type="button" class={parameterButtonClass} aria-expanded={saving} onclick={() => (saving = !saving)}>Save…</button>
240
+ {#if CustomPresetSelect}
241
+ <CustomPresetSelect
242
+ aria-label="Preset"
243
+ label="Preset"
244
+ value={view.activePreset ?? ''}
245
+ options={[
246
+ { value: '', label: view.presets.length ? 'Presets…' : 'No presets' },
247
+ ...view.presets.map((p) => ({ value: p.name, label: p.name, description: p.description }))
248
+ ]}
249
+ class={parameterInputClass}
250
+ style={parameterSelectStyle}
251
+ onchange={(val) => {
252
+ const str = String(val);
253
+ if (str) controller.applyPreset(str);
254
+ }}
255
+ />
256
+ {:else}
257
+ <select
258
+ aria-label="Preset"
259
+ class={parameterInputClass}
260
+ style={parameterSelectStyle}
261
+ value={view.activePreset ?? ''}
262
+ onchange={(e) => e.currentTarget.value && controller.applyPreset(e.currentTarget.value)}
263
+ >
264
+ <option value="" style={parameterSelectStyle}>{view.presets.length ? 'Presets…' : 'No presets'}</option>
265
+ {#each view.presets as p (p.name)}
266
+ <option value={p.name} title={p.description} style={parameterSelectStyle}>{p.name}</option>
267
+ {/each}
268
+ </select>
269
+ {/if}
270
+ <button type="button" class={parameterButtonClass} style={parameterButtonStyle} aria-expanded={saving} onclick={() => (saving = !saving)}>Save…</button>
236
271
  {#if activePreset && !activePreset.builtIn}
237
272
  <button
238
273
  type="button"
239
274
  class={parameterButtonClass}
275
+ style={parameterButtonStyle}
240
276
  aria-label="Delete preset {activePreset.name}"
241
277
  onclick={() => controller.deletePreset(activePreset.name)}>Delete</button
242
278
  >
@@ -245,8 +281,8 @@
245
281
  {#if saving}
246
282
  <form class="flex items-center gap-1.5" onsubmit={savePreset}>
247
283
  <!-- svelte-ignore a11y_autofocus -->
248
- <input autofocus aria-label="Preset name" placeholder="Preset name" class={parameterInputClass} bind:value={presetName} />
249
- <button type="submit" class={parameterButtonClass}>Save</button>
284
+ <input autofocus aria-label="Preset name" placeholder="Preset name" class={parameterInputClass} style={parameterInputStyle} bind:value={presetName} />
285
+ <button type="submit" class={parameterButtonClass} style={parameterButtonStyle}>Save</button>
250
286
  </form>
251
287
  {/if}
252
288
  {#if presetMessage}
@@ -1,6 +1,7 @@
1
1
  import { type Snippet } from 'svelte';
2
2
  import type { AgentPlayback } from '@pixerate/editor/tools';
3
3
  import { type ParametersController } from '@pixerate/editor/parameters';
4
+ import { type ParameterComponents } from './controls.js';
4
5
  interface Props {
5
6
  controller: ParametersController;
6
7
  /** Heading (default: the schema's title). Pass `null` for none. */
@@ -15,6 +16,8 @@ interface Props {
15
16
  showFieldReset?: boolean;
16
17
  /** Turns a picked file into a URL for image fields. */
17
18
  resolveFile?: (file: File) => string | Promise<string>;
19
+ /** Custom host components for inputs, sliders, and selects. */
20
+ components?: ParameterComponents;
18
21
  /** Shown when the schema has no fields. */
19
22
  emptyMessage?: string;
20
23
  /** Prefix for the panel's element ids. */
@@ -0,0 +1,89 @@
1
+ import { type Component } from 'svelte';
2
+ /** Props for a custom number input in parameter panels. Call `oncommit` when an edit is done (blur, Enter, Tab). */
3
+ export interface ParameterInputProps {
4
+ id?: string;
5
+ /** The stored value as text, without the unit. */
6
+ value: string;
7
+ disabled?: boolean;
8
+ 'aria-label'?: string;
9
+ /** The field's label. */
10
+ label: string;
11
+ inputmode?: 'decimal' | 'text' | 'numeric';
12
+ class?: string;
13
+ style?: string;
14
+ /** Commits typed text. Pass the element to have a refused edit show the stored value again. */
15
+ oncommit: (value: string, input?: HTMLInputElement | HTMLTextAreaElement) => void;
16
+ /** Arrow keys step the value (Shift ×10). */
17
+ onkeydown?: (e: KeyboardEvent) => void;
18
+ }
19
+ /** Props for a custom slider in parameter panels. */
20
+ export interface ParameterSliderProps {
21
+ id?: string;
22
+ value: number;
23
+ min: number;
24
+ max: number;
25
+ step: number;
26
+ disabled?: boolean;
27
+ 'aria-label'?: string;
28
+ /** The field's label. */
29
+ label: string;
30
+ 'aria-valuetext'?: string;
31
+ class?: string;
32
+ style?: string;
33
+ /** Every change while the value moves. */
34
+ oninput: (value: number) => void;
35
+ /** A drag (or key press) starts: changes until `ongestureend` merge into one undo step. */
36
+ ongesturestart?: () => void;
37
+ ongestureend?: () => void;
38
+ }
39
+ /** One option in a dropdown parameter control. */
40
+ export interface ParameterSelectOption {
41
+ value: string | number;
42
+ label: string;
43
+ description?: string;
44
+ }
45
+ /** Props for a custom select in parameter panels. `onchange` takes an option's `value` (or its string form). */
46
+ export interface ParameterSelectProps {
47
+ id?: string;
48
+ value: string | number;
49
+ options: readonly ParameterSelectOption[];
50
+ disabled?: boolean;
51
+ 'aria-label'?: string;
52
+ /** The control's label. */
53
+ label: string;
54
+ class?: string;
55
+ style?: string;
56
+ onchange: (value: string | number) => void;
57
+ }
58
+ /** Props for a custom colour control in parameter panels. */
59
+ export interface ParameterColorProps {
60
+ id?: string;
61
+ /** `#rrggbb`, or `#rrggbbaa` with `alpha`. */
62
+ value: string;
63
+ /** Whether the field has an alpha channel. */
64
+ alpha?: boolean;
65
+ /** Suggested colours for the field, if it has any. */
66
+ swatches?: readonly string[];
67
+ disabled?: boolean;
68
+ /** The field's label. */
69
+ label: string;
70
+ class?: string;
71
+ style?: string;
72
+ onchange: (value: string) => void;
73
+ /** A pick starts: changes until `ongestureend` merge into one undo step. */
74
+ ongesturestart?: () => void;
75
+ ongestureend?: () => void;
76
+ }
77
+ /** Host form controls for parameter panels. Any left out fall back to the default controls. */
78
+ export interface ParameterComponents {
79
+ input?: Component<ParameterInputProps>;
80
+ slider?: Component<ParameterSliderProps>;
81
+ select?: Component<ParameterSelectProps>;
82
+ color?: Component<ParameterColorProps>;
83
+ }
84
+ /** Makes the parameter panels below this component use the host's controls (call it while a component initialises). */
85
+ export declare function setParameterComponents(components: ParameterComponents): ParameterComponents;
86
+ /** The controls set by an ancestor with {@link setParameterComponents}, or none. */
87
+ export declare function getParameterComponents(): ParameterComponents;
88
+ /** The controls to use: each one from `explicit`, else from `fallback` (default: the context's). */
89
+ export declare function resolveParameterComponents(explicit?: ParameterComponents, fallback?: ParameterComponents): ParameterComponents;
@@ -0,0 +1,19 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ const KEY = Symbol('pixerate.parameters.components');
3
+ /** Makes the parameter panels below this component use the host's controls (call it while a component initialises). */
4
+ export function setParameterComponents(components) {
5
+ return setContext(KEY, components);
6
+ }
7
+ /** The controls set by an ancestor with {@link setParameterComponents}, or none. */
8
+ export function getParameterComponents() {
9
+ return getContext(KEY) ?? {};
10
+ }
11
+ /** The controls to use: each one from `explicit`, else from `fallback` (default: the context's). */
12
+ export function resolveParameterComponents(explicit, fallback = getParameterComponents()) {
13
+ return {
14
+ input: explicit?.input ?? fallback.input,
15
+ slider: explicit?.slider ?? fallback.slider,
16
+ select: explicit?.select ?? fallback.select,
17
+ color: explicit?.color ?? fallback.color,
18
+ };
19
+ }
@@ -13,5 +13,6 @@ export { default as ParameterText } from "./ParameterText.svelte";
13
13
  export { default as ParameterCommitInput } from "./ParameterCommitInput.svelte";
14
14
  export { default as KeyframeDiamond } from "./KeyframeDiamond.svelte";
15
15
  export * from "./createParameters.svelte.js";
16
+ export * from "./controls.js";
16
17
  export * from "./styles.js";
17
18
  export type ParametersPanelProps = ComponentProps<typeof ParametersPanelComponent>;
@@ -11,4 +11,5 @@ export { default as ParameterText } from "./ParameterText.svelte";
11
11
  export { default as ParameterCommitInput } from "./ParameterCommitInput.svelte";
12
12
  export { default as KeyframeDiamond } from "./KeyframeDiamond.svelte";
13
13
  export * from "./createParameters.svelte.js";
14
+ export * from "./controls.js";
14
15
  export * from "./styles.js";
@@ -1,3 +1,9 @@
1
1
  export declare const parameterInputClass = "h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground tabular-nums focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50";
2
2
  export declare const parameterButtonClass = "inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50";
3
3
  export declare const parameterRangeClass = "h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50";
4
+ /** Inline theme styles (`--pixerate-parameter-*` tokens with host fallbacks), shared with React through core. */
5
+ export declare const parameterInputStyle: string;
6
+ export declare const parameterSelectStyle: string;
7
+ /** Text and border only, so the button classes' `hover:` background still applies. */
8
+ export declare const parameterButtonStyle: string;
9
+ export declare const parameterRangeStyle: string;
@@ -1,4 +1,11 @@
1
+ import { parameterThemeStyleText } from "@pixerate/editor/parameters";
1
2
  // Class names shared by the parameter controls (the same as the React package's).
2
3
  export const parameterInputClass = "h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground tabular-nums focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50";
3
4
  export const parameterButtonClass = "inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50";
4
5
  export const parameterRangeClass = "h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50";
6
+ /** Inline theme styles (`--pixerate-parameter-*` tokens with host fallbacks), shared with React through core. */
7
+ export const parameterInputStyle = parameterThemeStyleText("input");
8
+ export const parameterSelectStyle = parameterThemeStyleText("select");
9
+ /** Text and border only, so the button classes' `hover:` background still applies. */
10
+ export const parameterButtonStyle = parameterThemeStyleText("button");
11
+ export const parameterRangeStyle = parameterThemeStyleText("range");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor-svelte",
3
- "version": "0.128.4",
3
+ "version": "0.129.0",
4
4
  "description": "Svelte bindings and prompt/rich-text components for @pixerate/editor",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -165,7 +165,7 @@
165
165
  "**/*.css"
166
166
  ],
167
167
  "dependencies": {
168
- "@pixerate/editor": "0.174.1"
168
+ "@pixerate/editor": "0.175.0"
169
169
  },
170
170
  "peerDependencies": {
171
171
  "@dagrejs/dagre": "^1.1.4",