// @flow strict import * as React from 'react'; import classify from '../../utils/classify'; import css from './Toggle.module.css'; /** * Note: * Do not wrap Toggle in a label. For simplicity's sake, Toggle uses an * internal label tag to handle click delegation to the hidden input, and * nesting labels is a bad idea. */ type ClassNames = $ReadOnly<{wrapper?: string, label?: string}>; export type ToggleProps = { name?: string, classNames?: ClassNames, children?: React.Node, checked?: boolean, onChange?: ({value: string, checked: boolean}) => mixed, disabled?: boolean, focused?: boolean, value?: string, ariaLabel?: string, labelPosition?: 'left' | 'right', }; export const Toggle: React$AbstractComponent = React.forwardRef( ( { name = 'toggle', value = '', classNames, children, disabled, checked, focused, onChange, ariaLabel, labelPosition = 'right', ...props }: ToggleProps, forwardRef, ): React.Node => { const toggleInput = React.createRef(); React.useImperativeHandle(forwardRef, () => toggleInput.current); const handleOnChange = () => { if (!disabled) { onChange && onChange({ value, checked: !checked, }); } }; const onWrapClickHandler = (e) => { e.nativeEvent.stopImmediatePropagation(); toggleInput.current?.click(); }; React.useEffect(() => { if (toggleInput.current && focused) { toggleInput.current.focus(); } }, [focused]); return (
{labelPosition === 'left' && React.Children.count(children) > 0 && (
{children}
)} {labelPosition === 'right' && React.Children.count(children) > 0 && (
{children}
)}
); }, );