import * as React from 'react'; import { useSpring, animated } from 'react-spring'; import { SVGUniqueID } from 'react-svg-unique-id'; export const defaultProperties = { dark: { circle: { r: 9, }, mask: { cx: '50%', cy: '23%', }, svg: { transform: 'rotate(40deg)', }, lines: { opacity: 0, }, }, light: { circle: { r: 5, }, mask: { cx: '100%', cy: 0, }, svg: { transform: 'rotate(90deg)', }, lines: { opacity: 1, }, }, springConfig: { mass: 4, tension: 250, friction: 35 }, }; type SVGProps = Omit, 'onChange'>; interface Props extends SVGProps { onChange: (checked: boolean) => void; checked: boolean; style?: React.CSSProperties; size?: number; animationProperties?: typeof defaultProperties; moonColor?: string; sunColor?: string; } export const DarkModeSwitch: React.FC = ({ onChange, children, checked = false, size = 24, animationProperties = defaultProperties, moonColor = 'white', sunColor = 'black', style, ...rest }) => { const properties = React.useMemo(() => { if (animationProperties !== defaultProperties) { return Object.assign(defaultProperties, animationProperties); } return animationProperties; }, [animationProperties]); const { circle, svg, lines, mask } = properties[checked ? 'dark' : 'light']; const svgContainerProps = useSpring({ ...svg, config: animationProperties.springConfig, }); const centerCircleProps = useSpring({ ...circle, config: animationProperties.springConfig, }); const maskedCircleProps = useSpring({ ...mask, config: animationProperties.springConfig, }); const linesProps = useSpring({ ...lines, config: animationProperties.springConfig, }); const toggle = () => { onChange(!checked); }; return ( ); };