import { computed, ref, onBeforeMount, toRef, onBeforeUnmount, createVNode, mergeProps, withDirectives, vModelDynamic } from "vue";
import "./styles/selection-control.scss";
import { useTextColor } from "../../composables/color/index.mjs";
import { makeDensityProps, useDensity } from "../../composables/density/index.mjs";
import { useForm } from "../../composables/form/index.mjs";
import { useProxiedModel } from "../../composables/proxied-model/index.mjs";
import { makeSizeProps, useSize } from "../../composables/size/index.mjs";
import { useSelectionGroupControl } from "../selection-group-control/selection-group-control.mjs";
import { makeThemeProps } from "../../composables/theme/index.mjs";
import { propsFactory, deepEqual, wrapInArray, getUid, useRender, filterInputAttrs, SUPPORTS_FOCUS_VISIBLE, pick } from "../../utils/dist/index.mjs";
import { Icon } from "../icon/icon.mjs";
import { Label } from "../label/label.mjs";
import { genericComponent } from "../../utils/define-component.mjs";
const makeSelectionControlProps = propsFactory({
  color: String,
  disabled: Boolean,
  error: Boolean,
  id: String,
  inline: Boolean,
  label: String,
  falseIcon: String,
  trueIcon: String,
  multiple: {
    type: Boolean,
    default: null
  },
  name: String,
  readonly: Boolean,
  trueValue: null,
  falseValue: null,
  modelValue: null,
  type: String,
  value: null,
  valueComparator: {
    type: Function,
    default: deepEqual
  },
  ...makeThemeProps(),
  ...makeSizeProps(),
  ...makeDensityProps()
}, "selection-control");
const SelectionControl = genericComponent()({
  name: "VeSelectionControl",
  inheritAttrs: false,
  props: makeSelectionControlProps(),
  emits: {
    "update:modelValue": (_modelValue) => true
  },
  setup(props, {
    attrs,
    slots
  }) {
    const group = useSelectionGroupControl();
    const {
      sizeClasses,
      sizeStyles
    } = useSize(props);
    const {
      densityClasses
    } = useDensity(props);
    const modelValue = useProxiedModel(props, "modelValue");
    const trueValue = computed(() => props.trueValue !== void 0 ? props.trueValue : props.value !== void 0 ? props.value : true);
    const falseValue = computed(() => props.falseValue !== void 0 ? props.falseValue : false);
    const isMultiple = computed(() => (group == null ? void 0 : group.multiple.value) || !!props.multiple || props.multiple == null && Array.isArray(modelValue.value));
    const model = computed({
      get() {
        const val = group ? group.modelValue.value : modelValue.value;
        if (isMultiple.value) {
          return (val || []).some((v) => props.valueComparator(v, trueValue.value));
        }
        return props.valueComparator(val, trueValue.value);
      },
      set(val) {
        const currentValue = val ? trueValue.value : falseValue.value;
        let newVal = currentValue;
        if (isMultiple.value) {
          const oldVal = group ? group.modelValue.value : modelValue.value;
          if (val) {
            newVal = [...wrapInArray(oldVal), currentValue];
          } else {
            newVal = wrapInArray(oldVal).filter((v) => !props.valueComparator(v, trueValue.value));
          }
        }
        if (group) {
          group.modelValue.value = newVal;
        } else {
          modelValue.value = newVal;
        }
      }
    });
    const {
      textColorClasses,
      textColorStyles
    } = useTextColor(computed(() => {
      return model.value ? props.color : void 0;
    }));
    const icon = computed(() => {
      var _a, _b;
      return model.value ? (_a = group == null ? void 0 : group.trueIcon.value) != null ? _a : props.trueIcon : (_b = group == null ? void 0 : group.falseIcon.value) != null ? _b : props.falseIcon;
    });
    const id = computed(() => props.name || props.id || `ve-selection-control-${getUid()}`);
    const isFocused = ref(false);
    const isFocusVisible = ref(false);
    const inputRef = ref();
    const form = useForm();
    onBeforeMount(() => {
      form == null ? void 0 : form.register(id.value, {
        name: toRef(props, "name"),
        modelValue: model
      });
    });
    onBeforeUnmount(() => {
      form == null ? void 0 : form.unregister(id.value);
    });
    function onFocus(e) {
      isFocused.value = true;
      if (!SUPPORTS_FOCUS_VISIBLE || SUPPORTS_FOCUS_VISIBLE && e.target.matches(":focus-visible")) {
        isFocusVisible.value = true;
      }
    }
    function onBlur() {
      isFocused.value = false;
      isFocusVisible.value = false;
    }
    useRender(() => {
      var _a, _b, _c, _d;
      const slotProps = {
        label: props.label,
        model,
        textColorClasses,
        textColorStyles,
        props: {
          onFocus,
          onBlur,
          id: id.value
        }
      };
      const type = (_a = group == null ? void 0 : group.type.value) != null ? _a : props.type;
      const hasLabel = !!(slots.label || props.label || props.value);
      const [rootAttrs, restAttrs] = filterInputAttrs(attrs);
      return createVNode("div", mergeProps(rootAttrs, {
        "class": ["ve-selection-control", {
          "ve-selection-control--dirty": model.value,
          "ve-selection-control--disabled": props.disabled,
          "ve-selection-control--error": props.error,
          "ve-selection-control--focused": isFocused.value,
          "ve-selection-control--focus-visible": isFocusVisible.value,
          "ve-selection-control--inline": (group == null ? void 0 : group.inline.value) || props.inline
        }, sizeClasses.value, densityClasses.value, textColorClasses.value],
        "style": sizeStyles.value
      }), [createVNode("div", {
        "class": "ve-selection-control__wrapper"
      }, [(_b = slots.default) == null ? void 0 : _b.call(slots, slotProps), createVNode("div", {
        "class": "ve-selection-control__input",
        "style": textColorStyles.value
      }, [icon.value && createVNode(Icon, {
        "icon": icon.value
      }, null), (_c = slots.input) == null ? void 0 : _c.call(slots, slotProps), withDirectives(createVNode("input", mergeProps({
        "class": "ve-native-control",
        "ref": inputRef,
        "onUpdate:modelValue": ($event) => model.value = $event,
        "disabled": props.disabled,
        "id": id.value,
        "onBlur": onBlur,
        "onFocus": onFocus,
        "readonly": props.readonly,
        "type": type,
        "value": trueValue.value,
        "name": (_d = group == null ? void 0 : group.name.value) != null ? _d : props.name,
        "aria-checked": type === "checkbox" ? model.value : void 0
      }, restAttrs), null), [[vModelDynamic, model.value]])])]), hasLabel && createVNode(Label, {
        "for": id.value
      }, {
        default: () => {
          var _a2, _b2, _c2;
          return [(_c2 = (_b2 = (_a2 = slots.label) == null ? void 0 : _a2.call(slots, slotProps)) != null ? _b2 : props.label) != null ? _c2 : props.value];
        }
      })]);
    });
    return {
      isFocused,
      inputRef
    };
  }
});
function filterSelectionControlProps(props) {
  return pick(props, Object.keys(SelectionControl.props));
}
export {
  SelectionControl,
  filterSelectionControlProps,
  makeSelectionControlProps
};
//# sourceMappingURL=selection-control.mjs.map
