'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var vue = require('vue');
var constants = require('../utils/constants');
var validators = require('../utils/validators');
var util = require('../utils/util');
var form = require('../el-form');

/**
 * Make a map and return a function for checking if a key
 * is in that map.
 * IMPORTANT: all calls of this function must be prefixed with
 * \/\*#\_\_PURE\_\_\*\/
 * So that rollup can tree-shake them if necessary.
 */
const EMPTY_OBJ = (process.env.NODE_ENV !== 'production')
    ? Object.freeze({})
    : {};
const EMPTY_ARR = (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];
const objectToString = Object.prototype.toString;
const toTypeString = (value) => objectToString.call(value);

const useCheckboxGroup = () => {
  const ELEMENT = util.useGlobalConfig();
  const elForm = vue.inject(form.elFormKey, {});
  const elFormItem = vue.inject(form.elFormItemKey, {});
  const checkboxGroup = vue.inject("CheckboxGroup", {});
  const isGroup = vue.computed(() => checkboxGroup && (checkboxGroup == null ? void 0 : checkboxGroup.name) === "ElCheckboxGroup");
  const elFormItemSize = vue.computed(() => {
    return elFormItem.size;
  });
  return {
    isGroup,
    checkboxGroup,
    elForm,
    ELEMENT,
    elFormItemSize,
    elFormItem
  };
};
const useModel = (props) => {
  const selfModel = vue.ref(false);
  const { emit } = vue.getCurrentInstance();
  const { isGroup, checkboxGroup } = useCheckboxGroup();
  const isLimitExceeded = vue.ref(false);
  const store = vue.computed(() => {
    var _a;
    return checkboxGroup ? (_a = checkboxGroup.modelValue) == null ? void 0 : _a.value : props.modelValue;
  });
  const model = vue.computed({
    get() {
      var _a;
      return isGroup.value ? store.value : (_a = props.modelValue) != null ? _a : selfModel.value;
    },
    set(val) {
      var _a;
      if (isGroup.value && Array.isArray(val)) {
        isLimitExceeded.value = false;
        if (checkboxGroup.min !== void 0 && val.length < checkboxGroup.min.value) {
          isLimitExceeded.value = true;
        }
        if (checkboxGroup.max !== void 0 && val.length > checkboxGroup.max.value) {
          isLimitExceeded.value = true;
        }
        isLimitExceeded.value === false && ((_a = checkboxGroup == null ? void 0 : checkboxGroup.changeEvent) == null ? void 0 : _a.call(checkboxGroup, val));
      } else {
        emit(constants.UPDATE_MODEL_EVENT, val);
        selfModel.value = val;
      }
    }
  });
  return {
    model,
    isLimitExceeded
  };
};
const useCheckboxStatus = (props, { model }) => {
  const { isGroup, checkboxGroup, elFormItemSize, ELEMENT } = useCheckboxGroup();
  const focus = vue.ref(false);
  const size = vue.computed(() => {
    var _a;
    return ((_a = checkboxGroup == null ? void 0 : checkboxGroup.checkboxGroupSize) == null ? void 0 : _a.value) || elFormItemSize.value || ELEMENT.size;
  });
  const isChecked = vue.computed(() => {
    const value = model.value;
    if (toTypeString(value) === "[object Boolean]") {
      return value;
    } else if (Array.isArray(value)) {
      return value.includes(props.label);
    } else if (value !== null && value !== void 0) {
      return value === props.trueLabel;
    }
  });
  const checkboxSize = vue.computed(() => {
    var _a;
    const temCheckboxSize = props.size || elFormItemSize.value || ELEMENT.size;
    return isGroup.value ? ((_a = checkboxGroup == null ? void 0 : checkboxGroup.checkboxGroupSize) == null ? void 0 : _a.value) || temCheckboxSize : temCheckboxSize;
  });
  return {
    isChecked,
    focus,
    size,
    checkboxSize
  };
};
const useDisabled = (props, { model, isChecked }) => {
  const { elForm, isGroup, checkboxGroup } = useCheckboxGroup();
  const isLimitDisabled = vue.computed(() => {
    var _a, _b;
    const max = (_a = checkboxGroup.max) == null ? void 0 : _a.value;
    const min = (_b = checkboxGroup.min) == null ? void 0 : _b.value;
    return !!(max || min) && (model.value.length >= max && !isChecked.value) || model.value.length <= min && isChecked.value;
  });
  const isDisabled = vue.computed(() => {
    var _a;
    const disabled = props.disabled || elForm.disabled;
    return isGroup.value ? ((_a = checkboxGroup.disabled) == null ? void 0 : _a.value) || disabled || isLimitDisabled.value : props.disabled || elForm.disabled;
  });
  return {
    isDisabled,
    isLimitDisabled
  };
};
const setStoreValue = (props, { model }) => {
  function addToStore() {
    if (Array.isArray(model.value) && !model.value.includes(props.label)) {
      model.value.push(props.label);
    } else {
      model.value = props.trueLabel || true;
    }
  }
  props.checked && addToStore();
};
const useEvent = (props, { isLimitExceeded }) => {
  const { elFormItem } = useCheckboxGroup();
  const { emit } = vue.getCurrentInstance();
  function handleChange(e) {
    var _a, _b;
    if (isLimitExceeded.value)
      return;
    const target = e.target;
    const value = target.checked ? (_a = props.trueLabel) != null ? _a : true : (_b = props.falseLabel) != null ? _b : false;
    emit("change", value, e);
  }
  vue.watch(() => props.modelValue, (val) => {
    var _a;
    (_a = elFormItem.formItemMitt) == null ? void 0 : _a.emit("el.form.change", [val]);
  });
  return {
    handleChange
  };
};
const useCheckbox = (props) => {
  const { model, isLimitExceeded } = useModel(props);
  const { focus, size, isChecked, checkboxSize } = useCheckboxStatus(props, { model });
  const { isDisabled } = useDisabled(props, { model, isChecked });
  const { handleChange } = useEvent(props, { isLimitExceeded });
  setStoreValue(props, { model });
  return {
    isChecked,
    isDisabled,
    checkboxSize,
    model,
    handleChange,
    focus,
    size
  };
};

