{"version":3,"file":"masked-inputs.cjs","names":[],"sources":["../../src/forms/masked-inputs.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport type { InputHTMLAttributes } from \"react\";\nimport { Input, type InputProps } from \"@/components/Input\";\nimport { formatCEP, formatCNPJ } from \"./br-validators\";\nimport { formatCPF, formatPhone } from \"@/utils/format\";\nimport { numberFormat } from \"@/utils/intl-cache\";\n\n/**\n * Props of every masked input.\n *\n * `value` and `onChange` are optional because the primary documented usage is\n * inside `<FormField>`, which supplies both through `cloneElement` — declaring\n * them required made `<FormField name=\"cpf\"><CPFInput /></FormField>` fail to\n * type-check while working perfectly at runtime. Standalone usage still passes\n * both; an uncontrolled input without `onChange` simply reports nothing.\n */\ntype MaskedFieldProps = Omit<InputProps, \"value\" | \"onChange\"> & {\n    value?: string;\n    onChange?: (value: string) => void;\n};\n\nfunction maskedInput(\n    mask: (input: string) => string,\n    inputMode: InputHTMLAttributes<HTMLInputElement>[\"inputMode\"] = \"numeric\",\n) {\n    return forwardRef<HTMLInputElement, MaskedFieldProps>(function MaskedInput(\n        { value, onChange, ...props },\n        ref,\n    ) {\n        return (\n            <Input\n                {...props}\n                ref={ref}\n                value={mask(value ?? \"\")}\n                inputMode={inputMode}\n                onChange={(event) => onChange?.(mask(event.target.value))}\n            />\n        );\n    });\n}\n\nexport const CPFInput = maskedInput(formatCPF);\nexport const CNPJInput = maskedInput(formatCNPJ);\nexport const PhoneInput = maskedInput(formatPhone, \"tel\");\nexport const CEPInput = maskedInput(formatCEP);\n\nexport interface MoneyInputProps extends Omit<InputProps, \"value\" | \"onChange\" | \"type\"> {\n    /** Cents (integer). Internally treated as 1/100 of the currency unit. */\n    value: number;\n    onChange: (cents: number) => void;\n    /** Currency code for `Intl.NumberFormat`. Default: `\"BRL\"`. */\n    currency?: string;\n    /** Locale for `Intl.NumberFormat`. Default: `\"pt-BR\"`. */\n    locale?: string;\n}\n\nfunction formatCents(cents: number, locale: string, currency: string): string {\n    return numberFormat(locale, { style: \"currency\", currency }).format(cents / 100);\n}\n\nfunction parseCents(text: string): number {\n    const digits = text.replace(/\\D/g, \"\");\n    if (!digits) return 0;\n    return Number.parseInt(digits, 10);\n}\n\n/**\n * Currency-masked input. Stores the value as an integer number of cents to\n * avoid floating-point error. Suitable for `react-hook-form` once you adapt\n * the field to expose cents.\n */\nexport const MoneyInput = forwardRef<HTMLInputElement, MoneyInputProps>(function MoneyInput(\n    { value, onChange, currency = \"BRL\", locale = \"pt-BR\", ...props },\n    ref,\n) {\n    return (\n        <Input\n            {...props}\n            ref={ref}\n            type=\"text\"\n            inputMode=\"numeric\"\n            value={formatCents(value || 0, locale, currency)}\n            onChange={(event) => onChange(parseCents(event.target.value))}\n        />\n    );\n});\n"],"mappings":"8MAqBA,SAAS,EACL,EACA,EAAgE,UAClE,CACE,OAAA,EAAO,EAAA,WAAA,CAA+C,SAClD,CAAE,QAAO,WAAU,GAAG,GACtB,EACF,CACE,OACI,EAAA,EAAA,IAAA,CAAC,EAAA,MAAD,CACI,GAAI,EACC,MACL,MAAO,EAAK,GAAS,EAAE,EACZ,YACX,SAAW,GAAU,IAAW,EAAK,EAAM,OAAO,KAAK,CAAC,CAC3D,CAAA,CAET,CAAC,CACL,CAEA,IAAa,EAAW,EAAY,EAAA,SAAS,EAChC,EAAY,EAAY,EAAA,UAAU,EAClC,EAAa,EAAY,EAAA,YAAa,KAAK,EAC3C,EAAW,EAAY,EAAA,SAAS,EAY7C,SAAS,EAAY,EAAe,EAAgB,EAA0B,CAC1E,OAAO,EAAA,aAAa,EAAQ,CAAE,MAAO,WAAY,UAAS,CAAC,CAAC,CAAC,OAAO,EAAQ,GAAG,CACnF,CAEA,SAAS,EAAW,EAAsB,CACtC,IAAM,EAAS,EAAK,QAAQ,MAAO,EAAE,EAErC,OADK,EACE,OAAO,SAAS,EAAQ,EAAE,EADb,CAExB,CAOA,IAAa,GAAA,EAAa,EAAA,WAAA,CAA8C,SACpE,CAAE,QAAO,WAAU,WAAW,MAAO,SAAS,QAAS,GAAG,GAC1D,EACF,CACE,OACI,EAAA,EAAA,IAAA,CAAC,EAAA,MAAD,CACI,GAAI,EACC,MACL,KAAK,OACL,UAAU,UACV,MAAO,EAAY,GAAS,EAAG,EAAQ,CAAQ,EAC/C,SAAW,GAAU,EAAS,EAAW,EAAM,OAAO,KAAK,CAAC,CAC/D,CAAA,CAET,CAAC"}