64 lines
1.7 KiB
Svelte
64 lines
1.7 KiB
Svelte
<!--
|
|
Component: Thumb
|
|
Renders a thumb to control ComparisonSlider position.
|
|
1px red vertical rule with square handles at top and bottom.
|
|
-->
|
|
<script lang="ts">
|
|
import clsx from 'clsx';
|
|
import { cubicOut } from 'svelte/easing';
|
|
import { fade } from 'svelte/transition';
|
|
|
|
interface Props {
|
|
/**
|
|
* Slider position percentage
|
|
*/
|
|
sliderPos: number;
|
|
/**
|
|
* Dragging state
|
|
*/
|
|
isDragging: boolean;
|
|
}
|
|
|
|
let { sliderPos, isDragging }: Props = $props();
|
|
</script>
|
|
|
|
<div
|
|
class="absolute top-0 bottom-0 z-50 pointer-events-none w-px bg-brand flex flex-col justify-between"
|
|
style:left="{sliderPos}%"
|
|
style:will-change={isDragging ? 'left' : 'auto'}
|
|
in:fade={{ duration: 300, delay: 150, easing: cubicOut }}
|
|
out:fade={{ duration: 150, easing: cubicOut }}
|
|
>
|
|
<!-- Top handle -->
|
|
<div
|
|
class={clsx(
|
|
'w-5 h-5 md:w-6 md:h-6',
|
|
'-ml-2.5 md:-ml-3',
|
|
'mt-2 md:mt-4',
|
|
'bg-brand text-white',
|
|
'flex items-center justify-center',
|
|
'rounded-none shadow-md',
|
|
'transition-transform duration-150',
|
|
isDragging ? 'scale-110' : 'scale-100',
|
|
)}
|
|
>
|
|
<div class="w-0.5 h-2 md:h-3 bg-white/80"></div>
|
|
</div>
|
|
|
|
<!-- Bottom handle -->
|
|
<div
|
|
class={clsx(
|
|
'w-5 h-5 md:w-6 md:h-6',
|
|
'-ml-2.5 md:-ml-3',
|
|
'mb-2 md:mb-4',
|
|
'bg-brand text-white',
|
|
'flex items-center justify-center',
|
|
'rounded-none shadow-md',
|
|
'transition-transform duration-150',
|
|
isDragging ? 'scale-110' : 'scale-100',
|
|
)}
|
|
>
|
|
<div class="w-0.5 h-2 md:h-3 bg-white/80"></div>
|
|
</div>
|
|
</div>
|