import React, { useContext } from 'react'; import { TouchableOpacity, Platform, TouchableOpacityProps, } from 'react-native'; import { mergeRefs } from './../../../utils'; import { useThemeProps } from '../../../hooks'; import { Center } from '../../composites/Center'; import { FormControlContext, IFormControlContext, } from '../../composites/FormControl'; import Box from '../Box'; import Icon from '../Icon'; import type { ICheckboxProps } from './types'; import { useToggleState } from '@react-stately/toggle'; import { VisuallyHidden } from '@react-aria/visually-hidden'; import { CheckboxGroupContext } from './CheckboxGroup'; import { useHover } from '@react-native-aria/interactions'; import { useCheckbox, useCheckboxGroupItem } from '@react-native-aria/checkbox'; import { useFocusRing } from '@react-native-aria/focus'; const Checkbox = ({ icon, ...props }: ICheckboxProps, ref: any) => { const formControlContext: IFormControlContext = React.useContext( FormControlContext ); const checkboxGroupContext = React.useContext(CheckboxGroupContext); const { activeColor, borderColor, iconColor, size, ...newProps } = useThemeProps('Checkbox', { ...checkboxGroupContext, ...formControlContext, ...props, }); let _ref = React.useRef(); const mergedRef = mergeRefs([ref, _ref]); let state = useToggleState({ ...props, defaultSelected: props.defaultIsChecked, isSelected: props.isChecked, }); let groupState = useContext(CheckboxGroupContext); const { isHovered } = useHover({}, _ref); // Swap hooks depending on whether this checkbox is inside a CheckboxGroup. // This is a bit unorthodox. Typically, hooks cannot be called in a conditional, // but since the checkbox won't move in and out of a group, it should be safe. let { inputProps } = groupState ? // eslint-disable-next-line react-hooks/rules-of-hooks useCheckboxGroupItem( { ...newProps, value: newProps.value, }, groupState.state, //@ts-ignore mergedRef ) : // eslint-disable-next-line react-hooks/rules-of-hooks useCheckbox( newProps, state, //@ts-ignore mergedRef ); const isChecked = inputProps.checked; const isDisabled = inputProps.disabled; const sizedIcon = icon ? () => React.cloneElement( icon, { size, color: icon.props.color ? icon.props.color : iconColor, }, icon.props.children ) : null; const outlineColor = isHovered && !isDisabled ? activeColor : isChecked ? isDisabled ? borderColor : activeColor : borderColor; const component = (
{icon && sizedIcon && isChecked ? ( sizedIcon() ) : ( )}
{props.children}
); const { focusProps, isFocusVisible } = useFocusRing(); return ( <> {Platform.OS === 'web' ? ( {component} ) : ( {component} )} ); }; export default React.memo(React.forwardRef(Checkbox));