dialkit 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +293 -2
- package/dist/index.cjs +905 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -9
- package/dist/index.d.ts +46 -9
- package/dist/index.js +910 -370
- package/dist/index.js.map +1 -1
- package/dist/solid/index.cjs +1042 -532
- package/dist/solid/index.cjs.map +1 -1
- package/dist/solid/index.d.cts +36 -3
- package/dist/solid/index.d.ts +36 -3
- package/dist/solid/index.js +911 -402
- package/dist/solid/index.js.map +1 -1
- package/dist/store/index.cjs +490 -0
- package/dist/store/index.cjs.map +1 -0
- package/dist/store/index.d.cts +146 -0
- package/dist/store/index.d.ts +146 -0
- package/dist/store/index.js +465 -0
- package/dist/store/index.js.map +1 -0
- package/dist/styles.css +287 -25
- package/dist/svelte/Portal.svelte +30 -0
- package/dist/svelte/Portal.svelte.d.ts +9 -0
- package/dist/svelte/Portal.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ButtonGroup.svelte +16 -0
- package/dist/svelte/components/ButtonGroup.svelte.d.ts +11 -0
- package/dist/svelte/components/ButtonGroup.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ColorControl.svelte +81 -0
- package/dist/svelte/components/ColorControl.svelte.d.ts +9 -0
- package/dist/svelte/components/ColorControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ControlRenderer.svelte +96 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts +11 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -0
- package/dist/svelte/components/DialRoot.svelte +79 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts +14 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -0
- package/dist/svelte/components/EasingVisualization.svelte +50 -0
- package/dist/svelte/components/EasingVisualization.svelte.d.ts +10 -0
- package/dist/svelte/components/EasingVisualization.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Folder.svelte +213 -0
- package/dist/svelte/components/Folder.svelte.d.ts +14 -0
- package/dist/svelte/components/Folder.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Panel.svelte +149 -0
- package/dist/svelte/components/Panel.svelte.d.ts +10 -0
- package/dist/svelte/components/Panel.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PresetManager.svelte +157 -0
- package/dist/svelte/components/PresetManager.svelte.d.ts +10 -0
- package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SegmentedControl.svelte +62 -0
- package/dist/svelte/components/SegmentedControl.svelte.d.ts +13 -0
- package/dist/svelte/components/SegmentedControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SelectControl.svelte +152 -0
- package/dist/svelte/components/SelectControl.svelte.d.ts +14 -0
- package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ShortcutListener.svelte +265 -0
- package/dist/svelte/components/ShortcutListener.svelte.d.ts +13 -0
- package/dist/svelte/components/ShortcutListener.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ShortcutsMenu.svelte +128 -0
- package/dist/svelte/components/ShortcutsMenu.svelte.d.ts +7 -0
- package/dist/svelte/components/ShortcutsMenu.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Slider.svelte +332 -0
- package/dist/svelte/components/Slider.svelte.d.ts +16 -0
- package/dist/svelte/components/Slider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SpringControl.svelte +126 -0
- package/dist/svelte/components/SpringControl.svelte.d.ts +12 -0
- package/dist/svelte/components/SpringControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SpringVisualization.svelte +115 -0
- package/dist/svelte/components/SpringVisualization.svelte.d.ts +9 -0
- package/dist/svelte/components/SpringVisualization.svelte.d.ts.map +1 -0
- package/dist/svelte/components/TextControl.svelte +19 -0
- package/dist/svelte/components/TextControl.svelte.d.ts +10 -0
- package/dist/svelte/components/TextControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Toggle.svelte +32 -0
- package/dist/svelte/components/Toggle.svelte.d.ts +12 -0
- package/dist/svelte/components/Toggle.svelte.d.ts.map +1 -0
- package/dist/svelte/components/TransitionControl.svelte +203 -0
- package/dist/svelte/components/TransitionControl.svelte.d.ts +12 -0
- package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/transitions.d.ts +6 -0
- package/dist/svelte/components/transitions.d.ts.map +1 -0
- package/dist/svelte/components/transitions.js +14 -0
- package/dist/svelte/createDialKit.svelte.d.ts +8 -0
- package/dist/svelte/createDialKit.svelte.d.ts.map +1 -0
- package/dist/svelte/createDialKit.svelte.js +82 -0
- package/dist/svelte/index.d.ts +23 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +23 -0
- package/dist/svelte/shims.d.ts +9 -0
- package/dist/svelte/theme-css.d.ts +2 -0
- package/dist/svelte/theme-css.d.ts.map +1 -0
- package/dist/svelte/theme-css.js +1328 -0
- package/dist/vue/index.cjs +3056 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.cts +675 -0
- package/dist/vue/index.d.ts +675 -0
- package/dist/vue/index.js +3014 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +50 -6
|
@@ -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,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext } from 'svelte';
|
|
3
|
+
import { DialStore } from 'dialkit/store';
|
|
4
|
+
import type { ControlMeta, DialValue, SpringConfig, TransitionConfig } from 'dialkit/store';
|
|
5
|
+
import Slider from './Slider.svelte';
|
|
6
|
+
import Toggle from './Toggle.svelte';
|
|
7
|
+
import Folder from './Folder.svelte';
|
|
8
|
+
import SpringControl from './SpringControl.svelte';
|
|
9
|
+
import TransitionControl from './TransitionControl.svelte';
|
|
10
|
+
import TextControl from './TextControl.svelte';
|
|
11
|
+
import SelectControl from './SelectControl.svelte';
|
|
12
|
+
import ColorControl from './ColorControl.svelte';
|
|
13
|
+
import ControlRenderer from './ControlRenderer.svelte';
|
|
14
|
+
import { SHORTCUT_CTX } from './ShortcutListener.svelte';
|
|
15
|
+
import type { ShortcutContextValue } from './ShortcutListener.svelte';
|
|
16
|
+
|
|
17
|
+
let { panelId, control, values } = $props<{
|
|
18
|
+
panelId: string;
|
|
19
|
+
control: ControlMeta;
|
|
20
|
+
values: Record<string, DialValue>;
|
|
21
|
+
}>();
|
|
22
|
+
|
|
23
|
+
const shortcutCtx = getContext<ShortcutContextValue | undefined>(SHORTCUT_CTX);
|
|
24
|
+
|
|
25
|
+
const controlValue = $derived(values[control.path]);
|
|
26
|
+
const isShortcutActive = $derived(
|
|
27
|
+
shortcutCtx ? shortcutCtx.activePanelId === panelId && shortcutCtx.activePath === control.path : false
|
|
28
|
+
);
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
{#if control.type === 'slider'}
|
|
32
|
+
<Slider
|
|
33
|
+
label={control.label}
|
|
34
|
+
value={controlValue as number}
|
|
35
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
36
|
+
min={control.min}
|
|
37
|
+
max={control.max}
|
|
38
|
+
step={control.step}
|
|
39
|
+
shortcut={control.shortcut}
|
|
40
|
+
shortcutActive={isShortcutActive}
|
|
41
|
+
/>
|
|
42
|
+
{:else if control.type === 'toggle'}
|
|
43
|
+
<Toggle
|
|
44
|
+
label={control.label}
|
|
45
|
+
checked={controlValue as boolean}
|
|
46
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
47
|
+
shortcut={control.shortcut}
|
|
48
|
+
shortcutActive={isShortcutActive}
|
|
49
|
+
/>
|
|
50
|
+
{:else if control.type === 'spring'}
|
|
51
|
+
<SpringControl
|
|
52
|
+
{panelId}
|
|
53
|
+
path={control.path}
|
|
54
|
+
label={control.label}
|
|
55
|
+
spring={controlValue as SpringConfig}
|
|
56
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
57
|
+
/>
|
|
58
|
+
{:else if control.type === 'transition'}
|
|
59
|
+
<TransitionControl
|
|
60
|
+
{panelId}
|
|
61
|
+
path={control.path}
|
|
62
|
+
label={control.label}
|
|
63
|
+
value={controlValue as TransitionConfig}
|
|
64
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
65
|
+
/>
|
|
66
|
+
{:else if control.type === 'folder'}
|
|
67
|
+
<Folder title={control.label} defaultOpen={control.defaultOpen ?? true}>
|
|
68
|
+
{#each control.children ?? [] as child (child.path)}
|
|
69
|
+
<ControlRenderer {panelId} control={child} {values} />
|
|
70
|
+
{/each}
|
|
71
|
+
</Folder>
|
|
72
|
+
{:else if control.type === 'text'}
|
|
73
|
+
<TextControl
|
|
74
|
+
label={control.label}
|
|
75
|
+
value={controlValue as string}
|
|
76
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
77
|
+
placeholder={control.placeholder}
|
|
78
|
+
/>
|
|
79
|
+
{:else if control.type === 'select'}
|
|
80
|
+
<SelectControl
|
|
81
|
+
label={control.label}
|
|
82
|
+
value={controlValue as string}
|
|
83
|
+
options={control.options ?? []}
|
|
84
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
85
|
+
/>
|
|
86
|
+
{:else if control.type === 'color'}
|
|
87
|
+
<ColorControl
|
|
88
|
+
label={control.label}
|
|
89
|
+
value={controlValue as string}
|
|
90
|
+
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
91
|
+
/>
|
|
92
|
+
{:else if control.type === 'action'}
|
|
93
|
+
<button class="dialkit-button" onclick={() => DialStore.triggerAction(panelId, control.path)}>
|
|
94
|
+
{control.label}
|
|
95
|
+
</button>
|
|
96
|
+
{/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":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
import ShortcutListener from './ShortcutListener.svelte';
|
|
8
|
+
|
|
9
|
+
export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
10
|
+
export type DialMode = 'popover' | 'inline';
|
|
11
|
+
export type DialTheme = 'light' | 'dark' | 'system';
|
|
12
|
+
|
|
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<{
|
|
22
|
+
position?: DialPosition;
|
|
23
|
+
defaultOpen?: boolean;
|
|
24
|
+
mode?: DialMode;
|
|
25
|
+
theme?: DialTheme;
|
|
26
|
+
productionEnabled?: boolean;
|
|
27
|
+
}>();
|
|
28
|
+
|
|
29
|
+
const inline = $derived(mode === 'inline');
|
|
30
|
+
|
|
31
|
+
let panels = $state<PanelConfig[]>([]);
|
|
32
|
+
let mounted = $state(false);
|
|
33
|
+
|
|
34
|
+
$effect(() => {
|
|
35
|
+
if (typeof document === 'undefined') return;
|
|
36
|
+
const id = 'dialkit-theme';
|
|
37
|
+
if (!document.getElementById(id)) {
|
|
38
|
+
const style = document.createElement('style');
|
|
39
|
+
style.id = id;
|
|
40
|
+
style.textContent = themeCSS;
|
|
41
|
+
document.head.appendChild(style);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
$effect(() => {
|
|
46
|
+
if (typeof window === 'undefined') return;
|
|
47
|
+
|
|
48
|
+
mounted = true;
|
|
49
|
+
panels = DialStore.getPanels();
|
|
50
|
+
|
|
51
|
+
const unsub = DialStore.subscribeGlobal(() => {
|
|
52
|
+
panels = DialStore.getPanels();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return unsub;
|
|
56
|
+
});
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
{#if productionEnabled && mounted && panels.length > 0}
|
|
60
|
+
{#snippet content()}
|
|
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>
|
|
68
|
+
</div>
|
|
69
|
+
</ShortcutListener>
|
|
70
|
+
{/snippet}
|
|
71
|
+
|
|
72
|
+
{#if inline}
|
|
73
|
+
{@render content()}
|
|
74
|
+
{:else}
|
|
75
|
+
<Portal target="body">
|
|
76
|
+
{@render content()}
|
|
77
|
+
</Portal>
|
|
78
|
+
{/if}
|
|
79
|
+
{/if}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
2
|
+
export type DialMode = 'popover' | 'inline';
|
|
3
|
+
export type DialTheme = 'light' | 'dark' | 'system';
|
|
4
|
+
type $$ComponentProps = {
|
|
5
|
+
position?: DialPosition;
|
|
6
|
+
defaultOpen?: boolean;
|
|
7
|
+
mode?: DialMode;
|
|
8
|
+
theme?: DialTheme;
|
|
9
|
+
productionEnabled?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare const DialRoot: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type DialRoot = ReturnType<typeof DialRoot>;
|
|
13
|
+
export default DialRoot;
|
|
14
|
+
//# 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":"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"}
|
|
@@ -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,213 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Spring } from 'svelte/motion';
|
|
3
|
+
import { slide } from 'svelte/transition';
|
|
4
|
+
|
|
5
|
+
import type { Snippet } from 'svelte';
|
|
6
|
+
import { ICON_PANEL, ICON_CHEVRON } from '../../icons';
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
title,
|
|
10
|
+
defaultOpen = true,
|
|
11
|
+
isRoot = false,
|
|
12
|
+
inline = false,
|
|
13
|
+
onOpenChange,
|
|
14
|
+
toolbar,
|
|
15
|
+
children,
|
|
16
|
+
} = $props<{
|
|
17
|
+
title: string;
|
|
18
|
+
defaultOpen?: boolean;
|
|
19
|
+
isRoot?: boolean;
|
|
20
|
+
inline?: boolean;
|
|
21
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
22
|
+
toolbar?: Snippet;
|
|
23
|
+
children?: Snippet;
|
|
24
|
+
}>();
|
|
25
|
+
|
|
26
|
+
let isOpen = $state(defaultOpen);
|
|
27
|
+
let isCollapsed = $state(!defaultOpen);
|
|
28
|
+
let contentHeight = $state<number | undefined>(undefined);
|
|
29
|
+
|
|
30
|
+
let contentRef: HTMLDivElement | undefined;
|
|
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
|
+
});
|
|
40
|
+
|
|
41
|
+
const chevronRotation = new Spring(defaultOpen ? 0 : 180, { stiffness: 0.2, damping: 0.6 });
|
|
42
|
+
const panelWidth = new Spring(defaultOpen ? 280 : 42, { stiffness: 0.2, damping: 0.62 });
|
|
43
|
+
const panelHeight = new Spring(defaultOpen ? 220 : 42, { stiffness: 0.2, damping: 0.62 });
|
|
44
|
+
const panelRadius = new Spring(defaultOpen ? 14 : 21, { stiffness: 0.2, damping: 0.62 });
|
|
45
|
+
const panelScale = new Spring(1, { stiffness: 0.25, damping: 0.7 });
|
|
46
|
+
|
|
47
|
+
$effect(() => {
|
|
48
|
+
if (!isRoot || !contentRef || typeof ResizeObserver === 'undefined') return;
|
|
49
|
+
|
|
50
|
+
const ro = new ResizeObserver(() => {
|
|
51
|
+
if (!isOpen) return;
|
|
52
|
+
const next = contentRef?.offsetHeight;
|
|
53
|
+
if (!next) return;
|
|
54
|
+
contentHeight = next;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
ro.observe(contentRef);
|
|
58
|
+
|
|
59
|
+
if (contentRef.offsetHeight > 0) {
|
|
60
|
+
contentHeight = contentRef.offsetHeight;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return () => {
|
|
64
|
+
ro.disconnect();
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
$effect(() => {
|
|
69
|
+
if (isRoot) return;
|
|
70
|
+
chevronRotation.set(isOpen ? 0 : 180);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
$effect(() => {
|
|
74
|
+
if (!isRoot) return;
|
|
75
|
+
|
|
76
|
+
const measured = contentHeight ?? panelRef?.getBoundingClientRect().height ?? 42;
|
|
77
|
+
const nextHeight = isOpen ? Math.min(measured + 10, windowHeight - 32) : 42;
|
|
78
|
+
|
|
79
|
+
panelWidth.set(isOpen ? 280 : 42);
|
|
80
|
+
panelHeight.set(nextHeight);
|
|
81
|
+
panelRadius.set(isOpen ? 14 : 21);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const handleToggle = () => {
|
|
85
|
+
if (inline && isRoot) return;
|
|
86
|
+
const next = !isOpen;
|
|
87
|
+
isOpen = next;
|
|
88
|
+
isCollapsed = !next;
|
|
89
|
+
onOpenChange?.(next);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const handleCollapsedTapStart = () => {
|
|
93
|
+
if (isOpen) return;
|
|
94
|
+
(document.activeElement as HTMLElement | null)?.blur?.();
|
|
95
|
+
panelScale.set(0.9);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const handleCollapsedTapEnd = () => {
|
|
99
|
+
if (isOpen) return;
|
|
100
|
+
panelScale.set(1);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const panelStyle = $derived(
|
|
104
|
+
`width:${panelWidth.current}px;height:${panelHeight.current}px;border-radius:${panelRadius.current}px;` +
|
|
105
|
+
`box-shadow:${isOpen ? 'var(--dial-shadow)' : 'var(--dial-shadow-collapsed)'};` +
|
|
106
|
+
`cursor:${isOpen ? '' : 'pointer'};overflow:${isOpen ? 'hidden auto' : 'hidden'};` +
|
|
107
|
+
`transform:scale(${panelScale.current});`
|
|
108
|
+
);
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
{#if isRoot && inline}
|
|
112
|
+
<div class="dialkit-panel-inner dialkit-panel-inline">
|
|
113
|
+
<div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
|
|
114
|
+
<div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
|
|
115
|
+
<div class="dialkit-folder-header-top">
|
|
116
|
+
<div class="dialkit-folder-title-row">
|
|
117
|
+
<span class="dialkit-folder-title dialkit-folder-title-root">{title}</span>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
|
|
122
|
+
{#if toolbar}{@render toolbar()}{/if}
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div class="dialkit-folder-content">
|
|
127
|
+
<div class="dialkit-folder-inner">
|
|
128
|
+
{#if children}{@render children()}{/if}
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
{:else if isRoot}
|
|
134
|
+
<div
|
|
135
|
+
bind:this={panelRef}
|
|
136
|
+
class="dialkit-panel-inner"
|
|
137
|
+
data-collapsed={String(isCollapsed)}
|
|
138
|
+
style={panelStyle}
|
|
139
|
+
onpointerdown={handleCollapsedTapStart}
|
|
140
|
+
onpointerup={handleCollapsedTapEnd}
|
|
141
|
+
onpointercancel={handleCollapsedTapEnd}
|
|
142
|
+
onpointerleave={handleCollapsedTapEnd}
|
|
143
|
+
onclick={() => { if (!isOpen) handleToggle(); }}
|
|
144
|
+
>
|
|
145
|
+
<div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
|
|
146
|
+
<div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
|
|
147
|
+
<div class="dialkit-folder-header-top">
|
|
148
|
+
{#if isOpen}
|
|
149
|
+
<div class="dialkit-folder-title-row">
|
|
150
|
+
<span class="dialkit-folder-title dialkit-folder-title-root">{title}</span>
|
|
151
|
+
</div>
|
|
152
|
+
{/if}
|
|
153
|
+
|
|
154
|
+
<svg class="dialkit-panel-icon" viewBox="0 0 16 16" fill="none">
|
|
155
|
+
<path
|
|
156
|
+
opacity="0.5"
|
|
157
|
+
d={ICON_PANEL.path}
|
|
158
|
+
fill="currentColor"
|
|
159
|
+
/>
|
|
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" />
|
|
163
|
+
</svg>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
{#if isOpen}
|
|
167
|
+
<div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
|
|
168
|
+
{#if toolbar}{@render toolbar()}{/if}
|
|
169
|
+
</div>
|
|
170
|
+
{/if}
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
{#if isOpen}
|
|
174
|
+
<div class="dialkit-folder-content">
|
|
175
|
+
<div class="dialkit-folder-inner">
|
|
176
|
+
{#if children}{@render children()}{/if}
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
{/if}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
{:else}
|
|
183
|
+
<div class="dialkit-folder">
|
|
184
|
+
<div class="dialkit-folder-header" onclick={handleToggle}>
|
|
185
|
+
<div class="dialkit-folder-header-top">
|
|
186
|
+
<div class="dialkit-folder-title-row">
|
|
187
|
+
<span class="dialkit-folder-title">{title}</span>
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<svg
|
|
191
|
+
class="dialkit-folder-icon"
|
|
192
|
+
viewBox="0 0 24 24"
|
|
193
|
+
fill="none"
|
|
194
|
+
stroke="currentColor"
|
|
195
|
+
stroke-width="2.5"
|
|
196
|
+
stroke-linecap="round"
|
|
197
|
+
stroke-linejoin="round"
|
|
198
|
+
style:transform={`rotate(${chevronRotation.current}deg)`}
|
|
199
|
+
>
|
|
200
|
+
<path d={ICON_CHEVRON} />
|
|
201
|
+
</svg>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
{#if isOpen}
|
|
206
|
+
<div class="dialkit-folder-content" style="clip-path: inset(0 -20px);" transition:slide={{ duration: 220 }}>
|
|
207
|
+
<div class="dialkit-folder-inner">
|
|
208
|
+
{#if children}{@render children()}{/if}
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
{/if}
|
|
212
|
+
</div>
|
|
213
|
+
{/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;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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Spring } from 'svelte/motion';
|
|
3
|
+
import { DialStore } from 'dialkit/store';
|
|
4
|
+
import type { DialValue, PanelConfig, Preset } from 'dialkit/store';
|
|
5
|
+
import Folder from './Folder.svelte';
|
|
6
|
+
import PresetManager from './PresetManager.svelte';
|
|
7
|
+
import ControlRenderer from './ControlRenderer.svelte';
|
|
8
|
+
import ShortcutsMenu from './ShortcutsMenu.svelte';
|
|
9
|
+
import { ICON_CLIPBOARD, ICON_CHECK, ICON_ADD_PRESET } from '../../icons';
|
|
10
|
+
|
|
11
|
+
let { panel, defaultOpen = true, inline = false } = $props<{ panel: PanelConfig; defaultOpen?: boolean; inline?: boolean }>();
|
|
12
|
+
|
|
13
|
+
const hasShortcuts = $derived(Object.keys(panel.shortcuts).length > 0);
|
|
14
|
+
|
|
15
|
+
let copied = $state(false);
|
|
16
|
+
let isPanelOpen = $state(defaultOpen);
|
|
17
|
+
let values = $state<Record<string, DialValue>>(DialStore.getValues(panel.id));
|
|
18
|
+
let presets = $state<Preset[]>(DialStore.getPresets(panel.id));
|
|
19
|
+
let activePresetId = $state<string | null>(DialStore.getActivePresetId(panel.id));
|
|
20
|
+
|
|
21
|
+
const addScale = new Spring(1, { stiffness: 0.25, damping: 0.7 });
|
|
22
|
+
const copyScale = new Spring(1, { stiffness: 0.25, damping: 0.7 });
|
|
23
|
+
const clipboardOpacity = new Spring(1, { stiffness: 0.25, damping: 0.7 });
|
|
24
|
+
const clipboardScale = new Spring(1, { stiffness: 0.2, damping: 0.6 });
|
|
25
|
+
const checkOpacity = new Spring(0, { stiffness: 0.25, damping: 0.7 });
|
|
26
|
+
const checkScale = new Spring(0.5, { stiffness: 0.2, damping: 0.6 });
|
|
27
|
+
|
|
28
|
+
let copyTimeout: ReturnType<typeof setTimeout> | undefined;
|
|
29
|
+
|
|
30
|
+
$effect(() => {
|
|
31
|
+
const unsub = DialStore.subscribe(panel.id, () => {
|
|
32
|
+
values = DialStore.getValues(panel.id);
|
|
33
|
+
presets = DialStore.getPresets(panel.id);
|
|
34
|
+
activePresetId = DialStore.getActivePresetId(panel.id);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return () => {
|
|
38
|
+
unsub();
|
|
39
|
+
if (copyTimeout) clearTimeout(copyTimeout);
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
$effect(() => {
|
|
44
|
+
if (copied) {
|
|
45
|
+
clipboardOpacity.set(0);
|
|
46
|
+
clipboardScale.set(0.5);
|
|
47
|
+
checkOpacity.set(1);
|
|
48
|
+
checkScale.set(1);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
clipboardOpacity.set(1);
|
|
53
|
+
clipboardScale.set(1);
|
|
54
|
+
checkOpacity.set(0);
|
|
55
|
+
checkScale.set(0.5);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const handleAddPreset = () => {
|
|
59
|
+
const nextNum = presets.length + 2;
|
|
60
|
+
DialStore.savePreset(panel.id, `Version ${nextNum}`);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const handleCopy = async () => {
|
|
64
|
+
const jsonStr = JSON.stringify(values, null, 2);
|
|
65
|
+
const instruction = `Update the createDialKit configuration for "${panel.name}" with these values:\n\n\`\`\`json\n${jsonStr}\n\`\`\`\n\nApply these values as the new defaults in the createDialKit call.`;
|
|
66
|
+
|
|
67
|
+
await navigator.clipboard.writeText(instruction);
|
|
68
|
+
copied = true;
|
|
69
|
+
|
|
70
|
+
if (copyTimeout) clearTimeout(copyTimeout);
|
|
71
|
+
copyTimeout = setTimeout(() => {
|
|
72
|
+
copied = false;
|
|
73
|
+
}, 1500);
|
|
74
|
+
};
|
|
75
|
+
</script>
|
|
76
|
+
|
|
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})`}
|
|
89
|
+
>
|
|
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})`}
|
|
110
|
+
>
|
|
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}
|
|
148
|
+
</Folder>
|
|
149
|
+
</div>
|