fixes/mobile-comparator #25

Merged
ilia merged 10 commits from fixes/mobile-comparator into main 2026-02-10 16:21:45 +00:00
Showing only changes of commit e39ed86a04 - Show all commits

View File

@@ -3,6 +3,7 @@
Animated wrapper for content that can be expanded and collapsed.
-->
<script lang="ts">
import { debounce } from '$shared/lib/utils';
import { cn } from '$shared/shadcn/utils/shadcn-utils';
import type { Snippet } from 'svelte';
import { cubicOut } from 'svelte/easing';
@@ -38,6 +39,10 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
* Optional badge to render
*/
badge?: Snippet<[{ expanded?: boolean; disabled?: boolean }]>;
/**
* Callback for when the element's size changes
*/
onResize?: (rect: DOMRectReadOnly) => void;
/**
* Rotation animation direction
* @default 'clockwise'
@@ -56,6 +61,7 @@ let {
visibleContent,
hiddenContent,
badge,
onResize,
rotation = 'clockwise',
class: className = '',
containerClassName = '',
@@ -64,7 +70,7 @@ let {
let timeoutId = $state<ReturnType<typeof setTimeout> | null>(null);
export const xSpring = new Spring(0, {
const xSpring = new Spring(0, {
stiffness: 0.14, // Lower is slower
damping: 0.5, // Settle
});
@@ -79,7 +85,7 @@ const scaleSpring = new Spring(1, {
damping: 0.65,
});
export const rotateSpring = new Spring(0, {
const rotateSpring = new Spring(0, {
stiffness: 0.12,
damping: 0.55,
});
@@ -107,6 +113,9 @@ function handleKeyDown(e: KeyboardEvent) {
}
}
// Create debounced recize callback
const debouncedResize = debounce((entry: ResizeObserverEntry) => onResize?.(entry.contentRect), 50);
// Elevation and scale on activation
$effect(() => {
if (expanded && !disabled) {
@@ -149,6 +158,21 @@ $effect(() => {
expanded = false;
}
});
// Use an effect to watch the element's actual physical size
$effect(() => {
if (!element) return;
const observer = new ResizeObserver(entries => {
const entry = entries[0];
if (entry) {
debouncedResize(entry);
}
});
observer.observe(element);
return () => observer.disconnect();
});
</script>
<div
@@ -158,7 +182,7 @@ $effect(() => {
role="button"
tabindex={0}
class={cn(
'will-change-transform duration-300',
'will-change-[transform, width, height] duration-300',
disabled ? 'pointer-events-none' : 'pointer-events-auto',
className,
)}