import React, { useContext, memo, forwardRef } from 'react';
import { mergeRefs } from './../../../utils';
import { usePropsResolution } from '../../../hooks/useThemeProps';
import { Center } from '../../composites/Center';
import { useFormControlContext } from '../../composites/FormControl';
import Box from '../Box';
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';
import { CheckIcon } from '../Icon/Icons';
const Checkbox = (
{ children, icon, wrapperRef, ...props }: ICheckboxProps,
ref: any
) => {
const formControlContext = useFormControlContext();
const checkboxGroupContext = React.useContext(CheckboxGroupContext);
const {
_interactionBox: {
_hover: _iterationBoxHover,
_focus: _iterationBoxFocus,
_disabled: _iterationBoxDisabled,
..._interactionBox
},
_checkbox: {
_checked: _checkboxChecked,
_disabled: _checkboxDisabled,
_invalid: _checkboxInvalid,
..._checkbox
},
_icon,
isInvalid,
...themedProps
} = usePropsResolution('Checkbox', {
...checkboxGroupContext,
...formControlContext,
...props,
});
const _ref = React.useRef();
const mergedRef = mergeRefs([ref, _ref]);
const state = useToggleState({
...props,
defaultSelected: props.defaultIsChecked,
isSelected: props.isChecked,
});
const 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.
const { inputProps } = groupState
? // eslint-disable-next-line react-hooks/rules-of-hooks
useCheckboxGroupItem(
{
...themedProps,
'aria-label': themedProps.accessibilityLabel,
'value': themedProps.value,
},
groupState.state,
//@ts-ignore
mergedRef
)
: // eslint-disable-next-line react-hooks/rules-of-hooks
useCheckbox(
{ ...themedProps, 'aria-label': themedProps.accessibilityLabel },
state,
//@ts-ignore
mergedRef
);
const { checked, disabled } = inputProps;
const sizedIcon = icon
? () =>
React.cloneElement(
icon,
{
..._icon,
},
icon.props.children
)
: null;
const { focusProps, isFocusVisible } = useFocusRing();
const component = (
{/* Interaction Box */}
{/* Checkbox */}
{icon && sizedIcon && checked ? (
sizedIcon()
) : (
)}
{children}
);
return (
{component}
);
};
export default memo(forwardRef(Checkbox));