{"version":3,"file":"useFormInput-CczKWnli.mjs","sources":["../src/utils/normalizeInput.ts","../src/utils/debounce.ts","../src/composables/useFormInput.ts"],"sourcesContent":["import type {Numberish} from '../types/CommonTypes'\n\nexport const normalizeInput = (\n  v: Numberish | null,\n  modelModifiers: Record<'number' | 'lazy' | 'trim', true | undefined>\n) => {\n  if (v === null) return\n  let update = v\n  if (modelModifiers.number && typeof update === 'string' && update !== '') {\n    const parsed = Number.parseFloat(update)\n    update = Number.isNaN(parsed) ? update : parsed\n  }\n  return update\n}\n","import {type MaybeRefOrGetter, toValue} from 'vue'\nimport type {\n  AnyFn,\n  ArgumentsType,\n  DebounceFilterOptions,\n  EventFilter,\n  FunctionArgs,\n  UseDebounceFnReturn,\n} from '@vueuse/core'\n\nexport const noop = () => {}\n\n/**\n * @internal\n */\nfunction createFilterWrapper<T extends AnyFn>(filter: EventFilter & {cancel: () => void}, fn: T) {\n  /* eslint-disable @typescript-eslint/no-explicit-any */\n  function wrapper(this: any, ...args: ArgumentsType<T>) {\n    return new Promise<Awaited<ReturnType<T>>>((resolve, reject) => {\n      // make sure it's a promise\n      Promise.resolve(filter(() => fn.apply(this, args), {fn, thisArg: this, args}))\n        .then(resolve)\n        .catch(reject)\n    })\n  }\n\n  // https://github.com/vueuse/vueuse/pull/4561\n  wrapper.cancel = filter.cancel\n  return wrapper\n}\n\n/**\n * Create an EventFilter that debounce the events\n */\nfunction debounceFilter(ms: MaybeRefOrGetter<number>, options: DebounceFilterOptions = {}) {\n  let timer: ReturnType<typeof setTimeout> | undefined\n  let maxTimer: ReturnType<typeof setTimeout> | undefined | null\n  let lastRejector: AnyFn = noop\n\n  const _clearTimeout = (timer: ReturnType<typeof setTimeout>) => {\n    clearTimeout(timer)\n    lastRejector()\n    lastRejector = noop\n  }\n\n  let lastInvoker: () => void\n\n  const filter: EventFilter & {cancel: () => void} = (invoke) => {\n    const duration = toValue(ms)\n    const maxDuration = toValue(options.maxWait)\n\n    if (timer) _clearTimeout(timer)\n\n    if (duration <= 0 || (maxDuration !== undefined && maxDuration <= 0)) {\n      if (maxTimer) {\n        _clearTimeout(maxTimer)\n        maxTimer = null\n      }\n      return Promise.resolve(invoke())\n    }\n\n    return new Promise((resolve, reject) => {\n      lastRejector = options.rejectOnCancel ? reject : resolve\n      lastInvoker = invoke\n      // Create the maxTimer. Clears the regular timer on invoke\n      if (maxDuration && !maxTimer) {\n        maxTimer = setTimeout(() => {\n          if (timer) _clearTimeout(timer)\n          maxTimer = null\n          resolve(lastInvoker())\n        }, maxDuration)\n      }\n\n      // Create the regular timer. Clears the max timer on invoke\n      timer = setTimeout(() => {\n        if (maxTimer) _clearTimeout(maxTimer)\n        maxTimer = null\n        resolve(invoke())\n      }, duration)\n    })\n  }\n\n  // https://github.com/vueuse/vueuse/pull/4561\n  filter.cancel = () => {\n    if (timer) _clearTimeout(timer)\n    if (maxTimer) _clearTimeout(maxTimer)\n    maxTimer = null\n  }\n\n  return filter\n}\n\n/**\n * Debounce execution of a function.\n *\n * @see https://vueuse.org/useDebounceFn\n * @param  fn          A function to be executed after delay milliseconds debounced.\n * @param  ms          A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n * @param  options     Options\n *\n * @return A new, debounce, function, provided with a cancel method.\n */\nexport function useDebounceFn<T extends FunctionArgs>(\n  fn: T,\n  ms: MaybeRefOrGetter<number> = 200,\n  options: DebounceFilterOptions = {}\n): UseDebounceFnReturn<T> & {cancel: () => void} {\n  return createFilterWrapper(debounceFilter(ms, options), fn)\n}\n","import type {Numberish} from '../types/CommonTypes'\nimport {\n  computed,\n  inject,\n  nextTick,\n  onActivated,\n  onMounted,\n  ref,\n  type Ref,\n  type ShallowRef,\n} from 'vue'\nimport {useAriaInvalid} from './useAriaInvalid'\nimport {useId} from './useId'\nimport {useFocus, useToNumber} from '@vueuse/core'\nimport type {CommonInputProps} from '../types/FormCommonInputProps'\nimport {formGroupKey} from '../utils/keys'\nimport {useDebounceFn} from '../utils/debounce'\nimport {useStateClass} from './useStateClass'\n\nexport const useFormInput = (\n  props: Readonly<CommonInputProps>,\n  input:\n    | Readonly<ShallowRef<HTMLInputElement | null>>\n    | Readonly<ShallowRef<HTMLTextAreaElement | null>>,\n  modelValue: Ref<Numberish | null>,\n  modelModifiers: Record<'number' | 'lazy' | 'trim', true | undefined>\n) => {\n  const forceUpdateKey = ref(0)\n\n  const computedId = useId(() => props.id, 'input')\n  const debounceNumber = useToNumber(() => props.debounce ?? 0, {nanToZero: true})\n  const debounceMaxWaitNumber = useToNumber(() => props.debounceMaxWait ?? NaN)\n\n  // This automatically adds the appropriate \"for\" attribute to a BFormGroup label\n  const formGroupData = inject(formGroupKey, null)?.(computedId)\n  const computedState = computed(() =>\n    props.state !== undefined ? props.state : (formGroupData?.state.value ?? null)\n  )\n  const computedAriaInvalid = useAriaInvalid(() => props.ariaInvalid, computedState)\n  const stateClass = useStateClass(computedState)\n\n  const internalUpdateModelValue = useDebounceFn(\n    (value: Numberish) => {\n      modelValue.value = value\n    },\n    () => (modelModifiers.lazy === true ? 0 : debounceNumber.value),\n    {maxWait: () => (modelModifiers.lazy === true ? NaN : debounceMaxWaitNumber.value)}\n  )\n\n  const updateModelValue = (value: Numberish, force = false, immediate = false) => {\n    if (modelModifiers.lazy === true && force === false) return\n    if (immediate) {\n      modelValue.value = value\n    } else {\n      internalUpdateModelValue(value)\n    }\n  }\n\n  const {focused} = useFocus(input, {\n    initialValue: props.autofocus,\n  })\n\n  const _formatValue = (value: string, evt: Readonly<Event>, force = false) => {\n    if (props.formatter !== undefined && (!props.lazyFormatter || force)) {\n      return props.formatter(value, evt)\n    }\n    return value\n  }\n  onMounted(() => {\n    if (input.value) {\n      input.value.value = modelValue.value?.toString() ?? ''\n    }\n  })\n\n  onActivated(() => {\n    nextTick(() => {\n      if (props.autofocus) {\n        focused.value = true\n      }\n    })\n  })\n\n  const onInput = (evt: Readonly<Event>) => {\n    const {value} = evt.target as HTMLInputElement\n    const formattedValue = _formatValue(value, evt)\n    if (evt.defaultPrevented) {\n      evt.preventDefault()\n      return\n    }\n\n    const nextModel = formattedValue\n\n    updateModelValue(nextModel)\n  }\n\n  const onChange = (evt: Readonly<Event>) => {\n    const {value} = evt.target as HTMLInputElement\n    const formattedValue = _formatValue(value, evt)\n    if (evt.defaultPrevented) {\n      evt.preventDefault()\n      return\n    }\n\n    const nextModel = formattedValue\n    if (modelValue.value !== nextModel) {\n      updateModelValue(formattedValue, true)\n    }\n  }\n\n  const onBlur = (evt: Readonly<FocusEvent>) => {\n    if (\n      !modelModifiers.lazy &&\n      !props.lazyFormatter &&\n      !modelModifiers.trim &&\n      debounceNumber.value <= 0\n    )\n      return\n\n    const {value} = evt.target as HTMLInputElement\n    const formattedValue = _formatValue(value, evt, true)\n\n    const nextModel = modelModifiers.trim ? formattedValue.trim() : formattedValue\n    const needsForceUpdate = nextModel.length !== formattedValue.length\n    // Cancel before modelValue.value comparison and update\n    internalUpdateModelValue.cancel()\n    if (modelValue.value !== nextModel) {\n      updateModelValue(formattedValue, true, true)\n    }\n    if (modelModifiers.trim && needsForceUpdate) {\n      // The value is trimmed but there would still exist some white space\n      // So, force update the value. You need to bind this to :key on the input element\n      forceUpdateKey.value = forceUpdateKey.value + 1\n    }\n  }\n\n  const focus = () => {\n    if (!props.disabled) {\n      focused.value = true\n    }\n  }\n\n  const blur = () => {\n    if (!props.disabled) {\n      focused.value = false\n    }\n  }\n\n  return {\n    input,\n    computedId,\n    computedAriaInvalid,\n    onInput,\n    onChange,\n    onBlur,\n    focus,\n    blur,\n    forceUpdateKey,\n    stateClass,\n  }\n}\n"],"names":["timer"],"mappings":"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"}