Thomas G. Lopes
MCPs (#91)
52c6f5c unverified
raw
history blame
1.38 kB
<script lang="ts">
import { classes } from "$lib/utils/styles.js";
import { type ComponentProps } from "melt";
import { Toggle, type ToggleProps } from "melt/builders";
import { ElementSize } from "runed";
let {
class: className,
value = $bindable(false),
...rest
}: ComponentProps<ToggleProps> & { class?: string } = $props();
const toggle = new Toggle({
value: () => value ?? false,
onValueChange: v => (value = v),
...rest,
});
let trigger = $state<HTMLButtonElement>();
const triggerSize = new ElementSize(() => trigger);
let thumb = $state<HTMLSpanElement>();
const thumbSize = new ElementSize(() => thumb);
const padding = 2;
const thumbX = $derived.by(() => {
if (toggle.value) {
return triggerSize.width - thumbSize.width - padding;
}
return padding;
});
let mounted = $state(false);
$effect(() => {
setTimeout(() => {
mounted = true;
});
});
</script>
<button
bind:this={trigger}
{...toggle.trigger}
class={classes(
"relative h-5 w-10 shrink-0 rounded-full bg-neutral-500 transition-all",
{ "bg-blue-500": toggle.value },
className,
)}
>
<span
bind:this={thumb}
class={classes("spring-bounce-20 spring-duration-200 absolute top-0.5 left-0 h-4 w-4 rounded-full bg-neutral-900", {
"bg-white": toggle.value,
"!duration-0": !mounted,
})}
style="transform: translateX({thumbX}px)"
></span>
</button>