Files
gridpilot.gg/apps/website/ui/Toggle.tsx
2026-01-18 23:24:30 +01:00

58 lines
1.6 KiB
TypeScript

import { Box } from './Box';
import { Text } from './Text';
export interface ToggleProps {
label: string;
description?: string;
checked: boolean;
onChange: (checked: boolean) => void;
disabled?: boolean;
}
export const Toggle = ({
label,
description,
checked,
onChange,
disabled = false
}: ToggleProps) => {
return (
<Box
as="label"
display="flex"
alignItems="center"
justifyContent="between"
paddingY={3}
borderBottom
style={{ cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1 }}
>
<Box flex={1} paddingRight={4}>
<Text weight="medium" variant="high" block>{label}</Text>
{description && (
<Text size="xs" variant="low" block marginTop={1}>
{description}
</Text>
)}
</Box>
<button
type="button"
role="switch"
aria-checked={checked}
onClick={() => !disabled && onChange(!checked)}
disabled={disabled}
className={`relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none ${
checked ? 'bg-[var(--ui-color-intent-primary)]' : 'bg-[var(--ui-color-bg-surface-muted)]'
}`}
>
<span
aria-hidden="true"
className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out ${
checked ? 'translate-x-5' : 'translate-x-0'
}`}
/>
</button>
</Box>
);
};