dialkit 1.1.0 → 1.2.1

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 (73) hide show
  1. package/README.md +174 -2
  2. package/dist/icons.d.ts +19 -0
  3. package/dist/icons.js +39 -0
  4. package/dist/icons.js.map +1 -0
  5. package/dist/index.cjs +876 -337
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +41 -6
  8. package/dist/index.d.ts +41 -6
  9. package/dist/index.js +878 -341
  10. package/dist/index.js.map +1 -1
  11. package/dist/shortcut-utils.d.ts +39 -0
  12. package/dist/shortcut-utils.js +100 -0
  13. package/dist/shortcut-utils.js.map +1 -0
  14. package/dist/solid/index.cjs +1011 -544
  15. package/dist/solid/index.cjs.map +1 -1
  16. package/dist/solid/index.d.cts +33 -3
  17. package/dist/solid/index.d.ts +33 -3
  18. package/dist/solid/index.js +864 -398
  19. package/dist/solid/index.js.map +1 -1
  20. package/dist/store/index.cjs +52 -12
  21. package/dist/store/index.cjs.map +1 -1
  22. package/dist/store/index.d.cts +25 -3
  23. package/dist/store/index.d.ts +25 -3
  24. package/dist/store/index.js +52 -12
  25. package/dist/store/index.js.map +1 -1
  26. package/dist/styles.css +256 -25
  27. package/dist/svelte/components/ControlRenderer.svelte +12 -0
  28. package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -1
  29. package/dist/svelte/components/DialRoot.svelte +22 -8
  30. package/dist/svelte/components/DialRoot.svelte.d.ts +3 -0
  31. package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
  32. package/dist/svelte/components/Folder.svelte +17 -8
  33. package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
  34. package/dist/svelte/components/Panel.svelte +14 -9
  35. package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
  36. package/dist/svelte/components/PresetManager.svelte +7 -6
  37. package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
  38. package/dist/svelte/components/SegmentedControl.svelte +30 -74
  39. package/dist/svelte/components/SegmentedControl.svelte.d.ts.map +1 -1
  40. package/dist/svelte/components/SelectControl.svelte +2 -1
  41. package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
  42. package/dist/svelte/components/ShortcutListener.svelte +265 -0
  43. package/dist/svelte/components/ShortcutListener.svelte.d.ts +13 -0
  44. package/dist/svelte/components/ShortcutListener.svelte.d.ts.map +1 -0
  45. package/dist/svelte/components/ShortcutsMenu.svelte +128 -0
  46. package/dist/svelte/components/ShortcutsMenu.svelte.d.ts +7 -0
  47. package/dist/svelte/components/ShortcutsMenu.svelte.d.ts.map +1 -0
  48. package/dist/svelte/components/Slider.svelte +16 -29
  49. package/dist/svelte/components/Slider.svelte.d.ts +3 -0
  50. package/dist/svelte/components/Slider.svelte.d.ts.map +1 -1
  51. package/dist/svelte/components/SpringControl.svelte +17 -15
  52. package/dist/svelte/components/SpringControl.svelte.d.ts.map +1 -1
  53. package/dist/svelte/components/Toggle.svelte +13 -2
  54. package/dist/svelte/components/Toggle.svelte.d.ts +3 -0
  55. package/dist/svelte/components/Toggle.svelte.d.ts.map +1 -1
  56. package/dist/svelte/components/TransitionControl.svelte +28 -25
  57. package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -1
  58. package/dist/svelte/createDialKit.svelte.d.ts +2 -1
  59. package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
  60. package/dist/svelte/createDialKit.svelte.js +1 -1
  61. package/dist/svelte/index.d.ts +6 -2
  62. package/dist/svelte/index.d.ts.map +1 -1
  63. package/dist/svelte/index.js +4 -0
  64. package/dist/svelte/theme-css.d.ts +1 -1
  65. package/dist/svelte/theme-css.d.ts.map +1 -1
  66. package/dist/svelte/theme-css.js +257 -26
  67. package/dist/vue/index.cjs +3056 -0
  68. package/dist/vue/index.cjs.map +1 -0
  69. package/dist/vue/index.d.cts +675 -0
  70. package/dist/vue/index.d.ts +675 -0
  71. package/dist/vue/index.js +3014 -0
  72. package/dist/vue/index.js.map +1 -0
  73. package/package.json +24 -4
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { getContext } from 'svelte';
2
3
  import { DialStore } from 'dialkit/store';
