/**
 * @license MIT
 * author: Cube Dev Team
 * @cube-dev/ui-kit v0.0.0-canary-032998c
 * Released under the MIT license.
 */

import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useFocusableRef } from '@react-spectrum/utils';
import { IconCheck, IconMinus } from '@tabler/icons-react';
import { forwardRef, useContext, useMemo, useRef } from 'react';
import { useCheckbox, useCheckboxGroupItem, useHover, } from 'react-aria';
import { useToggleState } from 'react-stately';
import { Icon } from '../../../icons/index.js';
import { useProviderProps } from '../../../provider.js';
import { CONTAINER_STYLES, Element, extractStyles, filterBaseProps, tasty, } from '../../../tasty/index.js';
import { mergeProps } from '../../../utils/react/index.js';
import { useFocus } from '../../../utils/react/interactions.js';
import { castNullableIsSelected, } from '../../../utils/react/nullableValue.js';
import { Text } from '../../content/Text.js';
import { INLINE_LABEL_STYLES, LABEL_STYLES, useFieldProps, useFormProps, wrapWithField, } from '../../form/index.js';
import { HiddenInput } from '../../HiddenInput.js';
import { CheckboxGroup } from './CheckboxGroup.js';
import { CheckboxGroupContext } from './context.js';
const CheckboxWrapperElement = tasty({
    as: 'label',
    qa: 'CheckboxWrapper',
    styles: {
        position: 'relative',
        display: 'flex',
        placeItems: 'center start',
        placeContent: 'baseline',
        gap: '1x',
        flow: 'row',
        preset: 'default',
        cursor: '$pointer',
        width: 'max max-content',
        color: '#dark-02',
    },
});
const CheckboxElement = tasty({
    qa: 'Checkbox',
    styles: {
        display: 'grid',
        placeItems: 'center',
        radius: '.5r',
        fill: {
            '': '#white',
            'checked | indeterminate': '#primary',
            'invalid & !checked': '#white',
            'invalid & checked': '#danger',
            disabled: '#dark.12',
        },
        color: {
            '': '#white',
            'disabled & !checked & !indeterminate': '#clear',
        },
        border: {
            '': '#dark.30',
            invalid: '#danger',
            'disabled | ((indeterminate | checked) & !invalid)': '#clear',
        },
        width: '(2x - 2bw)',
        height: '(2x - 2bw)',
        outline: {
            '': '#primary-text.0',
            focused: '1bw #primary-text',
        },
        outlineOffset: 1,
        transition: 'theme',
    },
});
function Checkbox(props, 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 groupState = useContext(CheckboxGroupContext);
    props = castNullableIsSelected(props);
    let originalProps = props;
    props = useProviderProps(props);
    props = useFormProps(props);
    props = useFieldProps(props, {
        defaultValidationTrigger: 'onChange',
        valuePropsMapper: ({ value, onChange }) => ({
            isSelected: value ?? false,
            isIndeterminate: false,
            onChange: onChange,
        }),
        unsafe__isDisabled: !!groupState,
    });
    let { qa, isIndeterminate = false, isDisabled = false, insideForm, isRequired, children, label, validationState, labelProps, labelStyles, labelPosition, inputStyles, isHidden, form, ...otherProps } = props;
    let styles = extractStyles(props, CONTAINER_STYLES);
    labelStyles = useMemo(() => ({
        ...(!groupState ? LABEL_STYLES : INLINE_LABEL_STYLES),
        ...labelStyles,
    }), [groupState, labelStyles]);
    let { isFocused, focusProps } = useFocus({ isDisabled }, true);
    let { hoverProps, isHovered } = useHover({ isDisabled });
    let inputRef = useRef(null);
    let domRef = useFocusableRef(ref, inputRef);
    const toggleState = useToggleState(props);
    let { inputProps } = groupState
        ? useCheckboxGroupItem({
            ...props,
            // Value is optional for standalone checkboxes, but required for CheckboxGroup items;
            // it's passed explicitly here to avoid typescript error (requires strictNullChecks disabled).
            value: props.value || '',
            // Only pass isRequired and validationState to react-aria if they came from
            // the props for this individual checkbox, and not from the group via context.
            isRequired: originalProps.isRequired,
            validationState: originalProps.validationState,
        }, groupState, inputRef)
        : useCheckbox({
            ...props,
            ...(typeof label === 'string' && label.trim()
                ? { 'aria-label': label }
                : {}),
        }, toggleState, inputRef);
    let markIcon = isIndeterminate ? (_jsx(Icon, { size: 12, stroke: 3, children: _jsx(IconMinus, {}) })) : (_jsx(Icon, { size: 12, stroke: 3, children: _jsx(IconCheck, {}) }));
    if (groupState) {
        for (let key of ['isSelected', 'defaultSelected', 'isEmphasized']) {
            if (originalProps[key] != null) {
                console.warn(`CubeUIKit: ${key} is unsupported on individual <Checkbox> elements within a <CheckboxGroup>. Please apply these props to the group instead.`);
            }
        }
        if (props.value == null) {
            console.warn('CubeUIKit: A <Checkbox> element within a <CheckboxGroup> requires a `value` property.');
        }
    }
    const mods = {
        checked: inputProps.checked,
        indeterminate: isIndeterminate,
        invalid: validationState === 'invalid',
        valid: validationState === 'valid',
        disabled: isDisabled,
        hovered: isHovered,
        focused: isFocused,
        'side-label': labelPosition === 'side',
        'inside-form': insideForm,
    };
    const checkbox = (_jsxs(_Fragment, { children: [_jsx(HiddenInput, { qa: qa || 'Checkbox', "data-input-type": "checkbox", ...mergeProps(inputProps, focusProps), ref: inputRef }), _jsx(CheckboxElement, { mods: mods, styles: inputStyles, children: markIcon })] }));
    const checkboxField = (_jsxs(CheckboxWrapperElement, { isHidden: isHidden, mods: mods, children: [checkbox, children && _jsx(Text, { nowrap: true, children: children })] }));
    if (!groupState) {
        return wrapWithField(checkboxField, domRef, {
            ...props,
            children: null,
            inputStyles,
        });
    }
    return (_jsxs(CheckboxWrapperElement, { styles: styles, isHidden: isHidden, ...hoverProps, ...filterBaseProps(otherProps), ref: domRef, children: [checkbox, (label ?? children) ? (_jsx(Element, { styles: labelStyles, mods: {
                    invalid: validationState === 'invalid',
                    valid: validationState === 'valid',
                    disabled: isDisabled,
                }, ...filterBaseProps(labelProps), children: label ?? children })) : null] }));
}
/**
 * Checkboxes allow users to select multiple items from a list of individual items,
 * or to mark one individual item as selected.
 */
let _Checkbox = forwardRef(Checkbox);
_Checkbox.cubeInputType = 'Checkbox';
let __Checkbox = Object.assign(_Checkbox, { Group: CheckboxGroup });
__Checkbox.displayName = 'Checkbox';
export { __Checkbox as Checkbox };
export { useCheckbox };

        