refactor: convert slider to switch (#18334)

This commit is contained in:
Jason Rasmussen 2025-05-16 13:59:47 -04:00 committed by GitHub
parent 21880aec14
commit 5353658114
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 5 additions and 99 deletions

View File

@ -1,94 +0,0 @@
<script lang="ts">
interface Props {
/**
* Unique identifier for the checkbox element, used to associate labels with the input element.
*/
id: string;
/**
* Optional aria-describedby attribute to associate the checkbox with a description.
*/
ariaDescribedBy?: string | undefined;
checked?: boolean;
disabled?: boolean;
onToggle?: ((checked: boolean) => void) | undefined;
}
let {
id,
ariaDescribedBy = undefined,
checked = $bindable(false),
disabled = false,
onToggle = undefined,
}: Props = $props();
const handleToggle = (event: Event) => onToggle?.((event.target as HTMLInputElement).checked);
</script>
<label class="relative inline-block h-[10px] w-[36px] flex-none">
<input
{id}
class="disabled::cursor-not-allowed h-0 w-0 opacity-0 peer"
type="checkbox"
bind:checked
onclick={handleToggle}
{disabled}
aria-describedby={ariaDescribedBy}
/>
{#if disabled}
<span
class="slider slider-disabled cursor-not-allowed border border-transparent before:border before:border-transparent"
></span>
{:else}
<span
class="slider slider-enabled cursor-pointer border-2 border-transparent before:border-2 before:border-transparent peer-focus-visible:outline before:peer-focus-visible:outline peer-focus-visible:dark:outline-gray-200 before:peer-focus-visible:dark:outline-gray-200 peer-focus-visible:outline-gray-600 before:peer-focus-visible:outline-gray-600 peer-focus-visible:dark:border-black before:peer-focus-visible:dark:border-black peer-focus-visible:border-white before:peer-focus-visible:border-white"
></span>
{/if}
</label>
<style>
.slider {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: transform 0.4s;
transition: transform 0.4s;
border-radius: 34px;
}
input:disabled {
cursor: not-allowed;
}
.slider:before {
position: absolute;
content: '';
height: 20px;
width: 20px;
left: -2px;
right: 0px;
bottom: -6px;
background-color: gray;
-webkit-transition: transform 0.4s;
transition: transform 0.4s;
border-radius: 50%;
}
input:checked + .slider:before {
-webkit-transform: translateX(18px);
-ms-transform: translateX(18px);
transform: translateX(18px);
background-color: #4250af;
}
input:checked + .slider-disabled {
background-color: gray;
}
input:checked + .slider-enabled {
background-color: #adcbfa;
}
</style>

View File

@ -1,10 +1,10 @@
<script lang="ts">
import { generateId } from '$lib/utils/generate-id';
import { Switch } from '@immich/ui';
import type { Snippet } from 'svelte';
import { t } from 'svelte-i18n';
import { quintOut } from 'svelte/easing';
import { fly } from 'svelte/transition';
import Slider from '$lib/components/elements/slider.svelte';
import { generateId } from '$lib/utils/generate-id';
import { t } from 'svelte-i18n';
import type { Snippet } from 'svelte';
interface Props {
title: string;
@ -54,5 +54,5 @@
{@render children?.()}
</div>
<Slider id={sliderId} bind:checked {disabled} {onToggle} ariaDescribedBy={subtitleId} />
<Switch id={sliderId} bind:checked {disabled} onCheckedChange={onToggle} aria-describedby={subtitleId} />
</div>