"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const seemly_1 = require("seemly");
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 index_cssr_1 = require("./styles/index.cssr");
const switchProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { size: {
        type: String,
        default: 'medium'
    }, value: {
        type: Boolean,
        default: undefined
    }, loading: Boolean, defaultValue: Boolean, disabled: Boolean, round: {
        type: Boolean,
        default: true
    }, 
    // eslint-disable-next-line vue/prop-name-casing
    'onUpdate:value': [Function, Array], onUpdateValue: [Function, Array], onChange: {
        type: [Function, Array],
        validator: () => {
            if (process.env.NODE_ENV !== 'production') {
                _utils_1.warn('switch', '`on-change` is deprecated, please use `on-update:value` instead.');
            }
            return true;
        },
        default: undefined
    } });
exports.default = vue_1.defineComponent({
    name: 'Switch',
    props: switchProps,
    setup(props) {
        const { mergedClsPrefixRef } = _mixins_1.useConfig(props);
        const themeRef = _mixins_1.useTheme('Switch', 'Switch', index_cssr_1.default, styles_1.switchLight, props, mergedClsPrefixRef);
        const formItem = _mixins_1.useFormItem(props);
        const { mergedSizeRef } = formItem;
        const uncontrolledValueRef = vue_1.ref(props.defaultValue);
        const controlledValueRef = vue_1.toRef(props, 'value');
        const mergedValueRef = vooks_1.useMergedState(controlledValueRef, uncontrolledValueRef);
        const pressedRef = vue_1.ref(false);
        function doUpdateValue(value) {
            const { 'onUpdate:value': _onUpdateValue, onChange, onUpdateValue } = props;
            const { nTriggerFormInput, nTriggerFormChange } = formItem;
            if (_onUpdateValue)
                _utils_1.call(_onUpdateValue, value);
            if (onUpdateValue)
                _utils_1.call(onUpdateValue, value);
            if (onChange)
                _utils_1.call(onChange, value);
            uncontrolledValueRef.value = value;
            nTriggerFormInput();
            nTriggerFormChange();
        }
        function doFocus() {
            const { nTriggerFormFocus } = formItem;
            nTriggerFormFocus();
        }
        function doBlur() {
            const { nTriggerFormBlur } = formItem;
            nTriggerFormBlur();
        }
        function handleClick() {
            if (!props.disabled) {
                doUpdateValue(!mergedValueRef.value);
            }
        }
        function handleFocus() {
            doFocus();
        }
        function handleBlur() {
            doBlur();
            pressedRef.value = false;
        }
        function handleKeyup(e) {
            if (e.code === 'Space') {
                doUpdateValue(!mergedValueRef.value);
                pressedRef.value = false;
            }
        }
        function handleKeydown(e) {
            if (e.code === 'Space') {
                e.preventDefault();
                pressedRef.value = true;
            }
        }
        return {
            handleClick,
            handleBlur,
            handleFocus,
            handleKeyup,
            handleKeydown,
            pressed: pressedRef,
            mergedClsPrefix: mergedClsPrefixRef,
            mergedValue: mergedValueRef,
            cssVars: vue_1.computed(() => {
                const { value: size } = mergedSizeRef;
                const { self: { opacityDisabled, railColor, railColorActive, buttonBoxShadow, buttonColor, boxShadowFocus, loadingColor, textColor, [_utils_1.createKey('buttonHeight', size)]: buttonHeight, [_utils_1.createKey('buttonWidth', size)]: buttonWidth, [_utils_1.createKey('buttonWidthPressed', size)]: buttonWidthPressed, [_utils_1.createKey('railHeight', size)]: railHeight, [_utils_1.createKey('railWidth', size)]: railWidth, [_utils_1.createKey('railBorderRadius', size)]: railBorderRadius, [_utils_1.createKey('buttonBorderRadius', size)]: buttonBorderRadius }, common: { cubicBezierEaseInOut } } = themeRef.value;
                const offset = seemly_1.pxfy((seemly_1.depx(railHeight) - seemly_1.depx(buttonHeight)) / 2);
                const height = seemly_1.pxfy(Math.max(seemly_1.depx(railHeight), seemly_1.depx(buttonHeight)));
                const width = seemly_1.depx(railHeight) > seemly_1.depx(buttonHeight)
                    ? railWidth
                    : seemly_1.pxfy(seemly_1.depx(railWidth) + seemly_1.depx(buttonHeight) - seemly_1.depx(railHeight));
                return {
                    '--bezier': cubicBezierEaseInOut,
                    '--button-border-radius': buttonBorderRadius,
                    '--button-box-shadow': buttonBoxShadow,
                    '--button-color': buttonColor,
                    '--button-width': buttonWidth,
                    '--button-width-pressed': buttonWidthPressed,
                    '--button-height': buttonHeight,
                    '--height': height,
                    '--offset': offset,
                    '--opacity-disabled': opacityDisabled,
                    '--rail-border-radius': railBorderRadius,
                    '--rail-color': railColor,
                    '--rail-color-active': railColorActive,
                    '--rail-height': railHeight,
                    '--rail-width': railWidth,
                    '--width': width,
                    '--box-shadow-focus': boxShadowFocus,
                    '--loading-color': loadingColor,
                    '--text-color': textColor
                };
            })
        };
    },
    render() {
        const { mergedClsPrefix, mergedValue, $slots } = this;
        const { checked: checkedSlot, unchecked: uncheckedSlot } = $slots;
        return (vue_1.h("div", { role: "switch", "aria-checked": mergedValue, class: [
                `${mergedClsPrefix}-switch`,
                {
                    [`${mergedClsPrefix}-switch--active`]: mergedValue,
                    [`${mergedClsPrefix}-switch--disabled`]: this.disabled,
                    [`${mergedClsPrefix}-switch--round`]: this.round,
                    [`${mergedClsPrefix}-switch--pressed`]: this.pressed
                }
            ], tabindex: !this.disabled ? 0 : undefined, style: this.cssVars, onClick: this.handleClick, onFocus: this.handleFocus, onBlur: this.handleBlur, onKeyup: this.handleKeyup, onKeydown: this.handleKeydown },
            vue_1.h("div", { class: `${mergedClsPrefix}-switch__rail`, "aria-hidden": "true" },
                (checkedSlot || uncheckedSlot) && (vue_1.h("div", { "aria-hidden": true, class: `${mergedClsPrefix}-switch__children-placeholder` },
                    vue_1.h("div", { class: `${mergedClsPrefix}-switch__rail-placeholder` },
                        vue_1.h("div", { class: `${mergedClsPrefix}-switch__button-placeholder` }), checkedSlot === null || checkedSlot === void 0 ? void 0 :
                        checkedSlot()),
                    vue_1.h("div", { class: `${mergedClsPrefix}-switch__rail-placeholder` },
                        vue_1.h("div", { class: `${mergedClsPrefix}-switch__button-placeholder` }), uncheckedSlot === null || uncheckedSlot === void 0 ? void 0 :
                        uncheckedSlot()))),
                vue_1.h("div", { class: `${mergedClsPrefix}-switch__button` },
                    vue_1.h(vue_1.Transition, { name: "fade-in-scale-up-transition" }, {
                        default: () => this.loading ? (vue_1.h(_internal_1.NBaseLoading, { key: "loading", clsPrefix: mergedClsPrefix, strokeWidth: 20 })) : null
                    }),
                    checkedSlot && (vue_1.h("div", { key: "checked", class: `${mergedClsPrefix}-switch__checked` }, checkedSlot())),
                    uncheckedSlot && (vue_1.h("div", { key: "unchecked", class: `${mergedClsPrefix}-switch__unchecked` }, uncheckedSlot()))))));
    }
});
