<script setup lang="ts">
import { useId } from 'vue'

defineProps<{
	label?: string
}>()

const model = defineModel<boolean>()
const id = useId()

const toggle = (e: MouseEvent) => {
	model.value = !model.value
}
</script>

<template>
	<div class="toggle-wrapper" @click.stop="toggle">
		<div class="label" v-if="label" :id="`${id}-label`">{{ label }}</div>
		<button
			type="button"
			role="switch"
			:aria-checked="model"
			:aria-labelledby="label ? `${id}-label` : undefined"
			class="toggle-track"
			:class="{ 'is-checked': model }"
		>
			<span class="toggle-thumb"></span>
		</button>
	</div>
</template>

<style scoped lang="scss">
@use '@/assets/variables' as *;

.toggle-wrapper {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	cursor: pointer;
}

.label {
	color: hsl(var(--text));
	font-weight: 500;
}

.toggle-track {
	display: inline-flex;
	width: 3rem;
	height: 1.75rem;
	background-color: hsla(var(--surface1) / 0.85);
	border-radius: 1rem;
	border: none;
	position: relative;
	cursor: pointer;
	flex-shrink: 0;

	box-sizing: unset;

	transition-timing-function: $ease-spring;
	transition-duration: 0.3s;
	outline-width: 4px;
	outline-offset: -1px;

	&:active,
	&:focus-visible {
		.toggle-thumb {
			transform: translateX(0.1rem);
			background-color: hsl(var(--base) / 0.8);
		}
	}

	&:focus-visible {
		outline-color: hsl(var(--accent));
		outline-offset: -1px;
	}

	&:hover {
		background-color: hsla(var(--surface1) / 1);
	}

	&:active {
		.toggle-thumb {
			width: calc(var(--width) + var(--pressed-grow));
		}
	}

	&.is-checked {
		background: hsl(var(--accent));

		.toggle-thumb {
			transform: translateX(1.25rem);
		}
		.toggle-label {
			color: hsl(var(--text));
		}

		&:active {
			.toggle-thumb {
				transform: translateX(calc(1.15rem - (var(--pressed-grow))));
			}
		}
	}
}

.toggle-thumb {
	--width: 1.35rem;
	--pressed-grow: 0.4rem;

	position: absolute;
	top: 0.2rem;
	left: 0.2rem;
	width: var(--width);
	height: 1.35rem;
	background: hsl(var(--base));
	border-radius: 2rem;

	transition-timing-function: $ease-spring;
	transition-duration: 0.3s;
	transition-property: $transition-properties, width;
}
</style>
