dialkit 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +653 -6
- package/dist/dropdown-position.d.ts +15 -0
- package/dist/dropdown-position.js +22 -0
- package/dist/dropdown-position.js.map +1 -0
- package/dist/icons.d.ts +4 -1
- package/dist/icons.js +13 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +3796 -768
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +315 -10
- package/dist/index.d.ts +315 -10
- package/dist/index.js +3733 -711
- package/dist/index.js.map +1 -1
- package/dist/panel-drag.d.ts +19 -0
- package/dist/panel-drag.js +72 -0
- package/dist/panel-drag.js.map +1 -0
- package/dist/solid/index.d.ts +264 -5
- package/dist/solid/index.js +5277 -1632
- package/dist/solid/index.js.map +1 -1
- package/dist/store/index.cjs +329 -57
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +43 -4
- package/dist/store/index.d.ts +43 -4
- package/dist/store/index.js +321 -56
- package/dist/store/index.js.map +1 -1
- package/dist/styles.css +809 -7
- package/dist/svelte/components/ControlRenderer.svelte +5 -2
- package/dist/svelte/components/ControlRenderer.svelte.d.ts +2 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -1
- package/dist/svelte/components/DialRoot.svelte +218 -16
- package/dist/svelte/components/DialRoot.svelte.d.ts +1 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Folder.svelte +24 -13
- package/dist/svelte/components/Folder.svelte.d.ts +1 -0
- package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Panel.svelte +104 -71
- package/dist/svelte/components/Panel.svelte.d.ts +4 -0
- package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
- package/dist/svelte/components/PresetManager.svelte +5 -5
- package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
- package/dist/svelte/components/SelectControl.svelte +6 -14
- package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
- package/dist/svelte/components/Timeline/ClipPopover.svelte +206 -0
- package/dist/svelte/components/Timeline/ClipPopover.svelte.d.ts +26 -0
- package/dist/svelte/components/Timeline/ClipPopover.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/DialTimeline.svelte +76 -0
- package/dist/svelte/components/Timeline/DialTimeline.svelte.d.ts +13 -0
- package/dist/svelte/components/Timeline/DialTimeline.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/TimelineClip.svelte +233 -0
- package/dist/svelte/components/Timeline/TimelineClip.svelte.d.ts +24 -0
- package/dist/svelte/components/Timeline/TimelineClip.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/TimelineSection.svelte +756 -0
- package/dist/svelte/components/Timeline/TimelineSection.svelte.d.ts +12 -0
- package/dist/svelte/components/Timeline/TimelineSection.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Timeline/TimelineToggleButton.svelte +25 -0
- package/dist/svelte/components/Timeline/TimelineToggleButton.svelte.d.ts +4 -0
- package/dist/svelte/components/Timeline/TimelineToggleButton.svelte.d.ts.map +1 -0
- package/dist/svelte/components/TransitionControl.svelte +26 -11
- package/dist/svelte/components/TransitionControl.svelte.d.ts +9 -0
- package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -1
- package/dist/svelte/createDialKit.svelte.d.ts +11 -1
- package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
- package/dist/svelte/createDialKit.svelte.js +61 -34
- package/dist/svelte/createDialTimeline.svelte.d.ts +4 -0
- package/dist/svelte/createDialTimeline.svelte.d.ts.map +1 -0
- package/dist/svelte/createDialTimeline.svelte.js +73 -0
- package/dist/svelte/index.d.ts +7 -3
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +4 -1
- package/dist/svelte/theme-css.d.ts +1 -1
- package/dist/svelte/theme-css.d.ts.map +1 -1
- package/dist/svelte/theme-css.js +809 -7
- package/dist/timeline/index.cjs +1288 -0
- package/dist/timeline/index.cjs.map +1 -0
- package/dist/timeline/index.d.cts +443 -0
- package/dist/timeline/index.d.ts +443 -0
- package/dist/timeline/index.js +1233 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/vue/index.d.ts +325 -12
- package/dist/vue/index.js +3226 -280
- package/dist/vue/index.js.map +1 -1
- package/package.json +23 -13
- package/dist/solid/index.cjs +0 -3079
- package/dist/solid/index.cjs.map +0 -1
- package/dist/solid/index.d.cts +0 -258
- package/dist/vue/index.cjs +0 -3056
- package/dist/vue/index.cjs.map +0 -1
- package/dist/vue/index.d.cts +0 -675
|
@@ -13,11 +13,13 @@
|
|
|
13
13
|
import ControlRenderer from './ControlRenderer.svelte';
|
|
14
14
|
import { SHORTCUT_CTX } from './ShortcutListener.svelte';
|
|
15
15
|
import type { ShortcutContextValue } from './ShortcutListener.svelte';
|
|
16
|
+
import type { TransitionDurationControl } from './TransitionControl.svelte';
|
|
16
17
|
|
|
17
|
-
let { panelId, control, values } = $props<{
|
|
18
|
+
let { panelId, control, values, transitionDuration } = $props<{
|
|
18
19
|
panelId: string;
|
|
19
20
|
control: ControlMeta;
|
|
20
21
|
values: Record<string, DialValue>;
|
|
22
|
+
transitionDuration?: TransitionDurationControl;
|
|
21
23
|
}>();
|
|
22
24
|
|
|
23
25
|
const shortcutCtx = getContext<ShortcutContextValue | undefined>(SHORTCUT_CTX);
|
|
@@ -62,11 +64,12 @@
|
|
|
62
64
|
label={control.label}
|
|
63
65
|
value={controlValue as TransitionConfig}
|
|
64
66
|
onChange={(v) => DialStore.updateValue(panelId, control.path, v)}
|
|
67
|
+
durationControl={transitionDuration}
|
|
65
68
|
/>
|
|
66
69
|
{:else if control.type === 'folder'}
|
|
67
70
|
<Folder title={control.label} defaultOpen={control.defaultOpen ?? true}>
|
|
68
71
|
{#each control.children ?? [] as child (child.path)}
|
|
69
|
-
<ControlRenderer {panelId} control={child} {values} />
|
|
72
|
+
<ControlRenderer {panelId} control={child} {values} {transitionDuration} />
|
|
70
73
|
{/each}
|
|
71
74
|
</Folder>
|
|
72
75
|
{:else if control.type === 'text'}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { ControlMeta, DialValue } from 'dialkit/store';
|
|
2
2
|
import ControlRenderer from './ControlRenderer.svelte';
|
|
3
|
+
import type { TransitionDurationControl } from './TransitionControl.svelte';
|
|
3
4
|
type $$ComponentProps = {
|
|
4
5
|
panelId: string;
|
|
5
6
|
control: ControlMeta;
|
|
6
7
|
values: Record<string, DialValue>;
|
|
8
|
+
transitionDuration?: TransitionDurationControl;
|
|
7
9
|
};
|
|
8
10
|
declare const ControlRenderer: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
11
|
type ControlRenderer = ReturnType<typeof ControlRenderer>;
|
|
@@ -1 +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;
|
|
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;AAGvD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAE3E,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CAChD,CAAC;AAwDJ,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -1,35 +1,68 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { DialStore } from 'dialkit/store';
|
|
3
3
|
import type { PanelConfig } from 'dialkit/store';
|
|
4
|
+
import { TimelineStore } from 'dialkit/timeline';
|
|
5
|
+
import type { TimelineMeta } from 'dialkit/timeline';
|
|
4
6
|
import { themeCSS } from '../theme-css';
|
|
5
7
|
import Portal from '../Portal.svelte';
|
|
8
|
+
import Folder from './Folder.svelte';
|
|
6
9
|
import Panel from './Panel.svelte';
|
|
10
|
+
import TimelineToggleButton from './Timeline/TimelineToggleButton.svelte';
|
|
7
11
|
import ShortcutListener from './ShortcutListener.svelte';
|
|
12
|
+
import {
|
|
13
|
+
blockPanelDragClick,
|
|
14
|
+
getPanelDragHandle,
|
|
15
|
+
getPanelDragOffset,
|
|
16
|
+
getPanelDragStart,
|
|
17
|
+
getPanelOriginX,
|
|
18
|
+
hasPanelDragMoved,
|
|
19
|
+
type PanelDragOffset,
|
|
20
|
+
type PanelDragStart,
|
|
21
|
+
} from '../../panel-drag';
|
|
8
22
|
|
|
9
23
|
export type DialPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
10
24
|
export type DialMode = 'popover' | 'inline';
|
|
11
25
|
export type DialTheme = 'light' | 'dark' | 'system';
|
|
12
26
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const isDevDefault =
|
|
16
|
-
?
|
|
17
|
-
:
|
|
18
|
-
?
|
|
27
|
+
const nodeEnv = (globalThis as typeof globalThis & { process?: { env?: { NODE_ENV?: string } } }).process?.env?.NODE_ENV;
|
|
28
|
+
const viteMode = (import.meta as { env?: { MODE?: string } }).env?.MODE;
|
|
29
|
+
const isDevDefault = nodeEnv
|
|
30
|
+
? nodeEnv !== 'production'
|
|
31
|
+
: viteMode
|
|
32
|
+
? viteMode !== 'production'
|
|
19
33
|
: true;
|
|
20
34
|
|
|
21
|
-
let { position = 'top-right', defaultOpen = true, mode = 'popover', theme = 'system' as DialTheme, productionEnabled = isDevDefault } = $props<{
|
|
35
|
+
let { position = 'top-right', defaultOpen = true, mode = 'popover', theme = 'system' as DialTheme, productionEnabled = isDevDefault, onOpenChange } = $props<{
|
|
22
36
|
position?: DialPosition;
|
|
23
37
|
defaultOpen?: boolean;
|
|
24
38
|
mode?: DialMode;
|
|
25
39
|
theme?: DialTheme;
|
|
26
40
|
productionEnabled?: boolean;
|
|
41
|
+
onOpenChange?: (open: boolean) => void;
|
|
27
42
|
}>();
|
|
28
43
|
|
|
29
44
|
const inline = $derived(mode === 'inline');
|
|
30
45
|
|
|
31
46
|
let panels = $state<PanelConfig[]>([]);
|
|
47
|
+
let timelines = $state<TimelineMeta[]>([]);
|
|
32
48
|
let mounted = $state(false);
|
|
49
|
+
let panelRef = $state<HTMLDivElement>();
|
|
50
|
+
let dragOffset = $state<PanelDragOffset | null>(null);
|
|
51
|
+
let activePosition = $state<DialPosition>(position);
|
|
52
|
+
let lastDragOffset: PanelDragOffset | null = null;
|
|
53
|
+
let dragging = false;
|
|
54
|
+
let dragStart: PanelDragStart | null = null;
|
|
55
|
+
let didDrag = false;
|
|
56
|
+
let dragTarget: HTMLElement | null = null;
|
|
57
|
+
let panelOpenStates = new Map<string, boolean>();
|
|
58
|
+
let rootOpen: boolean | undefined;
|
|
59
|
+
|
|
60
|
+
const dragStyle = $derived(
|
|
61
|
+
dragOffset
|
|
62
|
+
? `top:${dragOffset.y}px;left:${dragOffset.x}px;right:auto;bottom:auto;`
|
|
63
|
+
: undefined
|
|
64
|
+
);
|
|
65
|
+
const originX = $derived(inline ? undefined : getPanelOriginX(activePosition, dragOffset));
|
|
33
66
|
|
|
34
67
|
$effect(() => {
|
|
35
68
|
if (typeof document === 'undefined') return;
|
|
@@ -46,24 +79,193 @@
|
|
|
46
79
|
if (typeof window === 'undefined') return;
|
|
47
80
|
|
|
48
81
|
mounted = true;
|
|
49
|
-
panels = DialStore.getPanels();
|
|
82
|
+
panels = DialStore.getPanels('panel');
|
|
83
|
+
timelines = TimelineStore.getTimelines();
|
|
84
|
+
|
|
85
|
+
const unsubscribePanels = DialStore.subscribeGlobal(() => {
|
|
86
|
+
panels = DialStore.getPanels('panel');
|
|
87
|
+
});
|
|
88
|
+
const unsubscribeTimelines = TimelineStore.subscribeGlobal(() => {
|
|
89
|
+
timelines = TimelineStore.getTimelines();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return () => {
|
|
93
|
+
unsubscribePanels();
|
|
94
|
+
unsubscribeTimelines();
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
$effect(() => {
|
|
99
|
+
const fallbackOpen = inline || defaultOpen;
|
|
100
|
+
const nextStates = new Map<string, boolean>();
|
|
101
|
+
for (const panel of panels) {
|
|
102
|
+
nextStates.set(panel.id, panelOpenStates.get(panel.id) ?? fallbackOpen);
|
|
103
|
+
}
|
|
104
|
+
panelOpenStates = nextStates;
|
|
105
|
+
rootOpen = Array.from(nextStates.values()).some(Boolean);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
$effect(() => {
|
|
109
|
+
if (inline || !panelRef) return;
|
|
110
|
+
|
|
111
|
+
const observer = new MutationObserver(() => {
|
|
112
|
+
const inners = panelRef?.querySelectorAll('.dialkit-panel-inner');
|
|
113
|
+
if (!inners || inners.length === 0) return;
|
|
114
|
+
const collapsed = Array.from(inners).every((el) => el.getAttribute('data-collapsed') === 'true');
|
|
50
115
|
|
|
51
|
-
|
|
52
|
-
|
|
116
|
+
if (!collapsed) {
|
|
117
|
+
if (dragOffset) {
|
|
118
|
+
lastDragOffset = dragOffset;
|
|
119
|
+
const bubbleCenterX = dragOffset.x + 21;
|
|
120
|
+
activePosition = bubbleCenterX < window.innerWidth / 2 ? 'top-left' : 'top-right';
|
|
121
|
+
} else {
|
|
122
|
+
activePosition = position;
|
|
123
|
+
}
|
|
124
|
+
dragOffset = null;
|
|
125
|
+
} else if (dragOffset) {
|
|
126
|
+
lastDragOffset = dragOffset;
|
|
127
|
+
} else if (lastDragOffset) {
|
|
128
|
+
dragOffset = lastDragOffset;
|
|
129
|
+
}
|
|
53
130
|
});
|
|
54
131
|
|
|
55
|
-
|
|
132
|
+
observer.observe(panelRef, { subtree: true, attributes: true, attributeFilter: ['data-collapsed'] });
|
|
133
|
+
return () => observer.disconnect();
|
|
56
134
|
});
|
|
135
|
+
|
|
136
|
+
function handlePointerDown(event: PointerEvent) {
|
|
137
|
+
const panel = panelRef ?? null;
|
|
138
|
+
const handle = getPanelDragHandle(event.target, panel);
|
|
139
|
+
if (!panel || !handle) return;
|
|
140
|
+
|
|
141
|
+
dragTarget = handle;
|
|
142
|
+
dragStart = getPanelDragStart(event.clientX, event.clientY, panel);
|
|
143
|
+
didDrag = false;
|
|
144
|
+
dragging = true;
|
|
145
|
+
handle.setPointerCapture(event.pointerId);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function handlePointerMove(event: PointerEvent) {
|
|
149
|
+
if (!dragging || !dragStart) return;
|
|
150
|
+
|
|
151
|
+
if (!didDrag && !hasPanelDragMoved(dragStart, event.clientX, event.clientY)) return;
|
|
152
|
+
didDrag = true;
|
|
153
|
+
|
|
154
|
+
dragOffset = getPanelDragOffset(dragStart, event.clientX, event.clientY);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function handlePointerUp(event: PointerEvent) {
|
|
158
|
+
if (!dragging) return;
|
|
159
|
+
dragging = false;
|
|
160
|
+
dragStart = null;
|
|
161
|
+
const handle = dragTarget;
|
|
162
|
+
|
|
163
|
+
if (handle?.hasPointerCapture(event.pointerId)) {
|
|
164
|
+
handle.releasePointerCapture(event.pointerId);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (didDrag) {
|
|
168
|
+
event.stopPropagation();
|
|
169
|
+
if (handle) {
|
|
170
|
+
blockPanelDragClick(handle);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
dragTarget = null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function handlePanelOpenChange(panelId: string, open: boolean) {
|
|
178
|
+
panelOpenStates.set(panelId, open);
|
|
179
|
+
const fallbackOpen = inline || defaultOpen;
|
|
180
|
+
const nextRootOpen = panels.some((panel) => (
|
|
181
|
+
panelOpenStates.get(panel.id) ?? fallbackOpen
|
|
182
|
+
));
|
|
183
|
+
|
|
184
|
+
if (rootOpen === nextRootOpen) return;
|
|
185
|
+
rootOpen = nextRootOpen;
|
|
186
|
+
onOpenChange?.(nextRootOpen);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function handleRootOpenChange(open: boolean) {
|
|
190
|
+
if (rootOpen === open) return;
|
|
191
|
+
rootOpen = open;
|
|
192
|
+
onOpenChange?.(open);
|
|
193
|
+
}
|
|
194
|
+
|
|
57
195
|
</script>
|
|
58
196
|
|
|
59
|
-
{#
|
|
197
|
+
{#snippet timelineToolbar()}
|
|
198
|
+
{#if timelines.length > 0}
|
|
199
|
+
<TimelineToggleButton />
|
|
200
|
+
{/if}
|
|
201
|
+
{/snippet}
|
|
202
|
+
|
|
203
|
+
{#if productionEnabled && mounted && (panels.length > 0 || timelines.length > 0)}
|
|
60
204
|
{#snippet content()}
|
|
61
205
|
<ShortcutListener>
|
|
62
206
|
<div class="dialkit-root" data-mode={mode} data-theme={theme}>
|
|
63
|
-
<div
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
{
|
|
207
|
+
<div
|
|
208
|
+
bind:this={panelRef}
|
|
209
|
+
class="dialkit-panel"
|
|
210
|
+
data-mode={mode}
|
|
211
|
+
data-position={inline ? undefined : (dragOffset ? undefined : activePosition)}
|
|
212
|
+
data-origin-x={originX}
|
|
213
|
+
data-multiple={panels.length > 1 ? 'true' : undefined}
|
|
214
|
+
style={dragStyle}
|
|
215
|
+
onpointerdown={!inline ? handlePointerDown : undefined}
|
|
216
|
+
onpointermove={!inline ? handlePointerMove : undefined}
|
|
217
|
+
onpointerup={!inline ? handlePointerUp : undefined}
|
|
218
|
+
onpointercancel={!inline ? handlePointerUp : undefined}
|
|
219
|
+
>
|
|
220
|
+
{#if panels.length === 0}
|
|
221
|
+
<div class="dialkit-panel-wrapper">
|
|
222
|
+
<Folder
|
|
223
|
+
title="DialKit"
|
|
224
|
+
defaultOpen={inline || defaultOpen}
|
|
225
|
+
isRoot={true}
|
|
226
|
+
{inline}
|
|
227
|
+
onOpenChange={handleRootOpenChange}
|
|
228
|
+
panelHeightOffset={2}
|
|
229
|
+
>
|
|
230
|
+
{#snippet toolbar()}
|
|
231
|
+
{@render timelineToolbar()}
|
|
232
|
+
{/snippet}
|
|
233
|
+
<div class="dialkit-timeline-toolkit-only">Timeline</div>
|
|
234
|
+
</Folder>
|
|
235
|
+
</div>
|
|
236
|
+
{:else if panels.length > 1}
|
|
237
|
+
<div class="dialkit-panel-wrapper">
|
|
238
|
+
<Folder
|
|
239
|
+
title="DialKit"
|
|
240
|
+
defaultOpen={inline || defaultOpen}
|
|
241
|
+
isRoot={true}
|
|
242
|
+
{inline}
|
|
243
|
+
onOpenChange={handleRootOpenChange}
|
|
244
|
+
panelHeightOffset={2}
|
|
245
|
+
>
|
|
246
|
+
{#snippet toolbar()}
|
|
247
|
+
{@render timelineToolbar()}
|
|
248
|
+
{/snippet}
|
|
249
|
+
{#each panels as panel (panel.id)}
|
|
250
|
+
<Panel
|
|
251
|
+
{panel}
|
|
252
|
+
defaultOpen={true}
|
|
253
|
+
variant="section"
|
|
254
|
+
/>
|
|
255
|
+
{/each}
|
|
256
|
+
</Folder>
|
|
257
|
+
</div>
|
|
258
|
+
{:else}
|
|
259
|
+
{#each panels as panel (panel.id)}
|
|
260
|
+
<Panel
|
|
261
|
+
{panel}
|
|
262
|
+
defaultOpen={inline || defaultOpen}
|
|
263
|
+
{inline}
|
|
264
|
+
toolbarExtra={timelineToolbar}
|
|
265
|
+
onOpenChange={(open) => handlePanelOpenChange(panel.id, open)}
|
|
266
|
+
/>
|
|
267
|
+
{/each}
|
|
268
|
+
{/if}
|
|
67
269
|
</div>
|
|
68
270
|
</div>
|
|
69
271
|
</ShortcutListener>
|
|
@@ -7,6 +7,7 @@ type $$ComponentProps = {
|
|
|
7
7
|
mode?: DialMode;
|
|
8
8
|
theme?: DialTheme;
|
|
9
9
|
productionEnabled?: boolean;
|
|
10
|
+
onOpenChange?: (open: boolean) => void;
|
|
10
11
|
};
|
|
11
12
|
declare const DialRoot: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
13
|
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":"
|
|
1
|
+
{"version":3,"file":"DialRoot.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/DialRoot.svelte.ts"],"names":[],"mappings":"AAyBE,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;IAC5B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC,CAAC;AAwOJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
inline = false,
|
|
13
13
|
onOpenChange,
|
|
14
14
|
toolbar,
|
|
15
|
+
panelHeightOffset = 10,
|
|
15
16
|
children,
|
|
16
17
|
} = $props<{
|
|
17
18
|
title: string;
|
|
@@ -20,12 +21,14 @@
|
|
|
20
21
|
inline?: boolean;
|
|
21
22
|
onOpenChange?: (isOpen: boolean) => void;
|
|
22
23
|
toolbar?: Snippet;
|
|
24
|
+
panelHeightOffset?: number;
|
|
23
25
|
children?: Snippet;
|
|
24
26
|
}>();
|
|
25
27
|
|
|
26
28
|
let isOpen = $state(defaultOpen);
|
|
27
29
|
let isCollapsed = $state(!defaultOpen);
|
|
28
30
|
let contentHeight = $state<number | undefined>(undefined);
|
|
31
|
+
let hasInitializedRootSize = $state(!isRoot || !defaultOpen);
|
|
29
32
|
|
|
30
33
|
let contentRef: HTMLDivElement | undefined;
|
|
31
34
|
let panelRef: HTMLDivElement | undefined;
|
|
@@ -74,11 +77,16 @@
|
|
|
74
77
|
if (!isRoot) return;
|
|
75
78
|
|
|
76
79
|
const measured = contentHeight ?? panelRef?.getBoundingClientRect().height ?? 42;
|
|
77
|
-
const nextHeight = isOpen ? Math.min(measured +
|
|
80
|
+
const nextHeight = isOpen ? Math.min(measured + panelHeightOffset, windowHeight - 32) : 42;
|
|
81
|
+
const springOptions = !hasInitializedRootSize && isOpen ? { instant: true } : undefined;
|
|
78
82
|
|
|
79
|
-
panelWidth.set(isOpen ? 280 : 42);
|
|
80
|
-
panelHeight.set(nextHeight);
|
|
81
|
-
panelRadius.set(isOpen ? 14 : 21);
|
|
83
|
+
panelWidth.set(isOpen ? 280 : 42, springOptions);
|
|
84
|
+
panelHeight.set(nextHeight, springOptions);
|
|
85
|
+
panelRadius.set(isOpen ? 14 : 21, springOptions);
|
|
86
|
+
|
|
87
|
+
if (isOpen || !defaultOpen) {
|
|
88
|
+
hasInitializedRootSize = true;
|
|
89
|
+
}
|
|
82
90
|
});
|
|
83
91
|
|
|
84
92
|
const handleToggle = () => {
|
|
@@ -100,8 +108,9 @@
|
|
|
100
108
|
panelScale.set(1);
|
|
101
109
|
};
|
|
102
110
|
|
|
111
|
+
const panelHeightStyle = $derived(!hasInitializedRootSize && isOpen ? 'auto' : `${panelHeight.current}px`);
|
|
103
112
|
const panelStyle = $derived(
|
|
104
|
-
`width:${panelWidth.current}px;height:${
|
|
113
|
+
`width:${panelWidth.current}px;height:${panelHeightStyle};max-height:${Math.max(windowHeight - 32, 42)}px;border-radius:${panelRadius.current}px;` +
|
|
105
114
|
`box-shadow:${isOpen ? 'var(--dial-shadow)' : 'var(--dial-shadow-collapsed)'};` +
|
|
106
115
|
`cursor:${isOpen ? '' : 'pointer'};overflow:${isOpen ? 'hidden auto' : 'hidden'};` +
|
|
107
116
|
`transform:scale(${panelScale.current});`
|
|
@@ -110,7 +119,7 @@
|
|
|
110
119
|
|
|
111
120
|
{#if isRoot && inline}
|
|
112
121
|
<div class="dialkit-panel-inner dialkit-panel-inline">
|
|
113
|
-
<div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
|
|
122
|
+
<div bind:this={contentRef} class="dialkit-folder dialkit-folder-root" data-open={String(isOpen)}>
|
|
114
123
|
<div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
|
|
115
124
|
<div class="dialkit-folder-header-top">
|
|
116
125
|
<div class="dialkit-folder-title-row">
|
|
@@ -118,9 +127,11 @@
|
|
|
118
127
|
</div>
|
|
119
128
|
</div>
|
|
120
129
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
{#if toolbar}
|
|
131
|
+
<div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
|
|
132
|
+
{@render toolbar()}
|
|
133
|
+
</div>
|
|
134
|
+
{/if}
|
|
124
135
|
</div>
|
|
125
136
|
|
|
126
137
|
<div class="dialkit-folder-content">
|
|
@@ -142,7 +153,7 @@
|
|
|
142
153
|
onpointerleave={handleCollapsedTapEnd}
|
|
143
154
|
onclick={() => { if (!isOpen) handleToggle(); }}
|
|
144
155
|
>
|
|
145
|
-
<div bind:this={contentRef} class="dialkit-folder dialkit-folder-root">
|
|
156
|
+
<div bind:this={contentRef} class="dialkit-folder dialkit-folder-root" data-open={String(isOpen)}>
|
|
146
157
|
<div class="dialkit-folder-header dialkit-panel-header" onclick={(e) => { e.stopPropagation(); handleToggle(); }}>
|
|
147
158
|
<div class="dialkit-folder-header-top">
|
|
148
159
|
{#if isOpen}
|
|
@@ -163,9 +174,9 @@
|
|
|
163
174
|
</svg>
|
|
164
175
|
</div>
|
|
165
176
|
|
|
166
|
-
{#if isOpen}
|
|
177
|
+
{#if isOpen && toolbar}
|
|
167
178
|
<div class="dialkit-panel-toolbar" onclick={(e) => e.stopPropagation()}>
|
|
168
|
-
{
|
|
179
|
+
{@render toolbar()}
|
|
169
180
|
</div>
|
|
170
181
|
{/if}
|
|
171
182
|
</div>
|
|
@@ -180,7 +191,7 @@
|
|
|
180
191
|
</div>
|
|
181
192
|
</div>
|
|
182
193
|
{:else}
|
|
183
|
-
<div class="dialkit-folder">
|
|
194
|
+
<div class="dialkit-folder" data-open={String(isOpen)}>
|
|
184
195
|
<div class="dialkit-folder-header" onclick={handleToggle}>
|
|
185
196
|
<div class="dialkit-folder-header-top">
|
|
186
197
|
<div class="dialkit-folder-title-row">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Folder.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Folder.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"Folder.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Folder.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAoMJ,QAAA,MAAM,MAAM,sDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Spring } from 'svelte/motion';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
3
4
|
import { DialStore } from 'dialkit/store';
|
|
4
5
|
import type { DialValue, PanelConfig, Preset } from 'dialkit/store';
|
|
5
6
|
import Folder from './Folder.svelte';
|
|
@@ -8,7 +9,14 @@
|
|
|
8
9
|
import ShortcutsMenu from './ShortcutsMenu.svelte';
|
|
9
10
|
import { ICON_CLIPBOARD, ICON_CHECK, ICON_ADD_PRESET } from '../../icons';
|
|
10
11
|
|
|
11
|
-
let { panel, defaultOpen = true, inline = false } = $props<{
|
|
12
|
+
let { panel, defaultOpen = true, inline = false, onOpenChange, variant = 'root', toolbarExtra } = $props<{
|
|
13
|
+
panel: PanelConfig;
|
|
14
|
+
defaultOpen?: boolean;
|
|
15
|
+
inline?: boolean;
|
|
16
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
|
+
variant?: 'root' | 'section';
|
|
18
|
+
toolbarExtra?: Snippet;
|
|
19
|
+
}>();
|
|
12
20
|
|
|
13
21
|
const hasShortcuts = $derived(Object.keys(panel.shortcuts).length > 0);
|
|
14
22
|
|
|
@@ -72,78 +80,103 @@
|
|
|
72
80
|
copied = false;
|
|
73
81
|
}, 1500);
|
|
74
82
|
};
|
|
83
|
+
|
|
84
|
+
const handleOpenChange = (open: boolean) => {
|
|
85
|
+
isPanelOpen = open;
|
|
86
|
+
onOpenChange?.(open);
|
|
87
|
+
};
|
|
75
88
|
</script>
|
|
76
89
|
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
{#snippet panelToolbar()}
|
|
91
|
+
<button
|
|
92
|
+
class="dialkit-toolbar-add"
|
|
93
|
+
onclick={handleAddPreset}
|
|
94
|
+
onpointerdown={() => addScale.set(0.9)}
|
|
95
|
+
onpointerup={() => addScale.set(1)}
|
|
96
|
+
onpointercancel={() => addScale.set(1)}
|
|
97
|
+
onpointerleave={() => addScale.set(1)}
|
|
98
|
+
title="Add preset"
|
|
99
|
+
style:transform={`scale(${addScale.current})`}
|
|
100
|
+
>
|
|
101
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
102
|
+
<path d={ICON_ADD_PRESET[0]} />
|
|
103
|
+
<path d={ICON_ADD_PRESET[1]} />
|
|
104
|
+
<path d={ICON_ADD_PRESET[2]} />
|
|
105
|
+
<path d={ICON_ADD_PRESET[3]} />
|
|
106
|
+
<path d={ICON_ADD_PRESET[4]} />
|
|
107
|
+
</svg>
|
|
108
|
+
</button>
|
|
109
|
+
|
|
110
|
+
<PresetManager panelId={panel.id} {presets} {activePresetId} />
|
|
111
|
+
|
|
112
|
+
<button
|
|
113
|
+
class="dialkit-toolbar-copy"
|
|
114
|
+
onclick={handleCopy}
|
|
115
|
+
onpointerdown={() => copyScale.set(0.95)}
|
|
116
|
+
onpointerup={() => copyScale.set(1)}
|
|
117
|
+
onpointercancel={() => copyScale.set(1)}
|
|
118
|
+
onpointerleave={() => copyScale.set(1)}
|
|
119
|
+
title="Copy parameters"
|
|
120
|
+
style:transform={`scale(${copyScale.current})`}
|
|
121
|
+
>
|
|
122
|
+
<span class="dialkit-toolbar-copy-icon-wrap">
|
|
123
|
+
<svg
|
|
124
|
+
class="dialkit-toolbar-copy-icon"
|
|
125
|
+
viewBox="0 0 24 24"
|
|
126
|
+
fill="none"
|
|
127
|
+
style:opacity={clipboardOpacity.current}
|
|
128
|
+
style:transform={`scale(${clipboardScale.current})`}
|
|
129
|
+
style:filter={`blur(${(1 - clipboardOpacity.current) * 4}px)`}
|
|
89
130
|
>
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
onpointercancel={() => copyScale.set(1)}
|
|
107
|
-
onpointerleave={() => copyScale.set(1)}
|
|
108
|
-
title="Copy parameters"
|
|
109
|
-
style:transform={`scale(${copyScale.current})`}
|
|
131
|
+
<path d={ICON_CLIPBOARD.board} stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
|
|
132
|
+
<path d={ICON_CLIPBOARD.sparkle} fill="currentColor"/>
|
|
133
|
+
<path d={ICON_CLIPBOARD.body} stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
134
|
+
</svg>
|
|
135
|
+
|
|
136
|
+
<svg
|
|
137
|
+
class="dialkit-toolbar-copy-icon"
|
|
138
|
+
viewBox="0 0 24 24"
|
|
139
|
+
fill="none"
|
|
140
|
+
stroke="currentColor"
|
|
141
|
+
stroke-width="2"
|
|
142
|
+
stroke-linecap="round"
|
|
143
|
+
stroke-linejoin="round"
|
|
144
|
+
style:opacity={checkOpacity.current}
|
|
145
|
+
style:transform={`scale(${checkScale.current})`}
|
|
146
|
+
style:filter={`blur(${(1 - checkOpacity.current) * 4}px)`}
|
|
110
147
|
>
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
+
<path d={ICON_CHECK} />
|
|
149
|
+
</svg>
|
|
150
|
+
</span>
|
|
151
|
+
Copy
|
|
152
|
+
</button>
|
|
153
|
+
|
|
154
|
+
{#if toolbarExtra}
|
|
155
|
+
{@render toolbarExtra()}
|
|
156
|
+
{/if}
|
|
157
|
+
{/snippet}
|
|
158
|
+
|
|
159
|
+
{#snippet panelControls()}
|
|
160
|
+
{#each panel.controls as control (control.path)}
|
|
161
|
+
<ControlRenderer panelId={panel.id} {control} {values} />
|
|
162
|
+
{/each}
|
|
163
|
+
{/snippet}
|
|
164
|
+
|
|
165
|
+
{#if variant === 'section'}
|
|
166
|
+
<Folder title={panel.name} {defaultOpen} onOpenChange={handleOpenChange}>
|
|
167
|
+
<div class="dialkit-panel-section-toolbar" onclick={(e) => e.stopPropagation()}>
|
|
168
|
+
{@render panelToolbar()}
|
|
169
|
+
</div>
|
|
170
|
+
{@render panelControls()}
|
|
148
171
|
</Folder>
|
|
149
|
-
|
|
172
|
+
{:else}
|
|
173
|
+
<div class="dialkit-panel-wrapper">
|
|
174
|
+
<Folder title={panel.name} {defaultOpen} isRoot={true} {inline} onOpenChange={handleOpenChange}>
|
|
175
|
+
{#snippet toolbar()}
|
|
176
|
+
{@render panelToolbar()}
|
|
177
|
+
{/snippet}
|
|
178
|
+
|
|
179
|
+
{@render panelControls()}
|
|
180
|
+
</Folder>
|
|
181
|
+
</div>
|
|
182
|
+
{/if}
|