website refactor

This commit is contained in:
2026-01-18 17:55:04 +01:00
parent 489deb2991
commit 9ffe47da37
75 changed files with 1596 additions and 1259 deletions

View File

@@ -1,68 +1,74 @@
import { motion } from 'framer-motion';
import React from 'react';
import { Box } from './primitives/Box';
import { Text } from './Text';
import { motion } from 'framer-motion';
interface ToggleProps {
checked: boolean;
onChange: (checked: boolean) => void;
label: string;
description?: string;
checked: boolean;
onChange: (checked: boolean) => void;
disabled?: boolean;
}
export function Toggle({
checked,
onChange,
label,
description,
disabled = false,
}: ToggleProps) {
export function Toggle({ label, description, checked, onChange, disabled }: ToggleProps) {
return (
<label className={`flex items-start justify-between cursor-pointer py-3 border-b border-charcoal-outline/50 last:border-b-0 ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}>
<Box style={{ flex: 1, paddingRight: '1rem' }}>
<Box
as="label"
display="flex"
alignItems="start"
justifyContent="between"
cursor={disabled ? 'not-allowed' : 'pointer'}
py={3}
borderBottom
borderColor="border-charcoal-outline/50"
className="last:border-b-0"
opacity={disabled ? 0.5 : 1}
>
<Box flex={1} pr={4}>
<Text weight="medium" color="text-gray-200" block>{label}</Text>
{description && (
<Text size="sm" color="text-gray-500" block mt={1}>{description}</Text>
<Text size="xs" color="text-gray-500" block mt={1}>
{description}
</Text>
)}
</Box>
<button
type="button"
role="switch"
aria-checked={checked}
onClick={() => !disabled && onChange(!checked)}
disabled={disabled}
className={`relative w-12 h-6 rounded-full transition-colors duration-200 flex-shrink-0 focus:outline-none focus:ring-2 focus:ring-primary-blue/50 ${
checked
? 'bg-primary-blue'
: 'bg-iron-gray'
} ${disabled ? 'cursor-not-allowed' : ''}`}
>
{/* Glow effect when active */}
{checked && (
<Box position="relative">
<Box
as="button"
type="button"
role="switch"
aria-checked={checked}
onClick={() => !disabled && onChange(!checked)}
disabled={disabled}
w="12"
h="6"
rounded="full"
transition="all 0.2s"
flexShrink={0}
ring="primary-blue/50"
bg={checked ? 'bg-primary-blue/20' : 'bg-charcoal-outline'}
className="focus:outline-none focus:ring-2"
>
<motion.div
className="absolute inset-0 rounded-full bg-primary-blue"
initial={{ boxShadow: '0 0 0px rgba(25, 140, 255, 0)' }}
animate={{ boxShadow: '0 0 12px rgba(25, 140, 255, 0.4)' }}
transition={{ duration: 0.2 }}
animate={{
opacity: checked ? 1 : 0,
boxShadow: checked ? '0 0 10px rgba(25, 140, 255, 0.4)' : '0 0 0px rgba(25, 140, 255, 0)'
}}
/>
)}
{/* Knob */}
<motion.span
</Box>
<motion.span
className="absolute top-0.5 w-5 h-5 bg-white rounded-full shadow-md"
initial={false}
animate={{
x: checked ? 24 : 2,
scale: 1,
}}
whileTap={{ scale: disabled ? 1 : 0.9 }}
transition={{
type: 'spring',
stiffness: 500,
damping: 30,
left: checked ? '26px' : '2px',
}}
transition={{ type: "spring", stiffness: 500, damping: 30 }}
/>
</button>
</label>
</Box>
</Box>
);
}