import { computed, onBeforeMount, toRef, onBeforeUnmount, createVNode } from "vue";
import "./styles/form-control.scss";
import { makeDimensionProps, useDimension } from "../../composables/dimension/index.mjs";
import { makeDensityProps, useDensity } from "../../composables/density/index.mjs";
import { useForm } from "../../composables/form/index.mjs";
import { makeSizeProps, useSize } from "../../composables/size/index.mjs";
import { makeValidationProps, useValidation } from "../../composables/validation/index.mjs";
import { useProxiedModel } from "../../composables/proxied-model/index.mjs";
import { Icon } from "../icon/icon.mjs";
import { Label } from "../label/label.mjs";
import { Messages } from "../messages/messages.mjs";
import { genericComponent } from "../../utils/define-component.mjs";
import { getUid, useRender, convertToUnit, pick } from "../../utils/dist/index.mjs";
function filterFormControlSlots(slots) {
  return pick(slots, FormControlSlots);
}
const FormControlEmits = {
  "click:prepend": (_event) => true,
  "click:label": (_event) => true,
  "click:append": (_event) => true,
  "update:modelValue": (_modelValue) => true
};
const FormControlSlots = ["prepend", "label", "default", "append", "details"];
const FormControl = genericComponent()({
  name: "VeFormControl",
  props: {
    appendIcon: [String, Object],
    direction: {
      type: String,
      default: "horizontal",
      validator: (v) => ["horizontal", "vertical"].includes(v)
    },
    focused: Boolean,
    hideDetails: [Boolean, String],
    hint: String,
    inline: Boolean,
    label: [Boolean, String],
    labelId: String,
    labelWidth: [String, Number],
    messages: {
      type: [Array, String],
      default: () => []
    },
    name: String,
    prependIcon: String,
    persistentHint: Boolean,
    ...makeDimensionProps(),
    ...makeSizeProps(),
    ...makeDensityProps(),
    ...makeValidationProps()
  },
  emits: FormControlEmits,
  setup(props, {
    slots,
    emit
  }) {
    const {
      dimensionStyles
    } = useDimension(props);
    const {
      sizeClasses,
      sizeStyles
    } = useSize(props);
    const model = useProxiedModel(props, "modelValue");
    const computedDimensionStyles = computed(() => {
      var _a;
      return {
        ...dimensionStyles.value,
        minHeight: (_a = dimensionStyles.value.minHeight) != null ? _a : dimensionStyles.value.height
      };
    });
    const {
      densityClasses
    } = useDensity(props);
    const {
      errorMessages,
      isDisabled,
      isReadonly,
      isPristine,
      isValid,
      isValidating,
      reset,
      resetValidation,
      validate,
      validationClasses
    } = useValidation(props);
    const form = useForm();
    const id = computed(() => {
      var _a;
      return (_a = props.name) != null ? _a : `ve-form-control-${getUid()}`;
    });
    onBeforeMount(() => {
      form == null ? void 0 : form.register(id.value, {
        name: toRef(props, "name"),
        modelValue: model,
        validate,
        reset,
        resetValidation
      });
    });
    onBeforeUnmount(() => {
      form == null ? void 0 : form.unregister(id.value);
    });
    const slotProps = computed(() => ({
      isDisabled,
      isReadonly,
      isPristine,
      isValid,
      isValidating,
      reset,
      resetValidation,
      validate
    }));
    useRender(() => {
      var _a, _b, _c, _d;
      const hasPrepend = !!(slots.prepend || props.prependIcon);
      const hasLabel = !!(slots.label || props.label);
      const hasAppend = !!(slots.append || props.appendIcon);
      const hasHint = !!(slots.hint || props.hint);
      const hasMessages = !!(slots.messages || ((_a = props.messages) == null ? void 0 : _a.length) || errorMessages.value.length);
      const hasDetails = !props.hideDetails || props.hideDetails === "auto" && (hasMessages || hasHint);
      const showMessages = hasMessages || hasHint && (props.persistentHint || props.focused);
      return createVNode("div", {
        "class": ["ve-form-control", {
          [`ve-form-control--${props.direction}`]: !!props.direction,
          "ve-form-control--hide-details": props.hideDetails,
          "ve-form-control--inline": props.inline
        }, sizeClasses.value, densityClasses.value, validationClasses.value]
      }, [hasPrepend && createVNode("div", {
        "class": "ve-form-control__prepend"
      }, [(_b = slots.prepend) == null ? void 0 : _b.call(slots, slotProps.value), props.prependIcon && createVNode(Icon, {
        "onClick": (e) => emit("click:prepend", e),
        "icon": props.prependIcon
      }, null)]), hasLabel && createVNode("div", {
        "class": "ve-form-control__label",
        "style": {
          width: convertToUnit(props.labelWidth)
        }
      }, [createVNode(Label, {
        "disabled": isDisabled.value,
        "error": isValid.value === false,
        "onClick": (e) => emit("click:label", e),
        "for": props.labelId
      }, {
        default: () => {
          var _a2, _b2;
          return [(_b2 = (_a2 = slots.label) == null ? void 0 : _a2.call(slots, slotProps.value)) != null ? _b2 : props.label];
        }
      })]), slots.default && createVNode("div", {
        "class": "ve-form-control__control",
        "style": [sizeStyles.value, computedDimensionStyles.value]
      }, [slots.default(slotProps.value)]), hasAppend && createVNode("div", {
        "class": "ve-form-control__append"
      }, [props.appendIcon && createVNode(Icon, {
        "onClick": (e) => emit("click:append", e),
        "icon": props.appendIcon
      }, null), (_c = slots == null ? void 0 : slots.append) == null ? void 0 : _c.call(slots, slotProps.value)]), hasDetails && createVNode("div", {
        "class": "ve-form-control__details"
      }, [createVNode(Messages, {
        "active": showMessages,
        "value": hasMessages ? props.messages : [props.hint]
      }, {
        default: slots.messages
      }), (_d = slots.details) == null ? void 0 : _d.call(slots, slotProps.value)])]);
    });
    return {
      isDisabled,
      isReadonly,
      isPristine,
      isValid,
      isValidating,
      reset,
      resetValidation,
      validate
    };
  }
});
export {
  FormControl,
  FormControlEmits,
  FormControlSlots,
  filterFormControlSlots
};
//# sourceMappingURL=form-control.mjs.map
