dialkit 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +220 -3
  2. package/dist/dropdown-position.d.ts +15 -0
  3. package/dist/dropdown-position.js +22 -0
  4. package/dist/dropdown-position.js.map +1 -0
  5. package/dist/index.cjs +697 -307
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +42 -5
  8. package/dist/index.d.ts +42 -5
  9. package/dist/index.js +720 -331
  10. package/dist/index.js.map +1 -1
  11. package/dist/panel-drag.d.ts +19 -0
  12. package/dist/panel-drag.js +72 -0
  13. package/dist/panel-drag.js.map +1 -0
  14. package/dist/solid/index.cjs +661 -204
  15. package/dist/solid/index.cjs.map +1 -1
  16. package/dist/solid/index.d.cts +40 -3
  17. package/dist/solid/index.d.ts +40 -3
  18. package/dist/solid/index.js +646 -190
  19. package/dist/solid/index.js.map +1 -1
  20. package/dist/store/index.cjs +272 -41
  21. package/dist/store/index.cjs.map +1 -1
  22. package/dist/store/index.d.cts +30 -3
  23. package/dist/store/index.d.ts +30 -3
  24. package/dist/store/index.js +269 -40
  25. package/dist/store/index.js.map +1 -1
  26. package/dist/styles.css +105 -7
  27. package/dist/svelte/components/DialRoot.svelte +176 -11
  28. package/dist/svelte/components/DialRoot.svelte.d.ts +1 -0
  29. package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
  30. package/dist/svelte/components/Folder.svelte +24 -13
  31. package/dist/svelte/components/Folder.svelte.d.ts +1 -0
  32. package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
  33. package/dist/svelte/components/Panel.svelte +98 -71
  34. package/dist/svelte/components/Panel.svelte.d.ts +2 -0
  35. package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
  36. package/dist/svelte/components/PresetManager.svelte +5 -5
  37. package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
  38. package/dist/svelte/components/SelectControl.svelte +6 -14
  39. package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
  40. package/dist/svelte/createDialKit.svelte.d.ts +11 -1
  41. package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
  42. package/dist/svelte/createDialKit.svelte.js +61 -34
  43. package/dist/svelte/index.d.ts +3 -3
  44. package/dist/svelte/index.d.ts.map +1 -1
  45. package/dist/svelte/index.js +1 -1
  46. package/dist/svelte/theme-css.d.ts +1 -1
  47. package/dist/svelte/theme-css.d.ts.map +1 -1
  48. package/dist/svelte/theme-css.js +105 -7
  49. package/dist/vue/index.cjs +573 -132
  50. package/dist/vue/index.cjs.map +1 -1
  51. package/dist/vue/index.d.cts +53 -6
  52. package/dist/vue/index.d.ts +53 -6
  53. package/dist/vue/index.js +573 -133
  54. package/dist/vue/index.js.map +1 -1
  55. package/package.json +2 -2
@@ -12,6 +12,7 @@
12
12
  inline = false,
13
13
  onOpenChange,
14
14
  toolbar,
15
+ panelHeightOffset = 10,
15
16
  children,
16
17
  } = $props<{
17
18
  title: string;
@@ -20,12 +21,14 @@
20
21
  inline?: boolean;
21
22
  onOpenChange?: (isOpen: boolean) => void;
22
23
  toolbar?: Snippet;
24
+ panelHeightOffset?: number;
23
25
  children?: Snippet;
24
26
  }>();
25
27
 
26
28
  let isOpen = $state(defaultOpen);
27
29
  let isCollapsed = $state(!defaultOpen);
28
30
  let contentHeight = $state<number | undefined>(undefined);
31
+ let hasInitializedRootSize = $state(!isRoot || !defaultOpen);
29
32
 
30
33
  let contentRef: HTMLDivElement | undefined;
31
34
  let panelRef: HTMLDivElement | undefined;
@@ -74,11 +77,16 @@
74
77
  if (!isRoot) return;
75
78
 
76
79
  const measured = contentHeight ?? panelRef?.getBoundingClientRect().height ?? 42;
