import { withDirectives as _withDirectives, mergeProps as _mergeProps, vModelDynamic as _vModelDynamic, createVNode as _createVNode } from "vue";
import "./styles/selection-control.css";
import { computed, onBeforeMount, onBeforeUnmount, ref, toRef } from "vue";
import { SUPPORTS_FOCUS_VISIBLE, deepEqual, filterInputAttrs, getUid, pick, propsFactory, useRender, wrapInArray } from "@veno-ui/utils";
import { genericComponent } from "../../utils";
import { Icon } from "../icon";
import { Label } from "../label";
import { useTextColor } from "../../composables/color";
import { makeDensityProps, useDensity } from "../../composables/density";
import { useForm } from "../../composables/form";
import { useProxiedModel } from "../../composables/proxied-model";
import { makeSizeProps, useSize } from "../../composables/size";
import { useSelectionGroupControl } from "../selection-group-control/selection-group-control";
import { makeThemeProps } from "../../composables/theme";
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?.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(() => {
      return model.value ? group?.trueIcon.value ?? props.trueIcon : group?.falseIcon.value ?? 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?.register(id.value, {
        name: toRef(props, "name"),
        modelValue: model
      });
    });
    onBeforeUnmount(() => {
      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(() => {
      const slotProps = {
        label: props.label,
        model,
        textColorClasses,
        textColorStyles,
        props: {
          onFocus,
          onBlur,
          id: id.value
        }
      };
      const type = group?.type.value ?? 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?.inline.value || props.inline
        }, sizeClasses.value, densityClasses.value, textColorClasses.value],
        "style": sizeStyles.value
      }), [_createVNode("div", {
        "class": "ve-selection-control__wrapper"
      }, [slots.default?.(slotProps), _createVNode("div", {
        "class": "ve-selection-control__input",
        "style": textColorStyles.value
      }, [icon.value && _createVNode(Icon, {
        "icon": icon.value
      }, null), slots.input?.(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": group?.name.value ?? props.name,
        "aria-checked": type === "checkbox" ? model.value : void 0
      }, restAttrs), null), [[_vModelDynamic, model.value]])])]), hasLabel && _createVNode(Label, {
        "for": id.value
      }, {
        default: () => [slots.label?.(slotProps) ?? props.label ?? props.value]
      })]);
    });
    return {
      isFocused,
      inputRef
    };
  }
});
function filterSelectionControlProps(props) {
  return pick(props, Object.keys(SelectionControl.props));
}
export {
  SelectionControl,
  filterSelectionControlProps,
  makeSelectionControlProps
};
//# sourceMappingURL=selection-control.mjs.map
