@joewinke/jatui 0.1.31 → 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/collapse.js +29 -15
- package/dist/actions/floating.d.ts +53 -0
- package/dist/actions/floating.js +158 -0
- package/dist/actions/listNav.js +137 -108
- package/dist/actions/railNav.js +89 -72
- 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/markup.js +62 -59
- 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/session-nav/transcriptModel.js +66 -49
- 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/data/emojis.js +4 -4
- package/dist/dnd/autoScroll.js +12 -10
- package/dist/dnd/createDndBoard.svelte.js +110 -76
- package/dist/dnd/createDndBoard.test.js +161 -85
- package/dist/dnd/draggable.js +23 -15
- package/dist/dnd/dropTarget.js +29 -15
- package/dist/dnd/index.d.ts +0 -1
- package/dist/dnd/index.js +0 -1
- package/dist/dnd/types.d.ts +0 -9
- package/dist/dnd/types.js +14 -2
- package/dist/index.d.ts +60 -6
- package/dist/index.js +73 -6
- 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/confirmDialog.svelte.js +5 -5
- package/dist/stores/inputDialog.svelte.js +5 -5
- 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/types/booking.js +4 -4
- package/dist/types/comments.js +2 -2
- package/dist/types/messaging.js +3 -3
- package/dist/types/pipeline.js +2 -2
- package/dist/utils/currency.js +4 -2
- package/dist/utils/daisyuiColors.js +27 -25
- package/dist/utils/dateFormatters.d.ts +20 -0
- package/dist/utils/dateFormatters.js +65 -44
- package/dist/utils/googleMapsLoader.js +100 -46
- package/dist/utils/mentionParser.js +30 -30
- package/dist/utils/phone.js +27 -21
- package/dist/utils/phoneFormat.js +9 -9
- 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/taskUtils.js +1 -1
- 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 +56 -4
package/dist/index.js
CHANGED
|
@@ -82,7 +82,7 @@ export { default as AvailabilityModal } from './components/AvailabilityModal.sve
|
|
|
82
82
|
export { default as BookingForm } from './components/BookingForm.svelte';
|
|
83
83
|
export { DAYS_OF_WEEK, DAYS_SHORT, LOCATION_LABELS, LOCATION_ICONS } from './types/booking';
|
|
84
84
|
// Utilities — date formatting
|
|
85
|
-
export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, } from './utils/dateFormatters';
|
|
85
|
+
export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, pacingColor, } from './utils/dateFormatters';
|
|
86
86
|
// Utilities — task display helpers
|
|
87
87
|
export { statusColor, priorityColor, typeIcon, statusLabel, } from './utils/taskUtils';
|
|
88
88
|
// Utilities — phone formatting (legacy US-only)
|
|
@@ -141,8 +141,75 @@ export { default as LocationMap } from './components/LocationMap.svelte';
|
|
|
141
141
|
export { default as GPSTracker } from './components/GPSTracker.svelte';
|
|
142
142
|
// Utilities — Google Maps loader
|
|
143
143
|
export { loadGoogleMapsAPI, isGoogleMapsLoaded, isPlacesLoaded, isGeometryLoaded, } from './utils/googleMapsLoader';
|
|
144
|
-
// DnD — pragmatic-drag-and-drop wrappers
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
// DnD — pragmatic-drag-and-drop wrappers live behind the `@joewinke/jatui/dnd`
|
|
145
|
+
// subpath export, NOT this barrel. Re-exporting them here forced every barrel
|
|
146
|
+
// consumer to install the optional @atlaskit/pragmatic-drag-and-drop* peer deps
|
|
147
|
+
// (and broke bundlers that stub the unresolved optional peer). Import DnD via:
|
|
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;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
duration?: number;
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { duration = 12, class: className = '', children }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div
|
|
14
|
+
class="aurora-drift-root {className}"
|
|
15
|
+
style="--aurora-duration: {duration}s;"
|
|
16
|
+
>
|
|
17
|
+
<div class="aurora-drift-backdrop" aria-hidden="true"></div>
|
|
18
|
+
<div class="aurora-drift-content">
|
|
19
|
+
{#if children}
|
|
20
|
+
{@render children()}
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<style>
|
|
26
|
+
.aurora-drift-root {
|
|
27
|
+
position: relative;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.aurora-drift-backdrop {
|
|
32
|
+
position: absolute;
|
|
33
|
+
inset: -40%;
|
|
34
|
+
background:
|
|
35
|
+
radial-gradient(
|
|
36
|
+
40% 50% at 30% 38%,
|
|
37
|
+
color-mix(in srgb, oklch(var(--p)) 30%, transparent),
|
|
38
|
+
transparent 60%
|
|
39
|
+
),
|
|
40
|
+
radial-gradient(
|
|
41
|
+
45% 55% at 72% 62%,
|
|
42
|
+
color-mix(in srgb, oklch(var(--s)) 30%, transparent),
|
|
43
|
+
transparent 60%
|
|
44
|
+
),
|
|
45
|
+
radial-gradient(
|
|
46
|
+
40% 50% at 50% 82%,
|
|
47
|
+
color-mix(in srgb, oklch(var(--a)) 25%, transparent),
|
|
48
|
+
transparent 60%
|
|
49
|
+
);
|
|
50
|
+
filter: blur(16px);
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
animation: aurora-drift var(--aurora-duration) ease-in-out infinite alternate;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.aurora-drift-content {
|
|
56
|
+
position: relative;
|
|
57
|
+
z-index: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@keyframes aurora-drift {
|
|
61
|
+
0% {
|
|
62
|
+
transform: translate(-6%, -4%) rotate(0deg) scale(1.1);
|
|
63
|
+
}
|
|
64
|
+
100% {
|
|
65
|
+
transform: translate(6%, 4%) rotate(8deg) scale(1.3);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@media (prefers-reduced-motion: reduce) {
|
|
70
|
+
.aurora-drift-backdrop {
|
|
71
|
+
animation: none;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
duration?: number;
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const AuroraDrift: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type AuroraDrift = ReturnType<typeof AuroraDrift>;
|
|
9
|
+
export default AuroraDrift;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// pattern after magicui.design (MIT)
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Column span (default 1) */
|
|
7
|
+
colSpan?: number;
|
|
8
|
+
/** Row span (default 1) */
|
|
9
|
+
rowSpan?: number;
|
|
10
|
+
/** Hover tint color (CSS color). No tint if omitted (house rule: no shadows). */
|
|
11
|
+
hoverTint?: string;
|
|
12
|
+
class?: string;
|
|
13
|
+
children: Snippet;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let { colSpan = 1, rowSpan = 1, hoverTint, class: className = '', children }: Props = $props();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<div
|
|
20
|
+
class="bento-card {className}"
|
|
21
|
+
role="listitem"
|
|
22
|
+
style="
|
|
23
|
+
grid-column: span {colSpan};
|
|
24
|
+
grid-row: span {rowSpan};
|
|
25
|
+
{hoverTint ? `--bento-tint: ${hoverTint};` : ''}
|
|
26
|
+
"
|
|
27
|
+
>
|
|
28
|
+
{@render children()}
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<style>
|
|
32
|
+
.bento-card {
|
|
33
|
+
position: relative;
|
|
34
|
+
border-radius: var(--jatui-radius-box);
|
|
35
|
+
border: var(--jatui-border-w) solid oklch(var(--bc) / 0.1);
|
|
36
|
+
background: oklch(var(--b1));
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
transition: background var(--motion-fast) var(--motion-glide);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.bento-card:hover {
|
|
42
|
+
background: var(--bento-tint, oklch(var(--b2, var(--b1))));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media (prefers-reduced-motion: reduce) {
|
|
46
|
+
.bento-card {
|
|
47
|
+
transition: none;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Column span (default 1) */
|
|
4
|
+
colSpan?: number;
|
|
5
|
+
/** Row span (default 1) */
|
|
6
|
+
rowSpan?: number;
|
|
7
|
+
/** Hover tint color (CSS color). No tint if omitted (house rule: no shadows). */
|
|
8
|
+
hoverTint?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
children: Snippet;
|
|
11
|
+
}
|
|
12
|
+
declare const BentoCard: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type BentoCard = ReturnType<typeof BentoCard>;
|
|
14
|
+
export default BentoCard;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// pattern after magicui.design (MIT)
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Number of columns in the grid (default 3) */
|
|
7
|
+
cols?: number;
|
|
8
|
+
/** Gap between cells */
|
|
9
|
+
gap?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
children: Snippet;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let { cols = 3, gap = '1rem', class: className = '', children }: Props = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div
|
|
18
|
+
class="bento-grid {className}"
|
|
19
|
+
style="--bento-cols: {cols}; --bento-gap: {gap};"
|
|
20
|
+
role="list"
|
|
21
|
+
>
|
|
22
|
+
{@render children()}
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<style>
|
|
26
|
+
.bento-grid {
|
|
27
|
+
display: grid;
|
|
28
|
+
grid-template-columns: repeat(var(--bento-cols), 1fr);
|
|
29
|
+
gap: var(--bento-gap);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@media (max-width: 768px) {
|
|
33
|
+
.bento-grid {
|
|
34
|
+
grid-template-columns: 1fr;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@media (min-width: 769px) and (max-width: 1024px) {
|
|
39
|
+
.bento-grid {
|
|
40
|
+
grid-template-columns: repeat(min(var(--bento-cols), 2), 1fr);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Number of columns in the grid (default 3) */
|
|
4
|
+
cols?: number;
|
|
5
|
+
/** Gap between cells */
|
|
6
|
+
gap?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
children: Snippet;
|
|
9
|
+
}
|
|
10
|
+
declare const BentoGrid: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type BentoGrid = ReturnType<typeof BentoGrid>;
|
|
12
|
+
export default BentoGrid;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
duration?: number;
|
|
6
|
+
colorFrom?: string;
|
|
7
|
+
colorTo?: string;
|
|
8
|
+
borderRadius?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
children?: Snippet;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
duration = 3,
|
|
15
|
+
colorFrom = 'oklch(var(--p))',
|
|
16
|
+
colorTo = 'oklch(var(--a))',
|
|
17
|
+
borderRadius = '0.75rem',
|
|
18
|
+
class: className = '',
|
|
19
|
+
children
|
|
20
|
+
}: Props = $props();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<div
|
|
24
|
+
class="border-beam-root {className}"
|
|
25
|
+
style="--beam-duration: {duration}s; --beam-color-from: {colorFrom}; --beam-color-to: {colorTo}; --beam-radius: {borderRadius};"
|
|
26
|
+
>
|
|
27
|
+
<div class="border-beam-inner">
|
|
28
|
+
{#if children}
|
|
29
|
+
{@render children()}
|
|
30
|
+
{/if}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<style>
|
|
35
|
+
.border-beam-root {
|
|
36
|
+
position: relative;
|
|
37
|
+
padding: 1.5px;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
border-radius: var(--beam-radius);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.border-beam-root::before {
|
|
43
|
+
content: '';
|
|
44
|
+
position: absolute;
|
|
45
|
+
top: 50%;
|
|
46
|
+
left: 50%;
|
|
47
|
+
width: 200%;
|
|
48
|
+
height: 200%;
|
|
49
|
+
transform: translate(-50%, -50%);
|
|
50
|
+
background: conic-gradient(
|
|
51
|
+
from 0deg,
|
|
52
|
+
transparent 0 72%,
|
|
53
|
+
var(--beam-color-from) 84%,
|
|
54
|
+
var(--beam-color-to) 90%,
|
|
55
|
+
transparent 96% 100%
|
|
56
|
+
);
|
|
57
|
+
animation: beam-spin var(--beam-duration) linear infinite;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.border-beam-inner {
|
|
61
|
+
position: relative;
|
|
62
|
+
z-index: 1;
|
|
63
|
+
width: 100%;
|
|
64
|
+
height: 100%;
|
|
65
|
+
border-radius: calc(var(--beam-radius) - 1.5px);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@keyframes beam-spin {
|
|
69
|
+
to {
|
|
70
|
+
transform: translate(-50%, -50%) rotate(1turn);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@media (prefers-reduced-motion: reduce) {
|
|
75
|
+
.border-beam-root::before {
|
|
76
|
+
animation: none;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
duration?: number;
|
|
4
|
+
colorFrom?: string;
|
|
5
|
+
colorTo?: string;
|
|
6
|
+
borderRadius?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
declare const BorderBeam: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type BorderBeam = ReturnType<typeof BorderBeam>;
|
|
12
|
+
export default BorderBeam;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type Direction = 'left' | 'right' | 'top' | 'bottom';
|
|
5
|
+
type TriggerMode = 'mount' | 'intersect';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
direction?: Direction;
|
|
9
|
+
triggerMode?: TriggerMode;
|
|
10
|
+
duration?: number;
|
|
11
|
+
class?: string;
|
|
12
|
+
children: import('svelte').Snippet;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
direction = 'left',
|
|
17
|
+
triggerMode = 'mount',
|
|
18
|
+
duration = 500,
|
|
19
|
+
class: className = '',
|
|
20
|
+
children,
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
const startClip: Record<Direction, string> = {
|
|
24
|
+
left: 'inset(0 100% 0 0)',
|
|
25
|
+
right: 'inset(0 0 0 100%)',
|
|
26
|
+
top: 'inset(100% 0 0 0)',
|
|
27
|
+
bottom: 'inset(0 0 100% 0)',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const endClip = 'inset(0 0 0 0)';
|
|
31
|
+
|
|
32
|
+
let prefersReducedMotion = false;
|
|
33
|
+
let revealed = $state(false);
|
|
34
|
+
let el: HTMLDivElement | undefined = $state();
|
|
35
|
+
|
|
36
|
+
function trigger() {
|
|
37
|
+
revealed = true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onMount(() => {
|
|
41
|
+
prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
42
|
+
|
|
43
|
+
if (prefersReducedMotion) {
|
|
44
|
+
revealed = true;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (triggerMode === 'mount') {
|
|
49
|
+
// Defer one frame so the initial clip-path is painted before transitioning
|
|
50
|
+
requestAnimationFrame(() => {
|
|
51
|
+
trigger();
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
const observer = new IntersectionObserver(
|
|
55
|
+
(entries) => {
|
|
56
|
+
for (const entry of entries) {
|
|
57
|
+
if (entry.intersectionRatio >= 0.5) {
|
|
58
|
+
trigger();
|
|
59
|
+
observer.disconnect();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{ threshold: 0.5 }
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
if (el) {
|
|
67
|
+
observer.observe(el);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return () => observer.disconnect();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<div
|
|
76
|
+
bind:this={el}
|
|
77
|
+
class={className}
|
|
78
|
+
style:clip-path={prefersReducedMotion ? endClip : revealed ? endClip : startClip[direction]}
|
|
79
|
+
style:transition={prefersReducedMotion ? 'none' : `clip-path ${duration}ms var(--motion-glide)`}
|
|
80
|
+
>
|
|
81
|
+
{@render children()}
|
|
82
|
+
</div>
|