@pixerate/editor-react 0.76.0 → 0.78.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 (49) hide show
  1. package/dist/PaintGradientEditorView-CCPCY5Ib.d.cts +14 -0
  2. package/dist/PaintGradientEditorView-CCPCY5Ib.d.ts +14 -0
  3. package/dist/canvas/index.cjs +662 -561
  4. package/dist/canvas/index.cjs.map +1 -1
  5. package/dist/canvas/index.d.cts +36 -5
  6. package/dist/canvas/index.d.ts +36 -5
  7. package/dist/canvas/index.js +232 -129
  8. package/dist/canvas/index.js.map +1 -1
  9. package/dist/{chunk-LWMUV5TC.js → chunk-2EW42UXC.js} +639 -461
  10. package/dist/chunk-2EW42UXC.js.map +1 -0
  11. package/dist/chunk-FX3EREF5.js +206 -0
  12. package/dist/chunk-FX3EREF5.js.map +1 -0
  13. package/dist/chunk-MO354USR.js +126 -0
  14. package/dist/chunk-MO354USR.js.map +1 -0
  15. package/dist/chunk-ZQZAKUUM.js +416 -0
  16. package/dist/chunk-ZQZAKUUM.js.map +1 -0
  17. package/dist/effects/index.cjs +606 -0
  18. package/dist/effects/index.cjs.map +1 -0
  19. package/dist/effects/index.d.cts +80 -0
  20. package/dist/effects/index.d.ts +80 -0
  21. package/dist/effects/index.js +16 -0
  22. package/dist/effects/index.js.map +1 -0
  23. package/dist/image-editor/index.cjs +1388 -534
  24. package/dist/image-editor/index.cjs.map +1 -1
  25. package/dist/image-editor/index.d.cts +36 -3
  26. package/dist/image-editor/index.d.ts +36 -3
  27. package/dist/image-editor/index.js +10 -1
  28. package/dist/index.cjs +1806 -952
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +4 -1
  31. package/dist/index.d.ts +4 -1
  32. package/dist/index.js +10 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/paint-editor/index.cjs +438 -289
  35. package/dist/paint-editor/index.cjs.map +1 -1
  36. package/dist/paint-editor/index.d.cts +8 -3
  37. package/dist/paint-editor/index.d.ts +8 -3
  38. package/dist/paint-editor/index.js +215 -187
  39. package/dist/paint-editor/index.js.map +1 -1
  40. package/dist/parameters/index.js +55 -439
  41. package/dist/parameters/index.js.map +1 -1
  42. package/dist/video-editor/index.cjs +732 -17
  43. package/dist/video-editor/index.cjs.map +1 -1
  44. package/dist/video-editor/index.d.cts +31 -3
  45. package/dist/video-editor/index.d.ts +31 -3
  46. package/dist/video-editor/index.js +184 -17
  47. package/dist/video-editor/index.js.map +1 -1
  48. package/package.json +8 -3
  49. package/dist/chunk-LWMUV5TC.js.map +0 -1
@@ -1,3 +1,19 @@
1
+ import {
2
+ KeyframeDiamond,
3
+ ParameterColor,
4
+ ParameterCommitInput,
5
+ ParameterFieldControl,
6
+ ParameterImage,
7
+ ParameterNumberInput,
8
+ ParameterSelect,
9
+ ParameterSlider,
10
+ ParameterText,
11
+ ParameterToggle,
12
+ ParameterVector,
13
+ parameterButtonClass,
14
+ parameterInputClass
15
+ } from "../chunk-ZQZAKUUM.js";
16
+
1
17
  // src/parameters/useParameters.ts
2
18
  import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
3
19
  import {
@@ -51,414 +67,14 @@ function useParameterCommands(registry, controller, options = {}) {
51
67
  }, [registry, controller, prefix, group, scope]);
52
68
  }
53
69
 
