dialkit 1.2.1 → 1.4.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 +653 -6
- package/dist/dropdown-position.d.ts +15 -0
- package/dist/dropdown-position.js +22 -0
- package/dist/dropdown-position.js.map +1 -0
- package/dist/icons.d.ts +4 -1
- package/dist/icons.js +13 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +3796 -768
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +315 -10
- package/dist/index.d.ts +315 -10
- package/dist/index.js +3733 -711
- package/dist/index.js.map +1 -1
- package/dist/panel-drag.d.ts +19 -0
- package/dist/panel-drag.js +72 -0
- package/dist/panel-drag.js.map +1 -0
- package/dist/solid/index.d.ts +264 -5
- package/dist/solid/index.js +5277 -1632
- package/dist/solid/index.js.map +1 -1
- package/dist/store/index.cjs +329 -57
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +43 -4
- package/dist/store/index.d.ts +43 -4
- package/dist/store/index.js +321 -56
- package/dist/store/index.js.map +1 -1
- package/dist/styles.css +809 -7
- package/dist/svelte/components/ControlRenderer.svelte +5 -2
- package/dist/svelte/components/ControlRenderer.svelte.d.ts +2 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -1
- package/dist/svelte/components/DialRoot.svelte +218 -16
- package/dist/svelte/components/DialRoot.svelte.d.ts +1 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Folder.svelte +24 -13
- package/dist/svelte/components/Folder.svelte.d.ts +1 -0
- package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Panel.svelte +104 -71
- package/dist/svelte/components/Panel.svelte.d.ts +4 -0
- package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
- package/dist/svelte/components/PresetManager.svelte +5 -5
- package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
- package/dist/svelte/components/SelectControl.svelte +6 -14
- package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Timeline/ClipPopover.svelte +206 -0
- package/dist/svelte/components/Timeline/ClipPopover.svelte.d.ts +26 -0
- package/dist/svelte/components/Timeline/ClipPopover.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/DialTimeline.svelte +76 -0
- package/dist/svelte/components/Timeline/DialTimeline.svelte.d.ts +13 -0
- package/dist/svelte/components/Timeline/DialTimeline.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/TimelineClip.svelte +233 -0
- package/dist/svelte/components/Timeline/TimelineClip.svelte.d.ts +24 -0
- package/dist/svelte/components/Timeline/TimelineClip.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/TimelineSection.svelte +756 -0
- package/dist/svelte/components/Timeline/TimelineSection.svelte.d.ts +12 -0
- package/dist/svelte/components/Timeline/TimelineSection.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/TimelineToggleButton.svelte +25 -0
- package/dist/svelte/components/Timeline/TimelineToggleButton.svelte.d.ts +4 -0
- package/dist/svelte/components/Timeline/TimelineToggleButton.svelte.d.ts.map +1 -0
- package/dist/svelte/components/TransitionControl.svelte +26 -11
- package/dist/svelte/components/TransitionControl.svelte.d.ts +9 -0
- package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -1
- package/dist/svelte/createDialKit.svelte.d.ts +11 -1
- package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
- package/dist/svelte/createDialKit.svelte.js +61 -34
- package/dist/svelte/createDialTimeline.svelte.d.ts +4 -0
- package/dist/svelte/createDialTimeline.svelte.d.ts.map +1 -0
- package/dist/svelte/createDialTimeline.svelte.js +73 -0
- package/dist/svelte/index.d.ts +7 -3
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +4 -1
- 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 +809 -7
- package/dist/timeline/index.cjs +1288 -0
- package/dist/timeline/index.cjs.map +1 -0
- package/dist/timeline/index.d.cts +443 -0
- package/dist/timeline/index.d.ts +443 -0
- package/dist/timeline/index.js +1233 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/vue/index.d.ts +325 -12
- package/dist/vue/index.js +3226 -280
- package/dist/vue/index.js.map +1 -1
- package/package.json +23 -13
- package/dist/solid/index.cjs +0 -3079
- package/dist/solid/index.cjs.map +0 -1
- package/dist/solid/index.d.cts +0 -258
- package/dist/vue/index.cjs +0 -3056
- package/dist/vue/index.cjs.map +0 -1
- package/dist/vue/index.d.cts +0 -675
package/dist/store/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/store/DialStore.ts"],"sourcesContent":["// Lightweight state store with subscriptions for dialkit\n\nexport type SpringConfig = {\n type: 'spring';\n stiffness?: number;\n damping?: number;\n mass?: number;\n visualDuration?: number;\n bounce?: number;\n};\n\nexport type EasingConfig = {\n type: 'easing';\n duration: number;\n ease: [number, number, number, number];\n};\n\nexport type TransitionConfig = SpringConfig | EasingConfig;\n\nexport type ActionConfig = {\n type: 'action';\n label?: string;\n};\n\nexport type SelectConfig = {\n type: 'select';\n options: (string | { value: string; label: string })[];\n default?: string;\n};\n\nexport type ColorConfig = {\n type: 'color';\n default?: string;\n};\n\nexport type TextConfig = {\n type: 'text';\n default?: string;\n placeholder?: string;\n};\n\nexport type DialValue = number | boolean | string | SpringConfig | EasingConfig | ActionConfig | SelectConfig | ColorConfig | TextConfig;\n\nexport type DialConfig = {\n [key: string]: DialValue | [number, number, number, number?] | DialConfig;\n};\n\nexport type ResolvedValues<T extends DialConfig> = {\n [K in keyof T]: T[K] extends [number, number, number, number?]\n ? number\n : T[K] extends SpringConfig\n ? TransitionConfig\n : T[K] extends EasingConfig\n ? TransitionConfig\n : T[K] extends SelectConfig\n ? string\n : T[K] extends ColorConfig\n ? string\n : T[K] extends TextConfig\n ? string\n : T[K] extends DialConfig\n ? ResolvedValues<T[K]>\n : T[K];\n};\n\nexport type ShortcutMode = 'fine' | 'normal' | 'coarse';\nexport type ShortcutInteraction = 'scroll' | 'drag' | 'move' | 'scroll-only';\n\nexport type ShortcutConfig = {\n key?: string;\n modifier?: 'alt' | 'shift' | 'meta';\n mode?: ShortcutMode;\n interaction?: ShortcutInteraction;\n};\n\nexport type ControlMeta = {\n type: 'slider' | 'toggle' | 'spring' | 'transition' | 'folder' | 'action' | 'select' | 'color' | 'text';\n path: string;\n label: string;\n min?: number;\n max?: number;\n step?: number;\n children?: ControlMeta[];\n defaultOpen?: boolean;\n options?: (string | { value: string; label: string })[];\n placeholder?: string;\n shortcut?: ShortcutConfig;\n};\n\nexport type PanelConfig = {\n id: string;\n name: string;\n controls: ControlMeta[];\n values: Record<string, DialValue>;\n shortcuts: Record<string, ShortcutConfig>;\n};\n\ntype Listener = () => void;\ntype ActionListener = (action: string) => void;\n\nexport type Preset = {\n id: string;\n name: string;\n values: Record<string, DialValue>;\n};\n\n// Stable empty object for unregistered panels (React 19 useSyncExternalStore requirement)\nconst EMPTY_VALUES: Record<string, DialValue> = Object.freeze({});\n\nclass DialStoreClass {\n private panels: Map<string, PanelConfig> = new Map();\n private listeners: Map<string, Set<Listener>> = new Map();\n private globalListeners: Set<Listener> = new Set();\n private snapshots: Map<string, Record<string, DialValue>> = new Map();\n private actionListeners: Map<string, Set<ActionListener>> = new Map();\n private presets: Map<string, Preset[]> = new Map();\n private activePreset: Map<string, string | null> = new Map();\n private baseValues: Map<string, Record<string, DialValue>> = new Map();\n\n registerPanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>): void {\n const controls = this.parseConfig(config, '', shortcuts);\n const values = this.flattenValues(config, '');\n\n // Set initial transition modes based on config types\n this.initTransitionModes(config, '', values);\n\n this.panels.set(id, { id, name, controls, values, shortcuts: shortcuts ?? {} });\n this.snapshots.set(id, { ...values });\n this.baseValues.set(id, { ...values });\n this.notifyGlobal();\n }\n\n updatePanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>): void {\n const existing = this.panels.get(id);\n if (!existing) {\n this.registerPanel(id, name, config, shortcuts);\n return;\n }\n\n const controls = this.parseConfig(config, '', shortcuts);\n const controlsByPath = this.mapControlsByPath(controls);\n const defaultValues = this.flattenValues(config, '');\n const nextValues: Record<string, DialValue> = {};\n\n for (const [path, defaultValue] of Object.entries(defaultValues)) {\n nextValues[path] = this.normalizePreservedValue(\n existing.values[path],\n defaultValue,\n controlsByPath.get(path)\n );\n }\n\n // Set mode defaults for new transition controls first.\n this.initTransitionModes(config, '', nextValues);\n\n for (const [path, mode] of Object.entries(existing.values)) {\n if (!path.endsWith('.__mode')) {\n continue;\n }\n\n const transitionPath = path.slice(0, -'__mode'.length - 1);\n const transitionControl = controlsByPath.get(transitionPath);\n if (transitionControl?.type === 'transition') {\n nextValues[path] = mode;\n }\n }\n\n const nextPanel: PanelConfig = { id, name, controls, values: nextValues, shortcuts: shortcuts ?? existing.shortcuts };\n this.panels.set(id, nextPanel);\n this.snapshots.set(id, { ...nextValues });\n\n const previousBaseValues = this.baseValues.get(id) ?? {};\n const nextBaseValues: Record<string, DialValue> = {};\n for (const [path, defaultValue] of Object.entries(defaultValues)) {\n nextBaseValues[path] = this.normalizePreservedValue(\n previousBaseValues[path],\n defaultValue,\n controlsByPath.get(path)\n );\n }\n\n for (const [path, value] of Object.entries(nextValues)) {\n if (path.endsWith('.__mode')) {\n nextBaseValues[path] = value;\n }\n }\n\n this.baseValues.set(id, nextBaseValues);\n\n this.notify(id);\n this.notifyGlobal();\n }\n\n unregisterPanel(id: string): void {\n this.panels.delete(id);\n this.listeners.delete(id);\n this.snapshots.delete(id);\n this.actionListeners.delete(id);\n this.baseValues.delete(id);\n this.notifyGlobal();\n }\n\n updateValue(panelId: string, path: string, value: DialValue): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n panel.values[path] = value;\n\n // Auto-save to active preset or base values\n const activeId = this.activePreset.get(panelId);\n if (activeId) {\n const presets = this.presets.get(panelId) ?? [];\n const preset = presets.find(p => p.id === activeId);\n if (preset) preset.values[path] = value;\n } else {\n const base = this.baseValues.get(panelId);\n if (base) base[path] = value;\n }\n\n // Create a new snapshot reference so useSyncExternalStore detects the change\n this.snapshots.set(panelId, { ...panel.values });\n this.notify(panelId);\n }\n\n updateSpringMode(panelId: string, path: string, mode: 'simple' | 'advanced'): void {\n this.updateTransitionMode(panelId, path, mode);\n }\n\n getSpringMode(panelId: string, path: string): 'simple' | 'advanced' {\n const mode = this.getTransitionMode(panelId, path);\n if (mode === 'easing') return 'simple';\n return mode;\n }\n\n updateTransitionMode(panelId: string, path: string, mode: 'easing' | 'simple' | 'advanced'): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n panel.values[`${path}.__mode`] = mode;\n this.snapshots.set(panelId, { ...panel.values });\n this.notify(panelId);\n }\n\n getTransitionMode(panelId: string, path: string): 'easing' | 'simple' | 'advanced' {\n const panel = this.panels.get(panelId);\n if (!panel) return 'simple';\n return (panel.values[`${path}.__mode`] as 'easing' | 'simple' | 'advanced') || 'simple';\n }\n\n getValue(panelId: string, path: string): DialValue | undefined {\n const panel = this.panels.get(panelId);\n return panel?.values[path];\n }\n\n getValues(panelId: string): Record<string, DialValue> {\n // Return the snapshot for useSyncExternalStore compatibility\n // Use stable EMPTY_VALUES to avoid infinite loop in React 19\n return this.snapshots.get(panelId) ?? EMPTY_VALUES;\n }\n\n getPanels(): PanelConfig[] {\n return Array.from(this.panels.values());\n }\n\n getPanel(id: string): PanelConfig | undefined {\n return this.panels.get(id);\n }\n\n subscribe(panelId: string, listener: Listener): () => void {\n if (!this.listeners.has(panelId)) {\n this.listeners.set(panelId, new Set());\n }\n this.listeners.get(panelId)!.add(listener);\n\n return () => {\n this.listeners.get(panelId)?.delete(listener);\n };\n }\n\n subscribeGlobal(listener: Listener): () => void {\n this.globalListeners.add(listener);\n return () => this.globalListeners.delete(listener);\n }\n\n subscribeActions(panelId: string, listener: ActionListener): () => void {\n if (!this.actionListeners.has(panelId)) {\n this.actionListeners.set(panelId, new Set());\n }\n this.actionListeners.get(panelId)!.add(listener);\n\n return () => {\n this.actionListeners.get(panelId)?.delete(listener);\n };\n }\n\n triggerAction(panelId: string, path: string): void {\n this.actionListeners.get(panelId)?.forEach(fn => fn(path));\n }\n\n savePreset(panelId: string, name: string): string {\n const panel = this.panels.get(panelId);\n if (!panel) throw new Error(`Panel ${panelId} not found`);\n\n const id = `preset-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n const preset: Preset = {\n id,\n name,\n values: { ...panel.values },\n };\n\n const existing = this.presets.get(panelId) ?? [];\n this.presets.set(panelId, [...existing, preset]);\n this.activePreset.set(panelId, id);\n\n // Force re-render by creating new snapshot reference\n this.snapshots.set(panelId, { ...panel.values });\n this.notify(panelId);\n\n return id;\n }\n\n loadPreset(panelId: string, presetId: string): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n const presets = this.presets.get(panelId) ?? [];\n const preset = presets.find(p => p.id === presetId);\n if (!preset) return;\n\n // Apply preset values\n panel.values = { ...preset.values };\n this.snapshots.set(panelId, { ...panel.values });\n this.activePreset.set(panelId, presetId);\n this.notify(panelId);\n }\n\n deletePreset(panelId: string, presetId: string): void {\n const presets = this.presets.get(panelId) ?? [];\n this.presets.set(panelId, presets.filter(p => p.id !== presetId));\n\n // Clear active if deleted\n if (this.activePreset.get(panelId) === presetId) {\n this.activePreset.set(panelId, null);\n }\n\n // Force re-render by creating new snapshot reference\n const panel = this.panels.get(panelId);\n if (panel) {\n this.snapshots.set(panelId, { ...panel.values });\n }\n this.notify(panelId);\n }\n\n getPresets(panelId: string): Preset[] {\n return this.presets.get(panelId) ?? [];\n }\n\n getActivePresetId(panelId: string): string | null {\n return this.activePreset.get(panelId) ?? null;\n }\n\n clearActivePreset(panelId: string): void {\n const panel = this.panels.get(panelId);\n const base = this.baseValues.get(panelId);\n if (panel && base) {\n panel.values = { ...base };\n this.snapshots.set(panelId, { ...panel.values });\n }\n this.activePreset.set(panelId, null);\n this.notify(panelId);\n }\n\n resolveShortcutTarget(key: string, modifier?: 'alt' | 'shift' | 'meta'): {\n panelId: string;\n path: string;\n control: ControlMeta;\n } | null {\n for (const panel of this.panels.values()) {\n for (const [path, shortcut] of Object.entries(panel.shortcuts)) {\n if (!shortcut.key) continue; // skip keyless shortcuts\n if (shortcut.key.toLowerCase() !== key.toLowerCase()) continue;\n const scMod = shortcut.modifier ?? undefined;\n if (scMod !== modifier) continue;\n\n const control = this.findControlByPath(panel.controls, path);\n if (control) {\n return { panelId: panel.id, path, control };\n }\n }\n }\n return null;\n }\n\n resolveScrollOnlyTargets(): Array<{\n panelId: string;\n path: string;\n control: ControlMeta;\n shortcut: ShortcutConfig;\n }> {\n const results: Array<{ panelId: string; path: string; control: ControlMeta; shortcut: ShortcutConfig }> = [];\n for (const panel of this.panels.values()) {\n for (const [path, shortcut] of Object.entries(panel.shortcuts)) {\n if ((shortcut.interaction ?? 'scroll') !== 'scroll-only') continue;\n const control = this.findControlByPath(panel.controls, path);\n if (control) {\n results.push({ panelId: panel.id, path, control, shortcut });\n }\n }\n }\n return results;\n }\n\n private findControlByPath(controls: ControlMeta[], path: string): ControlMeta | null {\n for (const control of controls) {\n if (control.path === path) return control;\n if (control.type === 'folder' && control.children) {\n const found = this.findControlByPath(control.children, path);\n if (found) return found;\n }\n }\n return null;\n }\n\n private notify(panelId: string): void {\n this.listeners.get(panelId)?.forEach(fn => fn());\n }\n\n private notifyGlobal(): void {\n this.globalListeners.forEach(fn => fn());\n }\n\n private initTransitionModes(config: DialConfig, prefix: string, values: Record<string, DialValue>): void {\n for (const [key, value] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (this.isEasingConfig(value)) {\n values[`${path}.__mode`] = 'easing';\n } else if (this.isSpringConfig(value)) {\n // Detect physics mode from config\n const hasPhysics = value.stiffness !== undefined || value.damping !== undefined || value.mass !== undefined;\n const hasTime = value.visualDuration !== undefined || value.bounce !== undefined;\n values[`${path}.__mode`] = hasPhysics && !hasTime ? 'advanced' : 'simple';\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value) && !this.isActionConfig(value) && !this.isSelectConfig(value) && !this.isColorConfig(value) && !this.isTextConfig(value)) {\n this.initTransitionModes(value as DialConfig, path, values);\n }\n }\n }\n\n private parseConfig(config: DialConfig, prefix: string, shortcuts?: Record<string, ShortcutConfig>): ControlMeta[] {\n const controls: ControlMeta[] = [];\n\n for (const [key, value] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n const label = this.formatLabel(key);\n const shortcut = shortcuts?.[path];\n\n if (Array.isArray(value) && value.length <= 4 && typeof value[0] === 'number') {\n // Range tuple: [default, min, max]\n controls.push({\n type: 'slider',\n path,\n label,\n min: value[1],\n max: value[2],\n step: value[3] ?? this.inferStep(value[1], value[2]),\n shortcut,\n });\n } else if (typeof value === 'number') {\n // Single number - auto-infer range\n const { min, max, step } = this.inferRange(value);\n controls.push({ type: 'slider', path, label, min, max, step, shortcut });\n } else if (typeof value === 'boolean') {\n controls.push({ type: 'toggle', path, label, shortcut });\n } else if (this.isSpringConfig(value) || this.isEasingConfig(value)) {\n controls.push({ type: 'transition', path, label });\n } else if (this.isActionConfig(value)) {\n controls.push({ type: 'action', path, label: (value as ActionConfig).label || label });\n } else if (this.isSelectConfig(value)) {\n controls.push({ type: 'select', path, label, options: value.options });\n } else if (this.isColorConfig(value)) {\n controls.push({ type: 'color', path, label });\n } else if (this.isTextConfig(value)) {\n controls.push({ type: 'text', path, label, placeholder: value.placeholder });\n } else if (typeof value === 'string') {\n // Auto-detect: hex color vs text\n if (this.isHexColor(value)) {\n controls.push({ type: 'color', path, label });\n } else {\n controls.push({ type: 'text', path, label });\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object becomes a folder\n const folderConfig = value as DialConfig;\n const defaultOpen = '_collapsed' in folderConfig ? !(folderConfig._collapsed as boolean) : true;\n controls.push({\n type: 'folder',\n path,\n label,\n defaultOpen,\n children: this.parseConfig(folderConfig, path, shortcuts),\n });\n }\n }\n\n return controls;\n }\n\n private flattenValues(config: DialConfig, prefix: string): Record<string, DialValue> {\n const values: Record<string, DialValue> = {};\n\n for (const [key, value] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (Array.isArray(value) && value.length <= 4 && typeof value[0] === 'number') {\n values[path] = value[0]; // Default value\n } else if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string') {\n values[path] = value;\n } else if (this.isSpringConfig(value) || this.isEasingConfig(value)) {\n values[path] = value;\n } else if (this.isActionConfig(value)) {\n // Actions don't need stored values - they're just triggers\n values[path] = value;\n } else if (this.isSelectConfig(value)) {\n // Use default or first option's value\n const firstOption = value.options[0];\n const firstValue = typeof firstOption === 'string' ? firstOption : firstOption.value;\n values[path] = value.default ?? firstValue;\n } else if (this.isColorConfig(value)) {\n values[path] = value.default ?? '#000000';\n } else if (this.isTextConfig(value)) {\n values[path] = value.default ?? '';\n } else if (typeof value === 'object' && value !== null) {\n Object.assign(values, this.flattenValues(value as DialConfig, path));\n }\n }\n\n return values;\n }\n\n private isSpringConfig(value: unknown): value is SpringConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as SpringConfig).type === 'spring'\n );\n }\n\n private isEasingConfig(value: unknown): value is EasingConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as EasingConfig).type === 'easing'\n );\n }\n\n private isActionConfig(value: unknown): value is ActionConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as ActionConfig).type === 'action'\n );\n }\n\n private isSelectConfig(value: unknown): value is SelectConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as SelectConfig).type === 'select' &&\n 'options' in value &&\n Array.isArray((value as SelectConfig).options)\n );\n }\n\n private isColorConfig(value: unknown): value is ColorConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as ColorConfig).type === 'color'\n );\n }\n\n private isTextConfig(value: unknown): value is TextConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as TextConfig).type === 'text'\n );\n }\n\n private isHexColor(value: string): boolean {\n return /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(value);\n }\n\n private formatLabel(key: string): string {\n // Convert camelCase to Title Case\n return key\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, str => str.toUpperCase())\n .trim();\n }\n\n private inferRange(value: number): { min: number; max: number; step: number } {\n // Infer reasonable range based on value\n if (value >= 0 && value <= 1) {\n return { min: 0, max: 1, step: 0.01 };\n } else if (value >= 0 && value <= 10) {\n return { min: 0, max: value * 3 || 10, step: 0.1 };\n } else if (value >= 0 && value <= 100) {\n return { min: 0, max: value * 3 || 100, step: 1 };\n } else if (value >= 0) {\n return { min: 0, max: value * 3 || 1000, step: 10 };\n } else {\n return { min: value * 3, max: -value * 3, step: 1 };\n }\n }\n\n private inferStep(min: number, max: number): number {\n const range = max - min;\n if (range <= 1) return 0.01;\n if (range <= 10) return 0.1;\n if (range <= 100) return 1;\n return 10;\n }\n\n private normalizePreservedValue(\n existingValue: DialValue | undefined,\n defaultValue: DialValue,\n control: ControlMeta | undefined\n ): DialValue {\n if (existingValue === undefined || !control) {\n return defaultValue;\n }\n\n switch (control.type) {\n case 'slider': {\n if (typeof existingValue !== 'number' || typeof defaultValue !== 'number') {\n return defaultValue;\n }\n\n const min = control.min ?? Number.NEGATIVE_INFINITY;\n const max = control.max ?? Number.POSITIVE_INFINITY;\n const clamped = Math.min(max, Math.max(min, existingValue));\n\n if (typeof control.step !== 'number' || control.step <= 0) {\n return clamped;\n }\n\n return this.roundToStep(clamped, min, max, control.step);\n }\n case 'toggle':\n return typeof existingValue === 'boolean' ? existingValue : defaultValue;\n case 'select': {\n if (typeof existingValue !== 'string') {\n return defaultValue;\n }\n\n const options = control.options ?? [];\n const validValues = new Set(options.map((option) => (typeof option === 'string' ? option : option.value)));\n return validValues.has(existingValue) ? existingValue : defaultValue;\n }\n case 'color':\n case 'text':\n return typeof existingValue === 'string' ? existingValue : defaultValue;\n case 'transition':\n if (this.isSpringConfig(defaultValue)) {\n return this.isSpringConfig(existingValue) ? existingValue : defaultValue;\n }\n if (this.isEasingConfig(defaultValue)) {\n return this.isEasingConfig(existingValue) ? existingValue : defaultValue;\n }\n return defaultValue;\n case 'action':\n return defaultValue;\n default:\n return defaultValue;\n }\n }\n\n private roundToStep(value: number, min: number, max: number, step: number): number {\n const snapped = min + Math.round((value - min) / step) * step;\n const clamped = Math.min(max, Math.max(min, snapped));\n const precision = this.stepPrecision(step);\n return Number(clamped.toFixed(precision));\n }\n\n private stepPrecision(step: number): number {\n const text = String(step);\n const decimalIndex = text.indexOf('.');\n return decimalIndex === -1 ? 0 : text.length - decimalIndex - 1;\n }\n\n private mapControlsByPath(controls: ControlMeta[]): Map<string, ControlMeta> {\n const map = new Map<string, ControlMeta>();\n\n const visit = (nodes: ControlMeta[]) => {\n for (const node of nodes) {\n if (node.type === 'folder' && node.children) {\n visit(node.children);\n continue;\n }\n\n map.set(node.path, node);\n }\n };\n\n visit(controls);\n return map;\n }\n\n}\n\n// Singleton instance\nexport const DialStore = new DialStoreClass();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/store/DialStore.ts"],"sourcesContent":["// Lightweight state store with subscriptions for dialkit\n\nexport type SpringConfig = {\n type: 'spring';\n stiffness?: number;\n damping?: number;\n mass?: number;\n visualDuration?: number;\n bounce?: number;\n};\n\nexport type EasingConfig = {\n type: 'easing';\n duration: number;\n ease: [number, number, number, number];\n};\n\nexport type TransitionConfig = SpringConfig | EasingConfig;\n\nexport type ActionConfig = {\n type: 'action';\n label?: string;\n};\n\nexport type SelectConfig = {\n type: 'select';\n options: (string | { value: string; label: string })[];\n default?: string;\n};\n\nexport type ColorConfig = {\n type: 'color';\n default?: string;\n};\n\nexport type TextConfig = {\n type: 'text';\n default?: string;\n placeholder?: string;\n};\n\nexport type DialValue = number | boolean | string | SpringConfig | EasingConfig | ActionConfig | SelectConfig | ColorConfig | TextConfig;\n\nexport type DialConfig = {\n [key: string]: DialValue | [number, number, number, number?] | DialConfig;\n};\n\nexport type ResolvedValues<T extends DialConfig> = {\n [K in keyof T]: T[K] extends [number, number, number, number?]\n ? number\n : T[K] extends SpringConfig\n ? TransitionConfig\n : T[K] extends EasingConfig\n ? TransitionConfig\n : T[K] extends SelectConfig\n ? string\n : T[K] extends ColorConfig\n ? string\n : T[K] extends TextConfig\n ? string\n : T[K] extends DialConfig\n ? ResolvedValues<T[K]>\n : T[K];\n};\n\nexport type DialKitValueUpdates<T extends DialConfig> = {\n [K in keyof T as K extends '_collapsed' ? never : K]?: T[K] extends [number, number, number, number?]\n ? number\n : T[K] extends SpringConfig | EasingConfig\n ? TransitionConfig\n : T[K] extends ActionConfig\n ? never\n : T[K] extends SelectConfig | ColorConfig | TextConfig\n ? string\n : T[K] extends DialConfig\n ? DialKitValueUpdates<T[K]>\n : T[K];\n};\n\nexport type ShortcutMode = 'fine' | 'normal' | 'coarse';\nexport type ShortcutInteraction = 'scroll' | 'drag' | 'move' | 'scroll-only';\n\nexport type ShortcutConfig = {\n key?: string;\n modifier?: 'alt' | 'shift' | 'meta';\n mode?: ShortcutMode;\n interaction?: ShortcutInteraction;\n};\n\nexport type ControlMeta = {\n type: 'slider' | 'toggle' | 'spring' | 'transition' | 'folder' | 'action' | 'select' | 'color' | 'text';\n path: string;\n label: string;\n min?: number;\n max?: number;\n step?: number;\n children?: ControlMeta[];\n defaultOpen?: boolean;\n options?: (string | { value: string; label: string })[];\n placeholder?: string;\n shortcut?: ShortcutConfig;\n};\n\nexport type PanelConfig = {\n id: string;\n name: string;\n controls: ControlMeta[];\n values: Record<string, DialValue>;\n shortcuts: Record<string, ShortcutConfig>;\n kind?: 'timeline';\n};\n\ntype Listener = () => void;\ntype ActionListener = (action: string) => void;\n\nexport type Preset = {\n id: string;\n name: string;\n values: Record<string, DialValue>;\n};\n\nexport type DialKitPersistOptions = boolean | {\n key?: string;\n storage?: 'localStorage' | 'sessionStorage';\n presets?: boolean;\n};\n\nexport type DialStorePanelOptions = {\n retainOnUnmount?: boolean;\n persist?: DialKitPersistOptions;\n kind?: 'timeline';\n};\n\ntype PersistConfig = {\n key: string;\n storage: 'localStorage' | 'sessionStorage';\n presets: boolean;\n};\n\ntype PersistedPanelState = {\n version: 1;\n values?: Record<string, DialValue>;\n baseValues?: Record<string, DialValue>;\n presets?: Preset[];\n activePresetId?: string | null;\n};\n\n// Stable empty object for unregistered panels (React 19 useSyncExternalStore requirement)\nconst EMPTY_VALUES: Record<string, DialValue> = Object.freeze({});\n\nexport function resolveDialValues<T extends DialConfig>(\n config: T,\n flatValues: Record<string, DialValue>\n): ResolvedValues<T> {\n return resolveConfigValues(config, flatValues, '') as ResolvedValues<T>;\n}\n\nexport function flattenDialValueUpdates<T extends DialConfig>(\n config: T,\n updates: DialKitValueUpdates<T>\n): Record<string, DialValue> {\n const values: Record<string, DialValue> = {};\n if (typeof updates === 'object' && updates !== null) {\n flattenConfigUpdates(config, updates as Record<string, unknown>, '', values);\n }\n return values;\n}\n\nfunction resolveConfigValues(\n config: DialConfig,\n flatValues: Record<string, DialValue>,\n prefix: string\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, configValue] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (Array.isArray(configValue) && configValue.length <= 4 && typeof configValue[0] === 'number') {\n result[key] = flatValues[path] ?? configValue[0];\n } else if (typeof configValue === 'number' || typeof configValue === 'boolean' || typeof configValue === 'string') {\n result[key] = flatValues[path] ?? configValue;\n } else if (isSpringConfigValue(configValue) || isEasingConfigValue(configValue)) {\n result[key] = flatValues[path] ?? configValue;\n } else if (isActionConfigValue(configValue)) {\n result[key] = flatValues[path] ?? configValue;\n } else if (isSelectConfigValue(configValue)) {\n const defaultValue = configValue.default ?? getFirstOptionValue(configValue.options);\n result[key] = flatValues[path] ?? defaultValue;\n } else if (isColorConfigValue(configValue)) {\n result[key] = flatValues[path] ?? configValue.default ?? '#000000';\n } else if (isTextConfigValue(configValue)) {\n result[key] = flatValues[path] ?? configValue.default ?? '';\n } else if (typeof configValue === 'object' && configValue !== null) {\n result[key] = resolveConfigValues(configValue as DialConfig, flatValues, path);\n }\n }\n\n return result;\n}\n\nfunction flattenConfigUpdates(\n config: DialConfig,\n updates: Record<string, unknown>,\n prefix: string,\n values: Record<string, DialValue>\n): void {\n for (const [key, configValue] of Object.entries(config)) {\n if (key === '_collapsed' || !(key in updates)) continue;\n\n const nextValue = updates[key];\n if (nextValue === undefined) continue;\n\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (isActionConfigValue(configValue)) {\n continue;\n }\n\n if (isLeafConfigValue(configValue)) {\n values[path] = nextValue as DialValue;\n continue;\n }\n\n if (\n typeof configValue === 'object' &&\n configValue !== null &&\n typeof nextValue === 'object' &&\n nextValue !== null &&\n !Array.isArray(nextValue)\n ) {\n flattenConfigUpdates(configValue as DialConfig, nextValue as Record<string, unknown>, path, values);\n }\n }\n}\n\nfunction isLeafConfigValue(value: unknown): boolean {\n return (\n (Array.isArray(value) && value.length <= 4 && typeof value[0] === 'number') ||\n typeof value === 'number' ||\n typeof value === 'boolean' ||\n typeof value === 'string' ||\n isSpringConfigValue(value) ||\n isEasingConfigValue(value) ||\n isActionConfigValue(value) ||\n isSelectConfigValue(value) ||\n isColorConfigValue(value) ||\n isTextConfigValue(value)\n );\n}\n\nfunction hasType(value: unknown, type: string): boolean {\n return typeof value === 'object' && value !== null && 'type' in value && (value as { type: string }).type === type;\n}\n\nexport function isSpringConfigValue(value: unknown): value is SpringConfig {\n return hasType(value, 'spring');\n}\n\nexport function isEasingConfigValue(value: unknown): value is EasingConfig {\n return hasType(value, 'easing');\n}\n\nexport function isHexColor(value: string): boolean {\n return /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(value);\n}\n\n/** camelCase → Title Case, the label rule used everywhere a key becomes UI text. */\nexport function formatLabel(key: string): string {\n return key\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, str => str.toUpperCase())\n .trim();\n}\n\n/** Default slider step for a numeric range. */\nexport function inferStep(min: number, max: number): number {\n const range = max - min;\n if (range <= 1) return 0.01;\n if (range <= 10) return 0.1;\n if (range <= 100) return 1;\n return 10;\n}\n\nfunction isActionConfigValue(value: unknown): value is ActionConfig {\n return hasType(value, 'action');\n}\n\nfunction isSelectConfigValue(value: unknown): value is SelectConfig {\n return hasType(value, 'select') && 'options' in (value as object) && Array.isArray((value as SelectConfig).options);\n}\n\nfunction isColorConfigValue(value: unknown): value is ColorConfig {\n return hasType(value, 'color');\n}\n\nfunction isTextConfigValue(value: unknown): value is TextConfig {\n return hasType(value, 'text');\n}\n\nfunction getFirstOptionValue(options: (string | { value: string; label: string })[]): string {\n const first = options[0];\n if (first === undefined) return '';\n return typeof first === 'string' ? first : first.value;\n}\n\nclass DialStoreClass {\n private panels: Map<string, PanelConfig> = new Map();\n private panelsSnapshot: PanelConfig[] = [];\n private standardPanelsSnapshot: PanelConfig[] = [];\n private timelinePanelsSnapshot: PanelConfig[] = [];\n private listeners: Map<string, Set<Listener>> = new Map();\n private globalListeners: Set<Listener> = new Set();\n private snapshots: Map<string, Record<string, DialValue>> = new Map();\n private actionListeners: Map<string, Set<ActionListener>> = new Map();\n private presets: Map<string, Preset[]> = new Map();\n private activePreset: Map<string, string | null> = new Map();\n private baseValues: Map<string, Record<string, DialValue>> = new Map();\n private defaultValues: Map<string, Record<string, DialValue>> = new Map();\n private registrationCounts: Map<string, number> = new Map();\n private retainedPanels: Set<string> = new Set();\n private persistConfigs: Map<string, PersistConfig> = new Map();\n\n registerPanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>, options: DialStorePanelOptions = {}): void {\n const existingPanel = this.panels.get(id);\n if (existingPanel && existingPanel.kind !== options.kind) {\n console.warn(\n `[dialkit] Panel id \"${id}\" cannot be shared by a timeline and a standard panel; ` +\n `the most recent registration controls where it renders.`\n );\n }\n this.configurePanelRetention(id, options);\n this.registrationCounts.set(id, (this.registrationCounts.get(id) ?? 0) + 1);\n\n const controls = this.parseConfig(config, '', shortcuts);\n const controlsByPath = this.mapControlsByPath(controls);\n const defaultValues = this.flattenValues(config, '');\n\n // Set initial transition modes based on config types\n this.initTransitionModes(config, '', defaultValues);\n\n const persisted = this.loadPersistedPanel(id);\n const previousValues = this.panels.get(id)?.values ?? this.snapshots.get(id) ?? persisted?.values ?? {};\n const values = this.reconcileValues(defaultValues, previousValues, controlsByPath);\n\n const previousBaseValues = this.baseValues.get(id) ?? persisted?.baseValues ?? persisted?.values ?? {};\n const baseValues = this.reconcileValues(defaultValues, previousBaseValues, controlsByPath);\n\n this.panels.set(id, { id, name, controls, values, shortcuts: shortcuts ?? {}, kind: options.kind });\n this.snapshots.set(id, { ...values });\n this.baseValues.set(id, baseValues);\n this.defaultValues.set(id, { ...defaultValues });\n\n const existingPresets = this.presets.get(id) ?? persisted?.presets;\n if (existingPresets) {\n this.presets.set(id, this.reconcilePresets(existingPresets, defaultValues, controlsByPath));\n }\n if (!this.activePreset.has(id) && persisted?.activePresetId !== undefined) {\n this.activePreset.set(id, persisted.activePresetId);\n }\n\n this.persistPanel(id);\n this.notify(id);\n this.notifyGlobal();\n }\n\n updatePanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>, options: DialStorePanelOptions = {}): void {\n this.configurePanelRetention(id, options);\n const existing = this.panels.get(id);\n if (!existing) {\n this.registerPanel(id, name, config, shortcuts, options);\n return;\n }\n\n const controls = this.parseConfig(config, '', shortcuts);\n const controlsByPath = this.mapControlsByPath(controls);\n const defaultValues = this.flattenValues(config, '');\n this.initTransitionModes(config, '', defaultValues);\n const nextValues = this.reconcileValues(defaultValues, existing.values, controlsByPath);\n\n const nextPanel: PanelConfig = { id, name, controls, values: nextValues, shortcuts: shortcuts ?? existing.shortcuts, kind: options.kind ?? existing.kind };\n this.panels.set(id, nextPanel);\n this.snapshots.set(id, { ...nextValues });\n\n const previousBaseValues = this.baseValues.get(id) ?? {};\n const nextBaseValues = this.reconcileValues(defaultValues, previousBaseValues, controlsByPath);\n\n for (const [path, value] of Object.entries(nextValues)) {\n if (path.endsWith('.__mode')) {\n nextBaseValues[path] = value;\n }\n }\n\n this.baseValues.set(id, nextBaseValues);\n this.defaultValues.set(id, { ...defaultValues });\n this.presets.set(id, this.reconcilePresets(this.presets.get(id) ?? [], defaultValues, controlsByPath));\n\n this.persistPanel(id);\n this.notify(id);\n this.notifyGlobal();\n }\n\n unregisterPanel(id: string): void {\n const nextCount = (this.registrationCounts.get(id) ?? 1) - 1;\n if (nextCount > 0) {\n this.registrationCounts.set(id, nextCount);\n return;\n }\n\n this.registrationCounts.delete(id);\n this.panels.delete(id);\n // Keep listener sets: subscribed components can outlive the registration\n // (HMR unregister/re-register of the same id) and must keep receiving\n // notifications. Cleanup happens via unsubscribe closures.\n if (this.listeners.get(id)?.size === 0) this.listeners.delete(id);\n if (this.actionListeners.get(id)?.size === 0) this.actionListeners.delete(id);\n\n if (!this.retainedPanels.has(id)) {\n this.snapshots.delete(id);\n this.baseValues.delete(id);\n this.defaultValues.delete(id);\n this.presets.delete(id);\n this.activePreset.delete(id);\n this.persistConfigs.delete(id);\n }\n\n this.notifyGlobal();\n }\n\n updateValue(panelId: string, path: string, value: DialValue): void {\n this.updateValues(panelId, { [path]: value });\n }\n\n updateValues(panelId: string, updates: Record<string, DialValue>): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n const validUpdates: Record<string, DialValue> = {};\n\n for (const [path, value] of Object.entries(updates)) {\n if (!Object.prototype.hasOwnProperty.call(panel.values, path)) {\n continue;\n }\n\n const control = this.findControlByPath(panel.controls, path);\n if (control?.type === 'action') {\n continue;\n }\n\n panel.values[path] = value;\n validUpdates[path] = value;\n }\n\n if (Object.keys(validUpdates).length === 0) {\n return;\n }\n\n // Auto-save to active preset or base values\n const activeId = this.activePreset.get(panelId);\n if (activeId) {\n const presets = this.presets.get(panelId) ?? [];\n const preset = presets.find(p => p.id === activeId);\n if (preset) {\n for (const [path, value] of Object.entries(validUpdates)) {\n preset.values[path] = value;\n }\n }\n } else {\n const base = this.baseValues.get(panelId);\n if (base) {\n for (const [path, value] of Object.entries(validUpdates)) {\n base[path] = value;\n }\n }\n }\n\n // Create a new snapshot reference so useSyncExternalStore detects the change\n this.snapshots.set(panelId, { ...panel.values });\n this.persistPanel(panelId);\n this.notify(panelId);\n }\n\n resetValues(panelId: string): void {\n const panel = this.panels.get(panelId);\n const defaults = this.defaultValues.get(panelId);\n if (!panel || !defaults) return;\n\n panel.values = { ...defaults };\n this.snapshots.set(panelId, { ...panel.values });\n this.baseValues.set(panelId, { ...defaults });\n this.activePreset.set(panelId, null);\n this.persistPanel(panelId);\n this.notify(panelId);\n }\n\n updateSpringMode(panelId: string, path: string, mode: 'simple' | 'advanced'): void {\n this.updateTransitionMode(panelId, path, mode);\n }\n\n getSpringMode(panelId: string, path: string): 'simple' | 'advanced' {\n const mode = this.getTransitionMode(panelId, path);\n if (mode === 'easing') return 'simple';\n return mode;\n }\n\n updateTransitionMode(panelId: string, path: string, mode: 'easing' | 'simple' | 'advanced'): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n panel.values[`${path}.__mode`] = mode;\n this.snapshots.set(panelId, { ...panel.values });\n this.persistPanel(panelId);\n this.notify(panelId);\n }\n\n getTransitionMode(panelId: string, path: string): 'easing' | 'simple' | 'advanced' {\n const panel = this.panels.get(panelId);\n if (!panel) return 'simple';\n return (panel.values[`${path}.__mode`] as 'easing' | 'simple' | 'advanced') || 'simple';\n }\n\n getValue(panelId: string, path: string): DialValue | undefined {\n const panel = this.panels.get(panelId);\n return panel?.values[path];\n }\n\n getValues(panelId: string): Record<string, DialValue> {\n // Return the snapshot for useSyncExternalStore compatibility\n // Use stable EMPTY_VALUES to avoid infinite loop in React 19\n return this.snapshots.get(panelId) ?? EMPTY_VALUES;\n }\n\n getPanels(kind?: 'panel' | 'timeline'): PanelConfig[] {\n // Stable reference between global notifications: getSnapshot-style\n // consumers (React useSyncExternalStore, Solid `from`) compare by\n // identity, and a fresh array on every call makes them loop or re-render.\n if (kind === 'panel') return this.standardPanelsSnapshot;\n if (kind === 'timeline') return this.timelinePanelsSnapshot;\n return this.panelsSnapshot;\n }\n\n getPanel(id: string): PanelConfig | undefined {\n return this.panels.get(id);\n }\n\n subscribe(panelId: string, listener: Listener): () => void {\n if (!this.listeners.has(panelId)) {\n this.listeners.set(panelId, new Set());\n }\n this.listeners.get(panelId)!.add(listener);\n\n return () => {\n const listeners = this.listeners.get(panelId);\n listeners?.delete(listener);\n if (listeners?.size === 0 && !this.panels.has(panelId)) {\n this.listeners.delete(panelId);\n }\n };\n }\n\n subscribeGlobal(listener: Listener): () => void {\n this.globalListeners.add(listener);\n return () => this.globalListeners.delete(listener);\n }\n\n subscribeActions(panelId: string, listener: ActionListener): () => void {\n if (!this.actionListeners.has(panelId)) {\n this.actionListeners.set(panelId, new Set());\n }\n this.actionListeners.get(panelId)!.add(listener);\n\n return () => {\n const listeners = this.actionListeners.get(panelId);\n listeners?.delete(listener);\n if (listeners?.size === 0 && !this.panels.has(panelId)) {\n this.actionListeners.delete(panelId);\n }\n };\n }\n\n triggerAction(panelId: string, path: string): void {\n this.actionListeners.get(panelId)?.forEach(fn => fn(path));\n }\n\n savePreset(panelId: string, name: string): string {\n const panel = this.panels.get(panelId);\n if (!panel) throw new Error(`Panel ${panelId} not found`);\n\n const id = `preset-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n const preset: Preset = {\n id,\n name,\n values: { ...panel.values },\n };\n\n const existing = this.presets.get(panelId) ?? [];\n this.presets.set(panelId, [...existing, preset]);\n this.activePreset.set(panelId, id);\n\n // Force re-render by creating new snapshot reference\n this.snapshots.set(panelId, { ...panel.values });\n this.persistPanel(panelId);\n this.notify(panelId);\n\n return id;\n }\n\n loadPreset(panelId: string, presetId: string): void {\n const panel = this.panels.get(panelId);\n if (!panel) return;\n\n const presets = this.presets.get(panelId) ?? [];\n const preset = presets.find(p => p.id === presetId);\n if (!preset) return;\n\n // Apply preset values\n panel.values = { ...preset.values };\n this.snapshots.set(panelId, { ...panel.values });\n this.activePreset.set(panelId, presetId);\n this.persistPanel(panelId);\n this.notify(panelId);\n }\n\n deletePreset(panelId: string, presetId: string): void {\n const presets = this.presets.get(panelId) ?? [];\n this.presets.set(panelId, presets.filter(p => p.id !== presetId));\n\n // Clear active if deleted\n if (this.activePreset.get(panelId) === presetId) {\n this.activePreset.set(panelId, null);\n }\n\n // Force re-render by creating new snapshot reference\n const panel = this.panels.get(panelId);\n if (panel) {\n this.snapshots.set(panelId, { ...panel.values });\n }\n this.persistPanel(panelId);\n this.notify(panelId);\n }\n\n getPresets(panelId: string): Preset[] {\n return this.presets.get(panelId) ?? [];\n }\n\n getActivePresetId(panelId: string): string | null {\n return this.activePreset.get(panelId) ?? null;\n }\n\n clearActivePreset(panelId: string): void {\n const panel = this.panels.get(panelId);\n const base = this.baseValues.get(panelId);\n if (panel && base) {\n panel.values = { ...base };\n this.snapshots.set(panelId, { ...panel.values });\n }\n this.activePreset.set(panelId, null);\n this.persistPanel(panelId);\n this.notify(panelId);\n }\n\n resolveShortcutTarget(key: string, modifier?: 'alt' | 'shift' | 'meta'): {\n panelId: string;\n path: string;\n control: ControlMeta;\n } | null {\n for (const panel of this.panels.values()) {\n for (const [path, shortcut] of Object.entries(panel.shortcuts)) {\n if (!shortcut.key) continue; // skip keyless shortcuts\n if (shortcut.key.toLowerCase() !== key.toLowerCase()) continue;\n const scMod = shortcut.modifier ?? undefined;\n if (scMod !== modifier) continue;\n\n const control = this.findControlByPath(panel.controls, path);\n if (control) {\n return { panelId: panel.id, path, control };\n }\n }\n }\n return null;\n }\n\n resolveScrollOnlyTargets(): Array<{\n panelId: string;\n path: string;\n control: ControlMeta;\n shortcut: ShortcutConfig;\n }> {\n const results: Array<{ panelId: string; path: string; control: ControlMeta; shortcut: ShortcutConfig }> = [];\n for (const panel of this.panels.values()) {\n for (const [path, shortcut] of Object.entries(panel.shortcuts)) {\n if ((shortcut.interaction ?? 'scroll') !== 'scroll-only') continue;\n const control = this.findControlByPath(panel.controls, path);\n if (control) {\n results.push({ panelId: panel.id, path, control, shortcut });\n }\n }\n }\n return results;\n }\n\n private configurePanelRetention(id: string, options: DialStorePanelOptions): void {\n if (options.retainOnUnmount) {\n this.retainedPanels.add(id);\n }\n\n const persistConfig = this.normalizePersistConfig(id, options.persist);\n if (persistConfig) {\n this.persistConfigs.set(id, persistConfig);\n this.retainedPanels.add(id);\n }\n }\n\n private reconcileValues(\n defaultValues: Record<string, DialValue>,\n previousValues: Record<string, DialValue>,\n controlsByPath: Map<string, ControlMeta>\n ): Record<string, DialValue> {\n const nextValues: Record<string, DialValue> = {};\n\n for (const [path, defaultValue] of Object.entries(defaultValues)) {\n if (path.endsWith('.__mode')) {\n const transitionPath = path.slice(0, -'.__mode'.length);\n const transitionControl = controlsByPath.get(transitionPath);\n nextValues[path] = transitionControl?.type === 'transition' && previousValues[path] !== undefined\n ? previousValues[path]\n : defaultValue;\n continue;\n }\n\n nextValues[path] = this.normalizePreservedValue(\n previousValues[path],\n defaultValue,\n controlsByPath.get(path)\n );\n }\n\n return nextValues;\n }\n\n private reconcilePresets(\n presets: Preset[],\n defaultValues: Record<string, DialValue>,\n controlsByPath: Map<string, ControlMeta>\n ): Preset[] {\n return presets.map((preset) => ({\n ...preset,\n values: this.reconcileValues(defaultValues, preset.values, controlsByPath),\n }));\n }\n\n private normalizePersistConfig(id: string, persist: DialKitPersistOptions | undefined): PersistConfig | null {\n if (!persist) return null;\n const options = typeof persist === 'object' ? persist : {};\n return {\n key: options.key ?? `dialkit:${id}`,\n storage: options.storage ?? 'localStorage',\n presets: options.presets ?? true,\n };\n }\n\n private loadPersistedPanel(id: string): PersistedPanelState | null {\n const config = this.persistConfigs.get(id);\n if (!config) return null;\n\n const storage = this.getStorage(config.storage);\n if (!storage) return null;\n\n try {\n const raw = storage.getItem(config.key);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as PersistedPanelState;\n if (parsed?.version !== 1 || typeof parsed !== 'object') return null;\n return parsed;\n } catch {\n return null;\n }\n }\n\n private persistPanel(id: string): void {\n const config = this.persistConfigs.get(id);\n if (!config) return;\n\n const storage = this.getStorage(config.storage);\n if (!storage) return;\n\n const values = this.snapshots.get(id) ?? this.panels.get(id)?.values;\n if (!values) return;\n\n const state: PersistedPanelState = {\n version: 1,\n values,\n baseValues: this.baseValues.get(id) ?? values,\n activePresetId: this.activePreset.get(id) ?? null,\n };\n\n if (config.presets) {\n state.presets = this.presets.get(id) ?? [];\n }\n\n try {\n storage.setItem(config.key, JSON.stringify(state));\n } catch {\n // Ignore storage quota/security errors; DialKit should still work in-memory.\n }\n }\n\n private getStorage(kind: 'localStorage' | 'sessionStorage'): Storage | null {\n if (typeof globalThis === 'undefined' || !('window' in globalThis)) {\n return null;\n }\n\n try {\n return kind === 'sessionStorage'\n ? globalThis.window?.sessionStorage ?? null\n : globalThis.window?.localStorage ?? null;\n } catch {\n return null;\n }\n }\n\n private findControlByPath(controls: ControlMeta[], path: string): ControlMeta | null {\n for (const control of controls) {\n if (control.path === path) return control;\n if (control.type === 'folder' && control.children) {\n const found = this.findControlByPath(control.children, path);\n if (found) return found;\n }\n }\n return null;\n }\n\n private notify(panelId: string): void {\n this.listeners.get(panelId)?.forEach(fn => fn());\n }\n\n private notifyGlobal(): void {\n this.panelsSnapshot = Array.from(this.panels.values());\n this.standardPanelsSnapshot = this.panelsSnapshot.filter((panel) => panel.kind !== 'timeline');\n this.timelinePanelsSnapshot = this.panelsSnapshot.filter((panel) => panel.kind === 'timeline');\n this.globalListeners.forEach(fn => fn());\n }\n\n private initTransitionModes(config: DialConfig, prefix: string, values: Record<string, DialValue>): void {\n for (const [key, value] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (this.isEasingConfig(value)) {\n values[`${path}.__mode`] = 'easing';\n } else if (this.isSpringConfig(value)) {\n // Detect physics mode from config\n const hasPhysics = value.stiffness !== undefined || value.damping !== undefined || value.mass !== undefined;\n const hasTime = value.visualDuration !== undefined || value.bounce !== undefined;\n values[`${path}.__mode`] = hasPhysics && !hasTime ? 'advanced' : 'simple';\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value) && !this.isActionConfig(value) && !this.isSelectConfig(value) && !this.isColorConfig(value) && !this.isTextConfig(value)) {\n this.initTransitionModes(value as DialConfig, path, values);\n }\n }\n }\n\n private parseConfig(config: DialConfig, prefix: string, shortcuts?: Record<string, ShortcutConfig>): ControlMeta[] {\n const controls: ControlMeta[] = [];\n\n for (const [key, value] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n const label = this.formatLabel(key);\n const shortcut = shortcuts?.[path];\n\n if (Array.isArray(value) && value.length <= 4 && typeof value[0] === 'number') {\n // Range tuple: [default, min, max]\n controls.push({\n type: 'slider',\n path,\n label,\n min: value[1],\n max: value[2],\n step: value[3] ?? this.inferStep(value[1], value[2]),\n shortcut,\n });\n } else if (typeof value === 'number') {\n // Single number - auto-infer range\n const { min, max, step } = this.inferRange(value);\n controls.push({ type: 'slider', path, label, min, max, step, shortcut });\n } else if (typeof value === 'boolean') {\n controls.push({ type: 'toggle', path, label, shortcut });\n } else if (this.isSpringConfig(value) || this.isEasingConfig(value)) {\n controls.push({ type: 'transition', path, label });\n } else if (this.isActionConfig(value)) {\n controls.push({ type: 'action', path, label: (value as ActionConfig).label || label });\n } else if (this.isSelectConfig(value)) {\n controls.push({ type: 'select', path, label, options: value.options });\n } else if (this.isColorConfig(value)) {\n controls.push({ type: 'color', path, label });\n } else if (this.isTextConfig(value)) {\n controls.push({ type: 'text', path, label, placeholder: value.placeholder });\n } else if (typeof value === 'string') {\n // Auto-detect: hex color vs text\n if (this.isHexColor(value)) {\n controls.push({ type: 'color', path, label });\n } else {\n controls.push({ type: 'text', path, label });\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object becomes a folder\n const folderConfig = value as DialConfig;\n const defaultOpen = '_collapsed' in folderConfig ? !(folderConfig._collapsed as boolean) : true;\n controls.push({\n type: 'folder',\n path,\n label,\n defaultOpen,\n children: this.parseConfig(folderConfig, path, shortcuts),\n });\n }\n }\n\n return controls;\n }\n\n private flattenValues(config: DialConfig, prefix: string): Record<string, DialValue> {\n const values: Record<string, DialValue> = {};\n\n for (const [key, value] of Object.entries(config)) {\n if (key === '_collapsed') continue;\n const path = prefix ? `${prefix}.${key}` : key;\n\n if (Array.isArray(value) && value.length <= 4 && typeof value[0] === 'number') {\n values[path] = value[0]; // Default value\n } else if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string') {\n values[path] = value;\n } else if (this.isSpringConfig(value) || this.isEasingConfig(value)) {\n values[path] = value;\n } else if (this.isActionConfig(value)) {\n // Actions don't need stored values - they're just triggers\n values[path] = value;\n } else if (this.isSelectConfig(value)) {\n // Use default or first option's value\n const firstOption = value.options[0];\n const firstValue = typeof firstOption === 'string' ? firstOption : firstOption.value;\n values[path] = value.default ?? firstValue;\n } else if (this.isColorConfig(value)) {\n values[path] = value.default ?? '#000000';\n } else if (this.isTextConfig(value)) {\n values[path] = value.default ?? '';\n } else if (typeof value === 'object' && value !== null) {\n Object.assign(values, this.flattenValues(value as DialConfig, path));\n }\n }\n\n return values;\n }\n\n private isSpringConfig(value: unknown): value is SpringConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as SpringConfig).type === 'spring'\n );\n }\n\n private isEasingConfig(value: unknown): value is EasingConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as EasingConfig).type === 'easing'\n );\n }\n\n private isActionConfig(value: unknown): value is ActionConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as ActionConfig).type === 'action'\n );\n }\n\n private isSelectConfig(value: unknown): value is SelectConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as SelectConfig).type === 'select' &&\n 'options' in value &&\n Array.isArray((value as SelectConfig).options)\n );\n }\n\n private isColorConfig(value: unknown): value is ColorConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as ColorConfig).type === 'color'\n );\n }\n\n private isTextConfig(value: unknown): value is TextConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as TextConfig).type === 'text'\n );\n }\n\n private isHexColor(value: string): boolean {\n return isHexColor(value);\n }\n\n private formatLabel(key: string): string {\n return formatLabel(key);\n }\n\n private inferRange(value: number): { min: number; max: number; step: number } {\n // Infer reasonable range based on value\n if (value >= 0 && value <= 1) {\n return { min: 0, max: 1, step: 0.01 };\n } else if (value >= 0 && value <= 10) {\n return { min: 0, max: value * 3 || 10, step: 0.1 };\n } else if (value >= 0 && value <= 100) {\n return { min: 0, max: value * 3 || 100, step: 1 };\n } else if (value >= 0) {\n return { min: 0, max: value * 3 || 1000, step: 10 };\n } else {\n return { min: value * 3, max: -value * 3, step: 1 };\n }\n }\n\n private inferStep(min: number, max: number): number {\n return inferStep(min, max);\n }\n\n private normalizePreservedValue(\n existingValue: DialValue | undefined,\n defaultValue: DialValue,\n control: ControlMeta | undefined\n ): DialValue {\n if (existingValue === undefined || !control) {\n return defaultValue;\n }\n\n switch (control.type) {\n case 'slider': {\n if (typeof existingValue !== 'number' || typeof defaultValue !== 'number') {\n return defaultValue;\n }\n\n const min = control.min ?? Number.NEGATIVE_INFINITY;\n const max = control.max ?? Number.POSITIVE_INFINITY;\n const clamped = Math.min(max, Math.max(min, existingValue));\n\n if (typeof control.step !== 'number' || control.step <= 0) {\n return clamped;\n }\n\n return this.roundToStep(clamped, min, max, control.step);\n }\n case 'toggle':\n return typeof existingValue === 'boolean' ? existingValue : defaultValue;\n case 'select': {\n if (typeof existingValue !== 'string') {\n return defaultValue;\n }\n\n const options = control.options ?? [];\n const validValues = new Set(options.map((option) => (typeof option === 'string' ? option : option.value)));\n return validValues.has(existingValue) ? existingValue : defaultValue;\n }\n case 'color':\n case 'text':\n return typeof existingValue === 'string' ? existingValue : defaultValue;\n case 'transition':\n if (this.isSpringConfig(defaultValue)) {\n return this.isSpringConfig(existingValue) ? existingValue : defaultValue;\n }\n if (this.isEasingConfig(defaultValue)) {\n return this.isEasingConfig(existingValue) ? existingValue : defaultValue;\n }\n return defaultValue;\n case 'action':\n return defaultValue;\n default:\n return defaultValue;\n }\n }\n\n private roundToStep(value: number, min: number, max: number, step: number): number {\n const snapped = min + Math.round((value - min) / step) * step;\n const clamped = Math.min(max, Math.max(min, snapped));\n const precision = this.stepPrecision(step);\n return Number(clamped.toFixed(precision));\n }\n\n private stepPrecision(step: number): number {\n const text = String(step);\n const decimalIndex = text.indexOf('.');\n return decimalIndex === -1 ? 0 : text.length - decimalIndex - 1;\n }\n\n private mapControlsByPath(controls: ControlMeta[]): Map<string, ControlMeta> {\n const map = new Map<string, ControlMeta>();\n\n const visit = (nodes: ControlMeta[]) => {\n for (const node of nodes) {\n if (node.type === 'folder' && node.children) {\n visit(node.children);\n continue;\n }\n\n map.set(node.path, node);\n }\n };\n\n visit(controls);\n return map;\n }\n\n}\n\n// Singleton instance\nexport const DialStore = /* @__PURE__ */ new DialStoreClass();\n"],"mappings":"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","names":[]}
|
package/dist/store/index.d.cts
CHANGED
|
@@ -40,6 +40,9 @@ type DialConfig = {
|
|
|
40
40
|
type ResolvedValues<T extends DialConfig> = {
|
|
41
41
|
[K in keyof T]: T[K] extends [number, number, number, number?] ? number : T[K] extends SpringConfig ? TransitionConfig : T[K] extends EasingConfig ? TransitionConfig : T[K] extends SelectConfig ? string : T[K] extends ColorConfig ? string : T[K] extends TextConfig ? string : T[K] extends DialConfig ? ResolvedValues<T[K]> : T[K];
|
|
42
42
|
};
|
|
43
|
+
type DialKitValueUpdates<T extends DialConfig> = {
|
|
44
|
+
[K in keyof T as K extends '_collapsed' ? never : K]?: T[K] extends [number, number, number, number?] ? number : T[K] extends SpringConfig | EasingConfig ? TransitionConfig : T[K] extends ActionConfig ? never : T[K] extends SelectConfig | ColorConfig | TextConfig ? string : T[K] extends DialConfig ? DialKitValueUpdates<T[K]> : T[K];
|
|
45
|
+
};
|
|
43
46
|
type ShortcutMode = 'fine' | 'normal' | 'coarse';
|
|
44
47
|
type ShortcutInteraction = 'scroll' | 'drag' | 'move' | 'scroll-only';
|
|
45
48
|
type ShortcutConfig = {
|
|
@@ -70,6 +73,7 @@ type PanelConfig = {
|
|
|
70
73
|
controls: ControlMeta[];
|
|
71
74
|
values: Record<string, DialValue>;
|
|
72
75
|
shortcuts: Record<string, ShortcutConfig>;
|
|
76
|
+
kind?: 'timeline';
|
|
73
77
|
};
|
|
74
78
|
type Listener = () => void;
|
|
75
79
|
type ActionListener = (action: string) => void;
|
|
@@ -78,8 +82,30 @@ type Preset = {
|
|
|
78
82
|
name: string;
|
|
79
83
|
values: Record<string, DialValue>;
|
|
80
84
|
};
|
|
85
|
+
type DialKitPersistOptions = boolean | {
|
|
86
|
+
key?: string;
|
|
87
|
+
storage?: 'localStorage' | 'sessionStorage';
|
|
88
|
+
presets?: boolean;
|
|
89
|
+
};
|
|
90
|
+
type DialStorePanelOptions = {
|
|
91
|
+
retainOnUnmount?: boolean;
|
|
92
|
+
persist?: DialKitPersistOptions;
|
|
93
|
+
kind?: 'timeline';
|
|
94
|
+
};
|
|
95
|
+
declare function resolveDialValues<T extends DialConfig>(config: T, flatValues: Record<string, DialValue>): ResolvedValues<T>;
|
|
96
|
+
declare function flattenDialValueUpdates<T extends DialConfig>(config: T, updates: DialKitValueUpdates<T>): Record<string, DialValue>;
|
|
97
|
+
declare function isSpringConfigValue(value: unknown): value is SpringConfig;
|
|
98
|
+
declare function isEasingConfigValue(value: unknown): value is EasingConfig;
|
|
99
|
+
declare function isHexColor(value: string): boolean;
|
|
100
|
+
/** camelCase → Title Case, the label rule used everywhere a key becomes UI text. */
|
|
101
|
+
declare function formatLabel(key: string): string;
|
|
102
|
+
/** Default slider step for a numeric range. */
|
|
103
|
+
declare function inferStep(min: number, max: number): number;
|
|
81
104
|
declare class DialStoreClass {
|
|
82
105
|
private panels;
|
|
106
|
+
private panelsSnapshot;
|
|
107
|
+
private standardPanelsSnapshot;
|
|
108
|
+
private timelinePanelsSnapshot;
|
|
83
109
|
private listeners;
|
|
84
110
|
private globalListeners;
|
|
85
111
|
private snapshots;
|
|
@@ -87,17 +113,23 @@ declare class DialStoreClass {
|
|
|
87
113
|
private presets;
|
|
88
114
|
private activePreset;
|
|
89
115
|
private baseValues;
|
|
90
|
-
|
|
91
|
-
|
|
116
|
+
private defaultValues;
|
|
117
|
+
private registrationCounts;
|
|
118
|
+
private retainedPanels;
|
|
119
|
+
private persistConfigs;
|
|
120
|
+
registerPanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>, options?: DialStorePanelOptions): void;
|
|
121
|
+
updatePanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>, options?: DialStorePanelOptions): void;
|
|
92
122
|
unregisterPanel(id: string): void;
|
|
93
123
|
updateValue(panelId: string, path: string, value: DialValue): void;
|
|
124
|
+
updateValues(panelId: string, updates: Record<string, DialValue>): void;
|
|
125
|
+
resetValues(panelId: string): void;
|
|
94
126
|
updateSpringMode(panelId: string, path: string, mode: 'simple' | 'advanced'): void;
|
|
95
127
|
getSpringMode(panelId: string, path: string): 'simple' | 'advanced';
|
|
96
128
|
updateTransitionMode(panelId: string, path: string, mode: 'easing' | 'simple' | 'advanced'): void;
|
|
97
129
|
getTransitionMode(panelId: string, path: string): 'easing' | 'simple' | 'advanced';
|
|
98
130
|
getValue(panelId: string, path: string): DialValue | undefined;
|
|
99
131
|
getValues(panelId: string): Record<string, DialValue>;
|
|
100
|
-
getPanels(): PanelConfig[];
|
|
132
|
+
getPanels(kind?: 'panel' | 'timeline'): PanelConfig[];
|
|
101
133
|
getPanel(id: string): PanelConfig | undefined;
|
|
102
134
|
subscribe(panelId: string, listener: Listener): () => void;
|
|
103
135
|
subscribeGlobal(listener: Listener): () => void;
|
|
@@ -120,6 +152,13 @@ declare class DialStoreClass {
|
|
|
120
152
|
control: ControlMeta;
|
|
121
153
|
shortcut: ShortcutConfig;
|
|
122
154
|
}>;
|
|
155
|
+
private configurePanelRetention;
|
|
156
|
+
private reconcileValues;
|
|
157
|
+
private reconcilePresets;
|
|
158
|
+
private normalizePersistConfig;
|
|
159
|
+
private loadPersistedPanel;
|
|
160
|
+
private persistPanel;
|
|
161
|
+
private getStorage;
|
|
123
162
|
private findControlByPath;
|
|
124
163
|
private notify;
|
|
125
164
|
private notifyGlobal;
|
|
@@ -143,4 +182,4 @@ declare class DialStoreClass {
|
|
|
143
182
|
}
|
|
144
183
|
declare const DialStore: DialStoreClass;
|
|
145
184
|
|
|
146
|
-
export { type ActionConfig, type ColorConfig, type ControlMeta, type DialConfig, DialStore, type DialValue, type EasingConfig, type PanelConfig, type Preset, type ResolvedValues, type SelectConfig, type ShortcutConfig, type ShortcutInteraction, type ShortcutMode, type SpringConfig, type TextConfig, type TransitionConfig };
|
|
185
|
+
export { type ActionConfig, type ColorConfig, type ControlMeta, type DialConfig, type DialKitPersistOptions, type DialKitValueUpdates, DialStore, type DialStorePanelOptions, type DialValue, type EasingConfig, type PanelConfig, type Preset, type ResolvedValues, type SelectConfig, type ShortcutConfig, type ShortcutInteraction, type ShortcutMode, type SpringConfig, type TextConfig, type TransitionConfig, flattenDialValueUpdates, formatLabel, inferStep, isEasingConfigValue, isHexColor, isSpringConfigValue, resolveDialValues };
|
package/dist/store/index.d.ts
CHANGED
|
@@ -40,6 +40,9 @@ type DialConfig = {
|
|
|
40
40
|
type ResolvedValues<T extends DialConfig> = {
|
|
41
41
|
[K in keyof T]: T[K] extends [number, number, number, number?] ? number : T[K] extends SpringConfig ? TransitionConfig : T[K] extends EasingConfig ? TransitionConfig : T[K] extends SelectConfig ? string : T[K] extends ColorConfig ? string : T[K] extends TextConfig ? string : T[K] extends DialConfig ? ResolvedValues<T[K]> : T[K];
|
|
42
42
|
};
|
|
43
|
+
type DialKitValueUpdates<T extends DialConfig> = {
|
|
44
|
+
[K in keyof T as K extends '_collapsed' ? never : K]?: T[K] extends [number, number, number, number?] ? number : T[K] extends SpringConfig | EasingConfig ? TransitionConfig : T[K] extends ActionConfig ? never : T[K] extends SelectConfig | ColorConfig | TextConfig ? string : T[K] extends DialConfig ? DialKitValueUpdates<T[K]> : T[K];
|
|
45
|
+
};
|
|
43
46
|
type ShortcutMode = 'fine' | 'normal' | 'coarse';
|
|
44
47
|
type ShortcutInteraction = 'scroll' | 'drag' | 'move' | 'scroll-only';
|
|
45
48
|
type ShortcutConfig = {
|
|
@@ -70,6 +73,7 @@ type PanelConfig = {
|
|
|
70
73
|
controls: ControlMeta[];
|
|
71
74
|
values: Record<string, DialValue>;
|
|
72
75
|
shortcuts: Record<string, ShortcutConfig>;
|
|
76
|
+
kind?: 'timeline';
|
|
73
77
|
};
|
|
74
78
|
type Listener = () => void;
|
|
75
79
|
type ActionListener = (action: string) => void;
|
|
@@ -78,8 +82,30 @@ type Preset = {
|
|
|
78
82
|
name: string;
|
|
79
83
|
values: Record<string, DialValue>;
|
|
80
84
|
};
|
|
85
|
+
type DialKitPersistOptions = boolean | {
|
|
86
|
+
key?: string;
|
|
87
|
+
storage?: 'localStorage' | 'sessionStorage';
|
|
88
|
+
presets?: boolean;
|
|
89
|
+
};
|
|
90
|
+
type DialStorePanelOptions = {
|
|
91
|
+
retainOnUnmount?: boolean;
|
|
92
|
+
persist?: DialKitPersistOptions;
|
|
93
|
+
kind?: 'timeline';
|
|
94
|
+
};
|
|
95
|
+
declare function resolveDialValues<T extends DialConfig>(config: T, flatValues: Record<string, DialValue>): ResolvedValues<T>;
|
|
96
|
+
declare function flattenDialValueUpdates<T extends DialConfig>(config: T, updates: DialKitValueUpdates<T>): Record<string, DialValue>;
|
|
97
|
+
declare function isSpringConfigValue(value: unknown): value is SpringConfig;
|
|
98
|
+
declare function isEasingConfigValue(value: unknown): value is EasingConfig;
|
|
99
|
+
declare function isHexColor(value: string): boolean;
|
|
100
|
+
/** camelCase → Title Case, the label rule used everywhere a key becomes UI text. */
|
|
101
|
+
declare function formatLabel(key: string): string;
|
|
102
|
+
/** Default slider step for a numeric range. */
|
|
103
|
+
declare function inferStep(min: number, max: number): number;
|
|
81
104
|
declare class DialStoreClass {
|
|
82
105
|
private panels;
|
|
106
|
+
private panelsSnapshot;
|
|
107
|
+
private standardPanelsSnapshot;
|
|
108
|
+
private timelinePanelsSnapshot;
|
|
83
109
|
private listeners;
|
|
84
110
|
private globalListeners;
|
|
85
111
|
private snapshots;
|
|
@@ -87,17 +113,23 @@ declare class DialStoreClass {
|
|
|
87
113
|
private presets;
|
|
88
114
|
private activePreset;
|
|
89
115
|
private baseValues;
|
|
90
|
-
|
|
91
|
-
|
|
116
|
+
private defaultValues;
|
|
117
|
+
private registrationCounts;
|
|
118
|
+
private retainedPanels;
|
|
119
|
+
private persistConfigs;
|
|
120
|
+
registerPanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>, options?: DialStorePanelOptions): void;
|
|
121
|
+
updatePanel(id: string, name: string, config: DialConfig, shortcuts?: Record<string, ShortcutConfig>, options?: DialStorePanelOptions): void;
|
|
92
122
|
unregisterPanel(id: string): void;
|
|
93
123
|
updateValue(panelId: string, path: string, value: DialValue): void;
|
|
124
|
+
updateValues(panelId: string, updates: Record<string, DialValue>): void;
|
|
125
|
+
resetValues(panelId: string): void;
|
|
94
126
|
updateSpringMode(panelId: string, path: string, mode: 'simple' | 'advanced'): void;
|
|
95
127
|
getSpringMode(panelId: string, path: string): 'simple' | 'advanced';
|
|
96
128
|
updateTransitionMode(panelId: string, path: string, mode: 'easing' | 'simple' | 'advanced'): void;
|
|
97
129
|
getTransitionMode(panelId: string, path: string): 'easing' | 'simple' | 'advanced';
|
|
98
130
|
getValue(panelId: string, path: string): DialValue | undefined;
|
|
99
131
|
getValues(panelId: string): Record<string, DialValue>;
|
|
100
|
-
getPanels(): PanelConfig[];
|
|
132
|
+
getPanels(kind?: 'panel' | 'timeline'): PanelConfig[];
|
|
101
133
|
getPanel(id: string): PanelConfig | undefined;
|
|
102
134
|
subscribe(panelId: string, listener: Listener): () => void;
|
|
103
135
|
subscribeGlobal(listener: Listener): () => void;
|
|
@@ -120,6 +152,13 @@ declare class DialStoreClass {
|
|
|
120
152
|
control: ControlMeta;
|
|
121
153
|
shortcut: ShortcutConfig;
|
|
122
154
|
}>;
|
|
155
|
+
private configurePanelRetention;
|
|
156
|
+
private reconcileValues;
|
|
157
|
+
private reconcilePresets;
|
|
158
|
+
private normalizePersistConfig;
|
|
159
|
+
private loadPersistedPanel;
|
|
160
|
+
private persistPanel;
|
|
161
|
+
private getStorage;
|
|
123
162
|
private findControlByPath;
|
|
124
163
|
private notify;
|
|
125
164
|
private notifyGlobal;
|
|
@@ -143,4 +182,4 @@ declare class DialStoreClass {
|
|
|
143
182
|
}
|
|
144
183
|
declare const DialStore: DialStoreClass;
|
|
145
184
|
|
|
146
|
-
export { type ActionConfig, type ColorConfig, type ControlMeta, type DialConfig, DialStore, type DialValue, type EasingConfig, type PanelConfig, type Preset, type ResolvedValues, type SelectConfig, type ShortcutConfig, type ShortcutInteraction, type ShortcutMode, type SpringConfig, type TextConfig, type TransitionConfig };
|
|
185
|
+
export { type ActionConfig, type ColorConfig, type ControlMeta, type DialConfig, type DialKitPersistOptions, type DialKitValueUpdates, DialStore, type DialStorePanelOptions, type DialValue, type EasingConfig, type PanelConfig, type Preset, type ResolvedValues, type SelectConfig, type ShortcutConfig, type ShortcutInteraction, type ShortcutMode, type SpringConfig, type TextConfig, type TransitionConfig, flattenDialValueUpdates, formatLabel, inferStep, isEasingConfigValue, isHexColor, isSpringConfigValue, resolveDialValues };
|