dialkit 1.1.0 → 1.2.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 +171 -1
- package/dist/index.cjs +876 -337
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -6
- package/dist/index.d.ts +41 -6
- package/dist/index.js +878 -341
- package/dist/index.js.map +1 -1
- package/dist/solid/index.cjs +1011 -544
- package/dist/solid/index.cjs.map +1 -1
- package/dist/solid/index.d.cts +33 -3
- package/dist/solid/index.d.ts +33 -3
- package/dist/solid/index.js +864 -398
- package/dist/solid/index.js.map +1 -1
- package/dist/store/index.cjs +52 -12
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +25 -3
- package/dist/store/index.d.ts +25 -3
- package/dist/store/index.js +52 -12
- package/dist/store/index.js.map +1 -1
- package/dist/styles.css +256 -25
- package/dist/svelte/components/ControlRenderer.svelte +12 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -1
- package/dist/svelte/components/DialRoot.svelte +22 -8
- package/dist/svelte/components/DialRoot.svelte.d.ts +3 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Folder.svelte +17 -8
- package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Panel.svelte +14 -9
- package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
- package/dist/svelte/components/PresetManager.svelte +7 -6
- package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
- package/dist/svelte/components/SegmentedControl.svelte +30 -74
- package/dist/svelte/components/SegmentedControl.svelte.d.ts.map +1 -1
- package/dist/svelte/components/SelectControl.svelte +2 -1
- package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
- package/dist/svelte/components/ShortcutListener.svelte +265 -0
- package/dist/svelte/components/ShortcutListener.svelte.d.ts +13 -0
- package/dist/svelte/components/ShortcutListener.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ShortcutsMenu.svelte +128 -0
- package/dist/svelte/components/ShortcutsMenu.svelte.d.ts +7 -0
- package/dist/svelte/components/ShortcutsMenu.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Slider.svelte +16 -29
- package/dist/svelte/components/Slider.svelte.d.ts +3 -0
- package/dist/svelte/components/Slider.svelte.d.ts.map +1 -1
- package/dist/svelte/components/SpringControl.svelte +17 -15
- package/dist/svelte/components/SpringControl.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Toggle.svelte +13 -2
- package/dist/svelte/components/Toggle.svelte.d.ts +3 -0
- package/dist/svelte/components/Toggle.svelte.d.ts.map +1 -1
- package/dist/svelte/components/TransitionControl.svelte +28 -25
- package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -1
- package/dist/svelte/createDialKit.svelte.d.ts +2 -1
- package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
- package/dist/svelte/createDialKit.svelte.js +1 -1
- package/dist/svelte/index.d.ts +6 -2
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +4 -0
- package/dist/svelte/theme-css.d.ts +1 -1
- package/dist/svelte/theme-css.d.ts.map +1 -1
- package/dist/svelte/theme-css.js +257 -26
- package/dist/vue/index.cjs +3056 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.cts +675 -0
- package/dist/vue/index.d.ts +675 -0
- package/dist/vue/index.js +3014 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +24 -4
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
Folder: () => Folder,
|
|
30
30
|
PresetManager: () => PresetManager,
|
|
31
31
|
SelectControl: () => SelectControl,
|
|
32
|
+
ShortcutsMenu: () => ShortcutsMenu,
|
|
32
33
|
Slider: () => Slider,
|
|
33
34
|
SpringControl: () => SpringControl,
|
|
34
35
|
SpringVisualization: () => SpringVisualization,
|
|
@@ -55,22 +56,22 @@ var DialStoreClass = class {
|
|
|
55
56
|
this.activePreset = /* @__PURE__ */ new Map();
|
|
56
57
|
this.baseValues = /* @__PURE__ */ new Map();
|
|
57
58
|
}
|
|
58
|
-
registerPanel(id, name, config) {
|
|
59
|
-
const controls = this.parseConfig(config, "");
|
|
59
|
+
registerPanel(id, name, config, shortcuts) {
|
|
60
|
+
const controls = this.parseConfig(config, "", shortcuts);
|
|
60
61
|
const values = this.flattenValues(config, "");
|
|
61
62
|
this.initTransitionModes(config, "", values);
|
|
62
|
-
this.panels.set(id, { id, name, controls, values });
|
|
63
|
+
this.panels.set(id, { id, name, controls, values, shortcuts: shortcuts ?? {} });
|
|
63
64
|
this.snapshots.set(id, { ...values });
|
|
64
65
|
this.baseValues.set(id, { ...values });
|
|
65
66
|
this.notifyGlobal();
|
|
66
67
|
}
|
|
67
|
-
updatePanel(id, name, config) {
|
|
68
|
+
updatePanel(id, name, config, shortcuts) {
|
|
68
69
|
const existing = this.panels.get(id);
|
|
69
70
|
if (!existing) {
|
|
70
|
-
this.registerPanel(id, name, config);
|
|
71
|
+
this.registerPanel(id, name, config, shortcuts);
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
|
-
const controls = this.parseConfig(config, "");
|
|
74
|
+
const controls = this.parseConfig(config, "", shortcuts);
|
|
74
75
|
const controlsByPath = this.mapControlsByPath(controls);
|
|
75
76
|
const defaultValues = this.flattenValues(config, "");
|
|
76
77
|
const nextValues = {};
|
|
@@ -92,7 +93,7 @@ var DialStoreClass = class {
|
|
|
92
93
|
nextValues[path] = mode;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
const nextPanel = { id, name, controls, values: nextValues };
|
|
96
|
+
const nextPanel = { id, name, controls, values: nextValues, shortcuts: shortcuts ?? existing.shortcuts };
|
|
96
97
|
this.panels.set(id, nextPanel);
|
|
97
98
|
this.snapshots.set(id, { ...nextValues });
|
|
98
99
|
const previousBaseValues = this.baseValues.get(id) ?? {};
|
|
@@ -250,6 +251,44 @@ var DialStoreClass = class {
|
|
|
250
251
|
this.activePreset.set(panelId, null);
|
|
251
252
|
this.notify(panelId);
|
|
252
253
|
}
|
|
254
|
+
resolveShortcutTarget(key, modifier) {
|
|
255
|
+
for (const panel of this.panels.values()) {
|
|
256
|
+
for (const [path, shortcut] of Object.entries(panel.shortcuts)) {
|
|
257
|
+
if (!shortcut.key) continue;
|
|
258
|
+
if (shortcut.key.toLowerCase() !== key.toLowerCase()) continue;
|
|
259
|
+
const scMod = shortcut.modifier ?? void 0;
|
|
260
|
+
if (scMod !== modifier) continue;
|
|
261
|
+
const control = this.findControlByPath(panel.controls, path);
|
|
262
|
+
if (control) {
|
|
263
|
+
return { panelId: panel.id, path, control };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
resolveScrollOnlyTargets() {
|
|
270
|
+
const results = [];
|
|
271
|
+
for (const panel of this.panels.values()) {
|
|
272
|
+
for (const [path, shortcut] of Object.entries(panel.shortcuts)) {
|
|
273
|
+
if ((shortcut.interaction ?? "scroll") !== "scroll-only") continue;
|
|
274
|
+
const control = this.findControlByPath(panel.controls, path);
|
|
275
|
+
if (control) {
|
|
276
|
+
results.push({ panelId: panel.id, path, control, shortcut });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return results;
|
|
281
|
+
}
|
|
282
|
+
findControlByPath(controls, path) {
|
|
283
|
+
for (const control of controls) {
|
|
284
|
+
if (control.path === path) return control;
|
|
285
|
+
if (control.type === "folder" && control.children) {
|
|
286
|
+
const found = this.findControlByPath(control.children, path);
|
|
287
|
+
if (found) return found;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
253
292
|
notify(panelId) {
|
|
254
293
|
this.listeners.get(panelId)?.forEach((fn) => fn());
|
|
255
294
|
}
|
|
@@ -271,12 +310,13 @@ var DialStoreClass = class {
|
|
|
271
310
|
}
|
|
272
311
|
}
|
|
273
312
|
}
|
|
274
|
-
parseConfig(config, prefix) {
|
|
313
|
+
parseConfig(config, prefix, shortcuts) {
|
|
275
314
|
const controls = [];
|
|
276
315
|
for (const [key, value] of Object.entries(config)) {
|
|
277
316
|
if (key === "_collapsed") continue;
|
|
278
317
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
279
318
|
const label = this.formatLabel(key);
|
|
319
|
+
const shortcut = shortcuts?.[path];
|
|
280
320
|
if (Array.isArray(value) && value.length <= 4 && typeof value[0] === "number") {
|
|
281
321
|
controls.push({
|
|
282
322
|
type: "slider",
|
|
@@ -284,13 +324,14 @@ var DialStoreClass = class {
|
|
|
284
324
|
label,
|
|
285
325
|
min: value[1],
|
|
286
326
|
max: value[2],
|
|
287
|
-
step: value[3] ?? this.inferStep(value[1], value[2])
|
|
327
|
+
step: value[3] ?? this.inferStep(value[1], value[2]),
|
|
328
|
+
shortcut
|
|
288
329
|
});
|
|
289
330
|
} else if (typeof value === "number") {
|
|
290
331
|
const { min, max, step } = this.inferRange(value);
|
|
291
|
-
controls.push({ type: "slider", path, label, min, max, step });
|
|
332
|
+
controls.push({ type: "slider", path, label, min, max, step, shortcut });
|
|
292
333
|
} else if (typeof value === "boolean") {
|
|
293
|
-
controls.push({ type: "toggle", path, label });
|
|
334
|
+
controls.push({ type: "toggle", path, label, shortcut });
|
|
294
335
|
} else if (this.isSpringConfig(value) || this.isEasingConfig(value)) {
|
|
295
336
|
controls.push({ type: "transition", path, label });
|
|
296
337
|
} else if (this.isActionConfig(value)) {
|
|
@@ -315,7 +356,7 @@ var DialStoreClass = class {
|
|
|
315
356
|
path,
|
|
316
357
|
label,
|
|
317
358
|
defaultOpen,
|
|
318
|
-
children: this.parseConfig(folderConfig, path)
|
|
359
|
+
children: this.parseConfig(folderConfig, path, shortcuts)
|
|
319
360
|
});
|
|
320
361
|
}
|
|
321
362
|
}
|
|
@@ -473,8 +514,11 @@ function useDialKit(name, config, options) {
|
|
|
473
514
|
configRef.current = config;
|
|
474
515
|
const onActionRef = (0, import_react.useRef)(options?.onAction);
|
|
475
516
|
onActionRef.current = options?.onAction;
|
|
517
|
+
const shortcutsRef = (0, import_react.useRef)(options?.shortcuts);
|
|
518
|
+
shortcutsRef.current = options?.shortcuts;
|
|
519
|
+
const serializedShortcuts = JSON.stringify(options?.shortcuts);
|
|
476
520
|
(0, import_react.useEffect)(() => {
|
|
477
|
-
DialStore.registerPanel(panelId, name, configRef.current);
|
|
521
|
+
DialStore.registerPanel(panelId, name, configRef.current, shortcutsRef.current);
|
|
478
522
|
return () => DialStore.unregisterPanel(panelId);
|
|
479
523
|
}, [panelId, name]);
|
|
480
524
|
const mountedRef = (0, import_react.useRef)(false);
|
|
@@ -483,8 +527,8 @@ function useDialKit(name, config, options) {
|
|
|
483
527
|
mountedRef.current = true;
|
|
484
528
|
return;
|
|
485
529
|
}
|
|
486
|
-
DialStore.updatePanel(panelId, name, configRef.current);
|
|
487
|
-
}, [panelId, name, serializedConfig]);
|
|
530
|
+
DialStore.updatePanel(panelId, name, configRef.current, shortcutsRef.current);
|
|
531
|
+
}, [panelId, name, serializedConfig, serializedShortcuts]);
|
|
488
532
|
(0, import_react.useEffect)(() => {
|
|
489
533
|
return DialStore.subscribeActions(panelId, (action) => {
|
|
490
534
|
onActionRef.current?.(action);
|
|
@@ -557,16 +601,329 @@ var import_react_dom3 = require("react-dom");
|
|
|
557
601
|
var import_react15 = require("react");
|
|
558
602
|
var import_react16 = require("motion/react");
|
|
559
603
|
|
|
560
|
-
// src/components/
|
|
604
|
+
// src/components/ShortcutListener.tsx
|
|
561
605
|
var import_react2 = require("react");
|
|
562
|
-
|
|
606
|
+
|
|
607
|
+
// src/shortcut-utils.ts
|
|
608
|
+
function decimalsForStep(step) {
|
|
609
|
+
const s = step.toString();
|
|
610
|
+
const dot = s.indexOf(".");
|
|
611
|
+
return dot === -1 ? 0 : s.length - dot - 1;
|
|
612
|
+
}
|
|
613
|
+
function roundValue(val, step) {
|
|
614
|
+
const raw = Math.round(val / step) * step;
|
|
615
|
+
return parseFloat(raw.toFixed(decimalsForStep(step)));
|
|
616
|
+
}
|
|
617
|
+
function getEffectiveStep(control, shortcut) {
|
|
618
|
+
const min = control.min ?? 0;
|
|
619
|
+
const max = control.max ?? 1;
|
|
620
|
+
const range = max - min;
|
|
621
|
+
const mode = shortcut.mode ?? "normal";
|
|
622
|
+
return mode === "fine" ? range * 0.01 : mode === "coarse" ? range * 0.1 : control.step ?? 1;
|
|
623
|
+
}
|
|
624
|
+
function applySliderDelta(panelId, path, control, effectiveStep, direction) {
|
|
625
|
+
const currentValue = DialStore.getValue(panelId, path);
|
|
626
|
+
const min = control.min ?? 0;
|
|
627
|
+
const max = control.max ?? 1;
|
|
628
|
+
const newValue = Math.max(min, Math.min(max, currentValue + direction * effectiveStep));
|
|
629
|
+
DialStore.updateValue(panelId, path, roundValue(newValue, effectiveStep));
|
|
630
|
+
}
|
|
631
|
+
function snapToDecile(rawValue, min, max) {
|
|
632
|
+
const normalized = (rawValue - min) / (max - min);
|
|
633
|
+
const nearest = Math.round(normalized * 10) / 10;
|
|
634
|
+
if (Math.abs(normalized - nearest) <= 0.03125) {
|
|
635
|
+
return min + nearest * (max - min);
|
|
636
|
+
}
|
|
637
|
+
return rawValue;
|
|
638
|
+
}
|
|
639
|
+
function isInputFocused() {
|
|
640
|
+
const el = document.activeElement;
|
|
641
|
+
if (!el) return false;
|
|
642
|
+
const tag = el.tagName;
|
|
643
|
+
if (tag === "INPUT" || tag === "TEXTAREA") return true;
|
|
644
|
+
if (el.contentEditable === "true") return true;
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
function getActiveModifier(e) {
|
|
648
|
+
if (e.altKey) return "alt";
|
|
649
|
+
if (e.shiftKey) return "shift";
|
|
650
|
+
if (e.metaKey) return "meta";
|
|
651
|
+
return void 0;
|
|
652
|
+
}
|
|
653
|
+
function findControl(controls, path) {
|
|
654
|
+
for (const control of controls) {
|
|
655
|
+
if (control.path === path) return control;
|
|
656
|
+
if (control.type === "folder" && control.children) {
|
|
657
|
+
const found = findControl(control.children, path);
|
|
658
|
+
if (found) return found;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
var DRAG_SENSITIVITY = 4;
|
|
664
|
+
function formatInteractionLabel(interaction) {
|
|
665
|
+
switch (interaction) {
|
|
666
|
+
case "drag":
|
|
667
|
+
return "Drag";
|
|
668
|
+
case "move":
|
|
669
|
+
return "Move";
|
|
670
|
+
case "scroll-only":
|
|
671
|
+
return "Scroll";
|
|
672
|
+
default:
|
|
673
|
+
return "Scroll";
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
function formatSliderShortcut(sc) {
|
|
677
|
+
const interaction = sc.interaction ?? "scroll";
|
|
678
|
+
const actionLabel = formatInteractionLabel(interaction);
|
|
679
|
+
if (!sc.key) return actionLabel;
|
|
680
|
+
const mod = formatModifier(sc.modifier);
|
|
681
|
+
return `${mod}${sc.key.toUpperCase()}+${actionLabel}`;
|
|
682
|
+
}
|
|
683
|
+
function formatToggleShortcut(sc) {
|
|
684
|
+
if (!sc.key) return "Press";
|
|
685
|
+
const mod = formatModifier(sc.modifier);
|
|
686
|
+
return `${mod}${sc.key.toUpperCase()}`;
|
|
687
|
+
}
|
|
688
|
+
function formatModifier(modifier) {
|
|
689
|
+
return modifier === "alt" ? "\u2325" : modifier === "shift" ? "\u21E7" : modifier === "meta" ? "\u2318" : "";
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// src/components/ShortcutListener.tsx
|
|
563
693
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
const [
|
|
567
|
-
const
|
|
568
|
-
const
|
|
694
|
+
var ShortcutContext = (0, import_react2.createContext)({ activePanelId: null, activePath: null });
|
|
695
|
+
function ShortcutListener({ children }) {
|
|
696
|
+
const [activeShortcut, setActiveShortcut] = (0, import_react2.useState)({ activePanelId: null, activePath: null });
|
|
697
|
+
const activeKeysRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
698
|
+
const isDraggingRef = (0, import_react2.useRef)(false);
|
|
699
|
+
const lastMouseXRef = (0, import_react2.useRef)(null);
|
|
700
|
+
const dragAccumulatorRef = (0, import_react2.useRef)(0);
|
|
701
|
+
const resolveActiveTarget = (0, import_react2.useCallback)((interaction) => {
|
|
702
|
+
for (const key of activeKeysRef.current) {
|
|
703
|
+
const panels = DialStore.getPanels();
|
|
704
|
+
for (const panel of panels) {
|
|
705
|
+
for (const [path, shortcut] of Object.entries(panel.shortcuts)) {
|
|
706
|
+
if (!shortcut.key) continue;
|
|
707
|
+
if (shortcut.key.toLowerCase() !== key) continue;
|
|
708
|
+
if ((shortcut.interaction ?? "scroll") !== interaction) continue;
|
|
709
|
+
const control = findControl(panel.controls, path);
|
|
710
|
+
if (control && control.type === "slider") {
|
|
711
|
+
return { panelId: panel.id, path, control, shortcut };
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return null;
|
|
717
|
+
}, []);
|
|
569
718
|
(0, import_react2.useEffect)(() => {
|
|
719
|
+
const handleKeyDown = (e) => {
|
|
720
|
+
if (isInputFocused()) return;
|
|
721
|
+
const key = e.key.toLowerCase();
|
|
722
|
+
if (key === "arrowleft" || key === "arrowright" || key === "arrowup" || key === "arrowdown") {
|
|
723
|
+
if (activeKeysRef.current.size > 0) {
|
|
724
|
+
const target2 = resolveActiveTarget("scroll") || resolveActiveTarget("drag") || resolveActiveTarget("move");
|
|
725
|
+
if (target2 && target2.control.type === "slider") {
|
|
726
|
+
e.preventDefault();
|
|
727
|
+
const direction = key === "arrowright" || key === "arrowup" ? 1 : -1;
|
|
728
|
+
const effectiveStep = getEffectiveStep(target2.control, target2.shortcut);
|
|
729
|
+
applySliderDelta(target2.panelId, target2.path, target2.control, effectiveStep, direction);
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
const wasAlreadyHeld = activeKeysRef.current.has(key);
|
|
735
|
+
activeKeysRef.current.add(key);
|
|
736
|
+
const modifier = getActiveModifier(e);
|
|
737
|
+
const target = DialStore.resolveShortcutTarget(key, modifier);
|
|
738
|
+
if (target) {
|
|
739
|
+
setActiveShortcut({ activePanelId: target.panelId, activePath: target.path });
|
|
740
|
+
if (!wasAlreadyHeld && target.control.type === "toggle") {
|
|
741
|
+
const currentValue = DialStore.getValue(target.panelId, target.path);
|
|
742
|
+
DialStore.updateValue(target.panelId, target.path, !currentValue);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (!wasAlreadyHeld) {
|
|
746
|
+
lastMouseXRef.current = null;
|
|
747
|
+
dragAccumulatorRef.current = 0;
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
const handleKeyUp = (e) => {
|
|
751
|
+
const key = e.key.toLowerCase();
|
|
752
|
+
activeKeysRef.current.delete(key);
|
|
753
|
+
isDraggingRef.current = false;
|
|
754
|
+
lastMouseXRef.current = null;
|
|
755
|
+
dragAccumulatorRef.current = 0;
|
|
756
|
+
if (activeKeysRef.current.size === 0) {
|
|
757
|
+
setActiveShortcut({ activePanelId: null, activePath: null });
|
|
758
|
+
} else {
|
|
759
|
+
let found = false;
|
|
760
|
+
for (const remainingKey of activeKeysRef.current) {
|
|
761
|
+
const modifier = getActiveModifier(e);
|
|
762
|
+
const target = DialStore.resolveShortcutTarget(remainingKey, modifier);
|
|
763
|
+
if (target) {
|
|
764
|
+
setActiveShortcut({ activePanelId: target.panelId, activePath: target.path });
|
|
765
|
+
found = true;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
if (!found) {
|
|
770
|
+
setActiveShortcut({ activePanelId: null, activePath: null });
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
const handleWheel = (e) => {
|
|
775
|
+
if (isInputFocused()) return;
|
|
776
|
+
const modifier = getActiveModifier(e);
|
|
777
|
+
if (activeKeysRef.current.size > 0) {
|
|
778
|
+
for (const key of activeKeysRef.current) {
|
|
779
|
+
const target = DialStore.resolveShortcutTarget(key, modifier);
|
|
780
|
+
if (!target) continue;
|
|
781
|
+
const { panelId, path, control } = target;
|
|
782
|
+
const interaction = control.shortcut?.interaction ?? "scroll";
|
|
783
|
+
if (interaction !== "scroll" || control.type !== "slider") continue;
|
|
784
|
+
e.preventDefault();
|
|
785
|
+
const effectiveStep = getEffectiveStep(control, control.shortcut);
|
|
786
|
+
const direction = e.deltaY > 0 ? -1 : 1;
|
|
787
|
+
applySliderDelta(panelId, path, control, effectiveStep, direction);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
const scrollOnlyTargets = DialStore.resolveScrollOnlyTargets();
|
|
792
|
+
for (const { panelId, path, control, shortcut } of scrollOnlyTargets) {
|
|
793
|
+
if (control.type !== "slider") continue;
|
|
794
|
+
e.preventDefault();
|
|
795
|
+
const effectiveStep = getEffectiveStep(control, shortcut);
|
|
796
|
+
const direction = e.deltaY > 0 ? -1 : 1;
|
|
797
|
+
applySliderDelta(panelId, path, control, effectiveStep, direction);
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
const handleMouseDown = (e) => {
|
|
802
|
+
if (isInputFocused()) return;
|
|
803
|
+
if (activeKeysRef.current.size === 0) return;
|
|
804
|
+
const target = resolveActiveTarget("drag");
|
|
805
|
+
if (target) {
|
|
806
|
+
isDraggingRef.current = true;
|
|
807
|
+
lastMouseXRef.current = e.clientX;
|
|
808
|
+
dragAccumulatorRef.current = 0;
|
|
809
|
+
e.preventDefault();
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
const handleMouseUp = () => {
|
|
813
|
+
isDraggingRef.current = false;
|
|
814
|
+
lastMouseXRef.current = null;
|
|
815
|
+
dragAccumulatorRef.current = 0;
|
|
816
|
+
};
|
|
817
|
+
const handleMouseMove = (e) => {
|
|
818
|
+
if (isInputFocused()) return;
|
|
819
|
+
if (activeKeysRef.current.size === 0) return;
|
|
820
|
+
if (isDraggingRef.current) {
|
|
821
|
+
const target = resolveActiveTarget("drag");
|
|
822
|
+
if (target && lastMouseXRef.current !== null) {
|
|
823
|
+
const deltaX = e.clientX - lastMouseXRef.current;
|
|
824
|
+
lastMouseXRef.current = e.clientX;
|
|
825
|
+
dragAccumulatorRef.current += deltaX;
|
|
826
|
+
const effectiveStep = getEffectiveStep(target.control, target.shortcut);
|
|
827
|
+
const steps = Math.trunc(dragAccumulatorRef.current / DRAG_SENSITIVITY);
|
|
828
|
+
if (steps !== 0) {
|
|
829
|
+
dragAccumulatorRef.current -= steps * DRAG_SENSITIVITY;
|
|
830
|
+
applySliderDelta(target.panelId, target.path, target.control, effectiveStep, steps);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
const moveTarget = resolveActiveTarget("move");
|
|
836
|
+
if (moveTarget) {
|
|
837
|
+
if (lastMouseXRef.current === null) {
|
|
838
|
+
lastMouseXRef.current = e.clientX;
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const deltaX = e.clientX - lastMouseXRef.current;
|
|
842
|
+
lastMouseXRef.current = e.clientX;
|
|
843
|
+
dragAccumulatorRef.current += deltaX;
|
|
844
|
+
const effectiveStep = getEffectiveStep(moveTarget.control, moveTarget.shortcut);
|
|
845
|
+
const steps = Math.trunc(dragAccumulatorRef.current / DRAG_SENSITIVITY);
|
|
846
|
+
if (steps !== 0) {
|
|
847
|
+
dragAccumulatorRef.current -= steps * DRAG_SENSITIVITY;
|
|
848
|
+
applySliderDelta(moveTarget.panelId, moveTarget.path, moveTarget.control, effectiveStep, steps);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
const handleWindowBlur = () => {
|
|
853
|
+
activeKeysRef.current.clear();
|
|
854
|
+
isDraggingRef.current = false;
|
|
855
|
+
lastMouseXRef.current = null;
|
|
856
|
+
dragAccumulatorRef.current = 0;
|
|
857
|
+
setActiveShortcut({ activePanelId: null, activePath: null });
|
|
858
|
+
};
|
|
859
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
860
|
+
window.addEventListener("keyup", handleKeyUp);
|
|
861
|
+
window.addEventListener("wheel", handleWheel, { passive: false });
|
|
862
|
+
window.addEventListener("mousedown", handleMouseDown);
|
|
863
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
864
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
865
|
+
window.addEventListener("blur", handleWindowBlur);
|
|
866
|
+
return () => {
|
|
867
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
868
|
+
window.removeEventListener("keyup", handleKeyUp);
|
|
869
|
+
window.removeEventListener("wheel", handleWheel);
|
|
870
|
+
window.removeEventListener("mousedown", handleMouseDown);
|
|
871
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
872
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
873
|
+
window.removeEventListener("blur", handleWindowBlur);
|
|
874
|
+
};
|
|
875
|
+
}, [resolveActiveTarget]);
|
|
876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShortcutContext.Provider, { value: activeShortcut, children });
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// src/icons.ts
|
|
880
|
+
var ICON_CHEVRON = "M6 9.5L12 15.5L18 9.5";
|
|
881
|
+
var ICON_CHECK = "M5 12.75L10 19L19 5";
|
|
882
|
+
var ICON_CLIPBOARD = {
|
|
883
|
+
board: "M8 6C8 4.34315 9.34315 3 11 3H13C14.6569 3 16 4.34315 16 6V7H8V6Z",
|
|
884
|
+
sparkle: "M19.2405 16.1852L18.5436 14.3733C18.4571 14.1484 18.241 14 18 14C17.759 14 17.5429 14.1484 17.4564 14.3733L16.7595 16.1852C16.658 16.4493 16.4493 16.658 16.1852 16.7595L14.3733 17.4564C14.1484 17.5429 14 17.759 14 18C14 18.241 14.1484 18.4571 14.3733 18.5436L16.1852 19.2405C16.4493 19.342 16.658 19.5507 16.7595 19.8148L17.4564 21.6267C17.5429 21.8516 17.759 22 18 22C18.241 22 18.4571 21.8516 18.5436 21.6267L19.2405 19.8148C19.342 19.5507 19.5507 19.342 19.8148 19.2405L21.6267 18.5436C21.8516 18.4571 22 18.241 22 18C22 17.759 21.8516 17.5429 21.6267 17.4564L19.8148 16.7595C19.5507 16.658 19.342 16.4493 19.2405 16.1852Z",
|
|
885
|
+
body: "M16 5H17C18.6569 5 20 6.34315 20 8V11M8 5H7C5.34315 5 4 6.34315 4 8V18C4 19.6569 5.34315 21 7 21H12"
|
|
886
|
+
};
|
|
887
|
+
var ICON_ADD_PRESET = [
|
|
888
|
+
"M4 6H20",
|
|
889
|
+
"M4 12H10",
|
|
890
|
+
"M15 15L21 15",
|
|
891
|
+
"M18 12V18",
|
|
892
|
+
"M4 18H10"
|
|
893
|
+
];
|
|
894
|
+
var ICON_TRASH = [
|
|
895
|
+
"M5 6.5L5.80734 18.2064C5.91582 19.7794 7.22348 21 8.80023 21H15.1998C16.7765 21 18.0842 19.7794 18.1927 18.2064L19 6.5",
|
|
896
|
+
"M10 11V16",
|
|
897
|
+
"M14 11V16",
|
|
898
|
+
"M3.5 6H20.5",
|
|
899
|
+
"M8.07092 5.74621C8.42348 3.89745 10.0485 2.5 12 2.5C13.9515 2.5 15.5765 3.89745 15.9291 5.74621"
|
|
900
|
+
];
|
|
901
|
+
var ICON_PANEL = {
|
|
902
|
+
path: "M6.84766 11.75C6.78583 11.9899 6.75 12.2408 6.75 12.5C6.75 12.7592 6.78583 13.0101 6.84766 13.25H2C1.58579 13.25 1.25 12.9142 1.25 12.5C1.25 12.0858 1.58579 11.75 2 11.75H6.84766ZM14 11.75C14.4142 11.75 14.75 12.0858 14.75 12.5C14.75 12.9142 14.4142 13.25 14 13.25H12.6523C12.7142 13.0101 12.75 12.7592 12.75 12.5C12.75 12.2408 12.7142 11.9899 12.6523 11.75H14ZM3.09766 7.25C3.03583 7.48994 3 7.74075 3 8C3 8.25925 3.03583 8.51006 3.09766 8.75H2C1.58579 8.75 1.25 8.41421 1.25 8C1.25 7.58579 1.58579 7.25 2 7.25H3.09766ZM14 7.25C14.4142 7.25 14.75 7.58579 14.75 8C14.75 8.41421 14.4142 8.75 14 8.75H8.90234C8.96417 8.51006 9 8.25925 9 8C9 7.74075 8.96417 7.48994 8.90234 7.25H14ZM7.59766 2.75C7.53583 2.98994 7.5 3.24075 7.5 3.5C7.5 3.75925 7.53583 4.01006 7.59766 4.25H2C1.58579 4.25 1.25 3.91421 1.25 3.5C1.25 3.08579 1.58579 2.75 2 2.75H7.59766ZM14 2.75C14.4142 2.75 14.75 3.08579 14.75 3.5C14.75 3.91421 14.4142 4.25 14 4.25H13.4023C13.4642 4.01006 13.5 3.75925 13.5 3.5C13.5 3.24075 13.4642 2.98994 13.4023 2.75H14Z",
|
|
903
|
+
circles: [
|
|
904
|
+
{ cx: "6", cy: "8", r: "0.998596" },
|
|
905
|
+
{ cx: "10.4999", cy: "3.5", r: "0.998657" },
|
|
906
|
+
{ cx: "9.75015", cy: "12.5", r: "0.997986" }
|
|
907
|
+
]
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
// src/components/Folder.tsx
|
|
911
|
+
var import_react3 = require("react");
|
|
912
|
+
var import_react4 = require("motion/react");
|
|
913
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
914
|
+
function Folder({ title, children, defaultOpen = true, isRoot = false, inline = false, onOpenChange, toolbar }) {
|
|
915
|
+
const [isOpen, setIsOpen] = (0, import_react3.useState)(defaultOpen);
|
|
916
|
+
const [isCollapsed, setIsCollapsed] = (0, import_react3.useState)(!defaultOpen);
|
|
917
|
+
const contentRef = (0, import_react3.useRef)(null);
|
|
918
|
+
const [contentHeight, setContentHeight] = (0, import_react3.useState)(void 0);
|
|
919
|
+
const [windowHeight, setWindowHeight] = (0, import_react3.useState)(typeof window !== "undefined" ? window.innerHeight : 800);
|
|
920
|
+
(0, import_react3.useEffect)(() => {
|
|
921
|
+
if (!isRoot) return;
|
|
922
|
+
const onResize = () => setWindowHeight(window.innerHeight);
|
|
923
|
+
window.addEventListener("resize", onResize);
|
|
924
|
+
return () => window.removeEventListener("resize", onResize);
|
|
925
|
+
}, [isRoot]);
|
|
926
|
+
(0, import_react3.useEffect)(() => {
|
|
570
927
|
const el = contentRef.current;
|
|
571
928
|
if (!el) return;
|
|
572
929
|
const ro = new ResizeObserver(() => {
|
|
@@ -589,26 +946,24 @@ function Folder({ title, children, defaultOpen = true, isRoot = false, inline =
|
|
|
589
946
|
}
|
|
590
947
|
onOpenChange?.(next);
|
|
591
948
|
};
|
|
592
|
-
const folderContent = /* @__PURE__ */ (0,
|
|
593
|
-
/* @__PURE__ */ (0,
|
|
594
|
-
/* @__PURE__ */ (0,
|
|
595
|
-
isRoot ? isOpen && /* @__PURE__ */ (0,
|
|
596
|
-
isRoot && !inline && /* @__PURE__ */ (0,
|
|
949
|
+
const folderContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ref: isRoot ? contentRef : void 0, className: `dialkit-folder ${isRoot ? "dialkit-folder-root" : ""}`, children: [
|
|
950
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `dialkit-folder-header ${isRoot ? "dialkit-panel-header" : ""}`, onClick: handleToggle, children: [
|
|
951
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dialkit-folder-header-top", children: [
|
|
952
|
+
isRoot ? isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dialkit-folder-title-row", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dialkit-folder-title dialkit-folder-title-root", children: title }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dialkit-folder-title-row", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dialkit-folder-title", children: title }) }),
|
|
953
|
+
isRoot && !inline && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
597
954
|
"svg",
|
|
598
955
|
{
|
|
599
956
|
className: "dialkit-panel-icon",
|
|
600
957
|
viewBox: "0 0 16 16",
|
|
601
958
|
fill: "none",
|
|
602
959
|
children: [
|
|
603
|
-
/* @__PURE__ */ (0,
|
|
604
|
-
/* @__PURE__ */ (0,
|
|
605
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10.4999", cy: "3.5", r: "0.998657", fill: "currentColor", stroke: "currentColor", strokeWidth: "1.25" }),
|
|
606
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "9.75015", cy: "12.5", r: "0.997986", fill: "currentColor", stroke: "currentColor", strokeWidth: "1.25" })
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { opacity: "0.5", d: ICON_PANEL.path, fill: "currentColor" }),
|
|
961
|
+
ICON_PANEL.circles.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: c.cx, cy: c.cy, r: c.r, fill: "currentColor", stroke: "currentColor", strokeWidth: "1.25" }, i))
|
|
607
962
|
]
|
|
608
963
|
}
|
|
609
964
|
),
|
|
610
|
-
!isRoot && /* @__PURE__ */ (0,
|
|
611
|
-
|
|
965
|
+
!isRoot && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
966
|
+
import_react4.motion.svg,
|
|
612
967
|
{
|
|
613
968
|
className: "dialkit-folder-icon",
|
|
614
969
|
viewBox: "0 0 24 24",
|
|
@@ -620,14 +975,14 @@ function Folder({ title, children, defaultOpen = true, isRoot = false, inline =
|
|
|
620
975
|
initial: false,
|
|
621
976
|
animate: { rotate: isOpen ? 0 : 180 },
|
|
622
977
|
transition: { type: "spring", visualDuration: 0.35, bounce: 0.15 },
|
|
623
|
-
children: /* @__PURE__ */ (0,
|
|
978
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: ICON_CHEVRON })
|
|
624
979
|
}
|
|
625
980
|
)
|
|
626
981
|
] }),
|
|
627
|
-
isRoot && toolbar && isOpen && /* @__PURE__ */ (0,
|
|
982
|
+
isRoot && toolbar && isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dialkit-panel-toolbar", onClick: (e) => e.stopPropagation(), children: toolbar })
|
|
628
983
|
] }),
|
|
629
|
-
/* @__PURE__ */ (0,
|
|
630
|
-
|
|
984
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
985
|
+
import_react4.motion.div,
|
|
631
986
|
{
|
|
632
987
|
className: "dialkit-folder-content",
|
|
633
988
|
initial: isRoot ? void 0 : { height: 0, opacity: 0 },
|
|
@@ -635,17 +990,17 @@ function Folder({ title, children, defaultOpen = true, isRoot = false, inline =
|
|
|
635
990
|
exit: isRoot ? void 0 : { height: 0, opacity: 0 },
|
|
636
991
|
transition: isRoot ? void 0 : { type: "spring", visualDuration: 0.35, bounce: 0.1 },
|
|
637
992
|
style: isRoot ? void 0 : { clipPath: "inset(0 -20px)" },
|
|
638
|
-
children: /* @__PURE__ */ (0,
|
|
993
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dialkit-folder-inner", children })
|
|
639
994
|
}
|
|
640
995
|
) })
|
|
641
996
|
] });
|
|
642
997
|
if (isRoot) {
|
|
643
998
|
if (inline) {
|
|
644
|
-
return /* @__PURE__ */ (0,
|
|
999
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dialkit-panel-inner dialkit-panel-inline", children: folderContent });
|
|
645
1000
|
}
|
|
646
|
-
const panelStyle = isOpen ? { width: 280, height: contentHeight !== void 0 ? contentHeight +
|
|
647
|
-
return /* @__PURE__ */ (0,
|
|
648
|
-
|
|
1001
|
+
const panelStyle = isOpen ? { width: 280, height: contentHeight !== void 0 ? Math.min(contentHeight + 10, windowHeight - 32) : "auto", borderRadius: 14, boxShadow: "var(--dial-shadow)", cursor: void 0, overflowY: "auto" } : { width: 42, height: 42, borderRadius: "50%", boxSizing: "border-box", boxShadow: "var(--dial-shadow-collapsed)", overflow: "hidden", cursor: "pointer" };
|
|
1002
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1003
|
+
import_react4.motion.div,
|
|
649
1004
|
{
|
|
650
1005
|
className: "dialkit-panel-inner",
|
|
651
1006
|
style: panelStyle,
|
|
@@ -661,30 +1016,13 @@ function Folder({ title, children, defaultOpen = true, isRoot = false, inline =
|
|
|
661
1016
|
}
|
|
662
1017
|
|
|
663
1018
|
// src/components/Slider.tsx
|
|
664
|
-
var
|
|
665
|
-
var
|
|
666
|
-
var
|
|
1019
|
+
var import_react5 = require("react");
|
|
1020
|
+
var import_react6 = require("motion/react");
|
|
1021
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
667
1022
|
var CLICK_THRESHOLD = 3;
|
|
668
1023
|
var DEAD_ZONE = 32;
|
|
669
1024
|
var MAX_CURSOR_RANGE = 200;
|
|
670
1025
|
var MAX_STRETCH = 8;
|
|
671
|
-
function decimalsForStep(step) {
|
|
672
|
-
const s = step.toString();
|
|
673
|
-
const dot = s.indexOf(".");
|
|
674
|
-
return dot === -1 ? 0 : s.length - dot - 1;
|
|
675
|
-
}
|
|
676
|
-
function roundValue(val, step) {
|
|
677
|
-
const raw = Math.round(val / step) * step;
|
|
678
|
-
return parseFloat(raw.toFixed(decimalsForStep(step)));
|
|
679
|
-
}
|
|
680
|
-
function snapToDecile(rawValue, min, max) {
|
|
681
|
-
const normalized = (rawValue - min) / (max - min);
|
|
682
|
-
const nearest = Math.round(normalized * 10) / 10;
|
|
683
|
-
if (Math.abs(normalized - nearest) <= 0.03125) {
|
|
684
|
-
return min + nearest * (max - min);
|
|
685
|
-
}
|
|
686
|
-
return rawValue;
|
|
687
|
-
}
|
|
688
1026
|
function Slider({
|
|
689
1027
|
label,
|
|
690
1028
|
value,
|
|
@@ -692,49 +1030,51 @@ function Slider({
|
|
|
692
1030
|
min = 0,
|
|
693
1031
|
max = 1,
|
|
694
1032
|
step = 0.01,
|
|
695
|
-
unit
|
|
1033
|
+
unit,
|
|
1034
|
+
shortcut,
|
|
1035
|
+
shortcutActive
|
|
696
1036
|
}) {
|
|
697
|
-
const wrapperRef = (0,
|
|
698
|
-
const trackRef = (0,
|
|
699
|
-
const inputRef = (0,
|
|
700
|
-
const labelRef = (0,
|
|
701
|
-
const valueSpanRef = (0,
|
|
702
|
-
const [isInteracting, setIsInteracting] = (0,
|
|
703
|
-
const [isDragging, setIsDragging] = (0,
|
|
704
|
-
const [isHovered, setIsHovered] = (0,
|
|
705
|
-
const [isValueHovered, setIsValueHovered] = (0,
|
|
706
|
-
const [isValueEditable, setIsValueEditable] = (0,
|
|
707
|
-
const [showInput, setShowInput] = (0,
|
|
708
|
-
const [inputValue, setInputValue] = (0,
|
|
709
|
-
const hoverTimeoutRef = (0,
|
|
710
|
-
const pointerDownPos = (0,
|
|
711
|
-
const isClickRef = (0,
|
|
712
|
-
const animRef = (0,
|
|
713
|
-
const wrapperRectRef = (0,
|
|
714
|
-
const scaleRef = (0,
|
|
1037
|
+
const wrapperRef = (0, import_react5.useRef)(null);
|
|
1038
|
+
const trackRef = (0, import_react5.useRef)(null);
|
|
1039
|
+
const inputRef = (0, import_react5.useRef)(null);
|
|
1040
|
+
const labelRef = (0, import_react5.useRef)(null);
|
|
1041
|
+
const valueSpanRef = (0, import_react5.useRef)(null);
|
|
1042
|
+
const [isInteracting, setIsInteracting] = (0, import_react5.useState)(false);
|
|
1043
|
+
const [isDragging, setIsDragging] = (0, import_react5.useState)(false);
|
|
1044
|
+
const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
|
|
1045
|
+
const [isValueHovered, setIsValueHovered] = (0, import_react5.useState)(false);
|
|
1046
|
+
const [isValueEditable, setIsValueEditable] = (0, import_react5.useState)(false);
|
|
1047
|
+
const [showInput, setShowInput] = (0, import_react5.useState)(false);
|
|
1048
|
+
const [inputValue, setInputValue] = (0, import_react5.useState)("");
|
|
1049
|
+
const hoverTimeoutRef = (0, import_react5.useRef)(null);
|
|
1050
|
+
const pointerDownPos = (0, import_react5.useRef)(null);
|
|
1051
|
+
const isClickRef = (0, import_react5.useRef)(true);
|
|
1052
|
+
const animRef = (0, import_react5.useRef)(null);
|
|
1053
|
+
const wrapperRectRef = (0, import_react5.useRef)(null);
|
|
1054
|
+
const scaleRef = (0, import_react5.useRef)(1);
|
|
715
1055
|
const percentage = (value - min) / (max - min) * 100;
|
|
716
1056
|
const isActive = isInteracting || isHovered;
|
|
717
|
-
const fillPercent = (0,
|
|
718
|
-
const fillWidth = (0,
|
|
719
|
-
const handleLeft = (0,
|
|
1057
|
+
const fillPercent = (0, import_react6.useMotionValue)(percentage);
|
|
1058
|
+
const fillWidth = (0, import_react6.useTransform)(fillPercent, (pct) => `${pct}%`);
|
|
1059
|
+
const handleLeft = (0, import_react6.useTransform)(
|
|
720
1060
|
fillPercent,
|
|
721
1061
|
(pct) => `max(5px, calc(${pct}% - 9px))`
|
|
722
1062
|
);
|
|
723
|
-
const rubberStretchPx = (0,
|
|
724
|
-
const rubberBandWidth = (0,
|
|
1063
|
+
const rubberStretchPx = (0, import_react6.useMotionValue)(0);
|
|
1064
|
+
const rubberBandWidth = (0, import_react6.useTransform)(
|
|
725
1065
|
rubberStretchPx,
|
|
726
1066
|
(stretch) => `calc(100% + ${Math.abs(stretch)}px)`
|
|
727
1067
|
);
|
|
728
|
-
const rubberBandX = (0,
|
|
1068
|
+
const rubberBandX = (0, import_react6.useTransform)(
|
|
729
1069
|
rubberStretchPx,
|
|
730
1070
|
(stretch) => stretch < 0 ? stretch : 0
|
|
731
1071
|
);
|
|
732
|
-
(0,
|
|
1072
|
+
(0, import_react5.useEffect)(() => {
|
|
733
1073
|
if (!isInteracting && !animRef.current) {
|
|
734
1074
|
fillPercent.jump(percentage);
|
|
735
1075
|
}
|
|
736
1076
|
}, [percentage, isInteracting, fillPercent]);
|
|
737
|
-
const positionToValue = (0,
|
|
1077
|
+
const positionToValue = (0, import_react5.useCallback)(
|
|
738
1078
|
(clientX) => {
|
|
739
1079
|
const rect = wrapperRectRef.current;
|
|
740
1080
|
if (!rect) return value;
|
|
@@ -747,11 +1087,11 @@ function Slider({
|
|
|
747
1087
|
},
|
|
748
1088
|
[min, max, value]
|
|
749
1089
|
);
|
|
750
|
-
const percentFromValue = (0,
|
|
1090
|
+
const percentFromValue = (0, import_react5.useCallback)(
|
|
751
1091
|
(v) => (v - min) / (max - min) * 100,
|
|
752
1092
|
[min, max]
|
|
753
1093
|
);
|
|
754
|
-
const computeRubberStretch = (0,
|
|
1094
|
+
const computeRubberStretch = (0, import_react5.useCallback)(
|
|
755
1095
|
(clientX, sign) => {
|
|
756
1096
|
const rect = wrapperRectRef.current;
|
|
757
1097
|
if (!rect) return 0;
|
|
@@ -761,7 +1101,7 @@ function Slider({
|
|
|
761
1101
|
},
|
|
762
1102
|
[]
|
|
763
1103
|
);
|
|
764
|
-
const handlePointerDown = (0,
|
|
1104
|
+
const handlePointerDown = (0, import_react5.useCallback)(
|
|
765
1105
|
(e) => {
|
|
766
1106
|
if (showInput) return;
|
|
767
1107
|
e.preventDefault();
|
|
@@ -777,7 +1117,7 @@ function Slider({
|
|
|
777
1117
|
},
|
|
778
1118
|
[showInput]
|
|
779
1119
|
);
|
|
780
|
-
const handlePointerMove = (0,
|
|
1120
|
+
const handlePointerMove = (0, import_react5.useCallback)(
|
|
781
1121
|
(e) => {
|
|
782
1122
|
if (!isInteracting || !pointerDownPos.current) return;
|
|
783
1123
|
const dx = e.clientX - pointerDownPos.current.x;
|
|
@@ -818,7 +1158,7 @@ function Slider({
|
|
|
818
1158
|
computeRubberStretch
|
|
819
1159
|
]
|
|
820
1160
|
);
|
|
821
|
-
const handlePointerUp = (0,
|
|
1161
|
+
const handlePointerUp = (0, import_react5.useCallback)(
|
|
822
1162
|
(e) => {
|
|
823
1163
|
if (!isInteracting) return;
|
|
824
1164
|
if (isClickRef.current) {
|
|
@@ -829,7 +1169,7 @@ function Slider({
|
|
|
829
1169
|
if (animRef.current) {
|
|
830
1170
|
animRef.current.stop();
|
|
831
1171
|
}
|
|
832
|
-
animRef.current = (0,
|
|
1172
|
+
animRef.current = (0, import_react6.animate)(fillPercent, newPct, {
|
|
833
1173
|
type: "spring",
|
|
834
1174
|
stiffness: 300,
|
|
835
1175
|
damping: 25,
|
|
@@ -841,7 +1181,7 @@ function Slider({
|
|
|
841
1181
|
onChange(roundValue(snappedValue, step));
|
|
842
1182
|
}
|
|
843
1183
|
if (rubberStretchPx.get() !== 0) {
|
|
844
|
-
(0,
|
|
1184
|
+
(0, import_react6.animate)(rubberStretchPx, 0, {
|
|
845
1185
|
type: "spring",
|
|
846
1186
|
visualDuration: 0.35,
|
|
847
1187
|
bounce: 0.15
|
|
@@ -862,7 +1202,7 @@ function Slider({
|
|
|
862
1202
|
rubberStretchPx
|
|
863
1203
|
]
|
|
864
1204
|
);
|
|
865
|
-
(0,
|
|
1205
|
+
(0, import_react5.useEffect)(() => {
|
|
866
1206
|
if (isValueHovered && !showInput && !isValueEditable) {
|
|
867
1207
|
hoverTimeoutRef.current = setTimeout(() => {
|
|
868
1208
|
setIsValueEditable(true);
|
|
@@ -880,7 +1220,7 @@ function Slider({
|
|
|
880
1220
|
}
|
|
881
1221
|
};
|
|
882
1222
|
}, [isValueHovered, showInput, isValueEditable]);
|
|
883
|
-
(0,
|
|
1223
|
+
(0, import_react5.useEffect)(() => {
|
|
884
1224
|
if (showInput && inputRef.current) {
|
|
885
1225
|
inputRef.current.focus();
|
|
886
1226
|
inputRef.current.select();
|
|
@@ -935,11 +1275,10 @@ function Slider({
|
|
|
935
1275
|
}
|
|
936
1276
|
const valueDodge = percentage < leftThreshold || percentage > rightThreshold;
|
|
937
1277
|
const handleOpacity = !isActive ? 0 : valueDodge ? 0.1 : isDragging ? 0.9 : 0.5;
|
|
938
|
-
const fillBackground = isActive ? "rgba(255, 255, 255, 0.15)" : "rgba(255, 255, 255, 0.11)";
|
|
939
1278
|
const discreteSteps = (max - min) / step;
|
|
940
1279
|
const hashMarks = discreteSteps <= 10 ? Array.from({ length: discreteSteps - 1 }, (_, i) => {
|
|
941
1280
|
const pct = (i + 1) * step / (max - min) * 100;
|
|
942
|
-
return /* @__PURE__ */ (0,
|
|
1281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
943
1282
|
"div",
|
|
944
1283
|
{
|
|
945
1284
|
className: "dialkit-slider-hashmark",
|
|
@@ -949,7 +1288,7 @@ function Slider({
|
|
|
949
1288
|
);
|
|
950
1289
|
}) : Array.from({ length: 9 }, (_, i) => {
|
|
951
1290
|
const pct = (i + 1) * 10;
|
|
952
|
-
return /* @__PURE__ */ (0,
|
|
1291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
953
1292
|
"div",
|
|
954
1293
|
{
|
|
955
1294
|
className: "dialkit-slider-hashmark",
|
|
@@ -958,8 +1297,8 @@ function Slider({
|
|
|
958
1297
|
i
|
|
959
1298
|
);
|
|
960
1299
|
});
|
|
961
|
-
return /* @__PURE__ */ (0,
|
|
962
|
-
|
|
1300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: wrapperRef, className: "dialkit-slider-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1301
|
+
import_react6.motion.div,
|
|
963
1302
|
{
|
|
964
1303
|
ref: trackRef,
|
|
965
1304
|
className: `dialkit-slider ${isActive ? "dialkit-slider-active" : ""}`,
|
|
@@ -970,26 +1309,23 @@ function Slider({
|
|
|
970
1309
|
onMouseLeave: () => setIsHovered(false),
|
|
971
1310
|
style: { width: rubberBandWidth, x: rubberBandX },
|
|
972
1311
|
children: [
|
|
973
|
-
/* @__PURE__ */ (0,
|
|
974
|
-
/* @__PURE__ */ (0,
|
|
975
|
-
|
|
1312
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dialkit-slider-hashmarks", children: hashMarks }),
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1314
|
+
import_react6.motion.div,
|
|
976
1315
|
{
|
|
977
1316
|
className: "dialkit-slider-fill",
|
|
978
1317
|
style: {
|
|
979
|
-
|
|
980
|
-
width: fillWidth,
|
|
981
|
-
transition: "background 0.15s"
|
|
1318
|
+
width: fillWidth
|
|
982
1319
|
}
|
|
983
1320
|
}
|
|
984
1321
|
),
|
|
985
|
-
/* @__PURE__ */ (0,
|
|
986
|
-
|
|
1322
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1323
|
+
import_react6.motion.div,
|
|
987
1324
|
{
|
|
988
1325
|
className: "dialkit-slider-handle",
|
|
989
1326
|
style: {
|
|
990
1327
|
left: handleLeft,
|
|
991
|
-
y: "-50%"
|
|
992
|
-
background: "rgba(255, 255, 255, 0.9)"
|
|
1328
|
+
y: "-50%"
|
|
993
1329
|
},
|
|
994
1330
|
animate: {
|
|
995
1331
|
opacity: handleOpacity,
|
|
@@ -1003,8 +1339,11 @@ function Slider({
|
|
|
1003
1339
|
}
|
|
1004
1340
|
}
|
|
1005
1341
|
),
|
|
1006
|
-
/* @__PURE__ */ (0,
|
|
1007
|
-
|
|
1342
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { ref: labelRef, className: "dialkit-slider-label", children: [
|
|
1343
|
+
label,
|
|
1344
|
+
shortcut && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `dialkit-shortcut-pill${shortcutActive ? " dialkit-shortcut-pill-active" : ""}`, children: formatSliderShortcut(shortcut) })
|
|
1345
|
+
] }),
|
|
1346
|
+
showInput ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1008
1347
|
"input",
|
|
1009
1348
|
{
|
|
1010
1349
|
ref: inputRef,
|
|
@@ -1017,7 +1356,7 @@ function Slider({
|
|
|
1017
1356
|
onClick: (e) => e.stopPropagation(),
|
|
1018
1357
|
onMouseDown: (e) => e.stopPropagation()
|
|
1019
1358
|
}
|
|
1020
|
-
) : /* @__PURE__ */ (0,
|
|
1359
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1021
1360
|
"span",
|
|
1022
1361
|
{
|
|
1023
1362
|
ref: valueSpanRef,
|
|
@@ -1036,51 +1375,48 @@ function Slider({
|
|
|
1036
1375
|
}
|
|
1037
1376
|
|
|
1038
1377
|
// src/components/SegmentedControl.tsx
|
|
1039
|
-
var
|
|
1040
|
-
var
|
|
1041
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1378
|
+
var import_react7 = require("react");
|
|
1379
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1042
1380
|
function SegmentedControl({
|
|
1043
1381
|
options,
|
|
1044
1382
|
value,
|
|
1045
1383
|
onChange
|
|
1046
1384
|
}) {
|
|
1047
|
-
const containerRef = (0,
|
|
1048
|
-
const
|
|
1049
|
-
const [pillStyle, setPillStyle] = (0,
|
|
1050
|
-
const
|
|
1051
|
-
(0, import_react6.useLayoutEffect)(() => {
|
|
1052
|
-
const button = buttonRefs.current.get(value);
|
|
1385
|
+
const containerRef = (0, import_react7.useRef)(null);
|
|
1386
|
+
const hasAnimated = (0, import_react7.useRef)(false);
|
|
1387
|
+
const [pillStyle, setPillStyle] = (0, import_react7.useState)(null);
|
|
1388
|
+
const measure = (0, import_react7.useCallback)(() => {
|
|
1053
1389
|
const container = containerRef.current;
|
|
1054
|
-
if (
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1390
|
+
if (!container) return;
|
|
1391
|
+
const activeButton = container.querySelector('[data-active="true"]');
|
|
1392
|
+
if (!activeButton) return;
|
|
1393
|
+
setPillStyle({
|
|
1394
|
+
left: activeButton.offsetLeft,
|
|
1395
|
+
width: activeButton.offsetWidth
|
|
1396
|
+
});
|
|
1397
|
+
}, []);
|
|
1398
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
1399
|
+
measure();
|
|
1400
|
+
}, [value, options.length, measure]);
|
|
1401
|
+
const shouldAnimate = hasAnimated.current;
|
|
1402
|
+
hasAnimated.current = true;
|
|
1403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dialkit-segmented", ref: containerRef, children: [
|
|
1404
|
+
pillStyle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1405
|
+
"div",
|
|
1066
1406
|
{
|
|
1067
1407
|
className: "dialkit-segmented-pill",
|
|
1068
|
-
style: {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
hasAnimated.current = true;
|
|
1408
|
+
style: {
|
|
1409
|
+
left: pillStyle.left,
|
|
1410
|
+
width: pillStyle.width,
|
|
1411
|
+
transition: shouldAnimate ? "left 0.2s cubic-bezier(0.25, 1, 0.5, 1), width 0.2s cubic-bezier(0.25, 1, 0.5, 1)" : "none"
|
|
1073
1412
|
}
|
|
1074
1413
|
}
|
|
1075
1414
|
),
|
|
1076
1415
|
options.map((option) => {
|
|
1077
1416
|
const isActive = value === option.value;
|
|
1078
|
-
return /* @__PURE__ */ (0,
|
|
1417
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1079
1418
|
"button",
|
|
1080
1419
|
{
|
|
1081
|
-
ref: (el) => {
|
|
1082
|
-
if (el) buttonRefs.current.set(option.value, el);
|
|
1083
|
-
},
|
|
1084
1420
|
onClick: () => onChange(option.value),
|
|
1085
1421
|
className: "dialkit-segmented-button",
|
|
1086
1422
|
"data-active": String(isActive),
|
|
@@ -1093,11 +1429,14 @@ function SegmentedControl({
|
|
|
1093
1429
|
}
|
|
1094
1430
|
|
|
1095
1431
|
// src/components/Toggle.tsx
|
|
1096
|
-
var
|
|
1097
|
-
function Toggle({ label, checked, onChange }) {
|
|
1098
|
-
return /* @__PURE__ */ (0,
|
|
1099
|
-
/* @__PURE__ */ (0,
|
|
1100
|
-
|
|
1432
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1433
|
+
function Toggle({ label, checked, onChange, shortcut, shortcutActive }) {
|
|
1434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dialkit-labeled-control", children: [
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "dialkit-labeled-control-label", children: [
|
|
1436
|
+
label,
|
|
1437
|
+
shortcut && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `dialkit-shortcut-pill${shortcutActive ? " dialkit-shortcut-pill-active" : ""}`, children: formatToggleShortcut(shortcut) })
|
|
1438
|
+
] }),
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1101
1440
|
SegmentedControl,
|
|
1102
1441
|
{
|
|
1103
1442
|
options: [
|
|
@@ -1112,7 +1451,7 @@ function Toggle({ label, checked, onChange }) {
|
|
|
1112
1451
|
}
|
|
1113
1452
|
|
|
1114
1453
|
// src/components/SpringVisualization.tsx
|
|
1115
|
-
var
|
|
1454
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1116
1455
|
function generateSpringCurve(stiffness, damping, mass, duration) {
|
|
1117
1456
|
const points = [];
|
|
1118
1457
|
const steps = 100;
|
|
@@ -1167,13 +1506,13 @@ function SpringVisualization({ spring, isSimpleMode }) {
|
|
|
1167
1506
|
const x = width / 4 * i;
|
|
1168
1507
|
const y = height / 4 * i;
|
|
1169
1508
|
gridLines.push(
|
|
1170
|
-
/* @__PURE__ */ (0,
|
|
1171
|
-
/* @__PURE__ */ (0,
|
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: x, y1: 0, x2: x, y2: height, stroke: "rgba(255, 255, 255, 0.08)", strokeWidth: "1" }, `v-${i}`),
|
|
1510
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: 0, y1: y, x2: width, y2: y, stroke: "rgba(255, 255, 255, 0.08)", strokeWidth: "1" }, `h-${i}`)
|
|
1172
1511
|
);
|
|
1173
1512
|
}
|
|
1174
|
-
return /* @__PURE__ */ (0,
|
|
1513
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { viewBox: `0 0 ${width} ${height}`, className: "dialkit-spring-viz", children: [
|
|
1175
1514
|
gridLines,
|
|
1176
|
-
/* @__PURE__ */ (0,
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1177
1516
|
"line",
|
|
1178
1517
|
{
|
|
1179
1518
|
x1: 0,
|
|
@@ -1185,7 +1524,7 @@ function SpringVisualization({ spring, isSimpleMode }) {
|
|
|
1185
1524
|
strokeDasharray: "4,4"
|
|
1186
1525
|
}
|
|
1187
1526
|
),
|
|
1188
|
-
/* @__PURE__ */ (0,
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1189
1528
|
"path",
|
|
1190
1529
|
{
|
|
1191
1530
|
d: pathData,
|
|
@@ -1201,7 +1540,7 @@ function SpringVisualization({ spring, isSimpleMode }) {
|
|
|
1201
1540
|
|
|
1202
1541
|
// src/components/SpringControl.tsx
|
|
1203
1542
|
var import_react8 = require("react");
|
|
1204
|
-
var
|
|
1543
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1205
1544
|
function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
1206
1545
|
const mode = (0, import_react8.useSyncExternalStore)(
|
|
1207
1546
|
(cb) => DialStore.subscribe(panelId, cb),
|
|
@@ -1209,25 +1548,21 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1209
1548
|
() => DialStore.getSpringMode(panelId, path)
|
|
1210
1549
|
);
|
|
1211
1550
|
const isSimpleMode = mode === "simple";
|
|
1551
|
+
const cache = (0, import_react8.useRef)({
|
|
1552
|
+
simple: spring.visualDuration !== void 0 ? spring : { type: "spring", visualDuration: 0.3, bounce: 0.2 },
|
|
1553
|
+
advanced: spring.stiffness !== void 0 ? spring : { type: "spring", stiffness: 200, damping: 25, mass: 1 }
|
|
1554
|
+
});
|
|
1555
|
+
if (isSimpleMode) {
|
|
1556
|
+
cache.current.simple = spring;
|
|
1557
|
+
} else {
|
|
1558
|
+
cache.current.advanced = spring;
|
|
1559
|
+
}
|
|
1212
1560
|
const handleModeChange = (newMode) => {
|
|
1213
1561
|
DialStore.updateSpringMode(panelId, path, newMode);
|
|
1214
1562
|
if (newMode === "simple") {
|
|
1215
|
-
|
|
1216
|
-
onChange({
|
|
1217
|
-
...rest,
|
|
1218
|
-
type: "spring",
|
|
1219
|
-
visualDuration: spring.visualDuration ?? 0.3,
|
|
1220
|
-
bounce: spring.bounce ?? 0.2
|
|
1221
|
-
});
|
|
1563
|
+
onChange(cache.current.simple);
|
|
1222
1564
|
} else {
|
|
1223
|
-
|
|
1224
|
-
onChange({
|
|
1225
|
-
...rest,
|
|
1226
|
-
type: "spring",
|
|
1227
|
-
stiffness: spring.stiffness ?? 200,
|
|
1228
|
-
damping: spring.damping ?? 25,
|
|
1229
|
-
mass: spring.mass ?? 1
|
|
1230
|
-
});
|
|
1565
|
+
onChange(cache.current.advanced);
|
|
1231
1566
|
}
|
|
1232
1567
|
};
|
|
1233
1568
|
const handleUpdate = (key, value) => {
|
|
@@ -1239,11 +1574,11 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1239
1574
|
onChange({ ...rest, [key]: value });
|
|
1240
1575
|
}
|
|
1241
1576
|
};
|
|
1242
|
-
return /* @__PURE__ */ (0,
|
|
1243
|
-
/* @__PURE__ */ (0,
|
|
1244
|
-
/* @__PURE__ */ (0,
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1246
|
-
/* @__PURE__ */ (0,
|
|
1577
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Folder, { title: label, defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
1578
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SpringVisualization, { spring, isSimpleMode }),
|
|
1579
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "dialkit-labeled-control", children: [
|
|
1580
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dialkit-labeled-control-label", children: "Type" }),
|
|
1581
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1247
1582
|
SegmentedControl,
|
|
1248
1583
|
{
|
|
1249
1584
|
options: [
|
|
@@ -1255,8 +1590,8 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1255
1590
|
}
|
|
1256
1591
|
)
|
|
1257
1592
|
] }),
|
|
1258
|
-
isSimpleMode ? /* @__PURE__ */ (0,
|
|
1259
|
-
/* @__PURE__ */ (0,
|
|
1593
|
+
isSimpleMode ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1594
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1260
1595
|
Slider,
|
|
1261
1596
|
{
|
|
1262
1597
|
label: "Duration",
|
|
@@ -1268,7 +1603,7 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1268
1603
|
unit: "s"
|
|
1269
1604
|
}
|
|
1270
1605
|
),
|
|
1271
|
-
/* @__PURE__ */ (0,
|
|
1606
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1272
1607
|
Slider,
|
|
1273
1608
|
{
|
|
1274
1609
|
label: "Bounce",
|
|
@@ -1279,8 +1614,8 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1279
1614
|
step: 0.05
|
|
1280
1615
|
}
|
|
1281
1616
|
)
|
|
1282
|
-
] }) : /* @__PURE__ */ (0,
|
|
1283
|
-
/* @__PURE__ */ (0,
|
|
1617
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1618
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1284
1619
|
Slider,
|
|
1285
1620
|
{
|
|
1286
1621
|
label: "Stiffness",
|
|
@@ -1291,7 +1626,7 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1291
1626
|
step: 10
|
|
1292
1627
|
}
|
|
1293
1628
|
),
|
|
1294
|
-
/* @__PURE__ */ (0,
|
|
1629
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1295
1630
|
Slider,
|
|
1296
1631
|
{
|
|
1297
1632
|
label: "Damping",
|
|
@@ -1302,7 +1637,7 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1302
1637
|
step: 1
|
|
1303
1638
|
}
|
|
1304
1639
|
),
|
|
1305
|
-
/* @__PURE__ */ (0,
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1306
1641
|
Slider,
|
|
1307
1642
|
{
|
|
1308
1643
|
label: "Mass",
|
|
@@ -1318,7 +1653,7 @@ function SpringControl({ panelId, path, label, spring, onChange }) {
|
|
|
1318
1653
|
}
|
|
1319
1654
|
|
|
1320
1655
|
// src/components/EasingVisualization.tsx
|
|
1321
|
-
var
|
|
1656
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1322
1657
|
function EasingVisualization({ easing }) {
|
|
1323
1658
|
const ease = easing.ease;
|
|
1324
1659
|
const s = 200;
|
|
@@ -1334,14 +1669,14 @@ function EasingVisualization({ easing }) {
|
|
|
1334
1669
|
const p1 = toSvg(ease[0], ease[1]);
|
|
1335
1670
|
const p2 = toSvg(ease[2], ease[3]);
|
|
1336
1671
|
const curvePath = `M ${start.x} ${start.y} C ${p1.x} ${p1.y}, ${p2.x} ${p2.y}, ${end.x} ${end.y}`;
|
|
1337
|
-
return /* @__PURE__ */ (0,
|
|
1672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1338
1673
|
"svg",
|
|
1339
1674
|
{
|
|
1340
1675
|
viewBox: `0 0 ${s} ${s}`,
|
|
1341
1676
|
preserveAspectRatio: "xMidYMid slice",
|
|
1342
1677
|
className: "dialkit-spring-viz dialkit-easing-viz",
|
|
1343
1678
|
children: [
|
|
1344
|
-
/* @__PURE__ */ (0,
|
|
1679
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1345
1680
|
"line",
|
|
1346
1681
|
{
|
|
1347
1682
|
x1: start.x,
|
|
@@ -1353,7 +1688,7 @@ function EasingVisualization({ easing }) {
|
|
|
1353
1688
|
strokeDasharray: "4,4"
|
|
1354
1689
|
}
|
|
1355
1690
|
),
|
|
1356
|
-
/* @__PURE__ */ (0,
|
|
1691
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: curvePath, fill: "none", stroke: "rgba(255, 255, 255, 0.6)", strokeWidth: "2", strokeLinecap: "round" })
|
|
1357
1692
|
]
|
|
1358
1693
|
}
|
|
1359
1694
|
);
|
|
@@ -1361,7 +1696,7 @@ function EasingVisualization({ easing }) {
|
|
|
1361
1696
|
|
|
1362
1697
|
// src/components/TransitionControl.tsx
|
|
1363
1698
|
var import_react9 = require("react");
|
|
1364
|
-
var
|
|
1699
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1365
1700
|
function TransitionControl({ panelId, path, label, value, onChange }) {
|
|
1366
1701
|
const mode = (0, import_react9.useSyncExternalStore)(
|
|
1367
1702
|
(cb) => DialStore.subscribe(panelId, cb),
|
|
@@ -1370,26 +1705,28 @@ function TransitionControl({ panelId, path, label, value, onChange }) {
|
|
|
1370
1705
|
);
|
|
1371
1706
|
const isEasing = mode === "easing";
|
|
1372
1707
|
const isSimpleSpring = mode === "simple";
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1708
|
+
const cache = (0, import_react9.useRef)({
|
|
1709
|
+
easing: value.type === "easing" ? value : { type: "easing", duration: 0.3, ease: [1, -0.4, 0.5, 1] },
|
|
1710
|
+
simple: value.type === "spring" && value.visualDuration !== void 0 ? value : { type: "spring", visualDuration: 0.3, bounce: 0.2 },
|
|
1711
|
+
advanced: value.type === "spring" && value.stiffness !== void 0 ? value : { type: "spring", stiffness: 200, damping: 25, mass: 1 }
|
|
1712
|
+
});
|
|
1713
|
+
if (isEasing && value.type === "easing") {
|
|
1714
|
+
cache.current.easing = value;
|
|
1715
|
+
} else if (isSimpleSpring && value.type === "spring") {
|
|
1716
|
+
cache.current.simple = value;
|
|
1717
|
+
} else if (mode === "advanced" && value.type === "spring") {
|
|
1718
|
+
cache.current.advanced = value;
|
|
1719
|
+
}
|
|
1720
|
+
const spring = value.type === "spring" ? value : cache.current.simple;
|
|
1721
|
+
const easing = value.type === "easing" ? value : cache.current.easing;
|
|
1375
1722
|
const handleModeChange = (newMode) => {
|
|
1376
1723
|
DialStore.updateTransitionMode(panelId, path, newMode);
|
|
1377
1724
|
if (newMode === "easing") {
|
|
1378
|
-
|
|
1379
|
-
onChange({ type: "easing", duration, ease: easing.ease });
|
|
1725
|
+
onChange(cache.current.easing);
|
|
1380
1726
|
} else if (newMode === "simple") {
|
|
1381
|
-
onChange(
|
|
1382
|
-
type: "spring",
|
|
1383
|
-
visualDuration: spring.visualDuration ?? (value.type === "easing" ? value.duration : 0.3),
|
|
1384
|
-
bounce: spring.bounce ?? 0.2
|
|
1385
|
-
});
|
|
1727
|
+
onChange(cache.current.simple);
|
|
1386
1728
|
} else {
|
|
1387
|
-
onChange(
|
|
1388
|
-
type: "spring",
|
|
1389
|
-
stiffness: spring.stiffness ?? 200,
|
|
1390
|
-
damping: spring.damping ?? 25,
|
|
1391
|
-
mass: spring.mass ?? 1
|
|
1392
|
-
});
|
|
1729
|
+
onChange(cache.current.advanced);
|
|
1393
1730
|
}
|
|
1394
1731
|
};
|
|
1395
1732
|
const handleSpringUpdate = (key, val) => {
|
|
@@ -1406,11 +1743,11 @@ function TransitionControl({ panelId, path, label, value, onChange }) {
|
|
|
1406
1743
|
newEase[index] = val;
|
|
1407
1744
|
onChange({ ...easing, ease: newEase });
|
|
1408
1745
|
};
|
|
1409
|
-
return /* @__PURE__ */ (0,
|
|
1410
|
-
isEasing ? /* @__PURE__ */ (0,
|
|
1411
|
-
/* @__PURE__ */ (0,
|
|
1412
|
-
/* @__PURE__ */ (0,
|
|
1413
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Folder, { title: label, defaultOpen: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
|
|
1747
|
+
isEasing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EasingVisualization, { easing }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SpringVisualization, { spring, isSimpleMode: isSimpleSpring }),
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dialkit-labeled-control", children: [
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "dialkit-labeled-control-label", children: "Type" }),
|
|
1750
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1414
1751
|
SegmentedControl,
|
|
1415
1752
|
{
|
|
1416
1753
|
options: [
|
|
@@ -1423,20 +1760,20 @@ function TransitionControl({ panelId, path, label, value, onChange }) {
|
|
|
1423
1760
|
}
|
|
1424
1761
|
)
|
|
1425
1762
|
] }),
|
|
1426
|
-
isEasing ? /* @__PURE__ */ (0,
|
|
1427
|
-
/* @__PURE__ */ (0,
|
|
1428
|
-
/* @__PURE__ */ (0,
|
|
1429
|
-
/* @__PURE__ */ (0,
|
|
1430
|
-
/* @__PURE__ */ (0,
|
|
1431
|
-
/* @__PURE__ */ (0,
|
|
1432
|
-
/* @__PURE__ */ (0,
|
|
1433
|
-
] }) : isSimpleSpring ? /* @__PURE__ */ (0,
|
|
1434
|
-
/* @__PURE__ */ (0,
|
|
1435
|
-
/* @__PURE__ */ (0,
|
|
1436
|
-
] }) : /* @__PURE__ */ (0,
|
|
1437
|
-
/* @__PURE__ */ (0,
|
|
1438
|
-
/* @__PURE__ */ (0,
|
|
1439
|
-
/* @__PURE__ */ (0,
|
|
1763
|
+
isEasing ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1764
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "x1", value: easing.ease[0], onChange: (v) => updateEase(0, v), min: 0, max: 1, step: 0.01 }),
|
|
1765
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "y1", value: easing.ease[1], onChange: (v) => updateEase(1, v), min: -1, max: 2, step: 0.01 }),
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "x2", value: easing.ease[2], onChange: (v) => updateEase(2, v), min: 0, max: 1, step: 0.01 }),
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "y2", value: easing.ease[3], onChange: (v) => updateEase(3, v), min: -1, max: 2, step: 0.01 }),
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "Duration", value: easing.duration, onChange: (v) => onChange({ ...easing, duration: v }), min: 0.1, max: 2, step: 0.05, unit: "s" }),
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EaseTextInput, { ease: easing.ease, onChange: (newEase) => onChange({ ...easing, ease: newEase }) })
|
|
1770
|
+
] }) : isSimpleSpring ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1771
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "Duration", value: spring.visualDuration ?? 0.3, onChange: (v) => handleSpringUpdate("visualDuration", v), min: 0.1, max: 1, step: 0.05, unit: "s" }),
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "Bounce", value: spring.bounce ?? 0.2, onChange: (v) => handleSpringUpdate("bounce", v), min: 0, max: 1, step: 0.05 })
|
|
1773
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "Stiffness", value: spring.stiffness ?? 400, onChange: (v) => handleSpringUpdate("stiffness", v), min: 1, max: 1e3, step: 10 }),
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "Damping", value: spring.damping ?? 17, onChange: (v) => handleSpringUpdate("damping", v), min: 1, max: 100, step: 1 }),
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Slider, { label: "Mass", value: spring.mass ?? 1, onChange: (v) => handleSpringUpdate("mass", v), min: 0.1, max: 10, step: 0.1 })
|
|
1440
1777
|
] })
|
|
1441
1778
|
] }) });
|
|
1442
1779
|
}
|
|
@@ -1467,9 +1804,9 @@ function EaseTextInput({ ease, onChange }) {
|
|
|
1467
1804
|
e.target.blur();
|
|
1468
1805
|
}
|
|
1469
1806
|
};
|
|
1470
|
-
return /* @__PURE__ */ (0,
|
|
1471
|
-
/* @__PURE__ */ (0,
|
|
1472
|
-
/* @__PURE__ */ (0,
|
|
1807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dialkit-labeled-control", children: [
|
|
1808
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "dialkit-labeled-control-label", children: "Ease" }),
|
|
1809
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1473
1810
|
"input",
|
|
1474
1811
|
{
|
|
1475
1812
|
type: "text",
|
|
@@ -1486,11 +1823,11 @@ function EaseTextInput({ ease, onChange }) {
|
|
|
1486
1823
|
}
|
|
1487
1824
|
|
|
1488
1825
|
// src/components/TextControl.tsx
|
|
1489
|
-
var
|
|
1826
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1490
1827
|
function TextControl({ label, value, onChange, placeholder }) {
|
|
1491
|
-
return /* @__PURE__ */ (0,
|
|
1492
|
-
/* @__PURE__ */ (0,
|
|
1493
|
-
/* @__PURE__ */ (0,
|
|
1828
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dialkit-text-control", children: [
|
|
1829
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "dialkit-text-label", children: label }),
|
|
1830
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1494
1831
|
"input",
|
|
1495
1832
|
{
|
|
1496
1833
|
type: "text",
|
|
@@ -1507,7 +1844,7 @@ function TextControl({ label, value, onChange, placeholder }) {
|
|
|
1507
1844
|
var import_react10 = require("react");
|
|
1508
1845
|
var import_react_dom = require("react-dom");
|
|
1509
1846
|
var import_react11 = require("motion/react");
|
|
1510
|
-
var
|
|
1847
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1511
1848
|
function toTitleCase(s) {
|
|
1512
1849
|
return s.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1513
1850
|
}
|
|
@@ -1557,8 +1894,8 @@ function SelectControl({ label, value, options, onChange }) {
|
|
|
1557
1894
|
document.addEventListener("mousedown", handleClick);
|
|
1558
1895
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
1559
1896
|
}, [isOpen]);
|
|
1560
|
-
return /* @__PURE__ */ (0,
|
|
1561
|
-
/* @__PURE__ */ (0,
|
|
1897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dialkit-select-row", children: [
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1562
1899
|
"button",
|
|
1563
1900
|
{
|
|
1564
1901
|
ref: triggerRef,
|
|
@@ -1566,10 +1903,10 @@ function SelectControl({ label, value, options, onChange }) {
|
|
|
1566
1903
|
onClick: () => setIsOpen(!isOpen),
|
|
1567
1904
|
"data-open": String(isOpen),
|
|
1568
1905
|
children: [
|
|
1569
|
-
/* @__PURE__ */ (0,
|
|
1570
|
-
/* @__PURE__ */ (0,
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1572
|
-
/* @__PURE__ */ (0,
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dialkit-select-label", children: label }),
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "dialkit-select-right", children: [
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dialkit-select-value", children: selectedOption?.label ?? value }),
|
|
1909
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1573
1910
|
import_react11.motion.svg,
|
|
1574
1911
|
{
|
|
1575
1912
|
className: "dialkit-select-chevron",
|
|
@@ -1581,7 +1918,7 @@ function SelectControl({ label, value, options, onChange }) {
|
|
|
1581
1918
|
strokeLinejoin: "round",
|
|
1582
1919
|
animate: { rotate: isOpen ? 180 : 0 },
|
|
1583
1920
|
transition: { type: "spring", visualDuration: 0.2, bounce: 0.15 },
|
|
1584
|
-
children: /* @__PURE__ */ (0,
|
|
1921
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: ICON_CHEVRON })
|
|
1585
1922
|
}
|
|
1586
1923
|
)
|
|
1587
1924
|
] })
|
|
@@ -1589,7 +1926,7 @@ function SelectControl({ label, value, options, onChange }) {
|
|
|
1589
1926
|
}
|
|
1590
1927
|
),
|
|
1591
1928
|
portalTarget && (0, import_react_dom.createPortal)(
|
|
1592
|
-
/* @__PURE__ */ (0,
|
|
1929
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react11.AnimatePresence, { children: isOpen && pos && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1593
1930
|
import_react11.motion.div,
|
|
1594
1931
|
{
|
|
1595
1932
|
ref: dropdownRef,
|
|
@@ -1604,7 +1941,7 @@ function SelectControl({ label, value, options, onChange }) {
|
|
|
1604
1941
|
width: pos.width,
|
|
1605
1942
|
...pos.above ? { bottom: window.innerHeight - pos.top, transformOrigin: "bottom" } : { top: pos.top, transformOrigin: "top" }
|
|
1606
1943
|
},
|
|
1607
|
-
children: normalized.map((option) => /* @__PURE__ */ (0,
|
|
1944
|
+
children: normalized.map((option) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1608
1945
|
"button",
|
|
1609
1946
|
{
|
|
1610
1947
|
className: "dialkit-select-option",
|
|
@@ -1626,7 +1963,7 @@ function SelectControl({ label, value, options, onChange }) {
|
|
|
1626
1963
|
|
|
1627
1964
|
// src/components/ColorControl.tsx
|
|
1628
1965
|
var import_react12 = require("react");
|
|
1629
|
-
var
|
|
1966
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1630
1967
|
var HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
|
|
1631
1968
|
function ColorControl({ label, value, onChange }) {
|
|
1632
1969
|
const [isEditing, setIsEditing] = (0, import_react12.useState)(false);
|
|
@@ -1653,10 +1990,10 @@ function ColorControl({ label, value, onChange }) {
|
|
|
1653
1990
|
setEditValue(value);
|
|
1654
1991
|
}
|
|
1655
1992
|
}
|
|
1656
|
-
return /* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
1659
|
-
isEditing ? /* @__PURE__ */ (0,
|
|
1993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "dialkit-color-control", children: [
|
|
1994
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "dialkit-color-label", children: label }),
|
|
1995
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "dialkit-color-inputs", children: [
|
|
1996
|
+
isEditing ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1660
1997
|
"input",
|
|
1661
1998
|
{
|
|
1662
1999
|
type: "text",
|
|
@@ -1667,7 +2004,7 @@ function ColorControl({ label, value, onChange }) {
|
|
|
1667
2004
|
onKeyDown: handleKeyDown,
|
|
1668
2005
|
autoFocus: true
|
|
1669
2006
|
}
|
|
1670
|
-
) : /* @__PURE__ */ (0,
|
|
2007
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1671
2008
|
"span",
|
|
1672
2009
|
{
|
|
1673
2010
|
className: "dialkit-color-hex",
|
|
@@ -1675,7 +2012,7 @@ function ColorControl({ label, value, onChange }) {
|
|
|
1675
2012
|
children: (value ?? "").toUpperCase()
|
|
1676
2013
|
}
|
|
1677
2014
|
),
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
2015
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1679
2016
|
"button",
|
|
1680
2017
|
{
|
|
1681
2018
|
className: "dialkit-color-swatch",
|
|
@@ -1684,7 +2021,7 @@ function ColorControl({ label, value, onChange }) {
|
|
|
1684
2021
|
title: "Pick color"
|
|
1685
2022
|
}
|
|
1686
2023
|
),
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
2024
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1688
2025
|
"input",
|
|
1689
2026
|
{
|
|
1690
2027
|
ref: colorInputRef,
|
|
@@ -1706,7 +2043,7 @@ function expandShorthandHex(hex) {
|
|
|
1706
2043
|
var import_react13 = require("react");
|
|
1707
2044
|
var import_react_dom2 = require("react-dom");
|
|
1708
2045
|
var import_react14 = require("motion/react");
|
|
1709
|
-
var
|
|
2046
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1710
2047
|
function PresetManager({ panelId, presets, activePresetId, onAdd }) {
|
|
1711
2048
|
const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
|
|
1712
2049
|
const triggerRef = (0, import_react13.useRef)(null);
|
|
@@ -1749,8 +2086,8 @@ function PresetManager({ panelId, presets, activePresetId, onAdd }) {
|
|
|
1749
2086
|
e.stopPropagation();
|
|
1750
2087
|
DialStore.deletePreset(panelId, presetId);
|
|
1751
2088
|
};
|
|
1752
|
-
return /* @__PURE__ */ (0,
|
|
1753
|
-
/* @__PURE__ */ (0,
|
|
2089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "dialkit-preset-manager", children: [
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1754
2091
|
"button",
|
|
1755
2092
|
{
|
|
1756
2093
|
ref: triggerRef,
|
|
@@ -1760,8 +2097,8 @@ function PresetManager({ panelId, presets, activePresetId, onAdd }) {
|
|
|
1760
2097
|
"data-has-preset": String(!!activePreset),
|
|
1761
2098
|
"data-disabled": String(!hasPresets),
|
|
1762
2099
|
children: [
|
|
1763
|
-
/* @__PURE__ */ (0,
|
|
1764
|
-
/* @__PURE__ */ (0,
|
|
2100
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dialkit-preset-label", children: activePreset ? activePreset.name : "Version 1" }),
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1765
2102
|
import_react14.motion.svg,
|
|
1766
2103
|
{
|
|
1767
2104
|
className: "dialkit-select-chevron",
|
|
@@ -1773,14 +2110,14 @@ function PresetManager({ panelId, presets, activePresetId, onAdd }) {
|
|
|
1773
2110
|
strokeLinejoin: "round",
|
|
1774
2111
|
animate: { rotate: isOpen ? 180 : 0, opacity: hasPresets ? 0.6 : 0.25 },
|
|
1775
2112
|
transition: { type: "spring", visualDuration: 0.2, bounce: 0.15 },
|
|
1776
|
-
children: /* @__PURE__ */ (0,
|
|
2113
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: ICON_CHEVRON })
|
|
1777
2114
|
}
|
|
1778
2115
|
)
|
|
1779
2116
|
]
|
|
1780
2117
|
}
|
|
1781
2118
|
),
|
|
1782
2119
|
(0, import_react_dom2.createPortal)(
|
|
1783
|
-
/* @__PURE__ */ (0,
|
|
2120
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react14.AnimatePresence, { children: isOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1784
2121
|
import_react14.motion.div,
|
|
1785
2122
|
{
|
|
1786
2123
|
ref: dropdownRef,
|
|
@@ -1791,36 +2128,30 @@ function PresetManager({ panelId, presets, activePresetId, onAdd }) {
|
|
|
1791
2128
|
exit: { opacity: 0, y: 4, scale: 0.97, pointerEvents: "none" },
|
|
1792
2129
|
transition: { type: "spring", visualDuration: 0.15, bounce: 0 },
|
|
1793
2130
|
children: [
|
|
1794
|
-
/* @__PURE__ */ (0,
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1795
2132
|
"div",
|
|
1796
2133
|
{
|
|
1797
2134
|
className: "dialkit-preset-item",
|
|
1798
2135
|
"data-active": String(!activePresetId),
|
|
1799
2136
|
onClick: () => handleSelect(null),
|
|
1800
|
-
children: /* @__PURE__ */ (0,
|
|
2137
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dialkit-preset-name", children: "Version 1" })
|
|
1801
2138
|
}
|
|
1802
2139
|
),
|
|
1803
|
-
presets.map((preset) => /* @__PURE__ */ (0,
|
|
2140
|
+
presets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1804
2141
|
"div",
|
|
1805
2142
|
{
|
|
1806
2143
|
className: "dialkit-preset-item",
|
|
1807
2144
|
"data-active": String(preset.id === activePresetId),
|
|
1808
2145
|
onClick: () => handleSelect(preset.id),
|
|
1809
2146
|
children: [
|
|
1810
|
-
/* @__PURE__ */ (0,
|
|
1811
|
-
/* @__PURE__ */ (0,
|
|
2147
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "dialkit-preset-name", children: preset.name }),
|
|
2148
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1812
2149
|
"button",
|
|
1813
2150
|
{
|
|
1814
2151
|
className: "dialkit-preset-delete",
|
|
1815
2152
|
onClick: (e) => handleDelete(e, preset.id),
|
|
1816
2153
|
title: "Delete preset",
|
|
1817
|
-
children: /* @__PURE__ */ (0,
|
|
1818
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M5 6.5L5.80734 18.2064C5.91582 19.7794 7.22348 21 8.80023 21H15.1998C16.7765 21 18.0842 19.7794 18.1927 18.2064L19 6.5" }),
|
|
1819
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M10 11V16" }),
|
|
1820
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 11V16" }),
|
|
1821
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M3.5 6H20.5" }),
|
|
1822
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M8.07092 5.74621C8.42348 3.89745 10.0485 2.5 12 2.5C13.9515 2.5 15.5765 3.89745 15.9291 5.74621" })
|
|
1823
|
-
] })
|
|
2154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: ICON_TRASH.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d }, i)) })
|
|
1824
2155
|
}
|
|
1825
2156
|
)
|
|
1826
2157
|
]
|
|
@@ -1836,10 +2167,12 @@ function PresetManager({ panelId, presets, activePresetId, onAdd }) {
|
|
|
1836
2167
|
}
|
|
1837
2168
|
|
|
1838
2169
|
// src/components/Panel.tsx
|
|
1839
|
-
var
|
|
2170
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1840
2171
|
function Panel({ panel, defaultOpen = true, inline = false }) {
|
|
1841
2172
|
const [copied, setCopied] = (0, import_react15.useState)(false);
|
|
1842
2173
|
const [isPanelOpen, setIsPanelOpen] = (0, import_react15.useState)(defaultOpen);
|
|
2174
|
+
const shortcutCtx = (0, import_react15.useContext)(ShortcutContext);
|
|
2175
|
+
const hasShortcuts = Object.keys(panel.shortcuts).length > 0;
|
|
1843
2176
|
const values = (0, import_react15.useSyncExternalStore)(
|
|
1844
2177
|
(cb) => DialStore.subscribe(panel.id, cb),
|
|
1845
2178
|
() => DialStore.getValues(panel.id),
|
|
@@ -1868,7 +2201,7 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1868
2201
|
const value = values[control.path];
|
|
1869
2202
|
switch (control.type) {
|
|
1870
2203
|
case "slider":
|
|
1871
|
-
return /* @__PURE__ */ (0,
|
|
2204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1872
2205
|
Slider,
|
|
1873
2206
|
{
|
|
1874
2207
|
label: control.label,
|
|
@@ -1876,22 +2209,26 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1876
2209
|
onChange: (v) => DialStore.updateValue(panel.id, control.path, v),
|
|
1877
2210
|
min: control.min,
|
|
1878
2211
|
max: control.max,
|
|
1879
|
-
step: control.step
|
|
2212
|
+
step: control.step,
|
|
2213
|
+
shortcut: control.shortcut,
|
|
2214
|
+
shortcutActive: shortcutCtx.activePanelId === panel.id && shortcutCtx.activePath === control.path
|
|
1880
2215
|
},
|
|
1881
2216
|
control.path
|
|
1882
2217
|
);
|
|
1883
2218
|
case "toggle":
|
|
1884
|
-
return /* @__PURE__ */ (0,
|
|
2219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1885
2220
|
Toggle,
|
|
1886
2221
|
{
|
|
1887
2222
|
label: control.label,
|
|
1888
2223
|
checked: value,
|
|
1889
|
-
onChange: (v) => DialStore.updateValue(panel.id, control.path, v)
|
|
2224
|
+
onChange: (v) => DialStore.updateValue(panel.id, control.path, v),
|
|
2225
|
+
shortcut: control.shortcut,
|
|
2226
|
+
shortcutActive: shortcutCtx.activePanelId === panel.id && shortcutCtx.activePath === control.path
|
|
1890
2227
|
},
|
|
1891
2228
|
control.path
|
|
1892
2229
|
);
|
|
1893
2230
|
case "spring":
|
|
1894
|
-
return /* @__PURE__ */ (0,
|
|
2231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1895
2232
|
SpringControl,
|
|
1896
2233
|
{
|
|
1897
2234
|
panelId: panel.id,
|
|
@@ -1903,7 +2240,7 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1903
2240
|
control.path
|
|
1904
2241
|
);
|
|
1905
2242
|
case "transition":
|
|
1906
|
-
return /* @__PURE__ */ (0,
|
|
2243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1907
2244
|
TransitionControl,
|
|
1908
2245
|
{
|
|
1909
2246
|
panelId: panel.id,
|
|
@@ -1915,9 +2252,9 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1915
2252
|
control.path
|
|
1916
2253
|
);
|
|
1917
2254
|
case "folder":
|
|
1918
|
-
return /* @__PURE__ */ (0,
|
|
2255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Folder, { title: control.label, defaultOpen: control.defaultOpen ?? true, children: control.children?.map(renderControl) }, control.path);
|
|
1919
2256
|
case "text":
|
|
1920
|
-
return /* @__PURE__ */ (0,
|
|
2257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1921
2258
|
TextControl,
|
|
1922
2259
|
{
|
|
1923
2260
|
label: control.label,
|
|
@@ -1928,7 +2265,7 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1928
2265
|
control.path
|
|
1929
2266
|
);
|
|
1930
2267
|
case "select":
|
|
1931
|
-
return /* @__PURE__ */ (0,
|
|
2268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1932
2269
|
SelectControl,
|
|
1933
2270
|
{
|
|
1934
2271
|
label: control.label,
|
|
@@ -1939,7 +2276,7 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1939
2276
|
control.path
|
|
1940
2277
|
);
|
|
1941
2278
|
case "color":
|
|
1942
|
-
return /* @__PURE__ */ (0,
|
|
2279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1943
2280
|
ColorControl,
|
|
1944
2281
|
{
|
|
1945
2282
|
label: control.label,
|
|
@@ -1949,7 +2286,7 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1949
2286
|
control.path
|
|
1950
2287
|
);
|
|
1951
2288
|
case "action":
|
|
1952
|
-
return /* @__PURE__ */ (0,
|
|
2289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1953
2290
|
"button",
|
|
1954
2291
|
{
|
|
1955
2292
|
className: "dialkit-button",
|
|
@@ -1966,8 +2303,8 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1966
2303
|
return panel.controls.map(renderControl);
|
|
1967
2304
|
};
|
|
1968
2305
|
const iconTransition = { type: "spring", visualDuration: 0.4, bounce: 0.1 };
|
|
1969
|
-
const toolbar = /* @__PURE__ */ (0,
|
|
1970
|
-
/* @__PURE__ */ (0,
|
|
2306
|
+
const toolbar = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1971
2308
|
import_react16.motion.button,
|
|
1972
2309
|
{
|
|
1973
2310
|
className: "dialkit-toolbar-add",
|
|
@@ -1975,16 +2312,10 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1975
2312
|
title: "Add preset",
|
|
1976
2313
|
whileTap: { scale: 0.9 },
|
|
1977
2314
|
transition: { type: "spring", visualDuration: 0.15, bounce: 0.3 },
|
|
1978
|
-
children: /* @__PURE__ */ (0,
|
|
1979
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 6H20" }),
|
|
1980
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 12H10" }),
|
|
1981
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M15 15L21 15" }),
|
|
1982
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M18 12V18" }),
|
|
1983
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 18H10" })
|
|
1984
|
-
] })
|
|
2315
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: ICON_ADD_PRESET.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d }, i)) })
|
|
1985
2316
|
}
|
|
1986
2317
|
),
|
|
1987
|
-
/* @__PURE__ */ (0,
|
|
2318
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1988
2319
|
PresetManager,
|
|
1989
2320
|
{
|
|
1990
2321
|
panelId: panel.id,
|
|
@@ -1993,64 +2324,71 @@ Apply these values as the new defaults in the useDialKit call.`;
|
|
|
1993
2324
|
onAdd: handleAddPreset
|
|
1994
2325
|
}
|
|
1995
2326
|
),
|
|
1996
|
-
/* @__PURE__ */ (0,
|
|
2327
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1997
2328
|
import_react16.motion.button,
|
|
1998
2329
|
{
|
|
1999
|
-
className: "dialkit-toolbar-
|
|
2330
|
+
className: "dialkit-toolbar-add",
|
|
2000
2331
|
onClick: handleCopy,
|
|
2001
2332
|
title: "Copy parameters",
|
|
2002
|
-
whileTap: { scale: 0.
|
|
2333
|
+
whileTap: { scale: 0.9 },
|
|
2003
2334
|
transition: { type: "spring", visualDuration: 0.15, bounce: 0.3 },
|
|
2004
|
-
children:
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
) }) }),
|
|
2040
|
-
"Copy"
|
|
2041
|
-
]
|
|
2335
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { position: "relative", width: 16, height: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react16.AnimatePresence, { initial: false, mode: "wait", children: copied ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2336
|
+
import_react16.motion.svg,
|
|
2337
|
+
{
|
|
2338
|
+
viewBox: "0 0 24 24",
|
|
2339
|
+
fill: "none",
|
|
2340
|
+
stroke: "currentColor",
|
|
2341
|
+
strokeWidth: "2",
|
|
2342
|
+
strokeLinecap: "round",
|
|
2343
|
+
strokeLinejoin: "round",
|
|
2344
|
+
style: { position: "absolute", inset: 0, width: 16, height: 16, color: "var(--dial-text-label)" },
|
|
2345
|
+
initial: { scale: 0.8, opacity: 0 },
|
|
2346
|
+
animate: { scale: 1, opacity: 1 },
|
|
2347
|
+
exit: { scale: 0.8, opacity: 0 },
|
|
2348
|
+
transition: { duration: 0.08 },
|
|
2349
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: ICON_CHECK })
|
|
2350
|
+
},
|
|
2351
|
+
"check"
|
|
2352
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2353
|
+
import_react16.motion.svg,
|
|
2354
|
+
{
|
|
2355
|
+
viewBox: "0 0 24 24",
|
|
2356
|
+
fill: "none",
|
|
2357
|
+
style: { position: "absolute", inset: 0, width: 16, height: 16, color: "var(--dial-text-label)" },
|
|
2358
|
+
initial: { scale: 0.8, opacity: 0 },
|
|
2359
|
+
animate: { scale: 1, opacity: 1 },
|
|
2360
|
+
exit: { scale: 0.8, opacity: 0 },
|
|
2361
|
+
transition: { duration: 0.08 },
|
|
2362
|
+
children: [
|
|
2363
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: ICON_CLIPBOARD.board, stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
|
|
2364
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: ICON_CLIPBOARD.sparkle, fill: "currentColor" }),
|
|
2365
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: ICON_CLIPBOARD.body, stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
2366
|
+
]
|
|
2367
|
+
},
|
|
2368
|
+
"clipboard"
|
|
2369
|
+
) }) })
|
|
2042
2370
|
}
|
|
2043
2371
|
)
|
|
2044
2372
|
] });
|
|
2045
|
-
return /* @__PURE__ */ (0,
|
|
2373
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "dialkit-panel-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Folder, { title: panel.name, defaultOpen, isRoot: true, inline, onOpenChange: setIsPanelOpen, toolbar, children: renderControls() }) });
|
|
2046
2374
|
}
|
|
2047
2375
|
|
|
2048
2376
|
// src/components/DialRoot.tsx
|
|
2049
|
-
var
|
|
2050
|
-
|
|
2377
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2378
|
+
var import_meta = {};
|
|
2379
|
+
var isDevDefault = typeof process !== "undefined" && process?.env?.NODE_ENV ? process.env.NODE_ENV !== "production" : typeof import_meta !== "undefined" && import_meta.env?.MODE ? import_meta.env.MODE !== "production" : true;
|
|
2380
|
+
function DialRoot({ position = "top-right", defaultOpen = true, mode = "popover", theme = "system", productionEnabled = isDevDefault }) {
|
|
2381
|
+
if (!productionEnabled) return null;
|
|
2051
2382
|
const [panels, setPanels] = (0, import_react17.useState)([]);
|
|
2052
2383
|
const [mounted, setMounted] = (0, import_react17.useState)(false);
|
|
2053
2384
|
const inline = mode === "inline";
|
|
2385
|
+
const panelRef = (0, import_react17.useRef)(null);
|
|
2386
|
+
const [dragOffset, setDragOffset] = (0, import_react17.useState)(null);
|
|
2387
|
+
const [activePosition, setActivePosition] = (0, import_react17.useState)(position);
|
|
2388
|
+
const lastDragOffset = (0, import_react17.useRef)(null);
|
|
2389
|
+
const draggingRef = (0, import_react17.useRef)(false);
|
|
2390
|
+
const dragStartRef = (0, import_react17.useRef)(null);
|
|
2391
|
+
const didDragRef = (0, import_react17.useRef)(false);
|
|
2054
2392
|
(0, import_react17.useEffect)(() => {
|
|
2055
2393
|
setMounted(true);
|
|
2056
2394
|
setPanels(DialStore.getPanels());
|
|
@@ -2059,13 +2397,95 @@ function DialRoot({ position = "top-right", defaultOpen = true, mode = "popover"
|
|
|
2059
2397
|
});
|
|
2060
2398
|
return unsubscribe;
|
|
2061
2399
|
}, []);
|
|
2400
|
+
(0, import_react17.useEffect)(() => {
|
|
2401
|
+
if (!panelRef.current || inline) return;
|
|
2402
|
+
const observer = new MutationObserver(() => {
|
|
2403
|
+
const inner = panelRef.current?.querySelector(".dialkit-panel-inner");
|
|
2404
|
+
if (!inner) return;
|
|
2405
|
+
const collapsed = inner.getAttribute("data-collapsed") === "true";
|
|
2406
|
+
if (!collapsed) {
|
|
2407
|
+
if (dragOffset) {
|
|
2408
|
+
lastDragOffset.current = dragOffset;
|
|
2409
|
+
const bubbleCenterX = dragOffset.x + 21;
|
|
2410
|
+
const midX = window.innerWidth / 2;
|
|
2411
|
+
setActivePosition(bubbleCenterX < midX ? "top-left" : "top-right");
|
|
2412
|
+
} else {
|
|
2413
|
+
setActivePosition(position);
|
|
2414
|
+
}
|
|
2415
|
+
setDragOffset(null);
|
|
2416
|
+
} else if (lastDragOffset.current) {
|
|
2417
|
+
setDragOffset(lastDragOffset.current);
|
|
2418
|
+
}
|
|
2419
|
+
});
|
|
2420
|
+
observer.observe(panelRef.current, { subtree: true, attributes: true, attributeFilter: ["data-collapsed"] });
|
|
2421
|
+
return () => observer.disconnect();
|
|
2422
|
+
}, [inline, dragOffset, position]);
|
|
2423
|
+
const handlePointerDown = (0, import_react17.useCallback)((e) => {
|
|
2424
|
+
const inner = panelRef.current?.querySelector(".dialkit-panel-inner");
|
|
2425
|
+
if (!inner || inner.getAttribute("data-collapsed") !== "true") return;
|
|
2426
|
+
const rect = panelRef.current.getBoundingClientRect();
|
|
2427
|
+
dragStartRef.current = {
|
|
2428
|
+
pointerX: e.clientX,
|
|
2429
|
+
pointerY: e.clientY,
|
|
2430
|
+
elX: rect.left,
|
|
2431
|
+
elY: rect.top
|
|
2432
|
+
};
|
|
2433
|
+
didDragRef.current = false;
|
|
2434
|
+
draggingRef.current = true;
|
|
2435
|
+
e.target.setPointerCapture(e.pointerId);
|
|
2436
|
+
}, []);
|
|
2437
|
+
const handlePointerMove = (0, import_react17.useCallback)((e) => {
|
|
2438
|
+
if (!draggingRef.current || !dragStartRef.current) return;
|
|
2439
|
+
const dx = e.clientX - dragStartRef.current.pointerX;
|
|
2440
|
+
const dy = e.clientY - dragStartRef.current.pointerY;
|
|
2441
|
+
if (!didDragRef.current && Math.abs(dx) + Math.abs(dy) < 4) return;
|
|
2442
|
+
didDragRef.current = true;
|
|
2443
|
+
setDragOffset({
|
|
2444
|
+
x: dragStartRef.current.elX + dx,
|
|
2445
|
+
y: dragStartRef.current.elY + dy
|
|
2446
|
+
});
|
|
2447
|
+
}, []);
|
|
2448
|
+
const handlePointerUp = (0, import_react17.useCallback)((e) => {
|
|
2449
|
+
if (!draggingRef.current) return;
|
|
2450
|
+
draggingRef.current = false;
|
|
2451
|
+
dragStartRef.current = null;
|
|
2452
|
+
if (didDragRef.current) {
|
|
2453
|
+
e.stopPropagation();
|
|
2454
|
+
const inner = panelRef.current?.querySelector(".dialkit-panel-inner");
|
|
2455
|
+
if (inner) {
|
|
2456
|
+
const blocker = (ev) => {
|
|
2457
|
+
ev.stopPropagation();
|
|
2458
|
+
};
|
|
2459
|
+
inner.addEventListener("click", blocker, { capture: true, once: true });
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
}, []);
|
|
2062
2463
|
if (!mounted || typeof window === "undefined") {
|
|
2063
2464
|
return null;
|
|
2064
2465
|
}
|
|
2065
2466
|
if (panels.length === 0) {
|
|
2066
2467
|
return null;
|
|
2067
2468
|
}
|
|
2068
|
-
const
|
|
2469
|
+
const dragStyle = dragOffset ? {
|
|
2470
|
+
top: dragOffset.y,
|
|
2471
|
+
left: dragOffset.x,
|
|
2472
|
+
right: "auto",
|
|
2473
|
+
bottom: "auto"
|
|
2474
|
+
} : void 0;
|
|
2475
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ShortcutListener, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "dialkit-root", "data-mode": mode, "data-theme": theme, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2476
|
+
"div",
|
|
2477
|
+
{
|
|
2478
|
+
ref: panelRef,
|
|
2479
|
+
className: "dialkit-panel",
|
|
2480
|
+
"data-position": inline ? void 0 : dragOffset ? void 0 : activePosition,
|
|
2481
|
+
"data-mode": mode,
|
|
2482
|
+
style: dragStyle,
|
|
2483
|
+
onPointerDown: !inline ? handlePointerDown : void 0,
|
|
2484
|
+
onPointerMove: !inline ? handlePointerMove : void 0,
|
|
2485
|
+
onPointerUp: !inline ? handlePointerUp : void 0,
|
|
2486
|
+
children: panels.map((panel) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Panel, { panel, defaultOpen: inline || defaultOpen, inline }, panel.id))
|
|
2487
|
+
}
|
|
2488
|
+
) }) });
|
|
2069
2489
|
if (inline) {
|
|
2070
2490
|
return content;
|
|
2071
2491
|
}
|
|
@@ -2073,9 +2493,9 @@ function DialRoot({ position = "top-right", defaultOpen = true, mode = "popover"
|
|
|
2073
2493
|
}
|
|
2074
2494
|
|
|
2075
2495
|
// src/components/ButtonGroup.tsx
|
|
2076
|
-
var
|
|
2496
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2077
2497
|
function ButtonGroup({ buttons }) {
|
|
2078
|
-
return /* @__PURE__ */ (0,
|
|
2498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "dialkit-button-group", children: buttons.map((button, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2079
2499
|
"button",
|
|
2080
2500
|
{
|
|
2081
2501
|
className: "dialkit-button",
|
|
@@ -2085,6 +2505,124 @@ function ButtonGroup({ buttons }) {
|
|
|
2085
2505
|
index
|
|
2086
2506
|
)) });
|
|
2087
2507
|
}
|
|
2508
|
+
|
|
2509
|
+
// src/components/ShortcutsMenu.tsx
|
|
2510
|
+
var import_react18 = require("react");
|
|
2511
|
+
var import_react_dom4 = require("react-dom");
|
|
2512
|
+
var import_react19 = require("motion/react");
|
|
2513
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2514
|
+
function formatShortcutKey(sc) {
|
|
2515
|
+
if (!sc.key) return "\u2014";
|
|
2516
|
+
const mod = sc.modifier === "alt" ? "\u2325" : sc.modifier === "shift" ? "\u21E7" : sc.modifier === "meta" ? "\u2318" : "";
|
|
2517
|
+
return `${mod}${sc.key.toUpperCase()}`;
|
|
2518
|
+
}
|
|
2519
|
+
function formatInteraction(sc) {
|
|
2520
|
+
const interaction = sc.interaction ?? "scroll";
|
|
2521
|
+
switch (interaction) {
|
|
2522
|
+
case "scroll":
|
|
2523
|
+
return sc.key ? "key+scroll" : "scroll";
|
|
2524
|
+
case "drag":
|
|
2525
|
+
return "key+drag";
|
|
2526
|
+
case "move":
|
|
2527
|
+
return "key+move";
|
|
2528
|
+
case "scroll-only":
|
|
2529
|
+
return "scroll";
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
function ShortcutsMenu({ panelId }) {
|
|
2533
|
+
const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
|
|
2534
|
+
const triggerRef = (0, import_react18.useRef)(null);
|
|
2535
|
+
const dropdownRef = (0, import_react18.useRef)(null);
|
|
2536
|
+
const [pos, setPos] = (0, import_react18.useState)({ top: 0, right: 0 });
|
|
2537
|
+
const open = (0, import_react18.useCallback)(() => {
|
|
2538
|
+
const rect = triggerRef.current?.getBoundingClientRect();
|
|
2539
|
+
if (rect) {
|
|
2540
|
+
setPos({ top: rect.bottom + 4, right: window.innerWidth - rect.right });
|
|
2541
|
+
}
|
|
2542
|
+
setIsOpen(true);
|
|
2543
|
+
}, []);
|
|
2544
|
+
const close = (0, import_react18.useCallback)(() => setIsOpen(false), []);
|
|
2545
|
+
const toggle = (0, import_react18.useCallback)(() => {
|
|
2546
|
+
if (isOpen) close();
|
|
2547
|
+
else open();
|
|
2548
|
+
}, [isOpen, open, close]);
|
|
2549
|
+
(0, import_react18.useEffect)(() => {
|
|
2550
|
+
if (!isOpen) return;
|
|
2551
|
+
const handler = (e) => {
|
|
2552
|
+
const target = e.target;
|
|
2553
|
+
if (triggerRef.current?.contains(target) || dropdownRef.current?.contains(target)) return;
|
|
2554
|
+
close();
|
|
2555
|
+
};
|
|
2556
|
+
document.addEventListener("mousedown", handler);
|
|
2557
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
2558
|
+
}, [isOpen, close]);
|
|
2559
|
+
const panel = DialStore.getPanel(panelId);
|
|
2560
|
+
if (!panel) return null;
|
|
2561
|
+
const shortcuts = Object.entries(panel.shortcuts);
|
|
2562
|
+
if (shortcuts.length === 0) return null;
|
|
2563
|
+
const rows = shortcuts.map(([path, shortcut]) => {
|
|
2564
|
+
const findLabel = (controls) => {
|
|
2565
|
+
for (const c of controls) {
|
|
2566
|
+
if (c.path === path) return c.label;
|
|
2567
|
+
if (c.type === "folder" && c.children) {
|
|
2568
|
+
const found = findLabel(c.children);
|
|
2569
|
+
if (found) return found;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
return path;
|
|
2573
|
+
};
|
|
2574
|
+
return {
|
|
2575
|
+
path,
|
|
2576
|
+
shortcut,
|
|
2577
|
+
label: findLabel(panel.controls)
|
|
2578
|
+
};
|
|
2579
|
+
});
|
|
2580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2581
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2582
|
+
import_react19.motion.button,
|
|
2583
|
+
{
|
|
2584
|
+
ref: triggerRef,
|
|
2585
|
+
className: "dialkit-shortcuts-trigger",
|
|
2586
|
+
onClick: toggle,
|
|
2587
|
+
title: "Keyboard shortcuts",
|
|
2588
|
+
whileTap: { scale: 0.9 },
|
|
2589
|
+
transition: { type: "spring", visualDuration: 0.15, bounce: 0.3 },
|
|
2590
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2591
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("rect", { x: "2", y: "6", width: "20", height: "12", rx: "2" }),
|
|
2592
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M6 10H6.01" }),
|
|
2593
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M10 10H10.01" }),
|
|
2594
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M14 10H14.01" }),
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M18 10H18.01" }),
|
|
2596
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M8 14H16" })
|
|
2597
|
+
] })
|
|
2598
|
+
}
|
|
2599
|
+
),
|
|
2600
|
+
(0, import_react_dom4.createPortal)(
|
|
2601
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react19.AnimatePresence, { children: isOpen && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2602
|
+
import_react19.motion.div,
|
|
2603
|
+
{
|
|
2604
|
+
ref: dropdownRef,
|
|
2605
|
+
className: "dialkit-root dialkit-shortcuts-dropdown",
|
|
2606
|
+
style: { position: "fixed", top: pos.top, right: pos.right },
|
|
2607
|
+
initial: { opacity: 0, y: 4, scale: 0.97 },
|
|
2608
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
2609
|
+
exit: { opacity: 0, y: 4, scale: 0.97, pointerEvents: "none" },
|
|
2610
|
+
transition: { type: "spring", visualDuration: 0.15, bounce: 0 },
|
|
2611
|
+
children: [
|
|
2612
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "dialkit-shortcuts-title", children: "Keyboard Shortcuts" }),
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "dialkit-shortcuts-list", children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "dialkit-shortcuts-row", children: [
|
|
2614
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "dialkit-shortcuts-row-key", children: formatShortcutKey(row.shortcut) }),
|
|
2615
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "dialkit-shortcuts-row-label", children: row.label }),
|
|
2616
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "dialkit-shortcuts-row-mode", children: formatInteraction(row.shortcut) })
|
|
2617
|
+
] }, row.path)) }),
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "dialkit-shortcuts-hint", children: "See pill badges on controls for keys" })
|
|
2619
|
+
]
|
|
2620
|
+
}
|
|
2621
|
+
) }),
|
|
2622
|
+
document.body
|
|
2623
|
+
)
|
|
2624
|
+
] });
|
|
2625
|
+
}
|
|
2088
2626
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2089
2627
|
0 && (module.exports = {
|
|
2090
2628
|
ButtonGroup,
|
|
@@ -2095,6 +2633,7 @@ function ButtonGroup({ buttons }) {
|
|
|
2095
2633
|
Folder,
|
|
2096
2634
|
PresetManager,
|
|
2097
2635
|
SelectControl,
|
|
2636
|
+
ShortcutsMenu,
|
|
2098
2637
|
Slider,
|
|
2099
2638
|
SpringControl,
|
|
2100
2639
|
SpringVisualization,
|