Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| <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> | |