import React, { useCallback, useEffect, useMemo, useState } from 'react' import useTheme from '../use-theme' import { NormalTypes } from '../utils/prop-types' import { getColors } from './styles' import useScaleable, { withScaleable } from '../use-scaleable' export type ToggleTypes = NormalTypes export interface ToggleEventTarget { checked: boolean } export interface ToggleEvent { target: ToggleEventTarget stopPropagation: () => void preventDefault: () => void nativeEvent: React.ChangeEvent } interface Props { checked?: boolean initialChecked?: boolean onChange?: (ev: ToggleEvent) => void disabled?: boolean type?: ToggleTypes className?: string } const defaultProps = { type: 'default' as ToggleTypes, disabled: false, initialChecked: false, className: '', } type NativeAttrs = Omit, keyof Props> export type ToggleProps = Props & NativeAttrs export type ToggleSize = { width: string height: string } const ToggleComponent: React.FC = ({ initialChecked, checked, disabled, onChange, type, className, ...props }: ToggleProps & typeof defaultProps) => { const theme = useTheme() const { SCALES } = useScaleable() const [selfChecked, setSelfChecked] = useState(initialChecked) const changeHandle = useCallback( (ev: React.ChangeEvent) => { if (disabled) return const selfEvent: ToggleEvent = { target: { checked: !selfChecked, }, stopPropagation: ev.stopPropagation, preventDefault: ev.preventDefault, nativeEvent: ev, } setSelfChecked(!selfChecked) onChange && onChange(selfEvent) }, [disabled, selfChecked, onChange], ) const { bg } = useMemo(() => getColors(theme.palette, type), [theme.palette, type]) useEffect(() => { if (checked === undefined) return setSelfChecked(checked) }, [checked]) return ( ) } ToggleComponent.defaultProps = defaultProps ToggleComponent.displayName = 'GeistToggle' const Toggle = withScaleable(ToggleComponent) export default Toggle