"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const vooks_1 = require("vooks");
const _mixins_1 = require("../../_mixins");
const _internal_1 = require("../../_internal");
const _utils_1 = require("../../_utils");
const styles_1 = require("../styles");
const CheckMark_1 = require("./CheckMark");
const LineMark_1 = require("./LineMark");
const CheckboxGroup_1 = require("./CheckboxGroup");
const index_cssr_1 = require("./styles/index.cssr");
const checkboxProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { size: String, checked: {
        type: Boolean,
        default: undefined
    }, defaultChecked: Boolean, value: [String, Number], disabled: Boolean, indeterminate: Boolean, label: String, focusable: {
        type: Boolean,
        default: true
    }, 
    // eslint-disable-next-line vue/prop-name-casing
    'onUpdate:checked': [Function, Array], onUpdateChecked: [Function, Array], 
    // private
    privateTableHeader: Boolean, 
    // deprecated
    onChange: {
        type: [Function, Array],
        validator: () => {
            _utils_1.warn('checkbox', '`on-change` is deprecated, please use `on-update:checked` instead.');
            return true;
        },
        default: undefined
    } });
exports.default = vue_1.defineComponent({
    name: 'Checkbox',
    props: checkboxProps,
    setup(props) {
        const { mergedClsPrefixRef } = _mixins_1.useConfig(props);
        const NCheckboxGroup = vue_1.inject(CheckboxGroup_1.checkboxGroupInjectionKey, null);
        const uncontrolledCheckedRef = vue_1.ref(props.defaultChecked);
        const controlledCheckedRef = vue_1.toRef(props, 'checked');
        const mergedCheckedRef = vooks_1.useMergedState(controlledCheckedRef, uncontrolledCheckedRef);
        const renderedCheckedRef = vooks_1.useMemo(() => {
            if (NCheckboxGroup) {
                const groupValueSet = NCheckboxGroup.valueSetRef.value;
                if (groupValueSet && props.value !== undefined) {
                    return groupValueSet.has(props.value);
                }
                return false;
            }
            else {
                return mergedCheckedRef.value;
            }
        });
        const mergedDisabledRef = vooks_1.useMemo(() => {
            if (props.disabled)
                return true;
            if (NCheckboxGroup) {
                if (NCheckboxGroup.disabledRef.value)
                    return true;
                const { maxRef: { value: max }, checkedCountRef } = NCheckboxGroup;
                if (max !== undefined &&
                    checkedCountRef.value >= max &&
                    !renderedCheckedRef.value) {
                    return true;
                }
                const { minRef: { value: min } } = NCheckboxGroup;
                if (min !== undefined &&
                    checkedCountRef.value <= min &&
                    renderedCheckedRef.value) {
                    return true;
                }
            }
            return false;
        });
        const formItem = _mixins_1.useFormItem(props, {
            mergedSize(NFormItem) {
                const { size } = props;
                if (size !== undefined)
                    return size;
                if (NCheckboxGroup) {
                    const { value: mergedSize } = NCheckboxGroup.mergedSizeRef;
                    if (mergedSize !== undefined) {
                        return mergedSize;
                    }
                }
                if (NFormItem) {
                    const { mergedSize } = NFormItem;
                    if (mergedSize !== undefined)
                        return mergedSize.value;
                }
                return 'medium';
            }
        });
        const { mergedSizeRef } = formItem;
        const themeRef = _mixins_1.useTheme('Checkbox', 'Checkbox', index_cssr_1.default, styles_1.checkboxLight, props, mergedClsPrefixRef);
        function toggle() {
            if (NCheckboxGroup && props.value !== undefined) {
                NCheckboxGroup.toggleCheckbox(!renderedCheckedRef.value, props.value);
            }
            else {
                const { onChange, 'onUpdate:checked': _onUpdateCheck, onUpdateChecked } = props;
                const { nTriggerFormInput, nTriggerFormChange } = formItem;
                const nextChecked = !renderedCheckedRef.value;
                if (_onUpdateCheck)
                    _utils_1.call(_onUpdateCheck, nextChecked);
                if (onUpdateChecked)
                    _utils_1.call(onUpdateChecked, nextChecked);
                if (onChange)
                    _utils_1.call(onChange, nextChecked); // deprecated
                nTriggerFormInput();
                nTriggerFormChange();
                uncontrolledCheckedRef.value = nextChecked;
            }
        }
        function handleClick() {
            if (!mergedDisabledRef.value) {
                toggle();
            }
        }
        function handleKeyUp(e) {
            if (mergedDisabledRef.value)
                return;
            switch (e.code) {
                case 'Space':
                case 'Enter':
                case 'NumpadEnter':
                    toggle();
            }
        }
        function handleKeyDown(e) {
            switch (e.code) {
                case 'Space':
                    e.preventDefault();
            }
        }
        return Object.assign(formItem, {
            mergedClsPrefix: mergedClsPrefixRef,
            mergedDisabled: mergedDisabledRef,
            renderedChecked: renderedCheckedRef,
            mergedTheme: themeRef,
            handleClick,
            handleKeyUp,
            handleKeyDown,
            cssVars: vue_1.computed(() => {
                const { value: mergedSize } = mergedSizeRef;
                const { common: { cubicBezierEaseInOut }, self: { borderRadius, color, colorChecked, colorDisabled, colorTableHeader, colorTableHeaderModal, colorTableHeaderPopover, checkMarkColor, checkMarkColorDisabled, border, borderFocus, borderDisabled, borderChecked, boxShadowFocus, textColor, textColorDisabled, checkMarkColorDisabledChecked, colorDisabledChecked, borderDisabledChecked, labelPadding, [_utils_1.createKey('fontSize', mergedSize)]: fontSize, [_utils_1.createKey('size', mergedSize)]: size } } = themeRef.value;
                return {
                    '--size': size,
                    '--bezier': cubicBezierEaseInOut,
                    '--border-radius': borderRadius,
                    '--border': border,
                    '--border-checked': borderChecked,
                    '--border-focus': borderFocus,
                    '--border-disabled': borderDisabled,
                    '--border-disabled-checked': borderDisabledChecked,
                    '--box-shadow-focus': boxShadowFocus,
                    '--color': color,
                    '--color-checked': colorChecked,
                    '--color-table-header': colorTableHeader,
                    '--color-table-header-modal': colorTableHeaderModal,
                    '--color-table-header-popover': colorTableHeaderPopover,
                    '--color-disabled': colorDisabled,
                    '--color-disabled-checked': colorDisabledChecked,
                    '--text-color': textColor,
                    '--text-color-disabled': textColorDisabled,
                    '--check-mark-color': checkMarkColor,
                    '--check-mark-color-disabled': checkMarkColorDisabled,
                    '--check-mark-color-disabled-checked': checkMarkColorDisabledChecked,
                    '--font-size': fontSize,
                    '--label-padding': labelPadding
                };
            })
        });
    },
    render() {
        const { $slots, renderedChecked, mergedDisabled, indeterminate, privateTableHeader, cssVars, label, mergedClsPrefix, focusable, handleKeyUp, handleKeyDown, handleClick } = this;
        return (vue_1.h("div", { class: [
                `${mergedClsPrefix}-checkbox`,
                {
                    [`${mergedClsPrefix}-checkbox--checked`]: renderedChecked,
                    [`${mergedClsPrefix}-checkbox--disabled`]: mergedDisabled,
                    [`${mergedClsPrefix}-checkbox--indeterminate`]: indeterminate,
                    [`${mergedClsPrefix}-checkbox--table-header`]: privateTableHeader
                }
            ], tabindex: mergedDisabled || !focusable ? undefined : 0, style: cssVars, onKeyup: handleKeyUp, onKeydown: handleKeyDown, onClick: handleClick },
            vue_1.h("div", { class: `${mergedClsPrefix}-checkbox-box` },
                vue_1.h(_internal_1.NIconSwitchTransition, null, {
                    default: () => this.indeterminate ? (vue_1.h("div", { key: "indeterminate", class: `${mergedClsPrefix}-checkbox-icon` }, LineMark_1.default)) : (vue_1.h("div", { key: "check", class: `${mergedClsPrefix}-checkbox-icon` }, CheckMark_1.default))
                }),
                vue_1.h("div", { class: `${mergedClsPrefix}-checkbox-box__border` })),
            label !== null || $slots.default ? (vue_1.h("span", { class: `${mergedClsPrefix}-checkbox__label` }, vue_1.renderSlot($slots, 'default', undefined, () => [label]))) : null));
    }
});
