This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / ui / Toggle.svelte
1.9 kB 57 lines
1<script lang="ts"> 2 import type { Snippet } from "svelte"; 3 import type { HTMLInputAttributes } from "svelte/elements"; 4 5 interface Props extends Omit<HTMLInputAttributes, "type" | "class" | "checked" | "children"> { 6 checked?: boolean; 7 disabled?: boolean; 8 /** `inline` hugs the label, `block` stretches it to fill the row. */ 9 layout?: "inline" | "block"; 10 class?: string; 11 children?: Snippet; 12 } 13 14 let { 15 checked = $bindable(false), 16 disabled = false, 17 layout = "inline", 18 class: className, 19 children, 20 ...rest 21 }: Props = $props(); 22 23 const labelClasses = $derived( 24 [ 25 "items-center gap-2", 26 layout === "block" ? "flex w-full" : "inline-flex", 27 disabled ? "cursor-not-allowed text-foreground-disabled" : "cursor-pointer", 28 className ?? "" 29 ].join(" ") 30 ); 31 32 const inputClasses = [ 33 "peer absolute inset-0 size-full appearance-none rounded-full bg-background-muted cursor-pointer", 34 "transition-colors duration-150", 35 "checked:bg-foreground-default", 36 "enabled:hover:bg-background-strong checked:enabled:hover:bg-foreground-muted", 37 "focus-visible:ring-2 focus-visible:ring-border-strong focus-visible:outline-none", 38 "disabled:cursor-not-allowed disabled:bg-background-inset checked:disabled:bg-foreground-disabled" 39 ].join(" "); 40 41 const thumbClasses = [ 42 "pointer-events-none absolute top-px left-px size-4 rounded-full bg-background-default", 43 "transition-transform duration-150 peer-checked:translate-x-[15px]" 44 ].join(" "); 45 46 const textClasses = $derived(layout === "block" ? "min-w-0 flex-1" : "whitespace-nowrap"); 47</script> 48 49<label class={labelClasses}> 50 <span class="relative inline-flex h-4.5 w-8.25 shrink-0"> 51 <input type="checkbox" role="switch" bind:checked {disabled} class={inputClasses} {...rest} /> 52 <span class={thumbClasses} aria-hidden="true"></span> 53 </span> 54 {#if children} 55 <span class={textClasses}>{@render children()}</span> 56 {/if} 57</label>