dialkit 1.0.0 → 1.1.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 (85) hide show
  1. package/README.md +123 -2
  2. package/dist/index.cjs +42 -39
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +7 -5
  5. package/dist/index.d.ts +7 -5
  6. package/dist/index.js +42 -39
  7. package/dist/index.js.map +1 -1
  8. package/dist/solid/index.cjs +97 -54
  9. package/dist/solid/index.cjs.map +1 -1
  10. package/dist/solid/index.d.cts +4 -1
  11. package/dist/solid/index.d.ts +4 -1
  12. package/dist/solid/index.js +96 -53
  13. package/dist/solid/index.js.map +1 -1
  14. package/dist/store/index.cjs +450 -0
  15. package/dist/store/index.cjs.map +1 -0
  16. package/dist/store/index.d.cts +124 -0
  17. package/dist/store/index.d.ts +124 -0
  18. package/dist/store/index.js +425 -0
  19. package/dist/store/index.js.map +1 -0
  20. package/dist/styles.css +31 -0
  21. package/dist/svelte/Portal.svelte +30 -0
  22. package/dist/svelte/Portal.svelte.d.ts +9 -0
  23. package/dist/svelte/Portal.svelte.d.ts.map +1 -0
  24. package/dist/svelte/components/ButtonGroup.svelte +16 -0
  25. package/dist/svelte/components/ButtonGroup.svelte.d.ts +11 -0
  26. package/dist/svelte/components/ButtonGroup.svelte.d.ts.map +1 -0
  27. package/dist/svelte/components/ColorControl.svelte +81 -0
  28. package/dist/svelte/components/ColorControl.svelte.d.ts +9 -0
  29. package/dist/svelte/components/ColorControl.svelte.d.ts.map +1 -0
  30. package/dist/svelte/components/ControlRenderer.svelte +84 -0
  31. package/dist/svelte/components/ControlRenderer.svelte.d.ts +11 -0
  32. package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -0
  33. package/dist/svelte/components/DialRoot.svelte +65 -0
  34. package/dist/svelte/components/DialRoot.svelte.d.ts +11 -0
  35. package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -0
  36. package/dist/svelte/components/EasingVisualization.svelte +50 -0
  37. package/dist/svelte/components/EasingVisualization.svelte.d.ts +10 -0
  38. package/dist/svelte/components/EasingVisualization.svelte.d.ts.map +1 -0
  39. package/dist/svelte/components/Folder.svelte +204 -0
  40. package/dist/svelte/components/Folder.svelte.d.ts +14 -0
  41. package/dist/svelte/components/Folder.svelte.d.ts.map +1 -0
  42. package/dist/svelte/components/Panel.svelte +144 -0
  43. package/dist/svelte/components/Panel.svelte.d.ts +10 -0
  44. package/dist/svelte/components/Panel.svelte.d.ts.map +1 -0
  45. package/dist/svelte/components/PresetManager.svelte +156 -0
  46. package/dist/svelte/components/PresetManager.svelte.d.ts +10 -0
  47. package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -0
  48. package/dist/svelte/components/SegmentedControl.svelte +106 -0
  49. package/dist/svelte/components/SegmentedControl.svelte.d.ts +13 -0
  50. package/dist/svelte/components/SegmentedControl.svelte.d.ts.map +1 -0
  51. package/dist/svelte/components/SelectControl.svelte +151 -0
  52. package/dist/svelte/components/SelectControl.svelte.d.ts +14 -0
  53. package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -0
  54. package/dist/svelte/components/Slider.svelte +345 -0
  55. package/dist/svelte/components/Slider.svelte.d.ts +13 -0
  56. package/dist/svelte/components/Slider.svelte.d.ts.map +1 -0
  57. package/dist/svelte/components/SpringControl.svelte +124 -0
  58. package/dist/svelte/components/SpringControl.svelte.d.ts +12 -0
  59. package/dist/svelte/components/SpringControl.svelte.d.ts.map +1 -0
  60. package/dist/svelte/components/SpringVisualization.svelte +115 -0
  61. package/dist/svelte/components/SpringVisualization.svelte.d.ts +9 -0
  62. package/dist/svelte/components/SpringVisualization.svelte.d.ts.map +1 -0
  63. package/dist/svelte/components/TextControl.svelte +19 -0
  64. package/dist/svelte/components/TextControl.svelte.d.ts +10 -0
  65. package/dist/svelte/components/TextControl.svelte.d.ts.map +1 -0
  66. package/dist/svelte/components/Toggle.svelte +21 -0
  67. package/dist/svelte/components/Toggle.svelte.d.ts +9 -0
  68. package/dist/svelte/components/Toggle.svelte.d.ts.map +1 -0
  69. package/dist/svelte/components/TransitionControl.svelte +200 -0
  70. package/dist/svelte/components/TransitionControl.svelte.d.ts +12 -0
  71. package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -0
  72. package/dist/svelte/components/transitions.d.ts +6 -0
  73. package/dist/svelte/components/transitions.d.ts.map +1 -0
  74. package/dist/svelte/components/transitions.js +14 -0
  75. package/dist/svelte/createDialKit.svelte.d.ts +7 -0
  76. package/dist/svelte/createDialKit.svelte.d.ts.map +1 -0
  77. package/dist/svelte/createDialKit.svelte.js +82 -0
  78. package/dist/svelte/index.d.ts +19 -0
  79. package/dist/svelte/index.d.ts.map +1 -0
  80. package/dist/svelte/index.js +19 -0
  81. package/dist/svelte/shims.d.ts +9 -0
  82. package/dist/svelte/theme-css.d.ts +2 -0
  83. package/dist/svelte/theme-css.d.ts.map +1 -0
  84. package/dist/svelte/theme-css.js +1097 -0
  85. package/package.json +29 -5
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ let { target = 'body', children } = $props<{ target?: string | HTMLElement | null; children?: Snippet }>();
5
+
6
+ let portalEl: HTMLDivElement | undefined;
7
+
8
+ const resolveTarget = (): HTMLElement | null => {
9
+ if (typeof document === 'undefined') return null;
10
+ if (!target) return document.body;
11
+ if (typeof target === 'string') return document.querySelector(target);
12
+ return target;
13
+ };
14
+
15
+ $effect(() => {
16
+ if (!portalEl) return;
17
+ const root = resolveTarget();
18
+ if (!root) return;
19
+
20
+ root.appendChild(portalEl);
21
+
22
+ return () => {
23
+ portalEl?.remove();
24
+ };
25
+ });
26
+ </script>
27
+
28
+ <div bind:this={portalEl} style="display: contents;">
29
+ {#if children}{@render children()}{/if}
30
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ target?: string | HTMLElement | null;
4
+ children?: Snippet;
5
+ };
6
+ declare const Portal: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type Portal = ReturnType<typeof Portal>;
8
+ export default Portal;
9
+ //# sourceMappingURL=Portal.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Portal.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/Portal.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAErC,KAAK,gBAAgB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAkCtF,QAAA,MAAM,MAAM,sDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ export type ButtonAction = {
3
+ label: string;
4
+ onClick: () => void;
5
+ };
6
+
7
+ let { buttons } = $props<{ buttons: ButtonAction[] }>();
8
+ </script>
9
+
10
+ <div class="dialkit-button-group">
11
+ {#each buttons as button (button.label)}
12
+ <button class="dialkit-button" onclick={button.onClick}>
13
+ {button.label}
14
+ </button>
15
+ {/each}
16
+ </div>
@@ -0,0 +1,11 @@
1
+ export type ButtonAction = {
2
+ label: string;
3
+ onClick: () => void;
4
+ };
5
+ type $$ComponentProps = {
6
+ buttons: ButtonAction[];
7
+ };
8
+ declare const ButtonGroup: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type ButtonGroup = ReturnType<typeof ButtonGroup>;
10
+ export default ButtonGroup;
11
+ //# sourceMappingURL=ButtonGroup.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonGroup.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ButtonGroup.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AACH,KAAK,gBAAgB,GAAG;IAAE,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAiBrD,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,81 @@
1
+ <script lang="ts">
2
+ const HEX_COLOR_REGEX = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
3
+
4
+ let { label, value, onChange } = $props<{
5
+ label: string;
6
+ value: string;
7
+ onChange: (value: string) => void;
8
+ }>();
9
+
10
+ let isEditing = $state(false);
11
+ let editValue = $state(value);
12
+ let colorInputRef: HTMLInputElement | undefined;
13
+
14
+ const expandShorthandHex = (hex: string) => {
15
+ if (hex.length !== 4) return hex;
16
+ return `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`;
17
+ };
18
+
19
+ $effect(() => {
20
+ value;
21
+ if (!isEditing) {
22
+ editValue = value;
23
+ }
24
+ });
25
+
26
+ const handleTextSubmit = () => {
27
+ isEditing = false;
28
+ if (HEX_COLOR_REGEX.test(editValue)) {
29
+ onChange(editValue);
30
+ } else {
31
+ editValue = value;
32
+ }
33
+ };
34
+
35
+ const handleKeyDown = (e: KeyboardEvent) => {
36
+ if (e.key === 'Enter') {
37
+ handleTextSubmit();
38
+ } else if (e.key === 'Escape') {
39
+ isEditing = false;
40
+ editValue = value;
41
+ }
42
+ };
43
+ </script>
44
+
45
+ <div class="dialkit-color-control">
46
+ <label class="dialkit-color-label">{label}</label>
47
+ <div class="dialkit-color-inputs">
48
+ {#if isEditing}
49
+ <input
50
+ type="text"
51
+ class="dialkit-color-hex-input"
52
+ value={editValue}
53
+ oninput={(e) => (editValue = (e.currentTarget as HTMLInputElement).value)}
54
+ onblur={handleTextSubmit}
55
+ onkeydown={handleKeyDown}
56
+ autofocus
57
+ />
58
+ {:else}
59
+ <span class="dialkit-color-hex" onclick={() => (isEditing = true)}>
60
+ {(value ?? '').toUpperCase()}
61
+ </span>
62
+ {/if}
63
+
64
+ <button
65
+ class="dialkit-color-swatch"
66
+ style:background-color={value}
67
+ onclick={() => colorInputRef?.click()}
68
+ title="Pick color"
69
+ aria-label={`Pick color for ${label}`}
70
+ />
71
+
72
+ <input
73
+ bind:this={colorInputRef}
74
+ type="color"
75
+ class="dialkit-color-picker-native"
76
+ aria-label={`${label} color picker`}
77
+ value={value.length === 4 ? expandShorthandHex(value) : value.slice(0, 7)}
78
+ oninput={(e) => onChange((e.currentTarget as HTMLInputElement).value)}
79
+ />
80
+ </div>
81
+ </div>
@@ -0,0 +1,9 @@
1
+ type $$ComponentProps = {
2
+ label: string;
3
+ value: string;
4
+ onChange: (value: string) => void;
5
+ };
6
+ declare const ColorControl: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type ColorControl = ReturnType<typeof ColorControl>;
8
+ export default ColorControl;
9
+ //# sourceMappingURL=ColorControl.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ColorControl.svelte.ts"],"names":[],"mappings":"AAGC,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AA4DJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ import { DialStore } from 'dialkit/store';
3
+ import type { ControlMeta, DialValue, SpringConfig, TransitionConfig } from 'dialkit/store';
4
+ import Slider from './Slider.svelte';
5
+ import Toggle from './Toggle.svelte';
6
+ import Folder from './Folder.svelte';
7
+ import SpringControl from './SpringControl.svelte';
8
+ import TransitionControl from './TransitionControl.svelte';
9
+ import TextControl from './TextControl.svelte';
10
+ import SelectControl from './SelectControl.svelte';
11
+ import ColorControl from './ColorControl.svelte';
12
+ import ControlRenderer from './ControlRenderer.svelte';
13
+
14
+ let { panelId, control, values } = $props<{
15
+ panelId: string;
16
+ control: ControlMeta;
17
+ values: Record<string, DialValue>;
18
+ }>();
19
+
20
+ const controlValue = $derived(values[control.path]);
21
+ </script>
22
+
23
+ {#if control.type === 'slider'}
24
+ <Slider
25
+ label={control.label}
26
+ value={controlValue as number}
27
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
28
+ min={control.min}
29
+ max={control.max}
30
+ step={control.step}
31
+ />
32
+ {:else if control.type === 'toggle'}
33
+ <Toggle
34
+ label={control.label}
35
+ checked={controlValue as boolean}
36
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
37
+ />
38
+ {:else if control.type === 'spring'}
39
+ <SpringControl
40
+ {panelId}
41
+ path={control.path}
42
+ label={control.label}
43
+ spring={controlValue as SpringConfig}
44
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
45
+ />
46
+ {:else if control.type === 'transition'}
47
+ <TransitionControl
48
+ {panelId}
49
+ path={control.path}
50
+ label={control.label}
51
+ value={controlValue as TransitionConfig}
52
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
53
+ />
54
+ {:else if control.type === 'folder'}
55
+ <Folder title={control.label} defaultOpen={control.defaultOpen ?? true}>
56
+ {#each control.children ?? [] as child (child.path)}
57
+ <ControlRenderer {panelId} control={child} {values} />
58
+ {/each}
59
+ </Folder>
60
+ {:else if control.type === 'text'}
61
+ <TextControl
62
+ label={control.label}
63
+ value={controlValue as string}
64
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
65
+ placeholder={control.placeholder}
66
+ />
67
+ {:else if control.type === 'select'}
68
+ <SelectControl
69
+ label={control.label}
70
+ value={controlValue as string}
71
+ options={control.options ?? []}
72
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
73
+ />
74
+ {:else if control.type === 'color'}
75
+ <ColorControl
76
+ label={control.label}
77
+ value={controlValue as string}
78
+ onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
79
+ />
80
+ {:else if control.type === 'action'}
81
+ <button class="dialkit-button" onclick={() => DialStore.triggerAction(panelId, control.path)}>
82
+ {control.label}
83
+ </button>
84
+ {/if}
@@ -0,0 +1,11 @@
1
+ import type { ControlMeta, DialValue } from 'dialkit/store';
2
+ import ControlRenderer from './ControlRenderer.svelte';
3
+ type $$ComponentProps = {
4
+ panelId: string;
5
+ control: ControlMeta;
6
+ values: Record<string, DialValue>;
7
+ };
8
+ declare const ControlRenderer: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type ControlRenderer = ReturnType<typeof ControlRenderer>;
10
+ export default ControlRenderer;
11
+ //# sourceMappingURL=ControlRenderer.svelte.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,65 @@
1
+ <script lang="ts">
2
+ import { DialStore } from 'dialkit/store';
3
+ import type { PanelConfig } from 'dialkit/store';
4
+ import { themeCSS } from '../theme-css';
5
+ import Portal from '../Portal.svelte';
6
+ import Panel from './Panel.svelte';
7
+
8
+ export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
9
+ export type DialMode = 'popover' | 'inline';
10
+
11
+ let { position = 'top-right', defaultOpen = true, mode = 'popover' } = $props<{
12
+ position?: DialPosition;
13
+ defaultOpen?: boolean;
14
+ mode?: DialMode;
15
+ }>();
16
+
17
+ const inline = $derived(mode === 'inline');
18
+
19
+ let panels = $state<PanelConfig[]>([]);
20
+ let mounted = $state(false);
21
+
22
+ $effect(() => {
23
+ if (typeof document === 'undefined') return;
24
+ const id = 'dialkit-theme';
25
+ if (!document.getElementById(id)) {
26
+ const style = document.createElement('style');
27
+ style.id = id;
28
+ style.textContent = themeCSS;
29
+ document.head.appendChild(style);
30
+ }
31
+ });
32
+
33
+ $effect(() => {
34
+ if (typeof window === 'undefined') return;
35
+
36
+ mounted = true;
37
+ panels = DialStore.getPanels();
38
+
39
+ const unsub = DialStore.subscribeGlobal(() => {
40
+ panels = DialStore.getPanels();
41
+ });
42
+
43
+ return unsub;
44
+ });
45
+ </script>
46
+
47
+ {#if mounted && panels.length > 0}
48
+ {#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}
54
+ </div>
55
+ </div>
56
+ {/snippet}
57
+
58
+ {#if inline}
59
+ {@render content()}
60
+ {:else}
61
+ <Portal target="body">
62
+ {@render content()}
63
+ </Portal>
64
+ {/if}
65
+ {/if}
@@ -0,0 +1,11 @@
1
+ export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
2
+ export type DialMode = 'popover' | 'inline';
3
+ type $$ComponentProps = {
4
+ position?: DialPosition;
5
+ defaultOpen?: boolean;
6
+ mode?: DialMode;
7
+ };
8
+ declare const DialRoot: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type DialRoot = ReturnType<typeof DialRoot>;
10
+ export default DialRoot;
11
+ //# sourceMappingURL=DialRoot.svelte.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,50 @@
1
+ <script lang="ts">
2
+ import type { EasingConfig } from 'dialkit/store';
3
+
4
+ let { easing } = $props<{ easing: EasingConfig }>();
5
+
6
+ export const easingPresets: Record<string, [number, number, number, number]> = {
7
+ linear: [0, 0, 1, 1],
8
+ easeIn: [0.42, 0, 1, 1],
9
+ easeOut: [0, 0, 0.58, 1],
10
+ easeInOut: [0.42, 0, 0.58, 1],
11
+ };
12
+
13
+ const s = 200;
14
+ const pad = 10;
15
+ const inner = s - pad * 2;
16
+ const unit = inner / 2;
17
+
18
+ const toSvg = (nx: number, ny: number) => ({
19
+ x: pad + (nx + 0.5) * unit,
20
+ y: pad + (1.5 - ny) * unit,
21
+ });
22
+
23
+ const points = $derived.by(() => {
24
+ const ease = easing.ease;
25
+ const start = toSvg(0, 0);
26
+ const end = toSvg(1, 1);
27
+ const p1 = toSvg(ease[0], ease[1]);
28
+ const p2 = toSvg(ease[2], ease[3]);
29
+
30
+ return {
31
+ start,
32
+ end,
33
+ curvePath: `M ${start.x} ${start.y} C ${p1.x} ${p1.y}, ${p2.x} ${p2.y}, ${end.x} ${end.y}`,
34
+ };
35
+ });
36
+ </script>
37
+
38
+ <svg viewBox={`0 0 ${s} ${s}`} preserveAspectRatio="xMidYMid slice" class="dialkit-spring-viz dialkit-easing-viz">
39
+ <line
40
+ x1={points.start.x}
41
+ y1={points.start.y}
42
+ x2={points.end.x}
43
+ y2={points.end.y}
44
+ stroke="rgba(255, 255, 255, 0.15)"
45
+ stroke-width="1"
46
+ stroke-dasharray="4,4"
47
+ />
48
+
49
+ <path d={points.curvePath} fill="none" stroke="rgba(255, 255, 255, 0.6)" stroke-width="2" stroke-linecap="round" />
50
+ </svg>
@@ -0,0 +1,10 @@
1
+ import type { EasingConfig } from 'dialkit/store';
2
+ type $$ComponentProps = {
3
+ easing: EasingConfig;
4
+ };
5
+ declare const EasingVisualization: import("svelte").Component<$$ComponentProps, {
6
+ easingPresets: Record<string, [number, number, number, number]>;
7
+ }, "">;
8
+ type EasingVisualization = ReturnType<typeof EasingVisualization>;
9
+ export default EasingVisualization;
10
+ //# sourceMappingURL=EasingVisualization.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EasingVisualization.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/EasingVisualization.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjD,KAAK,gBAAgB,GAAG;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AA8ClD,QAAA,MAAM,mBAAmB;mBADyF,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;MACjG,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,204 @@
1
+ <script lang="ts">
2
+ import { Spring } from 'svelte/motion';
3
+ import { slide } from 'svelte/transition';
4
+
5
+ import type { Snippet } from 'svelte';
6
+
7
+ let {
8
+ title,
9
+ defaultOpen = true,
10
+ isRoot = false,
11
+ inline = false,
12
+ onOpenChange,
13
+ toolbar,
14
+ children,
15
+ } = $props<{
16
+ title: string;
17
+ defaultOpen?: boolean;
18
+ isRoot?: boolean;
19
+ inline?: boolean;
20
+ onOpenChange?: (isOpen: boolean) => void;
21
+ toolbar?: Snippet;
22
+ children?: Snippet;
23
+ }>();
24
+
25
+ let isOpen = $state(defaultOpen);
26
+ let isCollapsed = $state(!defaultOpen);
27
+ let contentHeight = $state<number | undefined>(undefined);
28
+
29
+ let contentRef: HTMLDivElement | undefined;
30
+ let panelRef: HTMLDivElement | undefined;
31
+
32
+ const chevronRotation = new Spring(defaultOpen ? 0 : 180, { stiffness: 0.2, damping: 0.6 });
33
+ const panelWidth = new Spring(defaultOpen ? 280 : 42, { stiffness: 0.2, damping: 0.62 });
34
+ const panelHeight = new Spring(defaultOpen ? 220 : 42, { stiffness: 0.2, damping: 0.62 });
35
+ const panelRadius = new Spring(defaultOpen ? 14 : 21, { stiffness: 0.2, damping: 0.62 });
36
+ const panelScale = new Spring(1, { stiffness: 0.25, damping: 0.7 });
37
+
38
+ $effect(() => {
39
+ if (!isRoot || !contentRef || typeof ResizeObserver === 'undefined') return;
40
+
41
+ const ro = new ResizeObserver(() => {
42
+ if (!isOpen) return;
43
+ const next = contentRef?.offsetHeight;
44
+ if (!next) return;
45
+ contentHeight = next;
46
+ });
47
+
48
+ ro.observe(contentRef);
49
+
50
+ if (contentRef.offsetHeight > 0) {
51
+ contentHeight = contentRef.offsetHeight;
52
+ }
53
+
54
+ return () => {
55
+ ro.disconnect();
56
+ };
57
+ });
58
+
59
+ $effect(() => {
60
+ if (isRoot) return;
61
+ chevronRotation.set(isOpen ? 0 : 180);
62
+ });
63
+
64
+ $effect(() => {
65
+ if (!isRoot) return;
66
+
67
+ const measured = contentHeight ?? panelRef?.getBoundingClientRect().height ?? 42;
68
+ const nextHeight = isOpen ? measured + 24 : 42;
69
+
70
+ panelWidth.set(isOpen ? 280 : 42);
71
+ panelHeight.set(nextHeight);
72
+ panelRadius.set(isOpen ? 14 : 21);
73
+ });
74
+
75
+ const handleToggle = () => {
76
+ if (inline && isRoot) return;
77
+ const next = !isOpen;
78
+ isOpen = next;
79
+ isCollapsed = !next;
80
+ onOpenChange?.(next);
81
+ };
82
+
83
+ const handleCollapsedTapStart = () => {
84
+ if (isOpen) return;
85
+ (document.activeElement as HTMLElement | null)?.blur?.();
86
+ panelScale.set(0.9);
87
+ };
88
+
89
+ const handleCollapsedTapEnd = () => {
90
+ if (isOpen) return;
91
+ panelScale.set(1);
92
+ };
93
+
94
+ const panelStyle = $derived(
95
+ `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'};` +
98
+ `transform:scale(${panelScale.current});`
99
+ );
100
+ </script>
101
+
102
+ {#if isRoot && inline}
103
+ <div class="dialkit-panel-inner dialkit-panel-inline">
104
+ <div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
105
+ <div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
106
+ <div class="dialkit-folder-header-top">
107
+ <div class="dialkit-folder-title-row">
108
+ <span class="dialkit-folder-title dialkit-folder-title-root">{title}</span>
109
+ </div>
110
+ </div>
111
+
112
+ <div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
113
+ {#if toolbar}{@render toolbar()}{/if}
114
+ </div>
115
+ </div>
116
+
117
+ <div class="dialkit-folder-content">
118
+ <div class="dialkit-folder-inner">
119
+ {#if children}{@render children()}{/if}
120
+ </div>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ {:else if isRoot}
125
+ <div
126
+ bind:this={panelRef}
127
+ class="dialkit-panel-inner"
128
+ data-collapsed={String(isCollapsed)}
129
+ style={panelStyle}
130
+ onpointerdown={handleCollapsedTapStart}
131
+ onpointerup={handleCollapsedTapEnd}
132
+ onpointercancel={handleCollapsedTapEnd}
133
+ onpointerleave={handleCollapsedTapEnd}
134
+ onclick={() => { if (!isOpen) handleToggle(); }}
135
+ >
136
+ <div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
137
+ <div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
138
+ <div class="dialkit-folder-header-top">
139
+ {#if isOpen}
140
+ <div class="dialkit-folder-title-row">
141
+ <span class="dialkit-folder-title dialkit-folder-title-root">{title}</span>
142
+ </div>
143
+ {/if}
144
+
145
+ <svg class="dialkit-panel-icon" viewBox="0 0 16 16" fill="none">
146
+ <path
147
+ 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"
149
+ fill="currentColor"
150
+ />
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" />
154
+ </svg>
155
+ </div>
156
+
157
+ {#if isOpen}
158
+ <div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
159
+ {#if toolbar}{@render toolbar()}{/if}
160
+ </div>
161
+ {/if}
162
+ </div>
163
+
164
+ {#if isOpen}
165
+ <div class="dialkit-folder-content">
166
+ <div class="dialkit-folder-inner">
167
+ {#if children}{@render children()}{/if}
168
+ </div>
169
+ </div>
170
+ {/if}
171
+ </div>
172
+ </div>
173
+ {:else}
174
+ <div class="dialkit-folder">
175
+ <div class="dialkit-folder-header" onclick={handleToggle}>
176
+ <div class="dialkit-folder-header-top">
177
+ <div class="dialkit-folder-title-row">
178
+ <span class="dialkit-folder-title">{title}</span>
179
+ </div>
180
+
181
+ <svg
182
+ class="dialkit-folder-icon"
183
+ viewBox="0 0 24 24"
184
+ fill="none"
185
+ stroke="currentColor"
186
+ stroke-width="2.5"
187
+ stroke-linecap="round"
188
+ stroke-linejoin="round"
189
+ style:transform={`rotate(${chevronRotation.current}deg)`}
190
+ >
191
+ <path d="M6 9.5L12 15.5L18 9.5" />
192
+ </svg>
193
+ </div>
194
+ </div>
195
+
196
+ {#if isOpen}
197
+ <div class="dialkit-folder-content" style="clip-path: inset(0 -20px);" transition:slide={{ duration: 220 }}>
198
+ <div class="dialkit-folder-inner">
199
+ {#if children}{@render children()}{/if}
200
+ </div>
201
+ </div>
202
+ {/if}
203
+ </div>
204
+ {/if}
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ title: string;
4
+ defaultOpen?: boolean;
5
+ isRoot?: boolean;
6
+ inline?: boolean;
7
+ onOpenChange?: (isOpen: boolean) => void;
8
+ toolbar?: Snippet;
9
+ children?: Snippet;
10
+ };
11
+ declare const Folder: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type Folder = ReturnType<typeof Folder>;
13
+ export default Folder;
14
+ //# sourceMappingURL=Folder.svelte.d.ts.map
@@ -0,0 +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"}