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.
Files changed (88) hide show
  1. package/README.md +653 -6
  2. package/dist/dropdown-position.d.ts +15 -0
  3. package/dist/dropdown-position.js +22 -0
  4. package/dist/dropdown-position.js.map +1 -0
  5. package/dist/icons.d.ts +4 -1
  6. package/dist/icons.js +13 -0
  7. package/dist/icons.js.map +1 -1
  8. package/dist/index.cjs +3796 -768
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +315 -10
  11. package/dist/index.d.ts +315 -10
  12. package/dist/index.js +3733 -711
  13. package/dist/index.js.map +1 -1
  14. package/dist/panel-drag.d.ts +19 -0
  15. package/dist/panel-drag.js +72 -0
  16. package/dist/panel-drag.js.map +1 -0
  17. package/dist/solid/index.d.ts +264 -5
  18. package/dist/solid/index.js +5277 -1632
  19. package/dist/solid/index.js.map +1 -1
  20. package/dist/store/index.cjs +329 -57
  21. package/dist/store/index.cjs.map +1 -1
  22. package/dist/store/index.d.cts +43 -4
  23. package/dist/store/index.d.ts +43 -4
  24. package/dist/store/index.js +321 -56
  25. package/dist/store/index.js.map +1 -1
  26. package/dist/styles.css +809 -7
  27. package/dist/svelte/components/ControlRenderer.svelte +5 -2
  28. package/dist/svelte/components/ControlRenderer.svelte.d.ts +2 -0
  29. package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -1
  30. package/dist/svelte/components/DialRoot.svelte +218 -16
  31. package/dist/svelte/components/DialRoot.svelte.d.ts +1 -0
  32. package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
  33. package/dist/svelte/components/Folder.svelte +24 -13
  34. package/dist/svelte/components/Folder.svelte.d.ts +1 -0
  35. package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
  36. package/dist/svelte/components/Panel.svelte +104 -71
  37. package/dist/svelte/components/Panel.svelte.d.ts +4 -0
  38. package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
  39. package/dist/svelte/components/PresetManager.svelte +5 -5
  40. package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
  41. package/dist/svelte/components/SelectControl.svelte +6 -14
  42. package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
  43. package/dist/svelte/components/Timeline/ClipPopover.svelte +206 -0
  44. package/dist/svelte/components/Timeline/ClipPopover.svelte.d.ts +26 -0
  45. package/dist/svelte/components/Timeline/ClipPopover.svelte.d.ts.map +1 -0
  46. package/dist/svelte/components/Timeline/DialTimeline.svelte +76 -0
  47. package/dist/svelte/components/Timeline/DialTimeline.svelte.d.ts +13 -0
  48. package/dist/svelte/components/Timeline/DialTimeline.svelte.d.ts.map +1 -0
  49. package/dist/svelte/components/Timeline/TimelineClip.svelte +233 -0
  50. package/dist/svelte/components/Timeline/TimelineClip.svelte.d.ts +24 -0
  51. package/dist/svelte/components/Timeline/TimelineClip.svelte.d.ts.map +1 -0
  52. package/dist/svelte/components/Timeline/TimelineSection.svelte +756 -0
  53. package/dist/svelte/components/Timeline/TimelineSection.svelte.d.ts +12 -0
  54. package/dist/svelte/components/Timeline/TimelineSection.svelte.d.ts.map +1 -0
  55. package/dist/svelte/components/Timeline/TimelineToggleButton.svelte +25 -0
  56. package/dist/svelte/components/Timeline/TimelineToggleButton.svelte.d.ts +4 -0
  57. package/dist/svelte/components/Timeline/TimelineToggleButton.svelte.d.ts.map +1 -0
  58. package/dist/svelte/components/TransitionControl.svelte +26 -11
  59. package/dist/svelte/components/TransitionControl.svelte.d.ts +9 -0
  60. package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -1
  61. package/dist/svelte/createDialKit.svelte.d.ts +11 -1
  62. package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
  63. package/dist/svelte/createDialKit.svelte.js +61 -34
  64. package/dist/svelte/createDialTimeline.svelte.d.ts +4 -0
  65. package/dist/svelte/createDialTimeline.svelte.d.ts.map +1 -0
  66. package/dist/svelte/createDialTimeline.svelte.js +73 -0
  67. package/dist/svelte/index.d.ts +7 -3
  68. package/dist/svelte/index.d.ts.map +1 -1
  69. package/dist/svelte/index.js +4 -1
  70. package/dist/svelte/theme-css.d.ts +1 -1
  71. package/dist/svelte/theme-css.d.ts.map +1 -1
  72. package/dist/svelte/theme-css.js +809 -7
  73. package/dist/timeline/index.cjs +1288 -0
  74. package/dist/timeline/index.cjs.map +1 -0
  75. package/dist/timeline/index.d.cts +443 -0
  76. package/dist/timeline/index.d.ts +443 -0
  77. package/dist/timeline/index.js +1233 -0
  78. package/dist/timeline/index.js.map +1 -0
  79. package/dist/vue/index.d.ts +325 -12
  80. package/dist/vue/index.js +3226 -280
  81. package/dist/vue/index.js.map +1 -1
  82. package/package.json +23 -13
  83. package/dist/solid/index.cjs +0 -3079
  84. package/dist/solid/index.cjs.map +0 -1
  85. package/dist/solid/index.d.cts +0 -258
  86. package/dist/vue/index.cjs +0 -3056
  87. package/dist/vue/index.cjs.map +0 -1
  88. package/dist/vue/index.d.cts +0 -675
