{"version":3,"file":"validation.mjs","names":["useForm","useProxiedModel","useToggleScope","makeFocusProps","computed","onBeforeMount","onBeforeUnmount","onMounted","ref","unref","watch","getCurrentInstanceName","getUid","propsFactory","wrapInArray","makeValidationProps","disabled","Boolean","error","errorMessages","type","Array","String","default","maxErrors","Number","name","label","readonly","rules","modelValue","validateOn","validationValue","useValidation","props","id","model","validationModel","undefined","value","form","internalErrorMessages","isPristine","isDirty","length","isDisabled","isReadonly","slice","Math","max","isValid","isValidating","validationClasses","uid","register","validate","reset","resetValidation","unregister","update","focused","unwatch","val","results","rule","handler","result","console","warn","push"],"sources":["../../src/composables/validation.ts"],"sourcesContent":["// Composables\nimport { useForm } from '@/composables/form'\nimport { useProxiedModel } from '@/composables/proxiedModel'\nimport { useToggleScope } from '@/composables/toggleScope'\nimport { makeFocusProps } from '@/composables/focus'\n\n// Utilities\nimport { computed, onBeforeMount, onBeforeUnmount, onMounted, ref, unref, watch } from 'vue'\nimport { getCurrentInstanceName, getUid, propsFactory, wrapInArray } from '@/util'\n\n// Types\nimport type { PropType } from 'vue'\nimport type { MaybeRef } from '@/util'\n\nexport type ValidationResult = string | boolean\nexport type ValidationRule =\n  | ValidationResult\n  | PromiseLike<ValidationResult>\n  | ((value: any) => ValidationResult)\n  | ((value: any) => PromiseLike<ValidationResult>)\n\nexport interface ValidationProps {\n  disabled: boolean\n  error: boolean\n  errorMessages: string | string[]\n  focused: boolean\n  maxErrors: string | number\n  name: string | undefined\n  label: string | undefined\n  readonly: boolean\n  rules: ValidationRule[]\n  modelValue: any\n  'onUpdate:modelValue': ((val: any) => void) | undefined\n  validateOn?: 'blur' | 'input' | 'submit'\n  validationValue: any\n}\n\nexport const makeValidationProps = propsFactory({\n  disabled: Boolean,\n  error: Boolean,\n  errorMessages: {\n    type: [Array, String] as PropType<string | string[]>,\n    default: () => ([]),\n  },\n  maxErrors: {\n    type: [Number, String],\n    default: 1,\n  },\n  name: String,\n  label: String,\n  readonly: Boolean,\n  rules: {\n    type: Array as PropType<ValidationRule[]>,\n    default: () => ([]),\n  },\n  modelValue: null,\n  validateOn: String as PropType<ValidationProps['validateOn']>,\n  validationValue: null,\n\n  ...makeFocusProps(),\n}, 'validation')\n\nexport function useValidation (\n  props: ValidationProps,\n  name = getCurrentInstanceName(),\n  id: MaybeRef<string | number> = getUid(),\n) {\n  const model = useProxiedModel(props, 'modelValue')\n  const validationModel = computed(() => props.validationValue === undefined ? model.value : props.validationValue)\n  const form = useForm()\n  const internalErrorMessages = ref<string[]>([])\n  const isPristine = ref(true)\n  const isDirty = computed(() => !!(\n    wrapInArray(model.value === '' ? null : model.value).length ||\n    wrapInArray(validationModel.value === '' ? null : validationModel.value).length\n  ))\n  const isDisabled = computed(() => !!(props.disabled || form?.isDisabled.value))\n  const isReadonly = computed(() => !!(props.readonly || form?.isReadonly.value))\n  const errorMessages = computed(() => {\n    return props.errorMessages.length\n      ? wrapInArray(props.errorMessages).slice(0, Math.max(0, +props.maxErrors))\n      : internalErrorMessages.value\n  })\n  const isValid = computed(() => {\n    if (props.error || errorMessages.value.length) return false\n    if (!props.rules.length) return true\n\n    return isPristine.value ? null : true\n  })\n  const isValidating = ref(false)\n  const validationClasses = computed(() => {\n    return {\n      [`${name}--error`]: isValid.value === false,\n      [`${name}--dirty`]: isDirty.value,\n      [`${name}--disabled`]: isDisabled.value,\n      [`${name}--readonly`]: isReadonly.value,\n    }\n  })\n\n  const uid = computed(() => props.name ?? unref(id))\n\n  onBeforeMount(() => {\n    form?.register({\n      id: uid.value,\n      validate,\n      reset,\n      resetValidation,\n    })\n  })\n\n  onBeforeUnmount(() => {\n    form?.unregister(uid.value)\n  })\n\n  const validateOn = computed(() => props.validateOn || form?.validateOn.value || 'input')\n\n  // Set initial valid state, for inputs that might not have rules\n  onMounted(() => form?.update(uid.value, isValid.value, errorMessages.value))\n\n  useToggleScope(() => validateOn.value === 'input', () => {\n    watch(validationModel, () => {\n      if (validationModel.value != null) {\n        validate()\n      } else if (props.focused) {\n        const unwatch = watch(() => props.focused, val => {\n          if (!val) validate()\n\n          unwatch()\n        })\n      }\n    })\n  })\n\n  useToggleScope(() => validateOn.value === 'blur', () => {\n    watch(() => props.focused, val => {\n      if (!val) validate()\n    })\n  })\n\n  watch(isValid, () => {\n    form?.update(uid.value, isValid.value, errorMessages.value)\n  })\n\n  function reset () {\n    resetValidation()\n    model.value = null\n  }\n\n  function resetValidation () {\n    isPristine.value = true\n    internalErrorMessages.value = []\n  }\n\n  async function validate () {\n    const results = []\n\n    isValidating.value = true\n\n    for (const rule of props.rules) {\n      if (results.length >= (props.maxErrors ?? 1)) {\n        break\n      }\n\n      const handler = typeof rule === 'function' ? rule : () => rule\n      const result = await handler(validationModel.value)\n\n      if (result === true) continue\n\n      if (typeof result !== 'string') {\n        // eslint-disable-next-line no-console\n        console.warn(`${result} is not a valid value. Rule functions must return boolean true or a string.`)\n\n        continue\n      }\n\n      results.push(result)\n    }\n\n    internalErrorMessages.value = results\n    isValidating.value = false\n    isPristine.value = false\n\n    return internalErrorMessages.value\n  }\n\n  return {\n    errorMessages,\n    isDirty,\n    isDisabled,\n    isReadonly,\n    isPristine,\n    isValid,\n    isValidating,\n    reset,\n    resetValidation,\n    validate,\n    validationClasses,\n  }\n}\n"],"mappings":"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"}