bolt.diy/app/components/ui/SettingsSlider.tsx

64 lines
1.7 KiB
TypeScript
Raw Normal View History

2024-12-07 15:27:50 +00:00
import { motion } from 'framer-motion';
import { memo } from 'react';
import { classNames } from '~/utils/classNames';
import '~/styles/components/SettingsSlider.scss';
2024-12-07 15:27:50 +00:00
interface SliderOption<T> {
value: T;
text: string;
}
export interface SliderOptions<T> {
left: SliderOption<T>;
right: SliderOption<T>;
}
interface SettingsSliderProps<T> {
selected: T;
options: SliderOptions<T>;
setSelected?: (selected: T) => void;
}
export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: SettingsSliderProps<T>) => {
const isLeftSelected = selected === options.left.value;
return (
<div className="settings-slider">
2024-12-07 15:27:50 +00:00
<motion.div
className={classNames(
'settings-slider__thumb',
isLeftSelected ? 'settings-slider__thumb--left' : 'settings-slider__thumb--right'
2024-12-07 15:27:50 +00:00
)}
initial={false}
animate={{
x: isLeftSelected ? 0 : '100%',
2024-12-07 15:53:33 +00:00
opacity: 0.2,
2024-12-07 15:27:50 +00:00
}}
transition={{
type: 'spring',
stiffness: 300,
2024-12-07 15:53:33 +00:00
damping: 30,
2024-12-07 15:27:50 +00:00
}}
/>
<button
onClick={() => setSelected?.(options.left.value)}
className={classNames(
'settings-slider__button',
isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected'
2024-12-07 15:27:50 +00:00
)}
>
{options.left.text}
</button>
<button
onClick={() => setSelected?.(options.right.value)}
className={classNames(
'settings-slider__button',
!isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected'
2024-12-07 15:27:50 +00:00
)}
>
{options.right.text}
</button>
</div>
);
2024-12-07 15:53:33 +00:00
});