var script = vue.defineComponent({
  name: "ElCheckbox",
  props: {
    modelValue: {
      type: [Boolean, Number, String],
      default: () => void 0
    },
    label: {
      type: [String, Boolean, Number, Object]
    },
    indeterminate: Boolean,
    disabled: Boolean,
    checked: Boolean,
    name: {
      type: String,
      default: void 0
    },
    trueLabel: {
      type: [String, Number],
      default: void 0
    },
    falseLabel: {
      type: [String, Number],
      default: void 0
    },
    id: {
      type: String,
      default: void 0
    },
    controls: {
      type: String,
      default: void 0
    },
    border: Boolean,
    size: {
      type: String,
      validator: validators.isValidComponentSize
    }
  },
  emits: [constants.UPDATE_MODEL_EVENT, "change"],
  setup(props) {
    return useCheckbox(props);
  }
});

const _hoisted_1 = /* @__PURE__ */ vue.createVNode("span", { class: "el-checkbox__inner" }, null, -1);
const _hoisted_2 = {
  key: 0,
  class: "el-checkbox__label"
};
function render(_ctx, _cache, $props, $setup, $data, $options) {
  return vue.openBlock(), vue.createBlock("label", {
    id: _ctx.id,
    class: ["el-checkbox", [
      _ctx.border && _ctx.checkboxSize ? "el-checkbox--" + _ctx.checkboxSize : "",
      { "is-disabled": _ctx.isDisabled },
      { "is-bordered": _ctx.border },
      { "is-checked": _ctx.isChecked }
    ]],
    "aria-controls": _ctx.indeterminate ? _ctx.controls : null
  }, [
    vue.createVNode("span", {
      class: ["el-checkbox__input", {
        "is-disabled": _ctx.isDisabled,
        "is-checked": _ctx.isChecked,
        "is-indeterminate": _ctx.indeterminate,
        "is-focus": _ctx.focus
      }],
      tabindex: _ctx.indeterminate ? 0 : false,
      role: _ctx.indeterminate ? "checkbox" : false,
      "aria-checked": _ctx.indeterminate ? "mixed" : false
    }, [
      _hoisted_1,
      _ctx.trueLabel || _ctx.falseLabel ? vue.withDirectives((vue.openBlock(), vue.createBlock("input", {
        key: 0,
        "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.model = $event),
        checked: _ctx.isChecked,
        class: "el-checkbox__original",
        type: "checkbox",
        "aria-hidden": _ctx.indeterminate ? "true" : "false",
        name: _ctx.name,
        disabled: _ctx.isDisabled,
        "true-value": _ctx.trueLabel,
        "false-value": _ctx.falseLabel,
        onChange: _cache[2] || (_cache[2] = (...args) => _ctx.handleChange && _ctx.handleChange(...args)),
        onFocus: _cache[3] || (_cache[3] = ($event) => _ctx.focus = true),
        onBlur: _cache[4] || (_cache[4] = ($event) => _ctx.focus = false)
      }, null, 40, ["checked", "aria-hidden", "name", "disabled", "true-value", "false-value"])), [
        [vue.vModelCheckbox, _ctx.model]
      ]) : vue.withDirectives((vue.openBlock(), vue.createBlock("input", {
        key: 1,
        "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => _ctx.model = $event),
        class: "el-checkbox__original",
        type: "checkbox",
        "aria-hidden": _ctx.indeterminate ? "true" : "false",
        disabled: _ctx.isDisabled,
        value: _ctx.label,
        name: _ctx.name,
        onChange: _cache[6] || (_cache[6] = (...args) => _ctx.handleChange && _ctx.handleChange(...args)),
        onFocus: _cache[7] || (_cache[7] = ($event) => _ctx.focus = true),
        onBlur: _cache[8] || (_cache[8] = ($event) => _ctx.focus = false)
      }, null, 40, ["aria-hidden", "disabled", "value", "name"])), [
        [vue.vModelCheckbox, _ctx.model]
      ])
    ], 10, ["tabindex", "role", "aria-checked"]),
    _ctx.$slots.default || _ctx.label ? (vue.openBlock(), vue.createBlock("span", _hoisted_2, [
      vue.renderSlot(_ctx.$slots, "default"),
      !_ctx.$slots.default ? (vue.openBlock(), vue.createBlock(vue.Fragment, { key: 0 }, [
        vue.createTextVNode(vue.toDisplayString(_ctx.label), 1)
      ], 2112)) : vue.createCommentVNode("v-if", true)
    ])) : vue.createCommentVNode("v-if", true)
  ], 10, ["id", "aria-controls"]);
}

script.render = render;
script.__file = "packages/checkbox/src/checkbox.vue";

script.install = (app) => {
  app.component(script.name, script);
};
const _Checkbox = script;

exports.default = _Checkbox;