3
4
  import type { ControlMeta, DialValue, SpringConfig, TransitionConfig } from 'dialkit/store';
4
5
  import Slider from './Slider.svelte';
@@ -10,6 +11,8 @@
10
11
  import SelectControl from './SelectControl.svelte';
11
12
  import ColorControl from './ColorControl.svelte';
12
13
  import ControlRenderer from './ControlRenderer.svelte';
14
+ import { SHORTCUT_CTX } from './ShortcutListener.svelte';
15
+ import type { ShortcutContextValue } from './ShortcutListener.svelte';
13
16
 
14
17
  let { panelId, control, values } = $props<{
15
18
  panelId: string;
@@ -17,7 +20,12 @@
17
20
  values: Record<string, DialValue>;
18
21
  }>();
19
22
 
23
+ const shortcutCtx = getContext<ShortcutContextValue | undefined>(SHORTCUT_CTX);
24
+
20
25
  const controlValue = $derived(values[control.path]);
26
+ const isShortcutActive = $derived(
27
+ shortcutCtx ? shortcutCtx.activePanelId === panelId && shortcutCtx.activePath === control.path : false
28
+ );
21
29
  </script>
22
30
 
23
31
  {#if control.type === 'slider'}
@@ -28,12 +36,16 @@
28
36
  min={control.min}
29
37
  max={control.max}
30
38
  step={control.step}
39
+ shortcut={control.shortcut}
40
+ shortcutActive={isShortcutActive}
31
41
  />
32
42
  {:else if control.type === 'toggle'}
33
43
  <Toggle
34
44
  label={control.label}
35
45
  checked={controlValue as boolean}
36
46
  onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
47
+ shortcut={control.shortcut}
48
+ shortcutActive={isShortcutActive}
37
49
  />
38
50
  {:else if control.type === 'spring'}
39
51
  <SpringControl
@@ -1 +1 @@
1
- {"version":3,"file":"ControlRenderer.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ControlRenderer.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAkC,MAAM,eAAe,CAAC;AAS5F,OAAO,eAAe,MAAM,0BAA0B,CAAC;AAEtD,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,CAAC;AA+CJ,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ControlRenderer.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ControlRenderer.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAkC,MAAM,eAAe,CAAC;AAS5F,OAAO,eAAe,MAAM,0BAA0B,CAAC;AAItD,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,CAAC;AAuDJ,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -4,14 +4,26 @@
4
4
  import { themeCSS } from '../theme-css';
5
5
  import Portal from '../Portal.svelte';
6
6
  import Panel from './Panel.svelte';
7
+ import ShortcutListener from './ShortcutListener.svelte';
7
8
 
8
9
  export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
9
10
  export type DialMode = 'popover' | 'inline';
11
+ export type DialTheme = 'light' | 'dark' | 'system';
10
12
 
11
- let { position = 'top-right', defaultOpen = true, mode = 'popover' } = $props<{
13
+ declare const process: { env?: { NODE_ENV?: string } } | undefined;
14
+
15
+ const isDevDefault = typeof process !== 'undefined' && process?.env?.NODE_ENV
16
+ ? process.env.NODE_ENV !== 'production'
17
+ : typeof import.meta !== 'undefined' && (import.meta as any).env?.MODE
18
+ ? (import.meta as any).env.MODE !== 'production'
19
+ : true;
20
+
21
+ let { position = 'top-right', defaultOpen = true, mode = 'popover', theme = 'system' as DialTheme, productionEnabled = isDevDefault } = $props<{
12
22
  position?: DialPosition;
13
23
  defaultOpen?: boolean;
14
24
  mode?: DialMode;
25
+ theme?: DialTheme;
26
+ productionEnabled?: boolean;
15
27
  }>();
16
28
 
17
29
  const inline = $derived(mode === 'inline');
@@ -44,15 +56,17 @@
44
56
  });
45
57
  </script>
46
58
 
47
- {#if mounted && panels.length > 0}
59
+ {#if productionEnabled && mounted && panels.length > 0}
48
60
  {#snippet content()}
49
- <div class="dialkit-root" data-mode={mode}>
50
- <div class="dialkit-panel" data-mode={mode} data-position={inline ? undefined : position}>
51
- {#each panels as panel (panel.id)}
52
- <Panel {panel} defaultOpen={inline || defaultOpen} {inline} />
53
- {/each}
61
+ <ShortcutListener>
62
+ <div class="dialkit-root" data-mode={mode} data-theme={theme}>
63
+ <div class="dialkit-panel" data-mode={mode} data-position={inline ? undefined : position}>
64
+ {#each panels as panel (panel.id)}
65
+ <Panel {panel} defaultOpen={inline || defaultOpen} {inline} />
66
+ {/each}
67
+ </div>
54
68
  </div>
55
- </div>
69
+ </ShortcutListener>
56
70
  {/snippet}
57
71
 
58
72
  {#if inline}
@@ -1,9 +1,12 @@
1
1
  export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
2
2
  export type DialMode = 'popover' | 'inline';
3
+ export type DialTheme = 'light' | 'dark' | 'system';
3
4
  type $$ComponentProps = {
4
5
  position?: DialPosition;
5
6
  defaultOpen?: boolean;
6
7
  mode?: DialMode;
8
+ theme?: DialTheme;
9
+ productionEnabled?: boolean;
7
10
  };
8
11
  declare const DialRoot: import("svelte").Component<$$ComponentProps, {}, "">;
9
12
  type DialRoot = ReturnType<typeof DialRoot>;
@@ -1 +1 @@
1
- {"version":3,"file":"DialRoot.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/DialRoot.svelte.ts"],"names":[],"mappings":"AAUE,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,CAAC;AACrF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC7C,KAAK,gBAAgB,GAAG;IACrB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,CAAC;AAgEJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"DialRoot.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/DialRoot.svelte.ts"],"names":[],"mappings":"AAWE,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,CAAC;AACrF,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AACrD,KAAK,gBAAgB,GAAG;IACrB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AA4EJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -3,6 +3,7 @@
3
3
  import { slide } from 'svelte/transition';
4
4
 
5
5
  import type { Snippet } from 'svelte';
6
+ import { ICON_PANEL, ICON_CHEVRON } from '../../icons';
6
7
 
7
8
  let {
8
9
  title,
@@ -28,6 +29,14 @@
28
29
 
29
30
  let contentRef: HTMLDivElement | undefined;
30
31
  let panelRef: HTMLDivElement | undefined;
32
+ let windowHeight = $state(typeof window !== 'undefined' ? window.innerHeight : 800);
33
+
34
+ $effect(() => {
35
+ if (!isRoot) return;
36
+ const onResize = () => { windowHeight = window.innerHeight; };
37
+ window.addEventListener('resize', onResize);
38
+ return () => window.removeEventListener('resize', onResize);
39
+ });
31
40
 
32
41
  const chevronRotation = new Spring(defaultOpen ? 0 : 180, { stiffness: 0.2, damping: 0.6 });
33
42
  const panelWidth = new Spring(defaultOpen ? 280 : 42, { stiffness: 0.2, damping: 0.62 });
@@ -65,7 +74,7 @@
65
74
  if (!isRoot) return;
66
75
 
67
76
  const measured = contentHeight ?? panelRef?.getBoundingClientRect().height ?? 42;
68
- const nextHeight = isOpen ? measured + 24 : 42;
77
+ const nextHeight = isOpen ? Math.min(measured + 10, windowHeight - 32) : 42;
69
78
 
70
79
  panelWidth.set(isOpen ? 280 : 42);
71
80
  panelHeight.set(nextHeight);
@@ -93,8 +102,8 @@
93
102
 
94
103
  const panelStyle = $derived(
95
104
  `width:${panelWidth.current}px;height:${panelHeight.current}px;border-radius:${panelRadius.current}px;` +
96
- `box-shadow:${isOpen ? '0 8px 32px rgba(0, 0, 0, 0.5)' : '0 4px 16px rgba(0, 0, 0, 0.25)'};` +
97
- `cursor:${isOpen ? '' : 'pointer'};overflow:${isOpen ? '' : 'hidden'};` +
105
+ `box-shadow:${isOpen ? 'var(--dial-shadow)' : 'var(--dial-shadow-collapsed)'};` +
106
+ `cursor:${isOpen ? '' : 'pointer'};overflow:${isOpen ? 'hidden auto' : 'hidden'};` +
98
107
  `transform:scale(${panelScale.current});`
99
108
  );
100
109
  </script>
@@ -145,12 +154,12 @@
145
154
  <svg class="dialkit-panel-icon" viewBox="0 0 16 16" fill="none">
146
155
  <path
147
156
  opacity="0.5"
148
- d="M6.84766 11.75C6.78583 11.9899 6.75 12.2408 6.75 12.5C6.75 12.7592 6.78583 13.0101 6.84766 13.25H2C1.58579 13.25 1.25 12.9142 1.25 12.5C1.25 12.0858 1.58579 11.75 2 11.75H6.84766ZM14 11.75C14.4142 11.75 14.75 12.0858 14.75 12.5C14.75 12.9142 14.4142 13.25 14 13.25H12.6523C12.7142 13.0101 12.75 12.7592 12.75 12.5C12.75 12.2408 12.7142 11.9899 12.6523 11.75H14ZM3.09766 7.25C3.03583 7.48994 3 7.74075 3 8C3 8.25925 3.03583 8.51006 3.09766 8.75H2C1.58579 8.75 1.25 8.41421 1.25 8C1.25 7.58579 1.58579 7.25 2 7.25H3.09766ZM14 7.25C14.4142 7.25 14.75 7.58579 14.75 8C14.75 8.41421 14.4142 8.75 14 8.75H8.90234C8.96417 8.51006 9 8.25925 9 8C9 7.74075 8.96417 7.48994 8.90234 7.25H14ZM7.59766 2.75C7.53583 2.98994 7.5 3.24075 7.5 3.5C7.5 3.75925 7.53583 4.01006 7.59766 4.25H2C1.58579 4.25 1.25 3.91421 1.25 3.5C1.25 3.08579 1.58579 2.75 2 2.75H7.59766ZM14 2.75C14.4142 2.75 14.75 3.08579 14.75 3.5C14.75 3.91421 14.4142 4.25 14 4.25H13.4023C13.4642 4.01006 13.5 3.75925 13.5 3.5C13.5 3.24075 13.4642 2.98994 13.4023 2.75H14Z"
157
+ d={ICON_PANEL.path}
149
158
  fill="currentColor"
150
159
  />
151
- <circle cx="6" cy="8" r="0.998596" fill="currentColor" stroke="currentColor" stroke-width="1.25" />
152
- <circle cx="10.4999" cy="3.5" r="0.998657" fill="currentColor" stroke="currentColor" stroke-width="1.25" />
153
- <circle cx="9.75015" cy="12.5" r="0.997986" fill="currentColor" stroke="currentColor" stroke-width="1.25" />
160
+ <circle cx={ICON_PANEL.circles[0].cx} cy={ICON_PANEL.circles[0].cy} r={ICON_PANEL.circles[0].r} fill="currentColor" stroke="currentColor" stroke-width="1.25" />
161
+ <circle cx={ICON_PANEL.circles[1].cx} cy={ICON_PANEL.circles[1].cy} r={ICON_PANEL.circles[1].r} fill="currentColor" stroke="currentColor" stroke-width="1.25" />
162
+ <circle cx={ICON_PANEL.circles[2].cx} cy={ICON_PANEL.circles[2].cy} r={ICON_PANEL.circles[2].r} fill="currentColor" stroke="currentColor" stroke-width="1.25" />
154
163
  </svg>
155
164
  </div>
156
165
 
@@ -188,7 +197,7 @@
188
197
  stroke-linejoin="round"
189
198
  style:transform={`rotate(${chevronRotation.current}deg)`}
190
199
  >
191
- <path d="M6 9.5L12 15.5L18 9.5" />
200
+ <path d={ICON_CHEVRON} />
192
201
  </svg>
193
202
  </div>
194
203
  </div>
@@ -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;AAErC,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;AAiLJ,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,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"}
@@ -5,9 +5,13 @@
5
5
  import Folder from './Folder.svelte';
6
6
  import PresetManager from './PresetManager.svelte';
7
7
  import ControlRenderer from './ControlRenderer.svelte';
8
+ import ShortcutsMenu from './ShortcutsMenu.svelte';
9
+ import { ICON_CLIPBOARD, ICON_CHECK, ICON_ADD_PRESET } from '../../icons';
8
10
 
9
11
  let { panel, defaultOpen = true, inline = false } = $props<{ panel: PanelConfig; defaultOpen?: boolean; inline?: boolean }>();
10
12
 
13
+ const hasShortcuts = $derived(Object.keys(panel.shortcuts).length > 0);
14
+
11
15
  let copied = $state(false);
12
16
  let isPanelOpen = $state(defaultOpen);
13
17
  let values = $state<Record<string, DialValue>>(DialStore.getValues(panel.id));
@@ -84,11 +88,11 @@
84
88
  style:transform={`scale(${addScale.current})`}
85
89
  >
86
90
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
87
- <path d="M4 6H20" />
88
- <path d="M4 12H10" />
89
- <path d="M15 15L21 15" />
90
- <path d="M18 12V18" />
91
- <path d="M4 18H10" />
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]} />
92
96
  </svg>
93
97
  </button>
94
98
 
@@ -113,9 +117,9 @@
113
117
  style:transform={`scale(${clipboardScale.current})`}
114
118
  style:filter={`blur(${(1 - clipboardOpacity.current) * 4}px)`}
115
119
  >
116
- <path d="M8 6C8 4.34315 9.34315 3 11 3H13C14.6569 3 16 4.34315 16 6V7H8V6Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
117
- <path d="M19.2405 16.1852L18.5436 14.3733C18.4571 14.1484 18.241 14 18 14C17.759 14 17.5429 14.1484 17.4564 14.3733L16.7595 16.1852C16.658 16.4493 16.4493 16.658 16.1852 16.7595L14.3733 17.4564C14.1484 17.5429 14 17.759 14 18C14 18.241 14.1484 18.4571 14.3733 18.5436L16.1852 19.2405C16.4493 19.342 16.658 19.5507 16.7595 19.8148L17.4564 21.6267C17.5429 21.8516 17.759 22 18 22C18.241 22 18.4571 21.8516 18.5436 21.6267L19.2405 19.8148C19.342 19.5507 19.5507 19.342 19.8148 19.2405L21.6267 18.5436C21.8516 18.4571 22 18.241 22 18C22 17.759 21.8516 17.5429 21.6267 17.4564L19.8148 16.7595C19.5507 16.658 19.342 16.4493 19.2405 16.1852Z" fill="currentColor"/>
118
- <path d="M16 5H17C18.6569 5 20 6.34315 20 8V11M8 5H7C5.34315 5 4 6.34315 4 8V18C4 19.6569 5.34315 21 7 21H12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
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"/>
119
123
  </svg>
120
124
 
121
125
  <svg
@@ -130,11 +134,12 @@
130
134
  style:transform={`scale(${checkScale.current})`}
131
135
  style:filter={`blur(${(1 - checkOpacity.current) * 4}px)`}
132
136
  >
133
- <path d="M5 12.75L10 19L19 5" />
137
+ <path d={ICON_CHECK} />
134
138
  </svg>
135
139
  </span>
136
140
  Copy
137
141
  </button>
142
+
138
143
  {/snippet}
139
144
 
140
145
  {#each panel.controls as control (control.path)}
@@ -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;AAKnE,KAAK,gBAAgB,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAgHzF,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;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"}
@@ -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 { ICON_CHEVRON, ICON_TRASH } from '../../icons';
7
8
 
8
9
  let { panelId, presets, activePresetId } = $props<{
9
10
  panelId: string;
@@ -106,7 +107,7 @@
106
107
  style:transform={`rotate(${chevronRotation.current}deg)`}
107
108
  style:opacity={chevronOpacity.current}
108
109
  >
109
- <path d="M6 9.5L12 15.5L18 9.5" />
110
+ <path d={ICON_CHEVRON} />
110
111
  </svg>
111
112
  </button>
112
113
 
@@ -140,11 +141,11 @@
140
141
  title="Delete preset"
141
142
  >
142
143
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
143
- <path d="M5 6.5L5.80734 18.2064C5.91582 19.7794 7.22348 21 8.80023 21H15.1998C16.7765 21 18.0842 19.7794 18.1927 18.2064L19 6.5" />
144
- <path d="M10 11V16" />
145
- <path d="M14 11V16" />
146
- <path d="M3.5 6H20.5" />
147
- <path d="M8.07092 5.74621C8.42348 3.89745 10.0485 2.5 12 2.5C13.9515 2.5 15.5765 3.89745 15.9291 5.74621" />
144
+ <path d={ICON_TRASH[0]} />
145
+ <path d={ICON_TRASH[1]} />
146
+ <path d={ICON_TRASH[2]} />
147
+ <path d={ICON_TRASH[3]} />
148
+ <path d={ICON_TRASH[4]} />
148
149
  </svg>
149
150
  </button>
150
151
  </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;AAG3C,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AA0HJ,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;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,6 +1,4 @@
1
1
  <script lang="ts">
2
- import { Spring } from 'svelte/motion';
3
-
4
2
  export interface SegmentedControlOption<T extends string = string> {
5
3
  value: T;
6
4
  label: string;
@@ -12,90 +10,48 @@
12
10
  onChange: (value: string) => void;
13
11
  }>();
14
12
 
15
- let containerRef: HTMLDivElement | undefined;
16
- const buttonRefs = new Map<string, HTMLButtonElement>();
17
- let pillReady = $state(false);
13
+ let containerRef = $state<HTMLDivElement | undefined>(undefined);
18
14
  let hasAnimated = false;
19
-
20
- const pillLeft = new Spring(0, { stiffness: 0.2, damping: 0.6 });
21
- const pillWidth = new Spring(0, { stiffness: 0.2, damping: 0.6 });
22
-
23
- const buttonRef = (node: HTMLButtonElement, key: string) => {
24
- buttonRefs.set(key, node);
25
- return {
26
- destroy() {
27
- buttonRefs.delete(key);
28
- },
29
- };
30
- };
31
-
32
- const measurePill = () => {
33
- const button = buttonRefs.get(value);
34
- if (!button || !containerRef) return null;
35
- const containerRect = containerRef.getBoundingClientRect();
36
- const buttonRect = button.getBoundingClientRect();
37
-
38
- return {
39
- left: buttonRect.left - containerRect.left,
40
- width: buttonRect.width,
41
- };
42
- };
43
-
44
- const updatePill = (shouldAnimate: boolean) => {
45
- const next = measurePill();
46
- if (!next) return;
47
-
48
- if (!pillReady) {
49
- pillLeft.set(next.left, { instant: true });
50
- pillWidth.set(next.width, { instant: true });
51
- pillReady = true;
52
- return;
53
- }
54
-
55
- if (!shouldAnimate || !hasAnimated) {
56
- pillLeft.set(next.left, { instant: true });
57
- pillWidth.set(next.width, { instant: true });
58
- return;
59
- }
60
-
61
- pillLeft.set(next.left);
62
- pillWidth.set(next.width);
63
- };
15
+ let pillLeft = $state<number | null>(null);
16
+ let pillWidth = $state<number | null>(null);
17
+
18
+ function measure() {
19
+ if (!containerRef) return;
20
+ const activeButton = containerRef.querySelector('[data-active="true"]') as HTMLElement | null;
21
+ if (!activeButton) return;
22
+ pillLeft = activeButton.offsetLeft;
23
+ pillWidth = activeButton.offsetWidth;
24
+ }
64
25
 
65
26
  $effect(() => {
66
- value;
67
- if (!pillReady) return;
68
- updatePill(true);
27
+ void value;
28
+ void options.length;
29
+ measure();
69
30
  });
70
31
 
71
- $effect(() => {
72
- if (!containerRef || typeof ResizeObserver === 'undefined') return;
73
-
74
- requestAnimationFrame(() => {
75
- updatePill(false);
32
+ let shouldAnimate = $derived.by(() => {
33
+ if (!hasAnimated) {
76
34
  hasAnimated = true;
77
- });
78
-
79
- const ro = new ResizeObserver(() => updatePill(false));
80
- ro.observe(containerRef);
81
-
82
- return () => {
83
- ro.disconnect();
84
- };
35
+ return false;
36
+ }
37
+ return true;
85
38
  });
86
39
  </script>
87
40
 
88
- <div bind:this={containerRef} class="dialkit-segmented">
89
- <div
90
- class="dialkit-segmented-pill"
91
- style:left={`${pillLeft.current}px`}
92
- style:width={`${pillWidth.current}px`}
93
- style:visibility={pillReady ? 'visible' : 'hidden'}
94
- />
41
+ <div class="dialkit-segmented" bind:this={containerRef}>
42
+ {#if pillLeft !== null && pillWidth !== null}
43
+ <div
44
+ class="dialkit-segmented-pill"
45
+ style:left="{pillLeft}px"
46
+ style:width="{pillWidth}px"
47
+ style:transition={shouldAnimate
48
+ ? 'left 0.2s cubic-bezier(0.25, 1, 0.5, 1), width 0.2s cubic-bezier(0.25, 1, 0.5, 1)'
49
+ : 'none'}
50
+ ></div>
51
+ {/if}
95
52
 
96
53
  {#each options as option (option.value)}
97
54
  <button
98
- use:buttonRef={option.value}
99
55
  onclick={() => onChange(option.value)}
100
56
  class="dialkit-segmented-button"
101
57
  data-active={String(value === option.value)}
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SegmentedControl.svelte.ts"],"names":[],"mappings":"AAME,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC/D,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AACF,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AA4FJ,QAAA,MAAM,gBAAgB,sDAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SegmentedControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SegmentedControl.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC/D,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AACF,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAkDJ,QAAA,MAAM,gBAAgB,sDAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,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 { ICON_CHEVRON } from '../../icons';
5
6
 
6
7
  type SelectOption = string | { value: string; label: string };
7
8
 
@@ -118,7 +119,7 @@
118
119
  stroke-linejoin="round"
119
120
  style:transform={`rotate(${chevronRotation.current}deg)`}
120
121
  >
121
- <path d="M6 9.5L12 15.5L18 9.5" />
122
+ <path d={ICON_CHEVRON} />
122
123
  </svg>
123
124
  </div>
124
125
  </button>
@@ -1 +1 @@
1
- {"version":3,"file":"SelectControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SelectControl.svelte.ts"],"names":[],"mappings":"AAQE,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;AA8HJ,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":"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"}