77
- const nextHeight = isOpen ? Math.min(measured + 10, windowHeight - 32) : 42;
80
+ const nextHeight = isOpen ? Math.min(measured + panelHeightOffset, windowHeight - 32) : 42;
81
+ const springOptions = !hasInitializedRootSize && isOpen ? { instant: true } : undefined;
78
82
 
79
- panelWidth.set(isOpen ? 280 : 42);
80
- panelHeight.set(nextHeight);
81
- panelRadius.set(isOpen ? 14 : 21);
83
+ panelWidth.set(isOpen ? 280 : 42, springOptions);
84
+ panelHeight.set(nextHeight, springOptions);
85
+ panelRadius.set(isOpen ? 14 : 21, springOptions);
86
+
87
+ if (isOpen || !defaultOpen) {
88
+ hasInitializedRootSize = true;
89
+ }
82
90
  });
83
91
 
84
92
  const handleToggle = () => {
@@ -100,8 +108,9 @@
100
108
  panelScale.set(1);
101
109
  };
102
110
 
111
+ const panelHeightStyle = $derived(!hasInitializedRootSize && isOpen ? 'auto' : `${panelHeight.current}px`);
103
112
  const panelStyle = $derived(
104
- `width:${panelWidth.current}px;height:${panelHeight.current}px;border-radius:${panelRadius.current}px;` +
113
+ `width:${panelWidth.current}px;height:${panelHeightStyle};max-height:${Math.max(windowHeight - 32, 42)}px;border-radius:${panelRadius.current}px;` +
105
114
  `box-shadow:${isOpen ? 'var(--dial-shadow)' : 'var(--dial-shadow-collapsed)'};` +
106
115
  `cursor:${isOpen ? '' : 'pointer'};overflow:${isOpen ? 'hidden auto' : 'hidden'};` +
107
116
  `transform:scale(${panelScale.current});`
@@ -110,7 +119,7 @@
110
119
 
111
120
  {#if isRoot && inline}
112
121
  <div class="dialkit-panel-inner dialkit-panel-inline">
113
- <div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
122
+ <div bind:this={contentRef} class="dialkit-folder dialkit-folder-root" data-open={String(isOpen)}>
114
123
  <div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
115
124
  <div class="dialkit-folder-header-top">
116
125
  <div class="dialkit-folder-title-row">
@@ -118,9 +127,11 @@
118
127
  </div>
119
128
  </div>
120
129
 
121
- <div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
122
- {#if toolbar}{@render toolbar()}{/if}
123
- </div>
130
+ {#if toolbar}
131
+ <div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
132
+ {@render toolbar()}
133
+ </div>
134
+ {/if}
124
135
  </div>
125
136
 
126
137
  <div class="dialkit-folder-content">
@@ -142,7 +153,7 @@
142
153
  onpointerleave={handleCollapsedTapEnd}
143
154
  onclick={() => { if (!isOpen) handleToggle(); }}
144
155
  >
145
- <div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
156
+ <div bind:this={contentRef} class="dialkit-folder dialkit-folder-root" data-open={String(isOpen)}>
146
157
  <div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
147
158
  <div class="dialkit-folder-header-top">
148
159
  {#if isOpen}
@@ -163,9 +174,9 @@
163
174
  </svg>
164
175
  </div>
165
176
 
166
- {#if isOpen}
177
+ {#if isOpen && toolbar}
167
178
  <div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
168
- {#if toolbar}{@render toolbar()}{/if}
179
+ {@render toolbar()}
169
180
  </div>
170
181
  {/if}
171
182
  </div>
@@ -180,7 +191,7 @@
180
191
  </div>
181
192
  </div>
182
193
  {:else}
183
- <div class="dialkit-folder">
194
+ <div class="dialkit-folder" data-open={String(isOpen)}>
184
195
  <div class="dialkit-folder-header" onclick={handleToggle}>
185
196
  <div class="dialkit-folder-header-top">
186
197
  <div class="dialkit-folder-title-row">
@@ -6,6 +6,7 @@ type $$ComponentProps = {
6
6
  inline?: boolean;
7
7
  onOpenChange?: (isOpen: boolean) => void;
8
8
  toolbar?: Snippet;
9
+ panelHeightOffset?: number;
9
10
  children?: Snippet;
10
11
  };
11
12
  declare const Folder: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"Folder.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Folder.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA0LJ,QAAA,MAAM,MAAM,sDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Folder.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Folder.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAoMJ,QAAA,MAAM,MAAM,sDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -8,7 +8,13 @@
8
8
  import ShortcutsMenu from './ShortcutsMenu.svelte';
9
9
  import { ICON_CLIPBOARD, ICON_CHECK, ICON_ADD_PRESET } from '../../icons';
10
10
 
11
- let { panel, defaultOpen = true, inline = false } = $props<{ panel: PanelConfig; defaultOpen?: boolean; inline?: boolean }>();
11
+ let { panel, defaultOpen = true, inline = false, onOpenChange, variant = 'root' } = $props<{
12
+ panel: PanelConfig;
13
+ defaultOpen?: boolean;
14
+ inline?: boolean;
15
+ onOpenChange?: (open: boolean) => void;
16
+ variant?: 'root' | 'section';
17
+ }>();
12
18
 
13
19
  const hasShortcuts = $derived(Object.keys(panel.shortcuts).length > 0);
14
20
 
@@ -72,78 +78,99 @@
72
78
  copied = false;
73
79
  }, 1500);
74
80
  };
81
+
82
+ const handleOpenChange = (open: boolean) => {
83
+ isPanelOpen = open;
84
+ onOpenChange?.(open);
85
+ };
75
86
  </script>
76
87
 
77
- <div class="dialkit-panel-wrapper">
78
- <Folder title={panel.name} {defaultOpen} isRoot={true} {inline} onOpenChange={(open) => (isPanelOpen = open)}>
79
- {#snippet toolbar()}
80
- <button
81
- class="dialkit-toolbar-add"
82
- onclick={handleAddPreset}
83
- onpointerdown={() => addScale.set(0.9)}
84
- onpointerup={() => addScale.set(1)}
85
- onpointercancel={() => addScale.set(1)}
86
- onpointerleave={() => addScale.set(1)}
87
- title="Add preset"
88
- style:transform={`scale(${addScale.current})`}
88
+ {#snippet panelToolbar()}
89
+ <button
90
+ class="dialkit-toolbar-add"
91
+ onclick={handleAddPreset}
92
+ onpointerdown={() => addScale.set(0.9)}
93
+ onpointerup={() => addScale.set(1)}
94
+ onpointercancel={() => addScale.set(1)}
95
+ onpointerleave={() => addScale.set(1)}
96
+ title="Add preset"
97
+ style:transform={`scale(${addScale.current})`}
98
+ >
99
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
100
+ <path d={ICON_ADD_PRESET[0]} />
101
+ <path d={ICON_ADD_PRESET[1]} />
102
+ <path d={ICON_ADD_PRESET[2]} />
103
+ <path d={ICON_ADD_PRESET[3]} />
104
+ <path d={ICON_ADD_PRESET[4]} />
105
+ </svg>
106
+ </button>
107
+
108
+ <PresetManager panelId={panel.id} {presets} {activePresetId} />
109
+
110
+ <button
111
+ class="dialkit-toolbar-copy"
112
+ onclick={handleCopy}
113
+ onpointerdown={() => copyScale.set(0.95)}
114
+ onpointerup={() => copyScale.set(1)}
115
+ onpointercancel={() => copyScale.set(1)}
116
+ onpointerleave={() => copyScale.set(1)}
117
+ title="Copy parameters"
118
+ style:transform={`scale(${copyScale.current})`}
119
+ >
120
+ <span class="dialkit-toolbar-copy-icon-wrap">
121
+ <svg
122
+ class="dialkit-toolbar-copy-icon"
123
+ viewBox="0 0 24 24"
124
+ fill="none"
125
+ style:opacity={clipboardOpacity.current}
126
+ style:transform={`scale(${clipboardScale.current})`}
127
+ style:filter={`blur(${(1 - clipboardOpacity.current) * 4}px)`}
89
128
  >
90
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
91
- <path d={ICON_ADD_PRESET[0]} />
92
- <path d={ICON_ADD_PRESET[1]} />
93
- <path d={ICON_ADD_PRESET[2]} />
94
- <path d={ICON_ADD_PRESET[3]} />
95
- <path d={ICON_ADD_PRESET[4]} />
96
- </svg>
97
- </button>
98
-
99
- <PresetManager panelId={panel.id} {presets} {activePresetId} />
100
-
101
- <button
102
- class="dialkit-toolbar-copy"
103
- onclick={handleCopy}
104
- onpointerdown={() => copyScale.set(0.95)}
105
- onpointerup={() => copyScale.set(1)}
106
- onpointercancel={() => copyScale.set(1)}
107
- onpointerleave={() => copyScale.set(1)}
108
- title="Copy parameters"
109
- style:transform={`scale(${copyScale.current})`}
129
+ <path d={ICON_CLIPBOARD.board} stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
130
+ <path d={ICON_CLIPBOARD.sparkle} fill="currentColor"/>
131
+ <path d={ICON_CLIPBOARD.body} stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
132
+ </svg>
133
+
134
+ <svg
135
+ class="dialkit-toolbar-copy-icon"
136
+ viewBox="0 0 24 24"
137
+ fill="none"
138
+ stroke="currentColor"
139
+ stroke-width="2"
140
+ stroke-linecap="round"
141
+ stroke-linejoin="round"
142
+ style:opacity={checkOpacity.current}
143
+ style:transform={`scale(${checkScale.current})`}
144
+ style:filter={`blur(${(1 - checkOpacity.current) * 4}px)`}
110
145
  >
111
- <span class="dialkit-toolbar-copy-icon-wrap">
112
- <svg
113
- class="dialkit-toolbar-copy-icon"
114
- viewBox="0 0 24 24"
115
- fill="none"
116
- style:opacity={clipboardOpacity.current}
117
- style:transform={`scale(${clipboardScale.current})`}
118
- style:filter={`blur(${(1 - clipboardOpacity.current) * 4}px)`}
119
- >
120
- <path d={ICON_CLIPBOARD.board} stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
121
- <path d={ICON_CLIPBOARD.sparkle} fill="currentColor"/>
122
- <path d={ICON_CLIPBOARD.body} stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
123
- </svg>
124
-
125
- <svg
126
- class="dialkit-toolbar-copy-icon"
127
- viewBox="0 0 24 24"
128
- fill="none"
129
- stroke="currentColor"
130
- stroke-width="2"
131
- stroke-linecap="round"
132
- stroke-linejoin="round"
133
- style:opacity={checkOpacity.current}
134
- style:transform={`scale(${checkScale.current})`}
135
- style:filter={`blur(${(1 - checkOpacity.current) * 4}px)`}
136
- >
137
- <path d={ICON_CHECK} />
138
- </svg>
139
- </span>
140
- Copy
141
- </button>
142
-
143
- {/snippet}
144
-
145
- {#each panel.controls as control (control.path)}
146
- <ControlRenderer panelId={panel.id} {control} {values} />
147
- {/each}
146
+ <path d={ICON_CHECK} />
147
+ </svg>
148
+ </span>
149
+ Copy
150
+ </button>
151
+ {/snippet}
152
+
153
+ {#snippet panelControls()}
154
+ {#each panel.controls as control (control.path)}
155
+ <ControlRenderer panelId={panel.id} {control} {values} />
156
+ {/each}
157
+ {/snippet}
158
+
159
+ {#if variant === 'section'}
160
+ <Folder title={panel.name} {defaultOpen} onOpenChange={handleOpenChange}>
161
+ <div class="dialkit-panel-section-toolbar" onclick={(e) => e.stopPropagation()}>
162
+ {@render panelToolbar()}
163
+ </div>
164
+ {@render panelControls()}
148
165
  </Folder>
149
- </div>
166
+ {:else}
167
+ <div class="dialkit-panel-wrapper">
168
+ <Folder title={panel.name} {defaultOpen} isRoot={true} {inline} onOpenChange={handleOpenChange}>
169
+ {#snippet toolbar()}
170
+ {@render panelToolbar()}
171
+ {/snippet}
172
+
173
+ {@render panelControls()}
174
+ </Folder>
175
+ </div>
176
+ {/if}
@@ -3,6 +3,8 @@ type $$ComponentProps = {
3
3
  panel: PanelConfig;
4
4
  defaultOpen?: boolean;
5
5
  inline?: boolean;
6
+ onOpenChange?: (open: boolean) => void;
7
+ variant?: 'root' | 'section';
6
8
  };
7
9
  declare const Panel: import("svelte").Component<$$ComponentProps, {}, "">;
8
10
  type Panel = ReturnType<typeof Panel>;
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Panel.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAa,WAAW,EAAU,MAAM,eAAe,CAAC;AAOnE,KAAK,gBAAgB,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAqHzF,QAAA,MAAM,KAAK,sDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Panel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Panel.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAa,WAAW,EAAU,MAAM,eAAe,CAAC;AAOnE,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AA0IJ,QAAA,MAAM,KAAK,sDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -4,6 +4,7 @@
4
4
  import { DialStore } from 'dialkit/store';
5
5
  import type { Preset } from 'dialkit/store';
6
6
  import { dropdownTransition } from './transitions';
7
+ import { getDialKitPortalRoot, getDropdownPosition } from '../../dropdown-position';
7
8
  import { ICON_CHEVRON, ICON_TRASH } from '../../icons';
8
9
 
9
10
  let { panelId, presets, activePresetId } = $props<{
@@ -25,9 +26,8 @@
25
26
  const activePreset = $derived(presets.find((p: Preset) => p.id === activePresetId));
26
27
 
27
28
  const updatePos = () => {
28
- const rect = triggerRef?.getBoundingClientRect();
29
- if (!rect) return;
30
- pos = { top: rect.bottom + 4, left: rect.left, width: rect.width };
29
+ if (!triggerRef || !portalTarget) return;
30
+ pos = getDropdownPosition(triggerRef, portalTarget, { allowAbove: false });
31
31
  };
32
32
 
33
33
  const openDropdown = () => {
@@ -42,7 +42,7 @@
42
42
 
43
43
  $effect(() => {
44
44
  if (typeof document === 'undefined' || !triggerRef) return;
45
- portalTarget = (triggerRef.closest('.dialkit-root') as HTMLElement | null) ?? document.body;
45
+ portalTarget = getDialKitPortalRoot(triggerRef) ?? document.body;
46
46
  });
47
47
 
48
48
  $effect(() => {
@@ -117,7 +117,7 @@
117
117
  <div
118
118
  bind:this={dropdownRef}
119
119
  class="dialkit-root dialkit-preset-dropdown"
120
- style={`position:fixed;top:${pos.top}px;left:${pos.left}px;min-width:${pos.width}px;`}
120
+ style={`position:absolute;top:${pos.top}px;left:${pos.left}px;min-width:${pos.width}px;`}
121
121
  transition:dropdownTransition={{ above: false }}
122
122
  >
123
123
  <div
@@ -1 +1 @@
1
- {"version":3,"file":"PresetManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/PresetManager.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI3C,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AA2HJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"PresetManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/PresetManager.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAK3C,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AA2HJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -2,6 +2,7 @@
2
2
  import { Spring } from 'svelte/motion';
3
3
  import Portal from '../Portal.svelte';
4
4
  import { dropdownTransition } from './transitions';
5
+ import { getDialKitPortalRoot, getDropdownPosition } from '../../dropdown-position';
5
6
  import { ICON_CHEVRON } from '../../icons';
6
7
 
7
8
  type SelectOption = string | { value: string; label: string };
@@ -32,18 +33,9 @@
32
33
  const selectedOption = $derived(normalized.find((o: { value: string; label: string }) => o.value === value));
33
34
 
34
35
  const updatePos = () => {
35
- if (!triggerRef || typeof window === 'undefined') return;
36
- const rect = triggerRef.getBoundingClientRect();
36
+ if (!triggerRef || !portalTarget || typeof window === 'undefined') return;
37
37
  const dropdownHeight = 8 + normalized.length * 36;
38
- const spaceBelow = window.innerHeight - rect.bottom - 4;
39
- const above = spaceBelow < dropdownHeight && rect.top > spaceBelow;
40
-
41
- pos = {
42
- top: above ? rect.top - 4 : rect.bottom + 4,
43
- left: rect.left,
44
- width: rect.width,
45
- above,
46
- };
38
+ pos = getDropdownPosition(triggerRef, portalTarget, { dropdownHeight });
47
39
  };
48
40
 
49
41
  const openDropdown = () => {
@@ -59,16 +51,16 @@
59
51
  if (!pos || typeof window === 'undefined') return '';
60
52
 
61
53
  if (pos.above) {
62
- return `position:fixed;left:${pos.left}px;width:${pos.width}px;bottom:${window.innerHeight - pos.top}px;transform-origin:bottom;`;
54
+ return `position:absolute;left:${pos.left}px;top:${pos.top}px;width:${pos.width}px;transform-origin:bottom;`;
63
55
  }
64
56
 
65
- return `position:fixed;left:${pos.left}px;width:${pos.width}px;top:${pos.top}px;transform-origin:top;`;
57
+ return `position:absolute;left:${pos.left}px;top:${pos.top}px;width:${pos.width}px;transform-origin:top;`;
66
58
  });
67
59
 
68
60
  $effect(() => {
69
61
  if (typeof document === 'undefined' || !triggerRef) return;
70
62
 
71
- portalTarget = (triggerRef.closest('.dialkit-root') as HTMLElement | null) ?? document.body;
63
+ portalTarget = getDialKitPortalRoot(triggerRef) ?? document.body;
72
64
  });
73
65
 
74
66
  $effect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"SelectControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SelectControl.svelte.ts"],"names":[],"mappings":"AASE,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AA+HJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"SelectControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SelectControl.svelte.ts"],"names":[],"mappings":"AAUE,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAuHJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -1,8 +1,18 @@
1
- import type { DialConfig, ResolvedValues, ShortcutConfig } from 'dialkit/store';
1
+ import type { DialConfig, DialKitPersistOptions, DialKitValueUpdates, DialValue, ResolvedValues, ShortcutConfig } from 'dialkit/store';
2
2
  export interface CreateDialOptions {
3
+ id?: string;
4
+ persist?: DialKitPersistOptions;
3
5
  onAction?: (action: string) => void;
4
6
  shortcuts?: Record<string, ShortcutConfig>;
5
7
  }
6
8
  export type DialKitValues<T> = T;
9
+ export interface DialKitController<T extends DialConfig> {
10
+ values: DialKitValues<ResolvedValues<T>>;
11
+ setValue: (path: string, value: DialValue) => void;
12
+ setValues: (values: DialKitValueUpdates<T>) => void;
13
+ resetValues: () => void;
14
+ getValues: () => ResolvedValues<T>;
15
+ }
7
16
  export declare function createDialKit<T extends DialConfig>(name: string, config: T, options?: CreateDialOptions): DialKitValues<ResolvedValues<T>>;
17
+ export declare function createDialKitController<T extends DialConfig>(name: string, config: T, options?: CreateDialOptions): DialKitController<T>;
8
18
  //# sourceMappingURL=createDialKit.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createDialKit.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/createDialKit.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,UAAU,EAGV,cAAc,EAEd,cAAc,EAGf,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC;AAIjC,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAChD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,iBAAiB,GAC1B,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CA0BlC"}
1
+ {"version":3,"file":"createDialKit.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/createDialKit.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,SAAS,EAET,cAAc,EAEd,cAAc,EAGf,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC;AAEjC,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,UAAU;IACrD,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACnD,SAAS,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACpD,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC;CACpC;AAID,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAChD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,iBAAiB,GAC1B,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAElC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,UAAU,EAC1D,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,iBAAiB,GAC1B,iBAAiB,CAAC,CAAC,CAAC,CA4CtB"}
@@ -1,11 +1,18 @@
1
- import { DialStore } from 'dialkit/store';
1
+ import { DialStore, flattenDialValueUpdates, resolveDialValues } from 'dialkit/store';
2
2
  let dialKitInstance = 0;
3
3
  export function createDialKit(name, config, options) {
4
- const panelId = `${name}-${++dialKitInstance}`;
5
- const resolve = () => buildResolvedValues(config, DialStore.getValues(panelId), '');
4
+ return createDialKitController(name, config, options).values;
5
+ }
6
+ export function createDialKitController(name, config, options) {
7
+ const hasStableId = options?.id !== undefined;
8
+ const panelId = options?.id ?? `${name}-${++dialKitInstance}`;
9
+ const resolve = () => resolveDialValues(config, DialStore.getValues(panelId));
6
10
  let values = $state(resolve());
7
11
  $effect(() => {
8
- DialStore.registerPanel(panelId, name, config, options?.shortcuts);
12
+ DialStore.registerPanel(panelId, name, config, options?.shortcuts, {
13
+ retainOnUnmount: hasStableId,
14
+ persist: options?.persist,
15
+ });
9
16
  values = resolve();
10
17
  const unsubValues = DialStore.subscribe(panelId, () => {
11
18
  values = resolve();
@@ -19,42 +26,66 @@ export function createDialKit(name, config, options) {
19
26
  DialStore.unregisterPanel(panelId);
20
27
  };
21
28
  });
22
- return values;
29
+ return {
30
+ values: buildReactiveValues(config, () => values, ''),
31
+ setValue(path, value) {
32
+ DialStore.updateValue(panelId, path, value);
33
+ },
34
+ setValues(nextValues) {
35
+ DialStore.updateValues(panelId, flattenDialValueUpdates(config, nextValues));
36
+ },
37
+ resetValues() {
38
+ DialStore.resetValues(panelId);
39
+ },
40
+ getValues() {
41
+ return resolve();
42
+ },
43
+ };
23
44
  }
24
- function buildResolvedValues(config, flatValues, prefix) {
45
+ function buildReactiveValues(config, getValues, prefix) {
25
46
  const result = {};
26
47
  for (const [key, configValue] of Object.entries(config)) {
27
48
  if (key === '_collapsed')
28
49
  continue;
29
50
  const path = prefix ? `${prefix}.${key}` : key;
30
- if (Array.isArray(configValue) && configValue.length <= 4 && typeof configValue[0] === 'number') {
31
- result[key] = flatValues[path] ?? configValue[0];
32
- }
33
- else if (typeof configValue === 'number' || typeof configValue === 'boolean' || typeof configValue === 'string') {
34
- result[key] = flatValues[path] ?? configValue;
35
- }
36
- else if (isSpringConfig(configValue) || isEasingConfig(configValue)) {
37
- result[key] = flatValues[path] ?? configValue;
38
- }
39
- else if (isActionConfig(configValue)) {
40
- result[key] = flatValues[path] ?? configValue;
41
- }
42
- else if (isSelectConfig(configValue)) {
43
- const defaultValue = configValue.default ?? getFirstOptionValue(configValue.options);
44
- result[key] = flatValues[path] ?? defaultValue;
45
- }
46
- else if (isColorConfig(configValue)) {
47
- result[key] = flatValues[path] ?? configValue.default ?? '#000000';
48
- }
49
- else if (isTextConfig(configValue)) {
50
- result[key] = flatValues[path] ?? configValue.default ?? '';
51
- }
52
- else if (typeof configValue === 'object' && configValue !== null) {
53
- result[key] = buildResolvedValues(configValue, flatValues, path);
51
+ if (typeof configValue === 'object' && configValue !== null && !isLeafConfigValue(configValue)) {
52
+ const nested = buildReactiveValues(configValue, getValues, path);
53
+ Object.defineProperty(result, key, {
54
+ enumerable: true,
55
+ get() {
56
+ return nested;
57
+ },
58
+ });
59
+ continue;
54
60
  }
61
+ Object.defineProperty(result, key, {
62
+ enumerable: true,
63
+ get() {
64
+ return getPathValue(getValues(), path);
65
+ },
66
+ });
55
67
  }
56
68
  return result;
57
69
  }
70
+ function getPathValue(source, path) {
71
+ return path.split('.').reduce((value, segment) => {
72
+ if (typeof value !== 'object' || value === null)
73
+ return undefined;
74
+ return value[segment];
75
+ }, source);
76
+ }
77
+ function isLeafConfigValue(value) {
78
+ return ((Array.isArray(value) && value.length <= 4 && typeof value[0] === 'number') ||
79
+ typeof value === 'number' ||
80
+ typeof value === 'boolean' ||
81
+ typeof value === 'string' ||
82
+ isSpringConfig(value) ||
83
+ isEasingConfig(value) ||
84
+ isActionConfig(value) ||
85
+ isSelectConfig(value) ||
86
+ isColorConfig(value) ||
87
+ isTextConfig(value));
88
+ }
58
89
  function hasType(value, type) {
59
90
  return typeof value === 'object' && value !== null && 'type' in value && value.type === type;
60
91
  }
@@ -76,7 +107,3 @@ function isColorConfig(value) {
76
107
  function isTextConfig(value) {
77
108
  return hasType(value, 'text');
78
109
  }
79
- function getFirstOptionValue(options) {
80
- const first = options[0];
81
- return typeof first === 'string' ? first : first.value;
82
- }
@@ -1,5 +1,5 @@
1
- export { createDialKit } from './createDialKit.svelte';
2
- export type { CreateDialOptions, DialKitValues } from './createDialKit.svelte';
1
+ export { createDialKit, createDialKitController } from './createDialKit.svelte.js';
2
+ export type { CreateDialOptions, DialKitController, DialKitValues } from './createDialKit.svelte.js';
3
3
  export { default as DialRoot } from './components/DialRoot.svelte';
4
4
  export type { DialPosition, DialMode, DialTheme } from './components/DialRoot.svelte';
5
5
  export { default as ShortcutListener } from './components/ShortcutListener.svelte';
@@ -19,5 +19,5 @@ export { default as SelectControl } from './components/SelectControl.svelte';
19
19
  export { default as ColorControl } from './components/ColorControl.svelte';
20
20
  export { default as PresetManager } from './components/PresetManager.svelte';
21
21
  export { DialStore } from 'dialkit/store';
22
- export type { SpringConfig, EasingConfig, TransitionConfig, ActionConfig, SelectConfig, ColorConfig, TextConfig, ShortcutConfig, Preset, DialValue, DialConfig, ResolvedValues, ControlMeta, PanelConfig, } from 'dialkit/store';
22
+ export type { SpringConfig, EasingConfig, TransitionConfig, ActionConfig, SelectConfig, ColorConfig, TextConfig, ShortcutConfig, Preset, DialValue, DialConfig, DialKitPersistOptions, DialKitValueUpdates, ResolvedValues, ControlMeta, PanelConfig, } from 'dialkit/store';
23
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAG7E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAG7E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,MAAM,EACN,SAAS,EACT,UAAU,EACV,cAAc,EACd,WAAW,EACX,WAAW,GACZ,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACnF,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAGrG,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAG7E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAG7E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,MAAM,EACN,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,WAAW,GACZ,MAAM,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  // Core API
2
- export { createDialKit } from './createDialKit.svelte';
2
+ export { createDialKit, createDialKitController } from './createDialKit.svelte.js';
3
3
  // Root component
4
4
  export { default as DialRoot } from './components/DialRoot.svelte';
5
5
  // Shortcut components