@joewinke/jatui 0.1.33 → 0.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/CLAUDE.md +22 -0
- package/dist/actions/attention.d.ts +24 -0
- package/dist/actions/attention.js +94 -0
- package/dist/actions/floating.d.ts +53 -0
- package/dist/actions/floating.js +158 -0
- package/dist/actions/staggerEntrance.d.ts +28 -0
- package/dist/actions/staggerEntrance.js +71 -0
- package/dist/actions/tooltip.d.ts +28 -0
- package/dist/actions/tooltip.js +186 -0
- package/dist/assets/sounds/README.md +47 -0
- package/dist/assets/sounds/error.d.ts +1 -0
- package/dist/assets/sounds/error.js +4 -0
- package/dist/assets/sounds/notify.d.ts +1 -0
- package/dist/assets/sounds/notify.js +4 -0
- package/dist/assets/sounds/pop.d.ts +1 -0
- package/dist/assets/sounds/pop.js +4 -0
- package/dist/assets/sounds/send.d.ts +1 -0
- package/dist/assets/sounds/send.js +4 -0
- package/dist/assets/sounds/success.d.ts +1 -0
- package/dist/assets/sounds/success.js +4 -0
- package/dist/assets/sounds/toggle.d.ts +1 -0
- package/dist/assets/sounds/toggle.js +4 -0
- package/dist/components/AnimatedNumber.svelte +112 -0
- package/dist/components/AnimatedNumber.svelte.d.ts +8 -0
- package/dist/components/Badge.svelte +75 -4
- package/dist/components/Badge.svelte.d.ts +6 -1
- package/dist/components/Button.svelte +196 -21
- package/dist/components/Button.svelte.d.ts +10 -1
- package/dist/components/Carousel.svelte +265 -0
- package/dist/components/Carousel.svelte.d.ts +21 -0
- package/dist/components/ChipInput.svelte +63 -3
- package/dist/components/Collapse.svelte +70 -14
- package/dist/components/Collapse.svelte.d.ts +11 -0
- package/dist/components/ColorSelector.svelte +21 -24
- package/dist/components/CommandPalette.svelte +475 -0
- package/dist/components/CommandPalette.svelte.d.ts +3 -0
- package/dist/components/ContextMenu.svelte +9 -73
- package/dist/components/CopyButton.svelte +156 -0
- package/dist/components/CopyButton.svelte.d.ts +12 -0
- package/dist/components/HoldToConfirm.svelte +183 -0
- package/dist/components/HoldToConfirm.svelte.d.ts +11 -0
- package/dist/components/KeyboardShortcutsOverlay.svelte +54 -8
- package/dist/components/KeyboardShortcutsOverlay.svelte.d.ts +3 -0
- package/dist/components/PasswordMeter.svelte +87 -0
- package/dist/components/PasswordMeter.svelte.d.ts +8 -0
- package/dist/components/PinInput.svelte +186 -0
- package/dist/components/PinInput.svelte.d.ts +13 -0
- package/dist/components/QuantityStepper.svelte +185 -0
- package/dist/components/QuantityStepper.svelte.d.ts +12 -0
- package/dist/components/Skeleton.svelte +123 -0
- package/dist/components/Skeleton.svelte.d.ts +12 -0
- package/dist/components/SpeechForm.svelte +37 -0
- package/dist/components/StatusBadge.svelte +31 -3
- package/dist/components/StatusBadge.svelte.d.ts +0 -5
- package/dist/components/Tabs.svelte +270 -0
- package/dist/components/Tabs.svelte.d.ts +15 -0
- package/dist/components/TextInput.svelte +138 -38
- package/dist/components/TextInput.svelte.d.ts +9 -1
- package/dist/components/VoicePlayer.svelte +51 -0
- package/dist/components/basic/Alert.svelte +36 -0
- package/dist/components/basic/Alert.svelte.d.ts +9 -0
- package/dist/components/basic/Breadcrumb.svelte +27 -0
- package/dist/components/basic/Breadcrumb.svelte.d.ts +11 -0
- package/dist/components/basic/ButtonGroup.svelte +15 -0
- package/dist/components/basic/ButtonGroup.svelte.d.ts +8 -0
- package/dist/components/basic/Checkbox.svelte +85 -0
- package/dist/components/basic/Checkbox.svelte.d.ts +15 -0
- package/dist/components/basic/Empty.svelte +17 -0
- package/dist/components/basic/Empty.svelte.d.ts +8 -0
- package/dist/components/basic/Kbd.svelte +16 -0
- package/dist/components/basic/Kbd.svelte.d.ts +8 -0
- package/dist/components/basic/Pagination.svelte +104 -0
- package/dist/components/basic/Pagination.svelte.d.ts +12 -0
- package/dist/components/basic/RadioGroup.svelte +71 -0
- package/dist/components/basic/RadioGroup.svelte.d.ts +18 -0
- package/dist/components/basic/Separator.svelte +19 -0
- package/dist/components/basic/Separator.svelte.d.ts +8 -0
- package/dist/components/basic/Slider.svelte +72 -0
- package/dist/components/basic/Slider.svelte.d.ts +17 -0
- package/dist/components/basic/Switch.svelte +88 -0
- package/dist/components/basic/Switch.svelte.d.ts +14 -0
- package/dist/components/basic/Toggle.svelte +43 -0
- package/dist/components/basic/Toggle.svelte.d.ts +14 -0
- package/dist/components/graph/GraphCanvas.svelte +103 -0
- package/dist/components/graph/GraphCanvas.svelte.d.ts +22 -0
- package/dist/components/graph/JatuiNode.svelte +128 -0
- package/dist/components/graph/JatuiNode.svelte.d.ts +14 -0
- package/dist/components/graph/theme.d.ts +27 -0
- package/dist/components/graph/theme.js +136 -0
- package/dist/components/messaging/MessageItem.svelte +92 -0
- package/dist/components/messaging/MessageItem.svelte.d.ts +5 -0
- package/dist/components/messaging/TypingIndicator.svelte +63 -0
- package/dist/components/messaging/TypingIndicator.svelte.d.ts +7 -0
- package/dist/components/pipeline/PipelineColumn.svelte +44 -3
- package/dist/components/progress/ProgressBar.svelte +189 -0
- package/dist/components/progress/ProgressBar.svelte.d.ts +17 -0
- package/dist/components/progress/ProgressRing.svelte +138 -0
- package/dist/components/progress/ProgressRing.svelte.d.ts +12 -0
- package/dist/components/progress/Steps.svelte +195 -0
- package/dist/components/progress/Steps.svelte.d.ts +14 -0
- package/dist/components/shell/NavigationMenu.svelte +422 -0
- package/dist/components/shell/NavigationMenu.svelte.d.ts +43 -0
- package/dist/components/shell/Sidebar.svelte +276 -0
- package/dist/components/shell/Sidebar.svelte.d.ts +32 -0
- package/dist/components/shell/SidebarGroup.svelte +180 -0
- package/dist/components/shell/SidebarGroup.svelte.d.ts +19 -0
- package/dist/components/shell/SidebarItem.svelte +170 -0
- package/dist/components/shell/SidebarItem.svelte.d.ts +24 -0
- package/dist/components/shell/shell.d.ts +30 -0
- package/dist/components/shell/shell.js +65 -0
- package/dist/components/table/DataTable.svelte +364 -0
- package/dist/components/table/DataTable.svelte.d.ts +4 -0
- package/dist/components/table/flexRender.d.ts +31 -0
- package/dist/components/table/flexRender.js +32 -0
- package/dist/components/table/types.d.ts +28 -0
- package/dist/components/table/types.js +1 -0
- package/dist/components/toast/ToastHost.svelte +21 -0
- package/dist/components/toast/ToastHost.svelte.d.ts +3 -0
- package/dist/components/toast/ToastItem.svelte +287 -0
- package/dist/components/toast/ToastItem.svelte.d.ts +9 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +67 -0
- package/dist/showcase/AnimatedBeam.svelte +183 -0
- package/dist/showcase/AnimatedBeam.svelte.d.ts +26 -0
- package/dist/showcase/AuroraDrift.svelte +74 -0
- package/dist/showcase/AuroraDrift.svelte.d.ts +9 -0
- package/dist/showcase/BentoCard.svelte +50 -0
- package/dist/showcase/BentoCard.svelte.d.ts +14 -0
- package/dist/showcase/BentoGrid.svelte +43 -0
- package/dist/showcase/BentoGrid.svelte.d.ts +12 -0
- package/dist/showcase/BorderBeam.svelte +79 -0
- package/dist/showcase/BorderBeam.svelte.d.ts +12 -0
- package/dist/showcase/ClipWipe.svelte +82 -0
- package/dist/showcase/ClipWipe.svelte.d.ts +12 -0
- package/dist/showcase/Confetti.svelte +71 -0
- package/dist/showcase/Confetti.svelte.d.ts +10 -0
- package/dist/showcase/CursorSpotlight.svelte +85 -0
- package/dist/showcase/CursorSpotlight.svelte.d.ts +9 -0
- package/dist/showcase/DeviceMock.svelte +186 -0
- package/dist/showcase/DeviceMock.svelte.d.ts +11 -0
- package/dist/showcase/Dock.svelte +123 -0
- package/dist/showcase/Dock.svelte.d.ts +17 -0
- package/dist/showcase/FlipCard.svelte +103 -0
- package/dist/showcase/FlipCard.svelte.d.ts +10 -0
- package/dist/showcase/FocusReveal.svelte +83 -0
- package/dist/showcase/FocusReveal.svelte.d.ts +11 -0
- package/dist/showcase/Globe.svelte +202 -0
- package/dist/showcase/Globe.svelte.d.ts +16 -0
- package/dist/showcase/KenBurns.svelte +105 -0
- package/dist/showcase/KenBurns.svelte.d.ts +13 -0
- package/dist/showcase/Marquee.svelte +89 -0
- package/dist/showcase/Marquee.svelte.d.ts +9 -0
- package/dist/showcase/ParallaxTilt.svelte +98 -0
- package/dist/showcase/ParallaxTilt.svelte.d.ts +10 -0
- package/dist/showcase/ScrambleText.svelte +98 -0
- package/dist/showcase/ScrambleText.svelte.d.ts +11 -0
- package/dist/showcase/ShineSweep.svelte +81 -0
- package/dist/showcase/ShineSweep.svelte.d.ts +9 -0
- package/dist/showcase/Terminal.svelte +230 -0
- package/dist/showcase/Terminal.svelte.d.ts +18 -0
- package/dist/showcase/TextSplitReveal.svelte +146 -0
- package/dist/showcase/TextSplitReveal.svelte.d.ts +13 -0
- package/dist/showcase/TextWave.svelte +55 -0
- package/dist/showcase/TextWave.svelte.d.ts +8 -0
- package/dist/showcase/TypewriterText.svelte +130 -0
- package/dist/showcase/TypewriterText.svelte.d.ts +9 -0
- package/dist/showcase/backdrop/GrainGradient.svelte +126 -0
- package/dist/showcase/backdrop/GrainGradient.svelte.d.ts +23 -0
- package/dist/showcase/backdrop/MeshGradient.svelte +104 -0
- package/dist/showcase/backdrop/MeshGradient.svelte.d.ts +20 -0
- package/dist/showcase/backdrop/Metaballs.svelte +116 -0
- package/dist/showcase/backdrop/Metaballs.svelte.d.ts +18 -0
- package/dist/showcase/backdrop/NeuroNoise.svelte +115 -0
- package/dist/showcase/backdrop/NeuroNoise.svelte.d.ts +20 -0
- package/dist/showcase/backdrop/ShowcaseBackdrop.svelte +48 -0
- package/dist/showcase/backdrop/ShowcaseBackdrop.svelte.d.ts +12 -0
- package/dist/showcase/generative/GenerativeBackdrop.svelte +234 -0
- package/dist/showcase/generative/GenerativeBackdrop.svelte.d.ts +9 -0
- package/dist/showcase/generative/intent.d.ts +7 -0
- package/dist/showcase/generative/intent.js +67 -0
- package/dist/showcase/generative/manifest.d.ts +9 -0
- package/dist/showcase/generative/manifest.js +97 -0
- package/dist/showcase/generative/types.d.ts +48 -0
- package/dist/showcase/generative/types.js +8 -0
- package/dist/showcase/index.d.ts +36 -0
- package/dist/showcase/index.js +46 -0
- package/dist/showcase/scroll/SmoothScroll.svelte +49 -0
- package/dist/showcase/scroll/SmoothScroll.svelte.d.ts +12 -0
- package/dist/showcase/scroll/scrollProgress.d.ts +24 -0
- package/dist/showcase/scroll/scrollProgress.js +65 -0
- package/dist/showcase/scroll/scrollReveal.d.ts +30 -0
- package/dist/showcase/scroll/scrollReveal.js +70 -0
- package/dist/stores/commandPalette.svelte.d.ts +24 -0
- package/dist/stores/commandPalette.svelte.js +82 -0
- package/dist/stores/toast.svelte.d.ts +28 -0
- package/dist/stores/toast.svelte.js +33 -0
- package/dist/styles/motion.css +46 -0
- package/dist/styles/tokens.css +31 -0
- package/dist/transitions/glide.d.ts +31 -0
- package/dist/transitions/glide.js +58 -0
- package/dist/utils/sound.d.ts +6 -0
- package/dist/utils/sound.js +113 -0
- package/dist/utils/splitText.d.ts +25 -0
- package/dist/utils/splitText.js +94 -0
- package/dist/utils/themeWipe.d.ts +21 -0
- package/dist/utils/themeWipe.js +94 -0
- package/dist/utils/viewTransition.d.ts +23 -0
- package/dist/utils/viewTransition.js +75 -0
- package/package.json +50 -3
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { dismissToast, type Toast } from '../../stores/toast.svelte.js';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
toast: Toast;
|
|
6
|
+
index: number;
|
|
7
|
+
total: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { toast, index, total }: Props = $props();
|
|
11
|
+
|
|
12
|
+
// Stack compression: older toasts (lower index) scale down and fade behind newer ones
|
|
13
|
+
// index 0 = oldest (back), index total-1 = newest (front)
|
|
14
|
+
const stackDepth = $derived(total - 1 - index);
|
|
15
|
+
const stackScale = $derived(Math.max(0.88, 1 - stackDepth * 0.04));
|
|
16
|
+
const stackOpacity = $derived(stackDepth >= 3 ? 0 : 1 - stackDepth * 0.1);
|
|
17
|
+
|
|
18
|
+
// Drag-to-dismiss state
|
|
19
|
+
let dragX = $state(0);
|
|
20
|
+
let isDragging = $state(false);
|
|
21
|
+
let startX = 0;
|
|
22
|
+
let startVelocityX = 0;
|
|
23
|
+
let lastX = 0;
|
|
24
|
+
let lastTime = 0;
|
|
25
|
+
|
|
26
|
+
// Entrance animation
|
|
27
|
+
let mounted = $state(false);
|
|
28
|
+
let exiting = $state(false);
|
|
29
|
+
|
|
30
|
+
$effect(() => {
|
|
31
|
+
requestAnimationFrame(() => {
|
|
32
|
+
mounted = true;
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Undo countdown
|
|
37
|
+
let undoProgress = $state(1);
|
|
38
|
+
let undoTimer: ReturnType<typeof setInterval> | null = null;
|
|
39
|
+
let undoDone = $state(false);
|
|
40
|
+
let hovered = $state(false);
|
|
41
|
+
let focused = $state(false);
|
|
42
|
+
|
|
43
|
+
const paused = $derived(hovered || focused);
|
|
44
|
+
|
|
45
|
+
$effect(() => {
|
|
46
|
+
if (!toast.onUndo) return;
|
|
47
|
+
const totalMs = toast.durationMs;
|
|
48
|
+
const steps = 60;
|
|
49
|
+
const stepMs = totalMs / steps;
|
|
50
|
+
let elapsed = 0;
|
|
51
|
+
|
|
52
|
+
const tick = () => {
|
|
53
|
+
if (paused) return;
|
|
54
|
+
elapsed += stepMs;
|
|
55
|
+
undoProgress = Math.max(0, 1 - elapsed / totalMs);
|
|
56
|
+
if (undoProgress <= 0) {
|
|
57
|
+
clearInterval(undoTimer!);
|
|
58
|
+
undoTimer = null;
|
|
59
|
+
undoDone = true;
|
|
60
|
+
triggerDismiss();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
undoTimer = setInterval(tick, stepMs);
|
|
65
|
+
return () => {
|
|
66
|
+
if (undoTimer) clearInterval(undoTimer);
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Auto-dismiss for non-undo toasts
|
|
71
|
+
let dismissTimer: ReturnType<typeof setTimeout> | null = null;
|
|
72
|
+
|
|
73
|
+
$effect(() => {
|
|
74
|
+
if (toast.onUndo) return;
|
|
75
|
+
const schedule = () => {
|
|
76
|
+
dismissTimer = setTimeout(() => {
|
|
77
|
+
if (!hovered && !focused) triggerDismiss();
|
|
78
|
+
else {
|
|
79
|
+
// Re-check on unhover
|
|
80
|
+
const resume = () => {
|
|
81
|
+
if (!hovered && !focused) triggerDismiss();
|
|
82
|
+
};
|
|
83
|
+
document.addEventListener('pointerleave', resume, { once: true });
|
|
84
|
+
}
|
|
85
|
+
}, toast.durationMs);
|
|
86
|
+
};
|
|
87
|
+
schedule();
|
|
88
|
+
return () => {
|
|
89
|
+
if (dismissTimer) clearTimeout(dismissTimer);
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Re-start timer when un-paused
|
|
94
|
+
$effect(() => {
|
|
95
|
+
if (paused && dismissTimer) {
|
|
96
|
+
clearTimeout(dismissTimer);
|
|
97
|
+
dismissTimer = null;
|
|
98
|
+
} else if (!paused && !dismissTimer && !toast.onUndo) {
|
|
99
|
+
dismissTimer = setTimeout(triggerDismiss, toast.durationMs);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
function triggerDismiss() {
|
|
104
|
+
exiting = true;
|
|
105
|
+
setTimeout(() => dismissToast(toast.id), 220);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function handleUndo() {
|
|
109
|
+
if (undoTimer) clearInterval(undoTimer);
|
|
110
|
+
toast.onUndo?.();
|
|
111
|
+
triggerDismiss();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Drag handlers
|
|
115
|
+
function onPointerDown(e: PointerEvent) {
|
|
116
|
+
if ((e.target as HTMLElement).closest('button')) return;
|
|
117
|
+
isDragging = true;
|
|
118
|
+
startX = e.clientX;
|
|
119
|
+
lastX = e.clientX;
|
|
120
|
+
lastTime = e.timeStamp;
|
|
121
|
+
dragX = 0;
|
|
122
|
+
startVelocityX = 0;
|
|
123
|
+
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function onPointerMove(e: PointerEvent) {
|
|
127
|
+
if (!isDragging) return;
|
|
128
|
+
const now = e.timeStamp;
|
|
129
|
+
const dt = now - lastTime;
|
|
130
|
+
if (dt > 0) {
|
|
131
|
+
startVelocityX = (e.clientX - lastX) / dt;
|
|
132
|
+
}
|
|
133
|
+
lastX = e.clientX;
|
|
134
|
+
lastTime = now;
|
|
135
|
+
dragX = e.clientX - startX;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function onPointerUp(e: PointerEvent) {
|
|
139
|
+
if (!isDragging) return;
|
|
140
|
+
isDragging = false;
|
|
141
|
+
const THRESHOLD = 100;
|
|
142
|
+
// Velocity-based fling: >0.5px/ms or past threshold
|
|
143
|
+
if (Math.abs(dragX) > THRESHOLD || Math.abs(startVelocityX) > 0.5) {
|
|
144
|
+
const dir = dragX > 0 ? 1 : -1;
|
|
145
|
+
dragX = dir * window.innerWidth;
|
|
146
|
+
exiting = true;
|
|
147
|
+
setTimeout(() => dismissToast(toast.id), 300);
|
|
148
|
+
} else {
|
|
149
|
+
// Snap back with spring
|
|
150
|
+
dragX = 0;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// DaisyUI alert class per type
|
|
155
|
+
const alertClass: Record<string, string> = {
|
|
156
|
+
info: 'alert-info',
|
|
157
|
+
success: 'alert-success',
|
|
158
|
+
warning: 'alert-warning',
|
|
159
|
+
error: 'alert-error'
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// ARIA role per type
|
|
163
|
+
const ariaRole = $derived(toast.type === 'error' ? 'alert' : 'status');
|
|
164
|
+
const ariaLive = $derived(toast.type === 'error' ? 'assertive' : 'polite');
|
|
165
|
+
|
|
166
|
+
// Entrance/exit transform
|
|
167
|
+
const itemTransform = $derived(
|
|
168
|
+
isDragging
|
|
169
|
+
? `translateX(${dragX}px) rotate(${dragX * 0.02}deg)`
|
|
170
|
+
: exiting
|
|
171
|
+
? `translateY(20px) scale(0.9)`
|
|
172
|
+
: mounted
|
|
173
|
+
? `translateX(0) rotate(0deg)`
|
|
174
|
+
: `translateY(40px) scale(0.92)`
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const itemOpacity = $derived(
|
|
178
|
+
isDragging
|
|
179
|
+
? Math.max(0, 1 - Math.abs(dragX) / 200)
|
|
180
|
+
: exiting
|
|
181
|
+
? 0
|
|
182
|
+
: mounted
|
|
183
|
+
? 1
|
|
184
|
+
: 0
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const dragTransition = $derived(
|
|
188
|
+
isDragging
|
|
189
|
+
? 'none'
|
|
190
|
+
: exiting
|
|
191
|
+
? 'transform var(--motion-enter) var(--motion-glide), opacity var(--motion-enter) var(--motion-glide)'
|
|
192
|
+
: 'transform var(--motion-enter) var(--motion-spring), opacity var(--motion-fast) var(--motion-glide)'
|
|
193
|
+
);
|
|
194
|
+
</script>
|
|
195
|
+
|
|
196
|
+
<li
|
|
197
|
+
class="toast-item pointer-events-auto w-full"
|
|
198
|
+
style:transform={itemTransform}
|
|
199
|
+
style:opacity={itemOpacity}
|
|
200
|
+
style:transition={dragTransition}
|
|
201
|
+
role={ariaRole}
|
|
202
|
+
aria-live={ariaLive}
|
|
203
|
+
onmouseenter={() => (hovered = true)}
|
|
204
|
+
onmouseleave={() => (hovered = false)}
|
|
205
|
+
onfocusin={() => (focused = true)}
|
|
206
|
+
onfocusout={() => (focused = false)}
|
|
207
|
+
onpointerdown={onPointerDown}
|
|
208
|
+
onpointermove={onPointerMove}
|
|
209
|
+
onpointerup={onPointerUp}
|
|
210
|
+
>
|
|
211
|
+
<div
|
|
212
|
+
class="alert {alertClass[toast.type]} shadow-sm relative overflow-hidden gap-3 pr-3"
|
|
213
|
+
style:transform="scale({stackScale})"
|
|
214
|
+
style:opacity={stackOpacity}
|
|
215
|
+
style:transition="transform var(--motion-move) var(--motion-glide), opacity var(--motion-move) var(--motion-glide)"
|
|
216
|
+
>
|
|
217
|
+
<!-- Undo countdown bar -->
|
|
218
|
+
{#if toast.onUndo && !undoDone}
|
|
219
|
+
<span
|
|
220
|
+
class="toast-progress absolute bottom-0 left-0 h-0.5 w-full origin-left bg-current opacity-40"
|
|
221
|
+
style:animation-duration="{toast.durationMs}ms"
|
|
222
|
+
style:animation-play-state={paused ? 'paused' : 'running'}
|
|
223
|
+
></span>
|
|
224
|
+
{/if}
|
|
225
|
+
|
|
226
|
+
<span class="flex-1 text-sm">{toast.message}</span>
|
|
227
|
+
|
|
228
|
+
{#if toast.onUndo}
|
|
229
|
+
<button
|
|
230
|
+
type="button"
|
|
231
|
+
class="btn btn-ghost btn-xs font-semibold"
|
|
232
|
+
onclick={handleUndo}
|
|
233
|
+
>
|
|
234
|
+
Undo
|
|
235
|
+
</button>
|
|
236
|
+
{:else if toast.action}
|
|
237
|
+
<button
|
|
238
|
+
type="button"
|
|
239
|
+
class="btn btn-ghost btn-xs font-semibold"
|
|
240
|
+
onclick={() => { toast.action!.onClick(); triggerDismiss(); }}
|
|
241
|
+
>
|
|
242
|
+
{toast.action.label}
|
|
243
|
+
</button>
|
|
244
|
+
{/if}
|
|
245
|
+
|
|
246
|
+
<button
|
|
247
|
+
type="button"
|
|
248
|
+
class="btn btn-ghost btn-xs btn-square"
|
|
249
|
+
aria-label="Dismiss notification"
|
|
250
|
+
onclick={triggerDismiss}
|
|
251
|
+
>
|
|
252
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
253
|
+
<path d="M18 6L6 18M6 6l12 12"/>
|
|
254
|
+
</svg>
|
|
255
|
+
</button>
|
|
256
|
+
</div>
|
|
257
|
+
</li>
|
|
258
|
+
|
|
259
|
+
<style>
|
|
260
|
+
.toast-item {
|
|
261
|
+
list-style: none;
|
|
262
|
+
touch-action: pan-y;
|
|
263
|
+
user-select: none;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.toast-progress {
|
|
267
|
+
animation-name: drain;
|
|
268
|
+
animation-timing-function: linear;
|
|
269
|
+
animation-fill-mode: forwards;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@keyframes drain {
|
|
273
|
+
from { transform: scaleX(1); }
|
|
274
|
+
to { transform: scaleX(0); }
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
@media (prefers-reduced-motion: reduce) {
|
|
278
|
+
.toast-progress {
|
|
279
|
+
animation: none;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.toast-item,
|
|
283
|
+
.toast-item > div {
|
|
284
|
+
transition: none !important;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Toast } from '../../stores/toast.svelte.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
toast: Toast;
|
|
4
|
+
index: number;
|
|
5
|
+
total: number;
|
|
6
|
+
};
|
|
7
|
+
declare const ToastItem: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type ToastItem = ReturnType<typeof ToastItem>;
|
|
9
|
+
export default ToastItem;
|
package/dist/index.d.ts
CHANGED
|
@@ -142,3 +142,62 @@ export { default as LocationMap } from './components/LocationMap.svelte';
|
|
|
142
142
|
export { default as GPSTracker } from './components/GPSTracker.svelte';
|
|
143
143
|
export type { MapJob, MapAgent } from './types/maps';
|
|
144
144
|
export { loadGoogleMapsAPI, isGoogleMapsLoaded, isPlacesLoaded, isGeometryLoaded, } from './utils/googleMapsLoader';
|
|
145
|
+
export { tooltip } from './actions/tooltip';
|
|
146
|
+
export type { TooltipOptions } from './actions/tooltip';
|
|
147
|
+
export { staggerEntrance } from './actions/staggerEntrance';
|
|
148
|
+
export type { StaggerEntranceOptions } from './actions/staggerEntrance';
|
|
149
|
+
export { attention } from './actions/attention';
|
|
150
|
+
export type { AttentionEffect, AttentionOptions } from './actions/attention';
|
|
151
|
+
export { floating, makeVirtualAnchor } from './actions/floating';
|
|
152
|
+
export type { FloatingOptions, Placement } from './actions/floating';
|
|
153
|
+
export { glide } from './transitions/glide';
|
|
154
|
+
export type { GlideOrigin, GlideParams } from './transitions/glide';
|
|
155
|
+
export { themeWipe } from './utils/themeWipe';
|
|
156
|
+
export { viewTransition } from './utils/viewTransition';
|
|
157
|
+
export { play as playSound, registerSound, isSoundEnabled, setSoundEnabled } from './utils/sound';
|
|
158
|
+
export { splitText } from './utils/splitText';
|
|
159
|
+
export type { SplitBy, SplitTextOptions, SplitTextResult } from './utils/splitText';
|
|
160
|
+
export { default as ToastHost } from './components/toast/ToastHost.svelte';
|
|
161
|
+
export { showToast, dismissToast, getToasts } from './stores/toast.svelte';
|
|
162
|
+
export type { Toast, ToastType, ToastOptions, DismissHandle } from './stores/toast.svelte';
|
|
163
|
+
export { default as Skeleton } from './components/Skeleton.svelte';
|
|
164
|
+
export { default as ProgressBar } from './components/progress/ProgressBar.svelte';
|
|
165
|
+
export { default as ProgressRing } from './components/progress/ProgressRing.svelte';
|
|
166
|
+
export { default as Steps } from './components/progress/Steps.svelte';
|
|
167
|
+
export { default as Tabs } from './components/Tabs.svelte';
|
|
168
|
+
export { default as CommandPalette } from './components/CommandPalette.svelte';
|
|
169
|
+
export { commandPalette } from './stores/commandPalette.svelte';
|
|
170
|
+
export type { CommandItem } from './stores/commandPalette.svelte';
|
|
171
|
+
export { default as AnimatedNumber } from './components/AnimatedNumber.svelte';
|
|
172
|
+
export { default as CopyButton } from './components/CopyButton.svelte';
|
|
173
|
+
export { default as HoldToConfirm } from './components/HoldToConfirm.svelte';
|
|
174
|
+
export { default as PinInput } from './components/PinInput.svelte';
|
|
175
|
+
export { default as PasswordMeter } from './components/PasswordMeter.svelte';
|
|
176
|
+
export { default as QuantityStepper } from './components/QuantityStepper.svelte';
|
|
177
|
+
export { default as TypingIndicator } from './components/messaging/TypingIndicator.svelte';
|
|
178
|
+
export { default as DataTable } from './components/table/DataTable.svelte';
|
|
179
|
+
export { flexRender } from './components/table/flexRender';
|
|
180
|
+
export type { DataTableProps, SelectionEvent, ColumnDef, Row } from './components/table/types';
|
|
181
|
+
export { default as GraphCanvas } from './components/graph/GraphCanvas.svelte';
|
|
182
|
+
export { default as JatuiNode } from './components/graph/JatuiNode.svelte';
|
|
183
|
+
export { getStatusColor, applyXyflowTheme, watchAndApplyTheme } from './components/graph/theme';
|
|
184
|
+
export type { NodeStatus } from './components/graph/theme';
|
|
185
|
+
export { default as Sidebar } from './components/shell/Sidebar.svelte';
|
|
186
|
+
export { default as SidebarGroup } from './components/shell/SidebarGroup.svelte';
|
|
187
|
+
export { default as SidebarItem } from './components/shell/SidebarItem.svelte';
|
|
188
|
+
export { default as NavigationMenu } from './components/shell/NavigationMenu.svelte';
|
|
189
|
+
export { createSidebarState } from './components/shell/shell';
|
|
190
|
+
export type { SidebarMode, SidebarState } from './components/shell/shell';
|
|
191
|
+
export { default as Carousel } from './components/Carousel.svelte';
|
|
192
|
+
export { default as Kbd } from './components/basic/Kbd.svelte';
|
|
193
|
+
export { default as Empty } from './components/basic/Empty.svelte';
|
|
194
|
+
export { default as Breadcrumb } from './components/basic/Breadcrumb.svelte';
|
|
195
|
+
export { default as Alert } from './components/basic/Alert.svelte';
|
|
196
|
+
export { default as ButtonGroup } from './components/basic/ButtonGroup.svelte';
|
|
197
|
+
export { default as Switch } from './components/basic/Switch.svelte';
|
|
198
|
+
export { default as Checkbox } from './components/basic/Checkbox.svelte';
|
|
199
|
+
export { default as RadioGroup } from './components/basic/RadioGroup.svelte';
|
|
200
|
+
export { default as Toggle } from './components/basic/Toggle.svelte';
|
|
201
|
+
export { default as Separator } from './components/basic/Separator.svelte';
|
|
202
|
+
export { default as Slider } from './components/basic/Slider.svelte';
|
|
203
|
+
export { default as Pagination } from './components/basic/Pagination.svelte';
|
package/dist/index.js
CHANGED
|
@@ -146,3 +146,70 @@ export { loadGoogleMapsAPI, isGoogleMapsLoaded, isPlacesLoaded, isGeometryLoaded
|
|
|
146
146
|
// consumer to install the optional @atlaskit/pragmatic-drag-and-drop* peer deps
|
|
147
147
|
// (and broke bundlers that stub the unresolved optional peer). Import DnD via:
|
|
148
148
|
// import { draggable, DropIndicator } from '@joewinke/jatui/dnd';
|
|
149
|
+
// ============================================================
|
|
150
|
+
// Wave 1+2 (jatui-pk6jz / jatui-x2hyv) — kinetics motion port,
|
|
151
|
+
// research-verified gap fills, generative-pipeline era exports.
|
|
152
|
+
// ============================================================
|
|
153
|
+
// Motion primitives
|
|
154
|
+
export { tooltip } from './actions/tooltip';
|
|
155
|
+
export { staggerEntrance } from './actions/staggerEntrance';
|
|
156
|
+
export { attention } from './actions/attention';
|
|
157
|
+
export { floating, makeVirtualAnchor } from './actions/floating';
|
|
158
|
+
export { glide } from './transitions/glide';
|
|
159
|
+
// View Transitions kit
|
|
160
|
+
export { themeWipe } from './utils/themeWipe';
|
|
161
|
+
export { viewTransition } from './utils/viewTransition';
|
|
162
|
+
// Sound kit (functional feedback, opt-in)
|
|
163
|
+
export { play as playSound, registerSound, isSoundEnabled, setSoundEnabled } from './utils/sound';
|
|
164
|
+
// Text utilities
|
|
165
|
+
export { splitText } from './utils/splitText';
|
|
166
|
+
// Toast system
|
|
167
|
+
export { default as ToastHost } from './components/toast/ToastHost.svelte';
|
|
168
|
+
export { showToast, dismissToast, getToasts } from './stores/toast.svelte';
|
|
169
|
+
// Loading & progress family
|
|
170
|
+
export { default as Skeleton } from './components/Skeleton.svelte';
|
|
171
|
+
export { default as ProgressBar } from './components/progress/ProgressBar.svelte';
|
|
172
|
+
export { default as ProgressRing } from './components/progress/ProgressRing.svelte';
|
|
173
|
+
export { default as Steps } from './components/progress/Steps.svelte';
|
|
174
|
+
// Navigation & overlays
|
|
175
|
+
export { default as Tabs } from './components/Tabs.svelte';
|
|
176
|
+
export { default as CommandPalette } from './components/CommandPalette.svelte';
|
|
177
|
+
export { commandPalette } from './stores/commandPalette.svelte';
|
|
178
|
+
// Micro primitives
|
|
179
|
+
export { default as AnimatedNumber } from './components/AnimatedNumber.svelte';
|
|
180
|
+
export { default as CopyButton } from './components/CopyButton.svelte';
|
|
181
|
+
export { default as HoldToConfirm } from './components/HoldToConfirm.svelte';
|
|
182
|
+
// Form gaps
|
|
183
|
+
export { default as PinInput } from './components/PinInput.svelte';
|
|
184
|
+
export { default as PasswordMeter } from './components/PasswordMeter.svelte';
|
|
185
|
+
export { default as QuantityStepper } from './components/QuantityStepper.svelte';
|
|
186
|
+
// Messaging
|
|
187
|
+
export { default as TypingIndicator } from './components/messaging/TypingIndicator.svelte';
|
|
188
|
+
// Data table
|
|
189
|
+
export { default as DataTable } from './components/table/DataTable.svelte';
|
|
190
|
+
export { flexRender } from './components/table/flexRender';
|
|
191
|
+
// Graph canvas (Svelte Flow)
|
|
192
|
+
export { default as GraphCanvas } from './components/graph/GraphCanvas.svelte';
|
|
193
|
+
export { default as JatuiNode } from './components/graph/JatuiNode.svelte';
|
|
194
|
+
export { getStatusColor, applyXyflowTheme, watchAndApplyTheme } from './components/graph/theme';
|
|
195
|
+
// App shell
|
|
196
|
+
export { default as Sidebar } from './components/shell/Sidebar.svelte';
|
|
197
|
+
export { default as SidebarGroup } from './components/shell/SidebarGroup.svelte';
|
|
198
|
+
export { default as SidebarItem } from './components/shell/SidebarItem.svelte';
|
|
199
|
+
export { default as NavigationMenu } from './components/shell/NavigationMenu.svelte';
|
|
200
|
+
export { createSidebarState } from './components/shell/shell';
|
|
201
|
+
// Carousel
|
|
202
|
+
export { default as Carousel } from './components/Carousel.svelte';
|
|
203
|
+
// Basic primitives (thin DaisyUI wraps — layering policy)
|
|
204
|
+
export { default as Kbd } from './components/basic/Kbd.svelte';
|
|
205
|
+
export { default as Empty } from './components/basic/Empty.svelte';
|
|
206
|
+
export { default as Breadcrumb } from './components/basic/Breadcrumb.svelte';
|
|
207
|
+
export { default as Alert } from './components/basic/Alert.svelte';
|
|
208
|
+
export { default as ButtonGroup } from './components/basic/ButtonGroup.svelte';
|
|
209
|
+
export { default as Switch } from './components/basic/Switch.svelte';
|
|
210
|
+
export { default as Checkbox } from './components/basic/Checkbox.svelte';
|
|
211
|
+
export { default as RadioGroup } from './components/basic/RadioGroup.svelte';
|
|
212
|
+
export { default as Toggle } from './components/basic/Toggle.svelte';
|
|
213
|
+
export { default as Separator } from './components/basic/Separator.svelte';
|
|
214
|
+
export { default as Slider } from './components/basic/Slider.svelte';
|
|
215
|
+
export { default as Pagination } from './components/basic/Pagination.svelte';
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// pattern after magicui.design (MIT)
|
|
3
|
+
import { onMount, onDestroy } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
/** ID of the start element */
|
|
7
|
+
fromId: string;
|
|
8
|
+
/** ID of the end element */
|
|
9
|
+
toId: string;
|
|
10
|
+
/** Containing element for coordinate calculations (defaults to document.body) */
|
|
11
|
+
containerId?: string;
|
|
12
|
+
/** Gradient start color */
|
|
13
|
+
colorFrom?: string;
|
|
14
|
+
/** Gradient end color */
|
|
15
|
+
colorTo?: string;
|
|
16
|
+
/** Stroke width */
|
|
17
|
+
strokeWidth?: number;
|
|
18
|
+
/** Beam sweep duration in seconds */
|
|
19
|
+
duration?: number;
|
|
20
|
+
/** Dash length as fraction of path (0–1) */
|
|
21
|
+
dashLength?: number;
|
|
22
|
+
/** Curvature 0–1 (0 = straight, 1 = very curved) */
|
|
23
|
+
curvature?: number;
|
|
24
|
+
/** Reverse beam direction */
|
|
25
|
+
reverse?: boolean;
|
|
26
|
+
class?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let {
|
|
30
|
+
fromId,
|
|
31
|
+
toId,
|
|
32
|
+
containerId,
|
|
33
|
+
colorFrom = 'oklch(var(--p))',
|
|
34
|
+
colorTo = 'oklch(var(--a))',
|
|
35
|
+
strokeWidth = 2,
|
|
36
|
+
duration = 3,
|
|
37
|
+
dashLength = 0.25,
|
|
38
|
+
curvature = 0.5,
|
|
39
|
+
reverse = false,
|
|
40
|
+
class: className = ''
|
|
41
|
+
}: Props = $props();
|
|
42
|
+
|
|
43
|
+
let svgEl: SVGSVGElement | undefined = $state();
|
|
44
|
+
let pathD = $state('');
|
|
45
|
+
let pathLength = $state(0);
|
|
46
|
+
let reducedMotion = $state(false);
|
|
47
|
+
|
|
48
|
+
const uid = Math.random().toString(36).slice(2, 8);
|
|
49
|
+
const gradId = `beam-grad-${uid}`;
|
|
50
|
+
const pathId = `beam-path-${uid}`;
|
|
51
|
+
|
|
52
|
+
function getCenter(el: Element, container: Element): { x: number; y: number } {
|
|
53
|
+
const elR = el.getBoundingClientRect();
|
|
54
|
+
const cR = container.getBoundingClientRect();
|
|
55
|
+
return {
|
|
56
|
+
x: elR.left + elR.width / 2 - cR.left,
|
|
57
|
+
y: elR.top + elR.height / 2 - cR.top
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function updatePath() {
|
|
62
|
+
const root = containerId ? document.getElementById(containerId) : svgEl?.parentElement;
|
|
63
|
+
if (!root || !svgEl) return;
|
|
64
|
+
|
|
65
|
+
const fromEl = document.getElementById(fromId);
|
|
66
|
+
const toEl = document.getElementById(toId);
|
|
67
|
+
if (!fromEl || !toEl) return;
|
|
68
|
+
|
|
69
|
+
const from = getCenter(fromEl, root);
|
|
70
|
+
const to = getCenter(toEl, root);
|
|
71
|
+
|
|
72
|
+
// Resize SVG to container
|
|
73
|
+
const rr = root.getBoundingClientRect();
|
|
74
|
+
svgEl.style.width = rr.width + 'px';
|
|
75
|
+
svgEl.style.height = rr.height + 'px';
|
|
76
|
+
|
|
77
|
+
// Cubic bezier: control points offset vertically by curvature
|
|
78
|
+
const dy = Math.abs(to.y - from.y) * curvature;
|
|
79
|
+
const cx1 = from.x;
|
|
80
|
+
const cy1 = from.y - dy;
|
|
81
|
+
const cx2 = to.x;
|
|
82
|
+
const cy2 = to.y + dy;
|
|
83
|
+
|
|
84
|
+
const d = `M ${from.x},${from.y} C ${cx1},${cy1} ${cx2},${cy2} ${to.x},${to.y}`;
|
|
85
|
+
pathD = d;
|
|
86
|
+
|
|
87
|
+
// Measure path length after DOM update
|
|
88
|
+
requestAnimationFrame(() => {
|
|
89
|
+
const pathEl = svgEl?.querySelector(`#${pathId}`) as SVGPathElement | null;
|
|
90
|
+
if (pathEl) pathLength = pathEl.getTotalLength();
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let resizeObs: ResizeObserver | undefined;
|
|
95
|
+
|
|
96
|
+
onMount(() => {
|
|
97
|
+
reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
98
|
+
updatePath();
|
|
99
|
+
|
|
100
|
+
const root = containerId ? document.getElementById(containerId) : svgEl?.parentElement;
|
|
101
|
+
if (root) {
|
|
102
|
+
resizeObs = new ResizeObserver(updatePath);
|
|
103
|
+
resizeObs.observe(root);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
onDestroy(() => {
|
|
108
|
+
resizeObs?.disconnect();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const dashArr = $derived(
|
|
112
|
+
pathLength > 0 ? `${pathLength * dashLength} ${pathLength * (1 - dashLength)}` : '0 1'
|
|
113
|
+
);
|
|
114
|
+
const dashOffset = $derived(pathLength > 0 ? (reverse ? -pathLength : pathLength) : 0);
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<!-- svelte-ignore a11y_aria_hidden_on_focusable -->
|
|
118
|
+
<svg
|
|
119
|
+
bind:this={svgEl}
|
|
120
|
+
class="animated-beam {className}"
|
|
121
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
122
|
+
style="pointer-events:none; position:absolute; inset:0; overflow:visible;"
|
|
123
|
+
aria-hidden="true"
|
|
124
|
+
>
|
|
125
|
+
<defs>
|
|
126
|
+
<linearGradient id={gradId} gradientUnits="userSpaceOnUse">
|
|
127
|
+
<stop offset="0%" stop-color={colorFrom} stop-opacity="0" />
|
|
128
|
+
<stop offset="20%" stop-color={colorFrom} />
|
|
129
|
+
<stop offset="80%" stop-color={colorTo} />
|
|
130
|
+
<stop offset="100%" stop-color={colorTo} stop-opacity="0" />
|
|
131
|
+
</linearGradient>
|
|
132
|
+
</defs>
|
|
133
|
+
|
|
134
|
+
<!-- Static base line -->
|
|
135
|
+
{#if pathD}
|
|
136
|
+
<path d={pathD} stroke="oklch(var(--bc) / 0.08)" stroke-width={strokeWidth} fill="none" />
|
|
137
|
+
|
|
138
|
+
<!-- Animated beam -->
|
|
139
|
+
{#if !reducedMotion}
|
|
140
|
+
<path
|
|
141
|
+
id={pathId}
|
|
142
|
+
d={pathD}
|
|
143
|
+
stroke="url(#{gradId})"
|
|
144
|
+
stroke-width={strokeWidth}
|
|
145
|
+
fill="none"
|
|
146
|
+
stroke-linecap="round"
|
|
147
|
+
stroke-dasharray={dashArr}
|
|
148
|
+
stroke-dashoffset="0"
|
|
149
|
+
style="animation: beam-sweep-{uid} {duration}s linear infinite var(--motion-glide);"
|
|
150
|
+
/>
|
|
151
|
+
{:else}
|
|
152
|
+
<!-- Reduced motion: static gradient line -->
|
|
153
|
+
<path
|
|
154
|
+
id={pathId}
|
|
155
|
+
d={pathD}
|
|
156
|
+
stroke="url(#{gradId})"
|
|
157
|
+
stroke-width={strokeWidth}
|
|
158
|
+
fill="none"
|
|
159
|
+
stroke-linecap="round"
|
|
160
|
+
opacity="0.6"
|
|
161
|
+
/>
|
|
162
|
+
{/if}
|
|
163
|
+
{/if}
|
|
164
|
+
</svg>
|
|
165
|
+
|
|
166
|
+
<style>
|
|
167
|
+
.animated-beam {
|
|
168
|
+
position: absolute;
|
|
169
|
+
inset: 0;
|
|
170
|
+
overflow: visible;
|
|
171
|
+
pointer-events: none;
|
|
172
|
+
}
|
|
173
|
+
</style>
|
|
174
|
+
|
|
175
|
+
<!-- Keyframes injected per-instance via a style tag to use the dynamic dashOffset -->
|
|
176
|
+
{#if pathLength > 0 && !reducedMotion}
|
|
177
|
+
{@html `<style>
|
|
178
|
+
@keyframes beam-sweep-${uid} {
|
|
179
|
+
0% { stroke-dashoffset: ${dashOffset}; }
|
|
180
|
+
100% { stroke-dashoffset: ${-dashOffset}; }
|
|
181
|
+
}
|
|
182
|
+
</style>`}
|
|
183
|
+
{/if}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** ID of the start element */
|
|
3
|
+
fromId: string;
|
|
4
|
+
/** ID of the end element */
|
|
5
|
+
toId: string;
|
|
6
|
+
/** Containing element for coordinate calculations (defaults to document.body) */
|
|
7
|
+
containerId?: string;
|
|
8
|
+
/** Gradient start color */
|
|
9
|
+
colorFrom?: string;
|
|
10
|
+
/** Gradient end color */
|
|
11
|
+
colorTo?: string;
|
|
12
|
+
/** Stroke width */
|
|
13
|
+
strokeWidth?: number;
|
|
14
|
+
/** Beam sweep duration in seconds */
|
|
15
|
+
duration?: number;
|
|
16
|
+
/** Dash length as fraction of path (0–1) */
|
|
17
|
+
dashLength?: number;
|
|
18
|
+
/** Curvature 0–1 (0 = straight, 1 = very curved) */
|
|
19
|
+
curvature?: number;
|
|
20
|
+
/** Reverse beam direction */
|
|
21
|
+
reverse?: boolean;
|
|
22
|
+
class?: string;
|
|
23
|
+
}
|
|
24
|
+
declare const AnimatedBeam: import("svelte").Component<Props, {}, "">;
|
|
25
|
+
type AnimatedBeam = ReturnType<typeof AnimatedBeam>;
|
|
26
|
+
export default AnimatedBeam;
|