@@ -1,8 +1,12 @@
1
+ import type { Snippet } from 'svelte';
1
2
  import type { PanelConfig } from 'dialkit/store';
2
3
  type $$ComponentProps = {
3
4
  panel: PanelConfig;
4
5
  defaultOpen?: boolean;
5
6
  inline?: boolean;
7
+ onOpenChange?: (open: boolean) => void;
8
+ variant?: 'root' | 'section';
9
+ toolbarExtra?: Snippet;
6
10
  };
7
11
  declare const Panel: import("svelte").Component<$$ComponentProps, {}, "">;
8
12
  type Panel = ReturnType<typeof Panel>;
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Panel.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAa,WAAW,EAAU,MAAM,eAAe,CAAC;AAOnE,KAAK,gBAAgB,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAqHzF,QAAA,MAAM,KAAK,sDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Panel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/Panel.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAa,WAAW,EAAU,MAAM,eAAe,CAAC;AAOnE,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AA+IJ,QAAA,MAAM,KAAK,sDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -4,6 +4,7 @@
4
4
  import { DialStore } from 'dialkit/store';
5
5
  import type { Preset } from 'dialkit/store';
6
6
  import { dropdownTransition } from './transitions';
7
+ import { getDialKitPortalRoot, getDropdownPosition } from '../../dropdown-position';
7
8
  import { ICON_CHEVRON, ICON_TRASH } from '../../icons';
8
9
 