54
- // src/parameters/fields.tsx
55
- import { useRef as useRef2 } from "react";
56
- import {
57
- choiceOptionLabel,
58
- formatParameterNumber,
59
- getChoiceOptions,
60
- isSliderField,
61
- normalizeHexColor,
62
- parameterLabel,
63
- parameterStep,
64
- parseParameterNumberInput,
65
- clampParameterNumber,
66
- vectorComponentField,
67
- vectorSize
68
- } from "@pixerate/editor/parameters";
69
- import { jsx, jsxs } from "react/jsx-runtime";
70
- var 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";
71
- var 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";
72
- var rangeClass = "h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50";
73
- function ParameterCommitInput({ value, onCommit, multiline, className, onKeyDown, ...rest }) {
74
- const commit = (el) => {
75
- if (el.value !== value) onCommit(el.value, el);
76
- };
77
- const keyDown = (e) => {
78
- onKeyDown?.(e);
79
- if (e.defaultPrevented) return;
80
- if (e.key === "Enter" && (!multiline || e.metaKey || e.ctrlKey)) {
81
- e.preventDefault();
82
- commit(e.currentTarget);
83
- }
84
- if (e.key === "Escape") e.currentTarget.value = value;
85
- };
86
- const props = {
87
- defaultValue: value,
88
- className: className ?? parameterInputClass,
89
- onBlur: (e) => commit(e.currentTarget),
90
- onKeyDown: keyDown,
91
- ...rest
92
- };
93
- return multiline ? /* @__PURE__ */ jsx("textarea", { ...props, className: `${props.className} h-auto min-h-[3.5rem] py-1` }, value) : /* @__PURE__ */ jsx("input", { type: "text", ...props }, value);
94
- }
95
- var plainNumber = (field, value) => formatParameterNumber({ ...field, unit: void 0 }, value);
96
- function ParameterNumberInput({
97
- field,
98
- value,
99
- onChange,
100
- disabled,
101
- id,
102
- "aria-label": ariaLabel
103
- }) {
104
- return /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
105
- /* @__PURE__ */ jsx(
106
- ParameterCommitInput,
107
- {
108
- id,
109
- inputMode: "decimal",
110
- "aria-label": ariaLabel ?? parameterLabel(field),
111
- value: plainNumber(field, value),
112
- disabled: disabled || field.readOnly,
113
- className: `${parameterInputClass} ${field.unit ? "pr-6" : ""}`,
114
- onCommit: (text, input) => {
115
- const n = parseParameterNumberInput(field, text);
116
- if (n === null || n === value) input.value = plainNumber(field, value);
117
- else onChange(n);
118
- },
119
- onKeyDown: (e) => {
120
- if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
121
- e.preventDefault();
122
- const step = parameterStep(field) * (e.shiftKey ? 10 : 1);
123
- onChange(clampParameterNumber(field, value + (e.key === "ArrowUp" ? step : -step)));
124
- }
125
- }
126
- ),
127
- field.unit && /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground", children: field.unit })
128
- ] });
129
- }
130
- function ParameterSlider(props) {
131
- const { field, value, onChange, onGestureStart, onGestureEnd, disabled } = props;
132
- const dragging = useRef2(false);
133
- const end = () => {
134
- if (!dragging.current) return;
135
- dragging.current = false;
136
- onGestureEnd?.();
137
- };
138
- if (!isSliderField(field)) return /* @__PURE__ */ jsx(ParameterNumberInput, { ...props });
139
- const step = parameterStep(field);
140
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
141
- /* @__PURE__ */ jsx(
142
- "input",
143
- {
144
- type: "range",
145
- "aria-label": parameterLabel(field),
146
- "aria-valuetext": formatParameterNumber(field, value),
147
- min: field.min,
148
- max: field.max,
149
- step,
150
- value,
151
- disabled: disabled || field.readOnly,
152
- className: rangeClass,
153
- onPointerDown: () => {
154
- if (dragging.current) return;
155
- dragging.current = true;
156
- onGestureStart?.();
157
- },
158
- onPointerUp: end,
159
- onPointerCancel: end,
160
- onBlur: end,
161
- onChange: (e) => onChange(clampParameterNumber(field, Number(e.target.value)))
162
- }
163
- ),
164
- /* @__PURE__ */ jsx("div", { className: "w-20 shrink-0", children: /* @__PURE__ */ jsx(ParameterNumberInput, { ...props, id: props.id, "aria-label": `${parameterLabel(field)} value` }) })
165
- ] });
166
- }
167
- function ParameterToggle({ field, value, onChange, disabled, id }) {
168
- return /* @__PURE__ */ jsx(
169
- "button",
170
- {
171
- type: "button",
172
- role: "switch",
173
- id,
174
- "aria-checked": value,
175
- "aria-label": parameterLabel(field),
176
- disabled: disabled || field.readOnly,
177
- onClick: () => onChange(!value),
178
- className: `relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-50 ${value ? "bg-primary" : "bg-muted"}`,
179
- children: /* @__PURE__ */ jsx(
180
- "span",
181
- {
182
- className: `pointer-events-none block h-4 w-4 rounded-full bg-background shadow transition-transform ${value ? "translate-x-4" : "translate-x-0.5"}`
183
- }
184
- )
185
- }
186
- );
187
- }
188
- function ParameterSelect({ field, value, onChange, disabled, id }) {
189
- const options = getChoiceOptions(field);
190
- const off = disabled || field.readOnly;
191
- if (field.control === "segmented") {
192
- return /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": parameterLabel(field), className: "inline-flex flex-wrap rounded-md border border-input bg-muted p-0.5", children: options.map((o) => /* @__PURE__ */ jsx(
193
- "button",
194
- {
195
- type: "button",
196
- role: "radio",
197
- "aria-checked": o.value === value,
198
- title: o.description,
199
- disabled: off,
200
- onClick: () => onChange(o.value),
201
- className: `rounded px-2 py-0.5 text-xs disabled:opacity-50 ${o.value === value ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
202
- children: choiceOptionLabel(o)
203
- },
204
- String(o.value)
205
- )) });
206
- }
207
- const index = options.findIndex((o) => o.value === value);
208
- return /* @__PURE__ */ jsx(
209
- "select",
210
- {
211
- id,
212
- "aria-label": parameterLabel(field),
213
- value: String(index),
214
- disabled: off,
215
- onChange: (e) => {
216
- const option = options[Number(e.target.value)];
217
- if (option) onChange(option.value);
218
- },
219
- className: parameterInputClass,
220
- children: options.map((o, i) => /* @__PURE__ */ jsx("option", { value: String(i), title: o.description, children: choiceOptionLabel(o) }, String(o.value)))
221
- }
222
- );
223
- }
224
- function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd, disabled, id }) {
225
- const picking = useRef2(false);
226
- const alpha = !!field.alpha;
227
- const hex = normalizeHexColor(value, true) ?? "#000000ff";
228
- const rgb = hex.slice(0, 7);
229
- const a = hex.slice(7);
230
- const off = disabled || field.readOnly;
231
- const start = () => {
232
- if (picking.current) return;
233
- picking.current = true;
234
- onGestureStart?.();
235
- };
236
- const end = () => {
237
- if (!picking.current) return;
238
- picking.current = false;
239
- onGestureEnd?.();
240
- };
241
- return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
242
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
243
- /* @__PURE__ */ jsxs("span", { className: "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]", children: [
244
- /* @__PURE__ */ jsx("span", { className: "absolute inset-0", style: { background: alpha ? hex : rgb } }),
245
- /* @__PURE__ */ jsx(
246
- "input",
247
- {
248
- type: "color",
249
- "aria-label": parameterLabel(field),
250
- value: rgb,
251
- disabled: off,
252
- className: "absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed",
253
- onChange: (e) => {
254
- start();
255
- onChange(alpha ? `${e.target.value}${a}` : e.target.value);
256
- },
257
- onBlur: end
258
- }
259
- )
260
- ] }),
261
- /* @__PURE__ */ jsx(
262
- ParameterCommitInput,
263
- {
264
- id,
265
- "aria-label": `${parameterLabel(field)} hex`,
266
- value: alpha ? hex : rgb,
267
- disabled: off,
268
- spellCheck: false,
269
- className: `${parameterInputClass} font-mono`,
270
- onCommit: (text) => {
271
- const next = normalizeHexColor(text, alpha);
272
- if (next) onChange(next);
273
- }
274
- }
275
- )
276
- ] }),
277
- alpha && /* @__PURE__ */ jsx(
278
- "input",
279
- {
280
- type: "range",
281
- "aria-label": `${parameterLabel(field)} opacity`,
282
- min: 0,
283
- max: 255,
284
- step: 1,
285
- value: parseInt(a, 16),
286
- disabled: off,
287
- className: rangeClass,
288
- onPointerDown: start,
289
- onPointerUp: end,
290
- onPointerCancel: end,
291
- onBlur: end,
292
- onChange: (e) => onChange(`${rgb}${Number(e.target.value).toString(16).padStart(2, "0")}`)
293
- }
294
- ),
295
- field.swatches && field.swatches.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: field.swatches.map((s) => {
296
- const swatch = normalizeHexColor(s, alpha);
297
- if (!swatch) return null;
298
- return /* @__PURE__ */ jsx(
299
- "button",
300
- {
301
- type: "button",
302
- title: swatch,
303
- "aria-label": `${parameterLabel(field)} ${swatch}`,
304
- "aria-pressed": swatch === (alpha ? hex : rgb),
305
- disabled: off,
306
- onClick: () => onChange(swatch),
307
- className: "h-5 w-5 rounded border border-input aria-pressed:ring-1 aria-pressed:ring-primary",
308
- style: { background: swatch }
309
- },
310
- s
311
- );
312
- }) })
313
- ] });
314
- }
315
- function ParameterVector({ field, value, onChange, disabled, id }) {
316
- const size = vectorSize(field);
317
- return /* @__PURE__ */ jsx("div", { className: "grid gap-1.5", style: { gridTemplateColumns: `repeat(${size}, minmax(0, 1fr))` }, children: Array.from({ length: size }, (_, i) => {
318
- const component = vectorComponentField(field, i);
319
- return /* @__PURE__ */ jsxs("label", { className: "flex min-w-0 items-center gap-1", children: [
320
- /* @__PURE__ */ jsx("span", { className: "w-3 shrink-0 text-[10px] uppercase text-muted-foreground", children: component.label }),
321
- /* @__PURE__ */ jsx(
322
- ParameterNumberInput,
323
- {
324
- field: component,
325
- value: value[i] ?? 0,
326
- id: i === 0 ? id : void 0,
327
- "aria-label": `${parameterLabel(field)} ${component.label}`,
328
- disabled: disabled || field.readOnly,
329
- onChange: (n) => onChange(Array.from({ length: size }, (_2, j) => j === i ? n : value[j] ?? 0))
330
- }
331
- )
332
- ] }, i);
333
- }) });
334
- }
335
- function ParameterImage({ field, value, onChange, disabled, id, resolveFile }) {
336
- const off = disabled || field.readOnly;
337
- const name = parameterLabel(field);
338
- return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
339
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
340
- /* @__PURE__ */ jsx("div", { className: "flex h-12 w-16 shrink-0 items-center justify-center overflow-hidden rounded-md border border-input bg-muted", children: value ? /* @__PURE__ */ jsx("img", { src: value, alt: name, className: "h-full w-full object-cover" }) : /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: "None" }) }),
341
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
342
- /* @__PURE__ */ jsx(
343
- ParameterCommitInput,
344
- {
345
- id,
346
- "aria-label": `${name} URL`,
347
- placeholder: "Image URL",
348
- value: value.startsWith("data:") ? "" : value,
349
- disabled: off,
350
- onCommit: (text) => onChange(text.trim())
351
- }
352
- ),
353
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
354
- resolveFile && /* @__PURE__ */ jsxs("label", { className: `${parameterButtonClass} cursor-pointer ${off ? "pointer-events-none opacity-50" : ""}`, children: [
355
- "Choose file\u2026",
356
- /* @__PURE__ */ jsx(
357
- "input",
358
- {
359
- type: "file",
360
- className: "sr-only",
361
- accept: field.accept ?? "image/*",
362
- disabled: off,
363
- "aria-label": `${name} file`,
364
- onChange: async (e) => {
365
- const file = e.target.files?.[0];
366
- e.target.value = "";
367
- if (file) onChange(await resolveFile(file));
368
- }
369
- }
370
- )
371
- ] }),
372
- value && /* @__PURE__ */ jsx("button", { type: "button", className: parameterButtonClass, disabled: off, onClick: () => onChange(""), "aria-label": `Clear ${name}`, children: "Clear" })
373
- ] })
374
- ] })
375
- ] }),
376
- field.options && field.options.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: field.options.map((o) => /* @__PURE__ */ jsx(
377
- "button",
378
- {
379
- type: "button",
380
- title: o.label ?? o.url,
381
- "aria-label": o.label ?? o.url,
382
- "aria-pressed": o.url === value,
383
- disabled: off,
384
- onClick: () => onChange(o.url),
385
- className: "h-9 w-12 overflow-hidden rounded border border-input aria-pressed:ring-2 aria-pressed:ring-primary",
386
- children: /* @__PURE__ */ jsx("img", { src: o.url, alt: "", className: "h-full w-full object-cover" })
387
- },
388
- o.url
389
- )) })
390
- ] });
391
- }
392
- function ParameterText({ field, value, onChange, disabled, id }) {
393
- return /* @__PURE__ */ jsx(
394
- ParameterCommitInput,
395
- {
396
- id,
397
- "aria-label": parameterLabel(field),
398
- multiline: field.multiline,
399
- placeholder: field.placeholder,
400
- maxLength: field.maxLength,
401
- value,
402
- disabled: disabled || field.readOnly,
403
- onCommit: onChange
404
- }
405
- );
406
- }
407
- function KeyframeDiamond({ state, onToggle, label, disabled, className = "" }) {
408
- const keyed = state === "keyed";
409
- return /* @__PURE__ */ jsx(
410
- "button",
411
- {
412
- type: "button",
413
- "data-key-state": state,
414
- "aria-pressed": keyed,
415
- "aria-label": `${keyed ? "Remove" : "Add"} keyframe for ${label}`,
416
- title: keyed ? "Remove keyframe here" : "Add keyframe at the playhead",
417
- disabled,
418
- onClick: onToggle,
419
- className: `inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-40 ${state === "none" ? "text-muted-foreground hover:text-foreground" : "text-amber-500"} ${className}`,
420
- children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 10 10", className: "h-2.5 w-2.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
421
- "path",
422
- {
423
- d: "M5 0.8 9.2 5 5 9.2 0.8 5Z",
424
- fill: keyed ? "currentColor" : "none",
425
- stroke: "currentColor",
426
- strokeWidth: "1.3",
427
- opacity: state === "animated" ? 0.7 : 1
428
- }
429
- ) })
430
- }
431
- );
432
- }
433
- function ParameterFieldControl({ field, value, onChange, resolveFile, ...rest }) {
434
- const set = onChange;
435
- switch (field.type) {
436
- case "number":
437
- case "int":
438
- return /* @__PURE__ */ jsx(ParameterSlider, { field, value, onChange: set, ...rest });
439
- case "boolean":
440
- return /* @__PURE__ */ jsx(ParameterToggle, { field, value, onChange: set, ...rest });
441
- case "choice":
442
- return /* @__PURE__ */ jsx(ParameterSelect, { field, value, onChange: set, ...rest });
443
- case "color":
444
- return /* @__PURE__ */ jsx(ParameterColor, { field, value, onChange: set, ...rest });
445
- case "vector":
446
- return /* @__PURE__ */ jsx(ParameterVector, { field, value, onChange: set, ...rest });
447
- case "image":
448
- return /* @__PURE__ */ jsx(ParameterImage, { field, value, onChange: set, resolveFile, ...rest });
449
- case "text":
450
- return /* @__PURE__ */ jsx(ParameterText, { field, value, onChange: set, ...rest });
451
- }
452
- }
453
-
454
70
  // src/parameters/ParametersPanel.tsx
455
71
  import { useId, useState } from "react";
456
72
  import {
457
73
  isParameterGroup,
458
- parameterLabel as parameterLabel2,
74
+ parameterLabel,
459
75
  parameterValuesEqual
460
76
  } from "@pixerate/editor/parameters";
461
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
77
+ import { jsx, jsxs } from "react/jsx-runtime";
462
78
  function FieldRow({
463
79
  controller,
464
80
  state,
@@ -468,16 +84,16 @@ function FieldRow({
468
84
  showFieldReset,
469
85
  resolveFile
470
86
  }) {
471
- const label = parameterLabel2(field);
87
+ const label = parameterLabel(field);
472
88
  const inputId = `${idBase}-${field.id}`;
473
89
  const value = state.values[field.id];
474
90
  const error = state.errors[field.id];
475
91
  const changed = !parameterValuesEqual(value, state.defaults[field.id]);
476
- return /* @__PURE__ */ jsxs2("div", { "data-parameter-id": field.id, "data-parameter-type": field.type, className: "space-y-1", children: [
477
- /* @__PURE__ */ jsxs2("div", { className: "flex min-h-[1.25rem] items-center gap-1.5", children: [
478
- showKeyframes && /* @__PURE__ */ jsx2(KeyframeDiamond, { state: state.keys[field.id] ?? "none", label, onToggle: () => controller.toggleKeyframe(field.id) }),
479
- /* @__PURE__ */ jsx2("label", { htmlFor: inputId, className: "min-w-0 flex-1 truncate text-xs font-medium text-foreground", title: field.description, children: label }),
480
- showFieldReset && changed && !field.readOnly && /* @__PURE__ */ jsx2(
92
+ return /* @__PURE__ */ jsxs("div", { "data-parameter-id": field.id, "data-parameter-type": field.type, className: "space-y-1", children: [
93
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-[1.25rem] items-center gap-1.5", children: [
94
+ showKeyframes && /* @__PURE__ */ jsx(KeyframeDiamond, { state: state.keys[field.id] ?? "none", label, onToggle: () => controller.toggleKeyframe(field.id) }),
95
+ /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "min-w-0 flex-1 truncate text-xs font-medium text-foreground", title: field.description, children: label }),
96
+ showFieldReset && changed && !field.readOnly && /* @__PURE__ */ jsx(
481
97
  "button",
482
98
  {
483
99
  type: "button",
@@ -489,8 +105,8 @@ function FieldRow({
489
105
  }
490
106
  )
491
107
  ] }),
492
- field.description && /* @__PURE__ */ jsx2("p", { className: "text-[11px] leading-snug text-muted-foreground", children: field.description }),
493
- /* @__PURE__ */ jsx2(
108
+ field.description && /* @__PURE__ */ jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: field.description }),
109
+ /* @__PURE__ */ jsx(
494
110
  ParameterFieldControl,
495
111
  {
496
112
  field,
@@ -502,7 +118,7 @@ function FieldRow({
502
118
  onGestureEnd: () => controller.endGesture()
503
119
  }
504
120
  ),
505
- error && /* @__PURE__ */ jsx2("p", { role: "alert", className: "text-[11px] text-destructive", children: error })
121
+ error && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-[11px] text-destructive", children: error })
506
122
  ] });
507
123
  }
508
124
  function PresetBar({ controller, state }) {
@@ -519,9 +135,9 @@ function PresetBar({ controller, state }) {
519
135
  setMessage(null);
520
136
  } else setMessage(result.message);
521
137
  };
522
- return /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5", "data-parameter-presets": "", children: [
523
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5", children: [
524
- /* @__PURE__ */ jsxs2(
138
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", "data-parameter-presets": "", children: [
139
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
140
+ /* @__PURE__ */ jsxs(
525
141
  "select",
526
142
  {
527
143
  "aria-label": "Preset",
@@ -529,16 +145,16 @@ function PresetBar({ controller, state }) {
529
145
  value: state.activePreset ?? "",
530
146
  onChange: (e) => e.target.value && controller.applyPreset(e.target.value),
531
147
  children: [
532
- /* @__PURE__ */ jsx2("option", { value: "", children: state.presets.length ? "Presets\u2026" : "No presets" }),
533
- state.presets.map((p) => /* @__PURE__ */ jsx2("option", { value: p.name, title: p.description, children: p.name }, p.name))
148
+ /* @__PURE__ */ jsx("option", { value: "", children: state.presets.length ? "Presets\u2026" : "No presets" }),
149
+ state.presets.map((p) => /* @__PURE__ */ jsx("option", { value: p.name, title: p.description, children: p.name }, p.name))
534
150
  ]
535
151
  }
536
152
  ),
537
- /* @__PURE__ */ jsx2("button", { type: "button", className: parameterButtonClass, onClick: () => setSaving((s) => !s), "aria-expanded": saving, children: "Save\u2026" }),
538
- active && !active.builtIn && /* @__PURE__ */ jsx2("button", { type: "button", className: parameterButtonClass, "aria-label": `Delete preset ${active.name}`, onClick: () => controller.deletePreset(active.name), children: "Delete" })
153
+ /* @__PURE__ */ jsx("button", { type: "button", className: parameterButtonClass, onClick: () => setSaving((s) => !s), "aria-expanded": saving, children: "Save\u2026" }),
154
+ active && !active.builtIn && /* @__PURE__ */ jsx("button", { type: "button", className: parameterButtonClass, "aria-label": `Delete preset ${active.name}`, onClick: () => controller.deletePreset(active.name), children: "Delete" })
539
155
  ] }),
540
- saving && /* @__PURE__ */ jsxs2("form", { className: "flex items-center gap-1.5", onSubmit: save, children: [
541
- /* @__PURE__ */ jsx2(
156
+ saving && /* @__PURE__ */ jsxs("form", { className: "flex items-center gap-1.5", onSubmit: save, children: [
157
+ /* @__PURE__ */ jsx(
542
158
  "input",
543
159
  {
544
160
  autoFocus: true,
@@ -549,9 +165,9 @@ function PresetBar({ controller, state }) {
549
165
  onChange: (e) => setName(e.target.value)
550
166
  }
551
167
  ),
552
- /* @__PURE__ */ jsx2("button", { type: "submit", className: parameterButtonClass, children: "Save" })
168
+ /* @__PURE__ */ jsx("button", { type: "submit", className: parameterButtonClass, children: "Save" })
553
169
  ] }),
554
- message && /* @__PURE__ */ jsx2("p", { role: "alert", className: "text-[11px] text-destructive", children: message })
170
+ message && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-[11px] text-destructive", children: message })
555
171
  ] });
556
172
  }
557
173
  function ParametersPanel({
@@ -572,7 +188,7 @@ function ParametersPanel({
572
188
  const renderItems = (items) => items.map((item) => {
573
189
  if (state.visible[item.id] === false) return null;
574
190
  if (isParameterGroup(item)) return renderGroup(item);
575
- return /* @__PURE__ */ jsx2(
191
+ return /* @__PURE__ */ jsx(
576
192
  FieldRow,
577
193
  {
578
194
  controller,
@@ -589,8 +205,8 @@ function ParametersPanel({
589
205
  const renderGroup = (group) => {
590
206
  const collapsed = !!state.collapsed[group.id];
591
207
  const bodyId = `${idBase}-group-${group.id}`;
592
- return /* @__PURE__ */ jsxs2("section", { "data-parameter-group": group.id, className: "rounded-md border border-border", children: [
593
- /* @__PURE__ */ jsxs2(
208
+ return /* @__PURE__ */ jsxs("section", { "data-parameter-group": group.id, className: "rounded-md border border-border", children: [
209
+ /* @__PURE__ */ jsxs(
594
210
  "button",
595
211
  {
596
212
  type: "button",
@@ -599,22 +215,22 @@ function ParametersPanel({
599
215
  onClick: () => controller.toggleCollapsed(group.id),
600
216
  className: "flex w-full items-center gap-1.5 px-2 py-1.5 text-left text-xs font-semibold text-foreground hover:bg-muted",
601
217
  children: [
602
- /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", className: `inline-block text-[10px] text-muted-foreground transition-transform ${collapsed ? "" : "rotate-90"}`, children: "\u25B6" }),
603
- parameterLabel2(group)
218
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: `inline-block text-[10px] text-muted-foreground transition-transform ${collapsed ? "" : "rotate-90"}`, children: "\u25B6" }),
219
+ parameterLabel(group)
604
220
  ]
605
221
  }
606
222
  ),
607
- !collapsed && /* @__PURE__ */ jsxs2("div", { id: bodyId, className: "space-y-3 border-t border-border px-2 py-2", children: [
608
- group.description && /* @__PURE__ */ jsx2("p", { className: "text-[11px] text-muted-foreground", children: group.description }),
223
+ !collapsed && /* @__PURE__ */ jsxs("div", { id: bodyId, className: "space-y-3 border-t border-border px-2 py-2", children: [
224
+ group.description && /* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground", children: group.description }),
609
225
  renderItems(group.fields)
610
226
  ] })
611
227
  ] }, group.id);
612
228
  };
613
- return /* @__PURE__ */ jsxs2("div", { className: `space-y-3 text-foreground ${className}`, "data-parameters-panel": "", children: [
614
- (heading || showToolbar) && /* @__PURE__ */ jsxs2("div", { className: "flex flex-wrap items-center gap-1.5", children: [
615
- heading && /* @__PURE__ */ jsx2("h3", { className: "mr-auto text-sm font-semibold", children: heading }),
616
- showToolbar && /* @__PURE__ */ jsxs2("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Parameter actions", children: [
617
- /* @__PURE__ */ jsx2(
229
+ return /* @__PURE__ */ jsxs("div", { className: `space-y-3 text-foreground ${className}`, "data-parameters-panel": "", children: [
230
+ (heading || showToolbar) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
231
+ heading && /* @__PURE__ */ jsx("h3", { className: "mr-auto text-sm font-semibold", children: heading }),
232
+ showToolbar && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Parameter actions", children: [
233
+ /* @__PURE__ */ jsx(
618
234
  "button",
619
235
  {
620
236
  type: "button",
@@ -625,7 +241,7 @@ function ParametersPanel({
625
241
  children: "Undo"
626
242
  }
627
243
  ),
628
- /* @__PURE__ */ jsx2(
244
+ /* @__PURE__ */ jsx(
629
245
  "button",
630
246
  {
631
247
  type: "button",
@@ -636,12 +252,12 @@ function ParametersPanel({
636
252
  children: "Redo"
637
253
  }
638
254
  ),
639
- /* @__PURE__ */ jsx2("button", { type: "button", className: parameterButtonClass, disabled: !state.modified, onClick: () => controller.reset(), children: "Reset" }),
640
- /* @__PURE__ */ jsx2("button", { type: "button", className: parameterButtonClass, onClick: () => controller.randomize(), children: "Randomize" })
255
+ /* @__PURE__ */ jsx("button", { type: "button", className: parameterButtonClass, disabled: !state.modified, onClick: () => controller.reset(), children: "Reset" }),
256
+ /* @__PURE__ */ jsx("button", { type: "button", className: parameterButtonClass, onClick: () => controller.randomize(), children: "Randomize" })
641
257
  ] })
642
258
  ] }),
643
- showPresets && /* @__PURE__ */ jsx2(PresetBar, { controller, state }),
644
- state.fields.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : renderItems(state.schema.fields)
259
+ showPresets && /* @__PURE__ */ jsx(PresetBar, { controller, state }),
260
+ state.fields.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : renderItems(state.schema.fields)
645
261
  ] });
646
262
  }
647
263
  export {