{"version":3,"file":"MaskedInput.mjs","sources":["../../../../src/lib/nextGenComponents/components/CustomRangePicker/MaskedInput.tsx"],"sourcesContent":["import type { ClipboardEvent, KeyboardEvent } from 'react'\nimport { useCallback, useRef, useState } from 'react'\n\nimport { cn } from '@/lib/utils'\n\nexport type MaskItem = RegExp | string\n\nexport const isMaskComplete = (value: string, placeholderChar = '_'): boolean =>\n  value.length > 0 && !value.includes(placeholderChar)\n\ntype Props = {\n  mask: MaskItem[] | ((value: string) => MaskItem[])\n  value: string\n  onChange: (conformedValue: string) => void\n  onBlur?: () => void\n  placeholderChar?: string\n  textPlaceholder?: string\n  className?: string\n}\n\nconst PLACEHOLDER = '_'\n\nconst resolveMask = (mask: Props['mask'], value: string): MaskItem[] =>\n  typeof mask === 'function' ? mask(value) : mask\n\nconst buildPlaceholder = (mask: MaskItem[], pc: string): string =>\n  mask.map(m => (typeof m === 'string' ? m : pc)).join('')\n\nconst conformToMask = (raw: string, resolvedMask: MaskItem[], placeholderChar: string): string =>\n  raw\n    .split('')\n    .map((c, i) => {\n      if (typeof resolvedMask[i] === 'string') return resolvedMask[i] as string\n      if (c === placeholderChar) return placeholderChar\n      if ((resolvedMask[i] as RegExp).test(c)) return c\n      return placeholderChar\n    })\n    .join('')\n\nexport const MaskedInput = ({\n  mask,\n  value,\n  onChange,\n  onBlur,\n  placeholderChar = PLACEHOLDER,\n  textPlaceholder,\n  className\n}: Props) => {\n  const inputRef = useRef<HTMLInputElement>(null)\n  const [isFocused, setIsFocused] = useState(false)\n  const maskArr = resolveMask(mask, value)\n  const maskPlaceholder = buildPlaceholder(maskArr, placeholderChar)\n  const maskedDisplay = value || maskPlaceholder\n\n  const showTextPlaceholder = !!textPlaceholder && !value && !isFocused\n  const inputValue = showTextPlaceholder ? '' : maskedDisplay\n\n  const nextEditablePos = useCallback((from: number, maskItems: MaskItem[]): number => {\n    let pos = from\n    while (pos < maskItems.length && typeof maskItems[pos] === 'string') pos++\n    return pos\n  }, [])\n\n  const prevEditablePos = useCallback((from: number, maskItems: MaskItem[]): number => {\n    let pos = from\n    while (pos >= 0 && typeof maskItems[pos] === 'string') pos--\n    return pos\n  }, [])\n\n  const handleKeyDown = useCallback(\n    (e: KeyboardEvent<HTMLInputElement>) => {\n      const input = e.target as HTMLInputElement\n      const pos = input.selectionStart ?? 0\n\n      if (e.key === 'Backspace') {\n        e.preventDefault()\n        const editPos = prevEditablePos(pos - 1, maskArr)\n        if (editPos >= 0) {\n          const chars = maskedDisplay.split('')\n          chars[editPos] = placeholderChar\n          const newVal = chars.join('')\n          const resolvedMask = resolveMask(mask, newVal)\n          const resolvedPlaceholder = buildPlaceholder(resolvedMask, placeholderChar)\n          const corrected = conformToMask(newVal, resolvedMask, placeholderChar)\n          onChange(corrected === resolvedPlaceholder ? '' : corrected)\n          requestAnimationFrame(() => input.setSelectionRange(editPos, editPos))\n        }\n        return\n      }\n\n      if (e.key === 'Delete') {\n        e.preventDefault()\n        const editPos = nextEditablePos(pos, maskArr)\n        if (editPos < maskArr.length) {\n          const chars = maskedDisplay.split('')\n          chars[editPos] = placeholderChar\n          const newVal = chars.join('')\n          const resolvedMask = resolveMask(mask, newVal)\n          const resolvedPlaceholder = buildPlaceholder(resolvedMask, placeholderChar)\n          const corrected = conformToMask(newVal, resolvedMask, placeholderChar)\n          onChange(corrected === resolvedPlaceholder ? '' : corrected)\n          requestAnimationFrame(() => input.setSelectionRange(editPos, editPos))\n        }\n        return\n      }\n\n      if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') return\n\n      if (e.key.length === 1 && !e.metaKey && !e.ctrlKey) {\n        e.preventDefault()\n        const editPos = nextEditablePos(pos, maskArr)\n        if (editPos >= maskArr.length) return\n\n        const regex = maskArr[editPos] as RegExp\n        if (!regex.test(e.key)) return\n\n        const chars = maskedDisplay.split('')\n        chars[editPos] = e.key\n        const newVal = chars.join('')\n\n        const resolvedMask = resolveMask(mask, newVal)\n        const corrected = conformToMask(newVal, resolvedMask, placeholderChar)\n\n        onChange(corrected)\n        const nextPos = nextEditablePos(editPos + 1, resolvedMask)\n        requestAnimationFrame(() => input.setSelectionRange(nextPos, nextPos))\n      }\n    },\n    [mask, maskArr, maskedDisplay, onChange, placeholderChar, nextEditablePos, prevEditablePos]\n  )\n\n  const handlePaste = useCallback(\n    (e: ClipboardEvent<HTMLInputElement>) => {\n      e.preventDefault()\n      const pasted = e.clipboardData.getData('text')\n      const input = e.target as HTMLInputElement\n      let pos = input.selectionStart ?? 0\n      const chars = maskedDisplay.split('')\n\n      for (const char of pasted) {\n        pos = nextEditablePos(pos, maskArr)\n        if (pos >= maskArr.length) break\n        if ((maskArr[pos] as RegExp).test(char)) {\n          chars[pos] = char\n          pos++\n        }\n      }\n\n      const newVal = chars.join('')\n      const resolvedMask = resolveMask(mask, newVal)\n      const corrected = conformToMask(newVal, resolvedMask, placeholderChar)\n\n      onChange(corrected)\n      const cursorPos = nextEditablePos(pos, resolvedMask)\n      requestAnimationFrame(() => input.setSelectionRange(cursorPos, cursorPos))\n    },\n    [mask, maskArr, maskedDisplay, onChange, placeholderChar, nextEditablePos]\n  )\n\n  const handleFocus = useCallback(() => {\n    setIsFocused(true)\n    requestAnimationFrame(() => {\n      const pos = maskedDisplay.indexOf(placeholderChar)\n      const cursorPos = pos === -1 ? maskedDisplay.length : pos\n      inputRef.current?.setSelectionRange(cursorPos, cursorPos)\n    })\n  }, [maskedDisplay, placeholderChar])\n\n  const handleBlurInternal = useCallback(() => {\n    setIsFocused(false)\n    onBlur?.()\n  }, [onBlur])\n\n  return (\n    <input\n      ref={inputRef}\n      value={inputValue}\n      placeholder={textPlaceholder}\n      onChange={() => {}}\n      onKeyDown={handleKeyDown}\n      onPaste={handlePaste}\n      onFocus={handleFocus}\n      onBlur={handleBlurInternal}\n      className={cn(\n        'flex h-10 rounded-md border border-solid border-input bg-background px-3 py-2 text-base placeholder:text-[#C4C2C8] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n        className\n      )}\n      spellCheck={false}\n      autoComplete=\"off\"\n    />\n  )\n}\n"],"names":["isMaskComplete","value","placeholderChar","PLACEHOLDER","resolveMask","mask","buildPlaceholder","pc","m","conformToMask","raw","resolvedMask","c","i","MaskedInput","onChange","onBlur","textPlaceholder","className","inputRef","useRef","isFocused","setIsFocused","useState","maskArr","maskPlaceholder","maskedDisplay","inputValue","nextEditablePos","useCallback","from","maskItems","pos","prevEditablePos","handleKeyDown","e","input","editPos","chars","newVal","resolvedPlaceholder","corrected","nextPos","handlePaste","pasted","char","cursorPos","handleFocus","_a","handleBlurInternal","jsx","cn"],"mappings":"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"}