9
10
  let { panelId, presets, activePresetId } = $props<{
@@ -25,9 +26,8 @@
25
26
  const activePreset = $derived(presets.find((p: Preset) => p.id === activePresetId));
26
27
 
27
28
  const updatePos = () => {
28
- const rect = triggerRef?.getBoundingClientRect();
29
- if (!rect) return;
30
- pos = { top: rect.bottom + 4, left: rect.left, width: rect.width };
29
+ if (!triggerRef || !portalTarget) return;
30
+ pos = getDropdownPosition(triggerRef, portalTarget, { allowAbove: false });
31
31
  };
32
32
 
33
33
  const openDropdown = () => {
@@ -42,7 +42,7 @@
42
42
 
43
43
  $effect(() => {
44
44
  if (typeof document === 'undefined' || !triggerRef) return;
45
- portalTarget = (triggerRef.closest('.dialkit-root') as HTMLElement | null) ?? document.body;
45
+ portalTarget = getDialKitPortalRoot(triggerRef) ?? document.body;
46
46
  });
47
47
 
48
48
  $effect(() => {
@@ -117,7 +117,7 @@
117
117
  <div
118
118
  bind:this={dropdownRef}
119
119
  class="dialkit-root dialkit-preset-dropdown"
120
- style={`position:fixed;top:${pos.top}px;left:${pos.left}px;min-width:${pos.width}px;`}
120
+ style={`position:absolute;top:${pos.top}px;left:${pos.left}px;min-width:${pos.width}px;`}
121
121
  transition:dropdownTransition={{ above: false }}
122
122
  >
123
123
  <div
@@ -1 +1 @@
1
- {"version":3,"file":"PresetManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/PresetManager.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI3C,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AA2HJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"PresetManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/PresetManager.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAK3C,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AA2HJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -2,6 +2,7 @@
2
2
  import { Spring } from 'svelte/motion';
3
3
  import Portal from '../Portal.svelte';
4
4
  import { dropdownTransition } from './transitions';
5
+ import { getDialKitPortalRoot, getDropdownPosition } from '../../dropdown-position';
5
6
  import { ICON_CHEVRON } from '../../icons';
6
7
 
7
8
  type SelectOption = string | { value: string; label: string };
@@ -32,18 +33,9 @@
32
33
  const selectedOption = $derived(normalized.find((o: { value: string; label: string }) => o.value === value));
33
34
 
34
35
  const updatePos = () => {
35
- if (!triggerRef || typeof window === 'undefined') return;
36
- const rect = triggerRef.getBoundingClientRect();
36
+ if (!triggerRef || !portalTarget || typeof window === 'undefined') return;
37
37
  const dropdownHeight = 8 + normalized.length * 36;
38
- const spaceBelow = window.innerHeight - rect.bottom - 4;
39
- const above = spaceBelow < dropdownHeight && rect.top > spaceBelow;
40
-
41
- pos = {
42
- top: above ? rect.top - 4 : rect.bottom + 4,
43
- left: rect.left,
44
- width: rect.width,
45
- above,
46
- };
38
+ pos = getDropdownPosition(triggerRef, portalTarget, { dropdownHeight });
47
39
  };
48
40
 
49
41
  const openDropdown = () => {
@@ -59,16 +51,16 @@
59
51
  if (!pos || typeof window === 'undefined') return '';
60
52
 
61
53
  if (pos.above) {
62
- return `position:fixed;left:${pos.left}px;width:${pos.width}px;bottom:${window.innerHeight - pos.top}px;transform-origin:bottom;`;
54
+ return `position:absolute;left:${pos.left}px;top:${pos.top}px;width:${pos.width}px;transform-origin:bottom;`;
63
55
  }
64
56
 
65
- return `position:fixed;left:${pos.left}px;width:${pos.width}px;top:${pos.top}px;transform-origin:top;`;
57
+ return `position:absolute;left:${pos.left}px;top:${pos.top}px;width:${pos.width}px;transform-origin:top;`;
66
58
  });
67
59
 
68
60
  $effect(() => {
69
61
  if (typeof document === 'undefined' || !triggerRef) return;
70
62
 
71
- portalTarget = (triggerRef.closest('.dialkit-root') as HTMLElement | null) ?? document.body;
63
+ portalTarget = getDialKitPortalRoot(triggerRef) ?? document.body;
72
64
  });
73
65
 
74
66
  $effect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"SelectControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SelectControl.svelte.ts"],"names":[],"mappings":"AASE,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AA+HJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"SelectControl.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/SelectControl.svelte.ts"],"names":[],"mappings":"AAUE,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,KAAK,gBAAgB,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAuHJ,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,206 @@
1
+ <script lang="ts">
2
+ import { DialStore } from 'dialkit/store';
3
+ import type { ControlMeta, DialValue } from 'dialkit/store';
4
+ import {
5
+ TIMELINE_MIN_CLIP_DURATION,
6
+ clamp,
7
+ formatStepLabel,
8
+ timelinePopoverDisplayValues,
9
+ } from 'dialkit/timeline';
10
+ import type { TimelineClipMeta } from 'dialkit/timeline';
11
+ import { findControl } from '../../../shortcut-utils';
12
+ import Portal from '../../Portal.svelte';
13
+ import ControlRenderer from '../ControlRenderer.svelte';
14
+ import type { DialTheme } from '../DialRoot.svelte';
15
+
16
+ const POPOVER_WIDTH = 280;
17
+
18
+ export type PopoverState = {
19
+ clip: TimelineClipMeta;
20
+ stepKey?: string;
21
+ anchor: { left: number; top: number; right: number; bottom: number; width: number; height: number };
22
+ };
23
+
24
+ let { panelId, popover, values, theme, onClose } = $props<{
25
+ panelId: string;
26
+ popover: PopoverState;
27
+ values: Record<string, DialValue>;
28
+ theme: DialTheme;
29
+ onClose: () => void;
30
+ }>();
31
+
32
+ let element = $state<HTMLDivElement>();
33
+ let naturalHeight = $state(0);
34
+ let viewport = $state(readViewport());
35
+
36
+ const presentation = $derived.by(() => {
37
+ const { clip, stepKey } = popover;
38
+ let controls: ControlMeta[];
39
+ let title: string;
40
+ if (stepKey) {
41
+ controls = getClipControls(panelId, `${clip.key}.${stepKey}`);
42
+ if (stepKey === clip.stepKeys?.[0]) {
43
+ const from = getControlAt(panelId, `${clip.key}.from`);
44
+ if (from) {
45
+ const index = controls.findIndex((control) => control.path === `${clip.key}.${stepKey}.to`);
46
+ controls = index >= 0
47
+ ? [...controls.slice(0, index), from, ...controls.slice(index)]
48
+ : [...controls, from];
49
+ }
50
+ }
51
+ title = `${clip.label} · ${formatStepLabel(stepKey)}`;
52
+ } else {
53
+ controls = getClipControls(panelId, clip.key, clipPopoverExclusions(clip));
54
+ title = clip.label;
55
+ }
56
+ const target = stepKey ? `${clip.key}.${stepKey}` : clip.key;
57
+ const durationMeta = getControlAt(panelId, `${target}.duration`);
58
+ const durationValue = durationMeta ? values[durationMeta.path] : undefined;
59
+ const transitionDuration = durationMeta?.type === 'slider' && typeof durationValue === 'number'
60
+ ? {
61
+ value: durationValue,
62
+ onChange: (next: number) => DialStore.updateValue(panelId, durationMeta.path, next),
63
+ min: Math.max(TIMELINE_MIN_CLIP_DURATION, durationMeta.min ?? 0),
64
+ max: durationMeta.max,
65
+ step: durationMeta.step,
66
+ }
67
+ : undefined;
68
+ return {
69
+ controls,
70
+ title,
71
+ transitionDuration,
72
+ displayValues: timelinePopoverDisplayValues(values, clip.key, clip.stepKeys, stepKey),
73
+ };
74
+ });
75
+
76
+ const position = $derived.by(() => {
77
+ const right = viewport.offsetLeft + viewport.width;
78
+ const bottom = viewport.offsetTop + viewport.height;
79
+ const width = Math.min(POPOVER_WIDTH, Math.max(220, viewport.width - 24));
80
+ const left = clamp(
81
+ popover.anchor.left + popover.anchor.width / 2 - width / 2,
82
+ viewport.offsetLeft + 12,
83
+ Math.max(viewport.offsetLeft + 12, right - width - 12)
84
+ );
85
+ const above = Math.max(0, popover.anchor.top - viewport.offsetTop - 22);
86
+ const below = Math.max(0, bottom - popover.anchor.bottom - 22);
87
+ const placeAbove = naturalHeight === 0
88
+ ? above >= below
89
+ : naturalHeight <= above || (naturalHeight > below && above >= below);
90
+ const availableHeight = placeAbove ? above : below;
91
+ const renderedHeight = Math.min(naturalHeight || availableHeight, availableHeight);
92
+ const rawTop = placeAbove ? popover.anchor.top - 10 - renderedHeight : popover.anchor.bottom + 10;
93
+ return {
94
+ left,
95
+ top: clamp(rawTop, viewport.offsetTop + 12, Math.max(viewport.offsetTop + 12, bottom - renderedHeight - 12)),
96
+ width,
97
+ availableHeight,
98
+ placeAbove,
99
+ };
100
+ });
101
+
102
+ $effect(() => {
103
+ if (!element) return;
104
+ popover.clip.key;
105
+ popover.stepKey;
106
+ const measure = () => {
107
+ if (element) naturalHeight = element.scrollHeight + 2;
108
+ };
109
+ measure();
110
+ const observer = new ResizeObserver(measure);
111
+ observer.observe(element.querySelector('.dialkit-timeline-popover-body') ?? element);
112
+ return () => observer.disconnect();
113
+ });
114
+
115
+ $effect(() => {
116
+ if (typeof window === 'undefined') return;
117
+ const updateViewport = () => { viewport = readViewport(); };
118
+ const outside = (event: PointerEvent) => {
119
+ const target = event.target as HTMLElement;
120
+ if (element?.contains(target) || target.closest?.('.dialkit-timeline-clip') || target.closest?.('.dialkit-timeline-label')) return;
121
+ onClose();
122
+ };
123
+ const keydown = (event: KeyboardEvent) => {
124
+ if (event.key === 'Escape') onClose();
125
+ };
126
+ window.addEventListener('resize', updateViewport);
127
+ window.visualViewport?.addEventListener('resize', updateViewport);
128
+ window.visualViewport?.addEventListener('scroll', updateViewport);
129
+ document.addEventListener('pointerdown', outside, true);
130
+ document.addEventListener('keydown', keydown);
131
+ return () => {
132
+ window.removeEventListener('resize', updateViewport);
133
+ window.visualViewport?.removeEventListener('resize', updateViewport);
134
+ window.visualViewport?.removeEventListener('scroll', updateViewport);
135
+ document.removeEventListener('pointerdown', outside, true);
136
+ document.removeEventListener('keydown', keydown);
137
+ };
138
+ });
139
+
140
+ function readViewport() {
141
+ if (typeof window === 'undefined') return { width: 1024, height: 768, offsetLeft: 0, offsetTop: 0 };
142
+ return {
143
+ width: window.visualViewport?.width ?? window.innerWidth,
144
+ height: window.visualViewport?.height ?? window.innerHeight,
145
+ offsetLeft: window.visualViewport?.offsetLeft ?? 0,
146
+ offsetTop: window.visualViewport?.offsetTop ?? 0,
147
+ };
148
+ }
149
+
150
+ function clipPopoverExclusions(clip: TimelineClipMeta) {
151
+ return new Set([...(clip.stepKeys ?? []), ...(clip.tracks?.map((track) => track.prop) ?? [])]);
152
+ }
153
+
154
+ function getClipControls(panel: string, path: string, exclusions?: Set<string>): ControlMeta[] {
155
+ const currentPanel = DialStore.getPanel(panel);
156
+ const folder = currentPanel ? findControl(currentPanel.controls, path) : null;
157
+ if (!folder?.children) return [];
158
+ return folder.children.filter((control) => {
159
+ const key = control.path.slice(path.length + 1);
160
+ return key !== 'at' && key !== 'duration' && !exclusions?.has(key);
161
+ });
162
+ }
163
+
164
+ function getControlAt(panel: string, path: string): ControlMeta | null {
165
+ const currentPanel = DialStore.getPanel(panel);
166
+ return currentPanel ? findControl(currentPanel.controls, path) : null;
167
+ }
168
+ </script>
169
+
170
+ {#if presentation.controls.length > 0}
171
+ <Portal target="body">
172
+ <div class="dialkit-root" data-theme={theme}>
173
+ <div
174
+ bind:this={element}
175
+ class="dialkit-timeline-popover"
176
+ data-placement={position.placeAbove ? 'above' : 'below'}
177
+ style:left={`${position.left}px`}
178
+ style:top={`${position.top}px`}
179
+ style:width={`${position.width}px`}
180
+ style:max-height={`${position.availableHeight}px`}
181
+ style:visibility={naturalHeight > 0 ? 'visible' : 'hidden'}
182
+ role="dialog"
183
+ aria-label={`Edit ${presentation.title}`}
184
+ >
185
+ <div class="dialkit-timeline-popover-header">
186
+ <span class="dialkit-timeline-popover-title">{presentation.title}</span>
187
+ <button class="dialkit-timeline-popover-close" onclick={onClose} title="Close editor" aria-label="Close editor">
188
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
189
+ <path d="M6 6L18 18M18 6L6 18" />
190
+ </svg>
191
+ </button>
192
+ </div>
193
+ <div class="dialkit-timeline-popover-body">
194
+ {#each presentation.controls as control (control.path)}
195
+ <ControlRenderer
196
+ {panelId}
197
+ {control}
198
+ values={presentation.displayValues}
199
+ transitionDuration={presentation.transitionDuration}
200
+ />
201
+ {/each}
202
+ </div>
203
+ </div>
204
+ </div>
205
+ </Portal>
206
+ {/if}
@@ -0,0 +1,26 @@
1
+ import type { DialValue } from 'dialkit/store';
2
+ import type { TimelineClipMeta } from 'dialkit/timeline';
3
+ import type { DialTheme } from '../DialRoot.svelte';
4
+ export type PopoverState = {
5
+ clip: TimelineClipMeta;
6
+ stepKey?: string;
7
+ anchor: {
8
+ left: number;
9
+ top: number;
10
+ right: number;
11
+ bottom: number;
12
+ width: number;
13
+ height: number;
14
+ };
15
+ };
16
+ type $$ComponentProps = {
17
+ panelId: string;
18
+ popover: PopoverState;
19
+ values: Record<string, DialValue>;
20
+ theme: DialTheme;
21
+ onClose: () => void;
22
+ };
23
+ declare const ClipPopover: import("svelte").Component<$$ComponentProps, {}, "">;
24
+ type ClipPopover = ReturnType<typeof ClipPopover>;
25
+ export default ClipPopover;
26
+ //# sourceMappingURL=ClipPopover.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClipPopover.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/Timeline/ClipPopover.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,eAAe,CAAC;AAO5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrG,CAAC;AACH,KAAK,gBAAgB,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAkLJ,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,76 @@
1
+ <script lang="ts">
2
+ import {
3
+ TimelineStore,
4
+ TimelineUiStore,
5
+ isDevDefault,
6
+ } from 'dialkit/timeline';
7
+ import type { TimelineMeta } from 'dialkit/timeline';
8
+ import Portal from '../../Portal.svelte';
9
+ import type { DialTheme } from '../DialRoot.svelte';
10
+ import TimelineSection from './TimelineSection.svelte';
11
+
12
+ let {
13
+ theme = 'system',
14
+ defaultVisible = true,
15
+ visible,
16
+ onVisibilityChange,
17
+ defaultOpen = true,
18
+ productionEnabled = isDevDefault,
19
+ } = $props<{
20
+ theme?: DialTheme;
21
+ defaultVisible?: boolean;
22
+ visible?: boolean;
23
+ onVisibilityChange?: (visible: boolean) => void;
24
+ defaultOpen?: boolean;
25
+ productionEnabled?: boolean;
26
+ }>();
27
+
28
+ const controllerId = Symbol('dialkit-timeline-visibility');
29
+ let mounted = $state(false);
30
+ let timelines = $state<TimelineMeta[]>([]);
31
+ let dockVisible = $state(TimelineUiStore.getVisible());
32
+
33
+ $effect(() => {
34
+ if (typeof window === 'undefined') return;
35
+ mounted = true;
36
+ timelines = TimelineStore.getTimelines();
37
+ dockVisible = TimelineUiStore.getVisible();
38
+ const unsubscribeVisibility = TimelineUiStore.subscribe(() => {
39
+ dockVisible = TimelineUiStore.getVisible();
40
+ });
41
+ const unregisterController = TimelineUiStore.registerController(controllerId, {
42
+ visible,
43
+ defaultVisible,
44
+ onVisibilityChange,
45
+ });
46
+ dockVisible = TimelineUiStore.getVisible();
47
+ const unsubscribeTimelines = TimelineStore.subscribeGlobal(() => {
48
+ timelines = TimelineStore.getTimelines();
49
+ });
50
+ return () => {
51
+ unregisterController();
52
+ unsubscribeTimelines();
53
+ unsubscribeVisibility();
54
+ };
55
+ });
56
+
57
+ $effect(() => {
58
+ TimelineUiStore.updateController(controllerId, {
59
+ visible,
60
+ defaultVisible,
61
+ onVisibilityChange,
62
+ });
63
+ });
64
+ </script>
65
+
66
+ {#if productionEnabled && mounted && timelines.length > 0}
67
+ <Portal target="body">
68
+ <div class="dialkit-root dialkit-timeline" data-theme={theme} hidden={!dockVisible}>
69
+ <div class="dialkit-timeline-dock">
70
+ {#each timelines as timeline (timeline.id)}
71
+ <TimelineSection meta={timeline} {defaultOpen} {theme} {dockVisible} />
72
+ {/each}
73
+ </div>
74
+ </div>
75
+ </Portal>
76
+ {/if}
@@ -0,0 +1,13 @@
1
+ import type { DialTheme } from '../DialRoot.svelte';
2
+ type $$ComponentProps = {
3
+ theme?: DialTheme;
4
+ defaultVisible?: boolean;
5
+ visible?: boolean;
6
+ onVisibilityChange?: (visible: boolean) => void;
7
+ defaultOpen?: boolean;
8
+ productionEnabled?: boolean;
9
+ };
10
+ declare const DialTimeline: import("svelte").Component<$$ComponentProps, {}, "">;
11
+ type DialTimeline = ReturnType<typeof DialTimeline>;
12
+ export default DialTimeline;
13
+ //# sourceMappingURL=DialTimeline.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DialTimeline.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/Timeline/DialTimeline.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGnD,KAAK,gBAAgB,GAAG;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAqEJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}