feature/project-redesign #28
@@ -1,6 +1,7 @@
|
||||
<!--
|
||||
Component: SliderLine
|
||||
Visual representation of the slider line.
|
||||
Visual representation of the comparison slider line.
|
||||
1px red vertical rule with square handles at top and bottom.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||
@@ -8,75 +9,47 @@ import { cubicOut } from 'svelte/easing';
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Position of the slider
|
||||
*/
|
||||
sliderPos: number;
|
||||
/**
|
||||
* Whether the slider is being dragged
|
||||
*/
|
||||
/** Position of the slider as a percentage (0–100) */
|
||||
sliderPos: number;
|
||||
/** Whether the slider is being dragged */
|
||||
isDragging: boolean;
|
||||
}
|
||||
|
||||
let { sliderPos, isDragging }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'absolute top-2 bottom-8 sm:top-4 sm:bottom-4 pointer-events-none -translate-x-1/2 z-50 flex flex-col justify-center items-center',
|
||||
// Force GPU layer with translateZ
|
||||
'translate-z-0',
|
||||
// Only transition left when NOT dragging
|
||||
isDragging ? '' : 'transition-[left] duration-300 ease-out',
|
||||
)}
|
||||
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 }}
|
||||
>
|
||||
<!-- We use part of lucide cursor svg icon as a handle -->
|
||||
<svg
|
||||
class={cn(
|
||||
'transition-all relative duration-300 text-black/80 drop-shadow-sm',
|
||||
isDragging ? 'size-6 sm:size-12' : 'size-4 sm:size-8',
|
||||
)}
|
||||
viewBox="0 0 24 12"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M17 10h-1a4 4 0 0 1-4-4V0" />
|
||||
<path d="M7 10h1a4 4 0 0 0 4-4V0" />
|
||||
</svg>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'relative h-full rounded-sm transition-all duration-300',
|
||||
'bg-background-3 ',
|
||||
// These are the visible "edges" of the glass
|
||||
'shadow-[0_0_40px_rgba(0,0,0,0.1)_inset_0_0_20px_rgba(255,255,255,0.1)]',
|
||||
'shadow-[0_10px_30px_-10px_rgba(0,0,0,0.2),inset_0_1px_1px_rgba(255,255,255,0.4)]',
|
||||
'rounded-full',
|
||||
isDragging ? 'w-16 sm:w-24' : 'w-12 sm:w-16',
|
||||
)}
|
||||
>
|
||||
<!-- Top handle -->
|
||||
<div class={cn(
|
||||
'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>
|
||||
|
||||
<!-- We use part of lucide cursor svg icon as a handle -->
|
||||
<svg
|
||||
class={cn(
|
||||
'transition-all relative duration-500 text-black/80 drop-shadow-sm',
|
||||
isDragging ? 'size-6 sm:size-12' : 'size-4 sm:size-8',
|
||||
)}
|
||||
viewBox="0 0 24 12"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M17 2h-1a4 4 0 0 0-4 4v6" />
|
||||
<path d="M7 2h1a4 4 0 0 1 4 4v6" />
|
||||
</svg>
|
||||
<!-- Bottom handle -->
|
||||
<div class={cn(
|
||||
'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>
|
||||
|
||||
Reference in New Issue
Block a user