58 lines
1.6 KiB
TypeScript
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>
|
|
);
|
|
};
|