diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ControlsWrapper.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ControlsWrapper.svelte index 4209cb7..8b572ba 100644 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ControlsWrapper.svelte +++ b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ControlsWrapper.svelte @@ -3,9 +3,9 @@ import type { TypographyControl } from '$shared/lib'; import { Input } from '$shared/shadcn/ui/input'; import { cn } from '$shared/shadcn/utils/shadcn-utils'; import { ComboControlV2 } from '$shared/ui'; +import { ExpandableWrapper } from '$shared/ui'; import AArrowUP from '@lucide/svelte/icons/a-arrow-up'; import { Spring } from 'svelte/motion'; -import { slide } from 'svelte/transition'; interface Props { wrapper?: HTMLDivElement | null; @@ -29,40 +29,27 @@ let { heightControl, }: Props = $props(); -let panelWidth = $state(0); +let panelWidth = $derived(wrapper?.clientWidth ?? 0); const margin = 24; let side = $state<'left' | 'right'>('left'); - // Unified active state for the entire wrapper let isActive = $state(false); +let timeoutId = $state | null>(null); -function handleWrapperClick() { - if (!isDragging) { - isActive = true; - } -} +const xSpring = new Spring(0, { + stiffness: 0.14, // Lower is slower + damping: 0.5, // Settle +}); -function handleClickOutside(e: MouseEvent) { - if (wrapper && !wrapper.contains(e.target as Node)) { - isActive = false; - } -} +const rotateSpring = new Spring(0, { + stiffness: 0.12, + damping: 0.55, +}); function handleInputFocus() { isActive = true; } -function handleKeyDown(e: KeyboardEvent) { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - handleWrapperClick(); - } - - if (isActive && e.key === 'Escape') { - isActive = false; - } -} - // Movement Logic $effect(() => { if (containerWidth === 0 || panelWidth === 0) return; @@ -78,144 +65,80 @@ $effect(() => { } }); -// The "Dodge" -const xSpring = new Spring(0, { - stiffness: 0.14, // Lower is slower - damping: 0.5, // Settle -}); - -// The "Focus" -const ySpring = new Spring(0, { - stiffness: 0.32, - damping: 0.65, -}); - -// The "Rise" -const scaleSpring = new Spring(1, { - stiffness: 0.32, - damping: 0.65, -}); - -// The "Lean" -const rotateSpring = new Spring(0, { - stiffness: 0.12, - damping: 0.55, -}); - $effect(() => { const targetX = side === 'right' ? containerWidth - panelWidth - margin * 2 : 0; - if (containerWidth > 0 && panelWidth > 0 && !isActive) { + if (containerWidth > 0 && panelWidth > 0) { // On side change set the position and the rotation xSpring.target = targetX; rotateSpring.target = side === 'right' ? 3.5 : -3.5; - setTimeout(() => { + timeoutId = setTimeout(() => { rotateSpring.target = 0; }, 600); } -}); -// Elevation and scale on focus and mouse over -$effect(() => { - if (isActive && !isDragging) { - // Lift up - ySpring.target = 8; - // Slightly bigger - scaleSpring.target = 1.1; - - rotateSpring.target = side === 'right' ? -1.1 : 1.1; - - setTimeout(() => { - rotateSpring.target = 0; - scaleSpring.target = 1.05; - }, 300); - } else { - ySpring.target = 0; - scaleSpring.target = 1; - rotateSpring.target = 0; - } -}); - -$effect(() => { - if (isDragging) { - isActive = false; - } -}); - -// Click outside handler -$effect(() => { - if (typeof window === 'undefined') return; - - document.addEventListener('click', handleClickOutside); - return () => document.removeEventListener('click', handleClickOutside); + return () => { + if (timeoutId) { + clearTimeout(timeoutId); + } + }; });
-
- -
- -
-
- -
- - {#if isActive} + {#snippet badge()}
+ +
+ {/snippet} + + {#snippet visibleContent()} +
+ +
+ {/snippet} + + {#snippet hiddenContent()} +
- {/if} -
+ {/snippet} +