import { createVNode as _createVNode } from "vue";
import "./styles/form-control.css";
import { computed, onBeforeMount, onBeforeUnmount, toRef } from "vue";
import { convertToUnit, getUid, pick, useRender } from "@veno-ui/utils";
import { genericComponent } from "../../utils";
import { Label } from "../label";
import { Messages } from "../messages";
import { Icon } from "../icon";
import { makeDimensionProps, useDimension } from "../../composables/dimension";
import { makeDensityProps, useDensity } from "../../composables/density";
import { useForm } from "../../composables/form";
import { makeSizeProps, useSize } from "../../composables/size";
import { makeValidationProps, useValidation } from "../../composables/validation";
import { useProxiedModel } from "../../composables/proxied-model";
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: {
    /**
     * @zh 后置图标
     */
    appendIcon: [String, Object],
    /**
     * @zh 布局方向
     */
    direction: {
      type: String,
      default: "horizontal",
      validator: (v) => ["horizontal", "vertical"].includes(v)
    },
    /**
     * @zh 聚焦的
     */
    focused: Boolean,
    /**
     * @zh 隐藏详情
     */
    hideDetails: [Boolean, String],
    /**
     * @zh 存在提示
     */
    hint: String,
    /**
     * @zh 内联
     */
    inline: Boolean,
    /**
     * @zh 标签文本
     */
    label: [Boolean, String],
    /**
     * @zh 标签ID
     */
    labelId: String,
    /**
     * @zh 标签宽度
     */
    labelWidth: [String, Number],
    /**
     * @zh 提示消息
     */
    messages: {
      type: [Array, String],
      default: () => []
    },
    /**
     * @zh 名称
     */
    name: String,
    /**
     * @zh 后置图标
     */
    prependIcon: String,
    /**
     * @zh 持续显示的提示
     */
    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(() => ({
      ...dimensionStyles.value,
      minHeight: dimensionStyles.value.minHeight ?? 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(() => props.name ?? `ve-form-control-${getUid()}`);
    onBeforeMount(() => {
      form?.register(id.value, {
        name: toRef(props, "name"),
        modelValue: model,
        validate,
        reset,
        resetValidation
      });
    });
    onBeforeUnmount(() => {
      form?.unregister(id.value);
    });
    const slotProps = computed(() => ({
      isDisabled,
      isReadonly,
      isPristine,
      isValid,
      isValidating,
      reset,
      resetValidation,
      validate
    }));
    useRender(() => {
      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 || props.messages?.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"
      }, [slots.prepend?.(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: () => [slots.label?.(slotProps.value) ?? 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), slots?.append?.(slotProps.value)]), hasDetails && _createVNode("div", {
        "class": "ve-form-control__details"
      }, [_createVNode(Messages, {
        "active": showMessages,
        "value": hasMessages ? props.messages : [props.hint]
      }, {
        default: slots.messages
      }), slots.details?.(slotProps.value)])]);
    });
    return {
      isDisabled,
      isReadonly,
      isPristine,
      isValid,
      isValidating,
      reset,
      resetValidation,
      validate
    };
  }
});
export {
  FormControl,
  FormControlEmits,
  FormControlSlots,
  filterFormControlSlots
};
//# sourceMappingURL=form-control.mjs.map
