use-mask-input 3.11.1 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +102 -1
  3. package/dist/antd.cjs +1 -1
  4. package/dist/antd.cjs.map +1 -1
  5. package/dist/antd.d.cts +1 -1
  6. package/dist/antd.d.mts +1 -1
  7. package/dist/antd.mjs +1 -1
  8. package/dist/antd.mjs.map +1 -1
  9. package/dist/{withMask-BQpBm8zG.cjs → core-BopfTGvA.cjs} +2 -2
  10. package/dist/core-BopfTGvA.cjs.map +1 -0
  11. package/dist/{withMask-DlC13MV7.mjs → core-CNGYEIpO.mjs} +2 -2
  12. package/dist/core-CNGYEIpO.mjs.map +1 -0
  13. package/dist/{index-HfKPnOg0.d.cts → index-CqBLkcNO.d.cts} +12 -3
  14. package/dist/{index-HfKPnOg0.d.mts → index-CqBLkcNO.d.mts} +12 -3
  15. package/dist/index-DAfluDSv.d.cts +25 -0
  16. package/dist/index-DGAwRzYx.d.mts +25 -0
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +2 -23
  20. package/dist/index.d.mts +2 -23
  21. package/dist/index.mjs +1 -1
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/vue.cjs +2 -0
  24. package/dist/vue.cjs.map +1 -0
  25. package/dist/vue.d.cts +92 -0
  26. package/dist/vue.d.mts +92 -0
  27. package/dist/vue.mjs +2 -0
  28. package/dist/vue.mjs.map +1 -0
  29. package/dist/withMask--iSmiRbB.cjs +2 -0
  30. package/dist/withMask--iSmiRbB.cjs.map +1 -0
  31. package/dist/withMask-DOmJHTJ4.mjs +2 -0
  32. package/dist/withMask-DOmJHTJ4.mjs.map +1 -0
  33. package/package.json +50 -6
  34. package/src/@types/inputmask.d.ts +6 -0
  35. package/src/types/index.ts +6 -26
  36. package/src/types/mask.ts +37 -0
  37. package/src/vue/applyMask.ts +99 -0
  38. package/src/vue/directive.ts +59 -0
  39. package/src/vue/index.ts +13 -0
  40. package/src/vue/resolveVueElement.ts +34 -0
  41. package/src/vue/types.ts +35 -0
  42. package/src/vue/useMaskInput.ts +56 -0
  43. package/dist/withMask-BQpBm8zG.cjs.map +0 -1
  44. package/dist/withMask-DlC13MV7.mjs.map +0 -1
@@ -809,13 +809,22 @@ interface CommandObject {
809
809
  rewritePosition?: number | undefined;
810
810
  }
811
811
  //#endregion
812
- //#region src/types/index.d.ts
812
+ //#region src/types/mask.d.ts
813
+ /**
814
+ * Framework-agnostic mask types.
815
+ *
816
+ * Split out of `./index.ts` so the Vue entry can import them without dragging
817
+ * in that module's `react` and `react-hook-form` type imports. `./index.ts`
818
+ * re-exports everything here, so the React-facing surface is unchanged.
819
+ */
813
820
  type Mask = 'datetime' | 'email' | 'numeric' | 'currency' | 'decimal' | 'integer' | 'percentage' | 'url' | 'ip' | 'mac' | 'ssn' | 'brl-currency' | 'cpf' | 'cnpj' | 'br-bank-account' | 'br-bank-agency' | (string & {}) | (string[] & {}) | null;
814
821
  type Options = Options$1;
815
822
  type Input = HTMLInputElement | HTMLTextAreaElement | HTMLElement;
816
823
  interface UnmaskedValueApi {
817
824
  unmaskedValue: () => string;
818
825
  }
826
+ //#endregion
827
+ //#region src/types/index.d.ts
819
828
  type UseMaskInputReturn = RefCallback<HTMLElement | null> & UnmaskedValueApi;
820
829
  interface UseHookFormMaskReturn<T extends FieldValues> extends UseFormRegisterReturn<Path<T>>, UnmaskedValueApi {
821
830
  ref: RefCallback<HTMLElement | null>;
@@ -834,5 +843,5 @@ type UseTanStackFormMaskReturn<T extends TanStackFormInputProps = TanStackFormIn
834
843
  prevRef: RefCallback<HTMLElement | null> | undefined;
835
844
  } & UnmaskedValueApi;
836
845
  //#endregion
837
- export { UnmaskedValueApi as a, UseTanStackFormMaskReturn as c, UseFormRegister as d, UseFormRegisterReturn as f, TanStackFormInputProps as i, RegisterOptions as l, Mask as n, UseHookFormMaskReturn as o, Path as p, Options as r, UseMaskInputReturn as s, Input as t, FieldValues as u };
838
- //# sourceMappingURL=index-HfKPnOg0.d.cts.map
846
+ export { Input as a, UnmaskedValueApi as c, UseFormRegister as d, UseFormRegisterReturn as f, UseTanStackFormMaskReturn as i, RegisterOptions as l, UseHookFormMaskReturn as n, Mask as o, Path as p, UseMaskInputReturn as r, Options as s, TanStackFormInputProps as t, FieldValues as u };
847
+ //# sourceMappingURL=index-CqBLkcNO.d.cts.map
@@ -809,13 +809,22 @@ interface CommandObject {
809
809
  rewritePosition?: number | undefined;
810
810
  }
811
811
  //#endregion
812
- //#region src/types/index.d.ts
812
+ //#region src/types/mask.d.ts
813
+ /**
814
+ * Framework-agnostic mask types.
815
+ *
816
+ * Split out of `./index.ts` so the Vue entry can import them without dragging
817
+ * in that module's `react` and `react-hook-form` type imports. `./index.ts`
818
+ * re-exports everything here, so the React-facing surface is unchanged.
819
+ */
813
820
  type Mask = 'datetime' | 'email' | 'numeric' | 'currency' | 'decimal' | 'integer' | 'percentage' | 'url' | 'ip' | 'mac' | 'ssn' | 'brl-currency' | 'cpf' | 'cnpj' | 'br-bank-account' | 'br-bank-agency' | (string & {}) | (string[] & {}) | null;
814
821
  type Options = Options$1;
815
822
  type Input = HTMLInputElement | HTMLTextAreaElement | HTMLElement;
816
823
  interface UnmaskedValueApi {
817
824
  unmaskedValue: () => string;
818
825
  }
826
+ //#endregion
827
+ //#region src/types/index.d.ts
819
828
  type UseMaskInputReturn = RefCallback<HTMLElement | null> & UnmaskedValueApi;
820
829
  interface UseHookFormMaskReturn<T extends FieldValues> extends UseFormRegisterReturn<Path<T>>, UnmaskedValueApi {
821
830
  ref: RefCallback<HTMLElement | null>;
@@ -834,5 +843,5 @@ type UseTanStackFormMaskReturn<T extends TanStackFormInputProps = TanStackFormIn
834
843
  prevRef: RefCallback<HTMLElement | null> | undefined;
835
844
  } & UnmaskedValueApi;
836
845
  //#endregion
837
- export { UnmaskedValueApi as a, UseTanStackFormMaskReturn as c, UseFormRegister as d, UseFormRegisterReturn as f, TanStackFormInputProps as i, RegisterOptions as l, Mask as n, UseHookFormMaskReturn as o, Path as p, Options as r, UseMaskInputReturn as s, Input as t, FieldValues as u };
838
- //# sourceMappingURL=index-HfKPnOg0.d.mts.map
846
+ export { Input as a, UnmaskedValueApi as c, UseFormRegister as d, UseFormRegisterReturn as f, UseTanStackFormMaskReturn as i, RegisterOptions as l, UseHookFormMaskReturn as n, Mask as o, Path as p, UseMaskInputReturn as r, Options as s, TanStackFormInputProps as t, FieldValues as u };
847
+ //# sourceMappingURL=index-CqBLkcNO.d.mts.map
@@ -0,0 +1,25 @@
1
+ import { o as Mask, s as Options } from "./index-CqBLkcNO.cjs";
2
+ //#region src/core/maskEngine.d.ts
3
+ /**
4
+ * Formats a raw value using the given mask, without needing a mounted element.
5
+ * Useful for displaying already-persisted (unmasked) values in the UI.
6
+ *
7
+ * @param value - The raw value to format
8
+ * @param mask - The mask pattern
9
+ * @param options - Optional configuration options
10
+ * @returns The masked value
11
+ */
12
+ declare function formatWithMask(value: string, mask: Mask, options?: Options): string;
13
+ /**
14
+ * Removes the mask from a formatted value, without needing a mounted element.
15
+ * Useful for sanitizing input before sending it to the backend.
16
+ *
17
+ * @param value - The masked value to unformat
18
+ * @param mask - The mask pattern
19
+ * @param options - Optional configuration options
20
+ * @returns The raw, unmasked value
21
+ */
22
+ declare function unformatWithMask(value: string, mask: Mask, options?: Options): string;
23
+ //#endregion
24
+ export { unformatWithMask as n, formatWithMask as t };
25
+ //# sourceMappingURL=index-DAfluDSv.d.cts.map
@@ -0,0 +1,25 @@
1
+ import { o as Mask, s as Options } from "./index-CqBLkcNO.mjs";
2
+ //#region src/core/maskEngine.d.ts
3
+ /**
4
+ * Formats a raw value using the given mask, without needing a mounted element.
5
+ * Useful for displaying already-persisted (unmasked) values in the UI.
6
+ *
7
+ * @param value - The raw value to format
8
+ * @param mask - The mask pattern
9
+ * @param options - Optional configuration options
10
+ * @returns The masked value
11
+ */
12
+ declare function formatWithMask(value: string, mask: Mask, options?: Options): string;
13
+ /**
14
+ * Removes the mask from a formatted value, without needing a mounted element.
15
+ * Useful for sanitizing input before sending it to the backend.
16
+ *
17
+ * @param value - The masked value to unformat
18
+ * @param mask - The mask pattern
19
+ * @param options - Optional configuration options
20
+ * @returns The raw, unmasked value
21
+ */
22
+ declare function unformatWithMask(value: string, mask: Mask, options?: Options): string;
23
+ //#endregion
24
+ export { unformatWithMask as n, formatWithMask as t };
25
+ //# sourceMappingURL=index-DGAwRzYx.d.mts.map
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./withMask-BQpBm8zG.cjs");let t=require("react");function n(...e){let{length:t}=e,n=t;for(;n>0;)if(--n,typeof e[n]!=`function`)throw TypeError(`Expected a function`);return(...n)=>{let r=0,i=t?e[r].apply(void 0,n):n[0];for(;r+1<t;)r+=1,i=e[r].call(void 0,i);return i}}function r(n){let{mask:r,register:i,options:a}=n,o=(0,t.useRef)(null),s=(0,t.useRef)(r),c=(0,t.useRef)(a),l=(0,t.useCallback)(()=>e.a(o.current),[]),u=(0,t.useCallback)(t=>{if(!t){o.current=null;return}o.current=e.u(t),e.t(s.current,c.current)(o.current)},[]);return(0,t.useEffect)(()=>{e.l||!o.current||!i||i(o.current)},[i]),e.l?e.c((()=>{}),()=>``):e.c(u,l)}function i(r){let i=(0,t.useRef)(new Map);return(0,t.useLayoutEffect)(()=>{i.current.forEach(e=>{let t=e;!t.element||!t.latestRHFRef||t.latestRHFRef!==t.syncedRHFRef&&(t.latestRHFRef(t.element),t.syncedRHFRef=t.latestRHFRef)})}),(0,t.useMemo)(()=>(i.current=new Map,(t,a,o)=>{if(!r)throw Error(`registerFn is required`);let s=r(t,o),{ref:c}=s,l=e.o(t,a),u=i.current.get(l);if(u)u.latestRHFRef=c;else{let t={element:null,latestRHFRef:c,syncedRHFRef:void 0,stableRef:null},r=n=>(t.element=n,n&&e.n(n,a,o),n),s=t.latestRHFRef?n(e=>(t.latestRHFRef?.(e),e),r):r;t.stableRef=(e=>{s(e)}),u=t,i.current.set(l,t)}let d={...s,ref:u.stableRef};return e.c(d,()=>e.a(u?.element??null)),e.s(d,c),d}),[r])}const a=new WeakMap;function o(t,n,r){let{ref:i}=t;if(!i){let a=null,o={...t,ref:(t=>{a=t,t&&e.n(t,n,r)})};return e.c(o,()=>e.a(a)),e.s(o,i),o}a.has(i)||a.set(i,new Map);let o=a.get(i),s=e.o(t.name??``,n);if(!o?.has(s)){let t=(a=>{t.currentElement=a,a&&e.n(a,n,r),i(a)});o?.set(s,t)}let c=o?.get(s),l={...t,ref:c};return e.c(l,()=>e.a(c?.currentElement??null)),e.s(l,i),l}function s(){return(0,t.useMemo)(()=>(e,t,n)=>o(t,e,n),[])}const c=new WeakMap;function l(t,n,r){let{ref:i}=t;if(!i){let n={...t,ref:null};return e.c(n,()=>``),e.s(n,i),n}c.has(i)||c.set(i,new Map);let a=c.get(i),o=e.o(t.name,n);if(!a?.has(o)){let t=(a=>(t.currentElement=a,a&&e.n(a,n,r),i(a)));a?.set(o,t)}let s=a?.get(o),l={...t,ref:s};return e.c(l,()=>e.a(s?.currentElement??null)),e.s(l,i),l}exports.formatWithMask=e.r,exports.unformatWithMask=e.i,exports.useHookFormMask=i,exports.useMaskInput=r,exports.useTanStackFormMask=s,exports.withHookFormMask=l,exports.withMask=e.t,exports.withTanStackFormMask=o;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./core-BopfTGvA.cjs"),t=require("./withMask--iSmiRbB.cjs");let n=require("react");function r(...e){let{length:t}=e,n=t;for(;n>0;)if(--n,typeof e[n]!=`function`)throw TypeError(`Expected a function`);return(...n)=>{let r=0,i=t?e[r].apply(void 0,n):n[0];for(;r+1<t;)r+=1,i=e[r].call(void 0,i);return i}}function i(r){let{mask:i,register:a,options:o}=r,s=(0,n.useRef)(null),c=(0,n.useRef)(i),l=(0,n.useRef)(o),u=(0,n.useCallback)(()=>e.a(s.current),[]),d=(0,n.useCallback)(n=>{if(!n){s.current=null;return}s.current=e.h(n),t.t(c.current,l.current)(s.current)},[]);return(0,n.useEffect)(()=>{e.u||!s.current||!a||a(s.current)},[a]),e.u?e.c((()=>{}),()=>``):e.c(d,u)}function a(t){let i=(0,n.useRef)(new Map);return(0,n.useLayoutEffect)(()=>{i.current.forEach(e=>{let t=e;!t.element||!t.latestRHFRef||t.latestRHFRef!==t.syncedRHFRef&&(t.latestRHFRef(t.element),t.syncedRHFRef=t.latestRHFRef)})}),(0,n.useMemo)(()=>(i.current=new Map,(n,a,o)=>{if(!t)throw Error(`registerFn is required`);let s=t(n,o),{ref:c}=s,l=e.o(n,a),u=i.current.get(l);if(u)u.latestRHFRef=c;else{let t={element:null,latestRHFRef:c,syncedRHFRef:void 0,stableRef:null},n=n=>(t.element=n,n&&e.t(n,a,o),n),s=t.latestRHFRef?r(e=>(t.latestRHFRef?.(e),e),n):n;t.stableRef=(e=>{s(e)}),u=t,i.current.set(l,t)}let d={...s,ref:u.stableRef};return e.c(d,()=>e.a(u?.element??null)),e.s(d,c),d}),[t])}const o=new WeakMap;function s(t,n,r){let{ref:i}=t;if(!i){let a=null,o={...t,ref:(t=>{a=t,t&&e.t(t,n,r)})};return e.c(o,()=>e.a(a)),e.s(o,i),o}o.has(i)||o.set(i,new Map);let a=o.get(i),s=e.o(t.name??``,n);if(!a?.has(s)){let t=(a=>{t.currentElement=a,a&&e.t(a,n,r),i(a)});a?.set(s,t)}let c=a?.get(s),l={...t,ref:c};return e.c(l,()=>e.a(c?.currentElement??null)),e.s(l,i),l}function c(){return(0,n.useMemo)(()=>(e,t,n)=>s(t,e,n),[])}const l=new WeakMap;function u(t,n,r){let{ref:i}=t;if(!i){let n={...t,ref:null};return e.c(n,()=>``),e.s(n,i),n}l.has(i)||l.set(i,new Map);let a=l.get(i),o=e.o(t.name,n);if(!a?.has(o)){let t=(a=>(t.currentElement=a,a&&e.t(a,n,r),i(a)));a?.set(o,t)}let s=a?.get(o),c={...t,ref:s};return e.c(c,()=>e.a(s?.currentElement??null)),e.s(c,i),c}exports.formatWithMask=e.n,exports.unformatWithMask=e.i,exports.useHookFormMask=a,exports.useMaskInput=i,exports.useTanStackFormMask=c,exports.withHookFormMask=u,exports.withMask=t.t,exports.withTanStackFormMask=s;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["getUnmaskedValue","resolveInputRef","isServer","setUnmaskedValue","makeMaskCacheKey","getUnmaskedValue","refCache","getUnmaskedValue","makeMaskCacheKey","makeMaskCacheKey","getUnmaskedValue"],"sources":["../src/utils/flow.ts","../src/api/useMaskInput.ts","../src/api/useHookFormMask.ts","../src/api/withTanStackFormMask.ts","../src/api/useTanStackFormMask.ts","../src/api/withHookFormMask.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\nexport default function flow(...funcs: Function[]): Function {\n const { length } = funcs;\n let index = length;\n while (index > 0) {\n index -= 1;\n if (typeof funcs[index] !== 'function') {\n throw new TypeError('Expected a function');\n }\n }\n return (...args: Function[]) => {\n let i = 0;\n let result = length ? funcs[i].apply(undefined, args) : args[0];\n while (i + 1 < length) {\n i += 1;\n result = funcs[i].call(undefined, result);\n }\n return result;\n };\n}\n","import {\n useCallback, useEffect, useRef,\n} from 'react';\n\nimport { resolveInputRef } from '../core';\nimport withMask from './withMask';\nimport isServer from '../utils/isServer';\nimport { getUnmaskedValue, setUnmaskedValue } from '../utils';\n\nimport type {\n Input, Mask, Options, UseMaskInputReturn,\n} from '../types';\n\ninterface UseMaskInputOptions {\n mask: Mask;\n register?: (element: HTMLElement) => void;\n options?: Options;\n}\n\n/**\n * React hook for applying input masks to form elements.\n * Works with Ant Design and other wrapped components too.\n *\n * @param props - Configuration object\n * @param props.mask - The mask pattern to apply\n * @param props.register - Optional callback that receives the element\n * @param props.options - Optional mask configuration options\n * @returns A ref callback function to attach to the input element\n */\nexport default function useMaskInput(props: UseMaskInputOptions): UseMaskInputReturn {\n const { mask, register, options } = props;\n const ref = useRef<HTMLInputElement | null>(null);\n const maskRef = useRef(mask);\n const optionsRef = useRef(options);\n const unmaskedValue = useCallback(() => getUnmaskedValue(ref.current), []);\n\n const refCallback = useCallback((input: Input | null): void => {\n if (!input) {\n ref.current = null;\n return;\n }\n\n ref.current = resolveInputRef(input);\n withMask(maskRef.current, optionsRef.current)(ref.current);\n }, []);\n\n useEffect(() => {\n if (isServer || !ref.current || !register) return;\n register(ref.current);\n }, [register]);\n\n if (isServer) {\n const noop = (() => {\n // server doesn't have dom, so just do nothing\n }) as unknown as UseMaskInputReturn;\n\n return setUnmaskedValue(noop, () => '');\n }\n\n return setUnmaskedValue(refCallback, unmaskedValue);\n}\n","import { useLayoutEffect, useMemo, useRef } from 'react';\n\nimport { applyMaskToElement } from '../core';\nimport {\n flow, getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type {\n FieldValues, Path,\n RegisterOptions,\n UseFormRegister,\n} from 'react-hook-form';\n\nimport type { Mask, Options, UseHookFormMaskReturn } from '../types';\n\ninterface CacheEntry {\n stableRef: RefCallback<HTMLElement | null>;\n element: HTMLElement | null;\n latestRHFRef?: RefCallback<HTMLElement | null>;\n syncedRHFRef?: RefCallback<HTMLElement | null>;\n}\n\n/**\n * Creates a masked version of React Hook Form's register function.\n * Takes react-hook-form's register and adds automatic masking. Like an upgrade.\n *\n * @template T - The form data type\n * @template D - The register options type\n * @param registerFn - The register function from useForm hook\n * @returns A function that registers a field with mask support\n */\nexport default function useHookFormMask<\n T extends FieldValues, D extends RegisterOptions,\n>(registerFn: UseFormRegister<T>): ((fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D) => UseHookFormMaskReturn<T>) {\n const entryCacheRef = useRef(new Map<string, CacheEntry>());\n\n useLayoutEffect(() => {\n entryCacheRef.current.forEach((entry) => {\n const currentEntry = entry;\n if (!currentEntry.element || !currentEntry.latestRHFRef) return;\n\n // After reset(), RHF gives us a new ref callback. React won't call it\n // because our outward ref identity stays stable, so we replay it here.\n if (currentEntry.latestRHFRef !== currentEntry.syncedRHFRef) {\n currentEntry.latestRHFRef(currentEntry.element);\n currentEntry.syncedRHFRef = currentEntry.latestRHFRef;\n }\n });\n });\n\n return useMemo(() => {\n // registerFn identity changed, so drop cached refs bound to the previous\n // register lifecycle.\n entryCacheRef.current = new Map<string, CacheEntry>();\n\n return (fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D): UseHookFormMaskReturn<T> => {\n if (!registerFn) throw new Error('registerFn is required');\n\n const registerReturn = registerFn(fieldName, options as Options);\n const { ref } = registerReturn as UseHookFormMaskReturn<T>;\n\n const cacheKey = makeMaskCacheKey(fieldName, mask);\n\n let entry = entryCacheRef.current.get(cacheKey);\n if (!entry) {\n const nextEntry: CacheEntry = {\n element: null,\n latestRHFRef: ref,\n syncedRHFRef: undefined,\n stableRef: null as unknown as RefCallback<HTMLElement | null>,\n };\n\n const applyMaskToRef = (_ref: HTMLElement | null) => {\n nextEntry.element = _ref;\n if (_ref) applyMaskToElement(_ref, mask, options as Options);\n return _ref;\n };\n\n // RHF must run first: it writes the field's predefined value onto the\n // element. If we masked before that, Inputmask would initialise with an\n // empty buffer and RHF's later value assignment would leave its internal\n // state out of sync with the DOM, swallowing the first onChange after a\n // select-all + delete (#193). Masking after RHF seeds Inputmask with the\n // current value, keeping its buffer in sync from the start.\n const syncRHFRef = (_ref: HTMLElement | null) => {\n nextEntry.latestRHFRef?.(_ref);\n return _ref;\n };\n\n const composedRef = nextEntry.latestRHFRef\n ? flow(syncRHFRef, applyMaskToRef)\n : applyMaskToRef;\n\n // React 19 treats a ref callback's return value as a cleanup function,\n // so the composed callback must return void — never the resolved element.\n nextEntry.stableRef = ((_ref: HTMLElement | null): void => {\n composedRef(_ref);\n }) as RefCallback<HTMLElement | null>;\n\n entry = nextEntry;\n entryCacheRef.current.set(cacheKey, nextEntry);\n } else {\n entry.latestRHFRef = ref;\n }\n\n const result = {\n ...registerReturn,\n ref: entry.stableRef,\n } as UseHookFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(entry?.element ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n };\n }, [registerFn]);\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\n\nimport type {\n Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances TanStack Form-compatible input props with mask support.\n * Works with objects returned by field.getInputProps().\n */\nexport default function withTanStackFormMask<T extends TanStackFormInputProps>(\n inputProps: T,\n mask: Mask,\n options?: Options,\n): UseTanStackFormMaskReturn<T> {\n const { ref } = inputProps;\n\n if (!ref) {\n let currentElement: HTMLElement | null = null;\n const result = {\n ...inputProps,\n ref: ((input: HTMLElement | null) => {\n currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n }) as RefCallback<HTMLElement | null>,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(currentElement));\n\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(inputProps.name ?? '', mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...inputProps,\n ref: maskedRef,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n return result;\n}\n","import { useMemo } from 'react';\n\nimport withTanStackFormMask from './withTanStackFormMask';\n\nimport type { Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn } from '../types';\n\n/**\n * Creates a helper to mask TanStack Form-compatible input props.\n * Designed for objects returned by field.getInputProps().\n */\nexport default function useTanStackFormMask(): <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n) => UseTanStackFormMaskReturn<T> {\n return useMemo(\n () => <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n ): UseTanStackFormMaskReturn<T> => withTanStackFormMask(inputProps, mask, options),\n [],\n );\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type { FieldValues } from 'react-hook-form';\n\nimport type {\n Mask, Options, UseFormRegisterReturn, UseHookFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances a React Hook Form register return object with mask support.\n * Takes an already registered field and adds mask to it.\n * Useful when you registered the field before.\n *\n * @param register - The register return object from React Hook Form\n * @param mask - The mask pattern to apply\n * @param options - Optional mask configuration options\n * @returns A new register return object with mask applied\n */\nexport default function withHookFormMask(\n register: UseFormRegisterReturn,\n mask: Mask,\n options?: Options,\n): UseHookFormMaskReturn<FieldValues> {\n const { ref } = register as UseHookFormMaskReturn<FieldValues>;\n\n // null ref — nothing to cache, return as-is.\n if (!ref) {\n const result = {\n ...register,\n ref: null as unknown as RefCallback<HTMLElement | null>,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => '');\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(register.name, mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n return ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...register,\n ref: maskedRef,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["getUnmaskedValue","resolveInputRef","isServer","setUnmaskedValue","makeMaskCacheKey","getUnmaskedValue","refCache","getUnmaskedValue","makeMaskCacheKey","makeMaskCacheKey","getUnmaskedValue"],"sources":["../src/utils/flow.ts","../src/api/useMaskInput.ts","../src/api/useHookFormMask.ts","../src/api/withTanStackFormMask.ts","../src/api/useTanStackFormMask.ts","../src/api/withHookFormMask.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\nexport default function flow(...funcs: Function[]): Function {\n const { length } = funcs;\n let index = length;\n while (index > 0) {\n index -= 1;\n if (typeof funcs[index] !== 'function') {\n throw new TypeError('Expected a function');\n }\n }\n return (...args: Function[]) => {\n let i = 0;\n let result = length ? funcs[i].apply(undefined, args) : args[0];\n while (i + 1 < length) {\n i += 1;\n result = funcs[i].call(undefined, result);\n }\n return result;\n };\n}\n","import {\n useCallback, useEffect, useRef,\n} from 'react';\n\nimport { resolveInputRef } from '../core';\nimport withMask from './withMask';\nimport isServer from '../utils/isServer';\nimport { getUnmaskedValue, setUnmaskedValue } from '../utils';\n\nimport type {\n Input, Mask, Options, UseMaskInputReturn,\n} from '../types';\n\ninterface UseMaskInputOptions {\n mask: Mask;\n register?: (element: HTMLElement) => void;\n options?: Options;\n}\n\n/**\n * React hook for applying input masks to form elements.\n * Works with Ant Design and other wrapped components too.\n *\n * @param props - Configuration object\n * @param props.mask - The mask pattern to apply\n * @param props.register - Optional callback that receives the element\n * @param props.options - Optional mask configuration options\n * @returns A ref callback function to attach to the input element\n */\nexport default function useMaskInput(props: UseMaskInputOptions): UseMaskInputReturn {\n const { mask, register, options } = props;\n const ref = useRef<HTMLInputElement | null>(null);\n const maskRef = useRef(mask);\n const optionsRef = useRef(options);\n const unmaskedValue = useCallback(() => getUnmaskedValue(ref.current), []);\n\n const refCallback = useCallback((input: Input | null): void => {\n if (!input) {\n ref.current = null;\n return;\n }\n\n ref.current = resolveInputRef(input);\n withMask(maskRef.current, optionsRef.current)(ref.current);\n }, []);\n\n useEffect(() => {\n if (isServer || !ref.current || !register) return;\n register(ref.current);\n }, [register]);\n\n if (isServer) {\n const noop = (() => {\n // server doesn't have dom, so just do nothing\n }) as unknown as UseMaskInputReturn;\n\n return setUnmaskedValue(noop, () => '');\n }\n\n return setUnmaskedValue(refCallback, unmaskedValue);\n}\n","import { useLayoutEffect, useMemo, useRef } from 'react';\n\nimport { applyMaskToElement } from '../core';\nimport {\n flow, getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type {\n FieldValues, Path,\n RegisterOptions,\n UseFormRegister,\n} from 'react-hook-form';\n\nimport type { Mask, Options, UseHookFormMaskReturn } from '../types';\n\ninterface CacheEntry {\n stableRef: RefCallback<HTMLElement | null>;\n element: HTMLElement | null;\n latestRHFRef?: RefCallback<HTMLElement | null>;\n syncedRHFRef?: RefCallback<HTMLElement | null>;\n}\n\n/**\n * Creates a masked version of React Hook Form's register function.\n * Takes react-hook-form's register and adds automatic masking. Like an upgrade.\n *\n * @template T - The form data type\n * @template D - The register options type\n * @param registerFn - The register function from useForm hook\n * @returns A function that registers a field with mask support\n */\nexport default function useHookFormMask<\n T extends FieldValues, D extends RegisterOptions,\n>(registerFn: UseFormRegister<T>): ((fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D) => UseHookFormMaskReturn<T>) {\n const entryCacheRef = useRef(new Map<string, CacheEntry>());\n\n useLayoutEffect(() => {\n entryCacheRef.current.forEach((entry) => {\n const currentEntry = entry;\n if (!currentEntry.element || !currentEntry.latestRHFRef) return;\n\n // After reset(), RHF gives us a new ref callback. React won't call it\n // because our outward ref identity stays stable, so we replay it here.\n if (currentEntry.latestRHFRef !== currentEntry.syncedRHFRef) {\n currentEntry.latestRHFRef(currentEntry.element);\n currentEntry.syncedRHFRef = currentEntry.latestRHFRef;\n }\n });\n });\n\n return useMemo(() => {\n // registerFn identity changed, so drop cached refs bound to the previous\n // register lifecycle.\n entryCacheRef.current = new Map<string, CacheEntry>();\n\n return (fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D): UseHookFormMaskReturn<T> => {\n if (!registerFn) throw new Error('registerFn is required');\n\n const registerReturn = registerFn(fieldName, options as Options);\n const { ref } = registerReturn as UseHookFormMaskReturn<T>;\n\n const cacheKey = makeMaskCacheKey(fieldName, mask);\n\n let entry = entryCacheRef.current.get(cacheKey);\n if (!entry) {\n const nextEntry: CacheEntry = {\n element: null,\n latestRHFRef: ref,\n syncedRHFRef: undefined,\n stableRef: null as unknown as RefCallback<HTMLElement | null>,\n };\n\n const applyMaskToRef = (_ref: HTMLElement | null) => {\n nextEntry.element = _ref;\n if (_ref) applyMaskToElement(_ref, mask, options as Options);\n return _ref;\n };\n\n // RHF must run first: it writes the field's predefined value onto the\n // element. If we masked before that, Inputmask would initialise with an\n // empty buffer and RHF's later value assignment would leave its internal\n // state out of sync with the DOM, swallowing the first onChange after a\n // select-all + delete (#193). Masking after RHF seeds Inputmask with the\n // current value, keeping its buffer in sync from the start.\n const syncRHFRef = (_ref: HTMLElement | null) => {\n nextEntry.latestRHFRef?.(_ref);\n return _ref;\n };\n\n const composedRef = nextEntry.latestRHFRef\n ? flow(syncRHFRef, applyMaskToRef)\n : applyMaskToRef;\n\n // React 19 treats a ref callback's return value as a cleanup function,\n // so the composed callback must return void — never the resolved element.\n nextEntry.stableRef = ((_ref: HTMLElement | null): void => {\n composedRef(_ref);\n }) as RefCallback<HTMLElement | null>;\n\n entry = nextEntry;\n entryCacheRef.current.set(cacheKey, nextEntry);\n } else {\n entry.latestRHFRef = ref;\n }\n\n const result = {\n ...registerReturn,\n ref: entry.stableRef,\n } as UseHookFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(entry?.element ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n };\n }, [registerFn]);\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\n\nimport type {\n Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances TanStack Form-compatible input props with mask support.\n * Works with objects returned by field.getInputProps().\n */\nexport default function withTanStackFormMask<T extends TanStackFormInputProps>(\n inputProps: T,\n mask: Mask,\n options?: Options,\n): UseTanStackFormMaskReturn<T> {\n const { ref } = inputProps;\n\n if (!ref) {\n let currentElement: HTMLElement | null = null;\n const result = {\n ...inputProps,\n ref: ((input: HTMLElement | null) => {\n currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n }) as RefCallback<HTMLElement | null>,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(currentElement));\n\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(inputProps.name ?? '', mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...inputProps,\n ref: maskedRef,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n return result;\n}\n","import { useMemo } from 'react';\n\nimport withTanStackFormMask from './withTanStackFormMask';\n\nimport type { Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn } from '../types';\n\n/**\n * Creates a helper to mask TanStack Form-compatible input props.\n * Designed for objects returned by field.getInputProps().\n */\nexport default function useTanStackFormMask(): <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n) => UseTanStackFormMaskReturn<T> {\n return useMemo(\n () => <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n ): UseTanStackFormMaskReturn<T> => withTanStackFormMask(inputProps, mask, options),\n [],\n );\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type { FieldValues } from 'react-hook-form';\n\nimport type {\n Mask, Options, UseFormRegisterReturn, UseHookFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances a React Hook Form register return object with mask support.\n * Takes an already registered field and adds mask to it.\n * Useful when you registered the field before.\n *\n * @param register - The register return object from React Hook Form\n * @param mask - The mask pattern to apply\n * @param options - Optional mask configuration options\n * @returns A new register return object with mask applied\n */\nexport default function withHookFormMask(\n register: UseFormRegisterReturn,\n mask: Mask,\n options?: Options,\n): UseHookFormMaskReturn<FieldValues> {\n const { ref } = register as UseHookFormMaskReturn<FieldValues>;\n\n // null ref — nothing to cache, return as-is.\n if (!ref) {\n const result = {\n ...register,\n ref: null as unknown as RefCallback<HTMLElement | null>,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => '');\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(register.name, mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n return ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...register,\n ref: maskedRef,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
- import { a as UnmaskedValueApi, c as UseTanStackFormMaskReturn, d as UseFormRegister, f as UseFormRegisterReturn, i as TanStackFormInputProps, l as RegisterOptions, n as Mask, o as UseHookFormMaskReturn, p as Path, r as Options, s as UseMaskInputReturn, t as Input, u as FieldValues } from "./index-HfKPnOg0.cjs";
1
+ import { a as Input, c as UnmaskedValueApi, d as UseFormRegister, f as UseFormRegisterReturn, i as UseTanStackFormMaskReturn, l as RegisterOptions, n as UseHookFormMaskReturn, o as Mask, p as Path, r as UseMaskInputReturn, s as Options, t as TanStackFormInputProps, u as FieldValues } from "./index-CqBLkcNO.cjs";
2
+ import { n as unformatWithMask, t as formatWithMask } from "./index-DAfluDSv.cjs";
2
3
  //#region src/api/useMaskInput.d.ts
3
4
  interface UseMaskInputOptions {
4
5
  mask: Mask;
@@ -67,27 +68,5 @@ declare function withHookFormMask(register: UseFormRegisterReturn, mask: Mask, o
67
68
  */
68
69
  declare function withTanStackFormMask<T extends TanStackFormInputProps>(inputProps: T, mask: Mask, options?: Options): UseTanStackFormMaskReturn<T>;
69
70
  //#endregion
70
- //#region src/core/maskEngine.d.ts
71
- /**
72
- * Formats a raw value using the given mask, without needing a mounted element.
73
- * Useful for displaying already-persisted (unmasked) values in the UI.
74
- *
75
- * @param value - The raw value to format
76
- * @param mask - The mask pattern
77
- * @param options - Optional configuration options
78
- * @returns The masked value
79
- */
80
- declare function formatWithMask(value: string, mask: Mask, options?: Options): string;
81
- /**
82
- * Removes the mask from a formatted value, without needing a mounted element.
83
- * Useful for sanitizing input before sending it to the backend.
84
- *
85
- * @param value - The masked value to unformat
86
- * @param mask - The mask pattern
87
- * @param options - Optional configuration options
88
- * @returns The raw, unmasked value
89
- */
90
- declare function unformatWithMask(value: string, mask: Mask, options?: Options): string;
91
- //#endregion
92
71
  export { type Input, type Mask, type Options, type TanStackFormInputProps, type UnmaskedValueApi, type UseFormRegister, type UseFormRegisterReturn, type UseMaskInputReturn, type UseTanStackFormMaskReturn, formatWithMask, unformatWithMask, useHookFormMask, useMaskInput, useTanStackFormMask, withHookFormMask, withMask, withTanStackFormMask };
93
72
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { a as UnmaskedValueApi, c as UseTanStackFormMaskReturn, d as UseFormRegister, f as UseFormRegisterReturn, i as TanStackFormInputProps, l as RegisterOptions, n as Mask, o as UseHookFormMaskReturn, p as Path, r as Options, s as UseMaskInputReturn, t as Input, u as FieldValues } from "./index-HfKPnOg0.mjs";
1
+ import { a as Input, c as UnmaskedValueApi, d as UseFormRegister, f as UseFormRegisterReturn, i as UseTanStackFormMaskReturn, l as RegisterOptions, n as UseHookFormMaskReturn, o as Mask, p as Path, r as UseMaskInputReturn, s as Options, t as TanStackFormInputProps, u as FieldValues } from "./index-CqBLkcNO.mjs";
2
+ import { n as unformatWithMask, t as formatWithMask } from "./index-DGAwRzYx.mjs";
2
3
  //#region src/api/useMaskInput.d.ts
3
4
  interface UseMaskInputOptions {
4
5
  mask: Mask;
@@ -67,27 +68,5 @@ declare function withHookFormMask(register: UseFormRegisterReturn, mask: Mask, o
67
68
  */
68
69
  declare function withTanStackFormMask<T extends TanStackFormInputProps>(inputProps: T, mask: Mask, options?: Options): UseTanStackFormMaskReturn<T>;
69
70
  //#endregion
70
- //#region src/core/maskEngine.d.ts
71
- /**
72
- * Formats a raw value using the given mask, without needing a mounted element.
73
- * Useful for displaying already-persisted (unmasked) values in the UI.
74
- *
75
- * @param value - The raw value to format
76
- * @param mask - The mask pattern
77
- * @param options - Optional configuration options
78
- * @returns The masked value
79
- */
80
- declare function formatWithMask(value: string, mask: Mask, options?: Options): string;
81
- /**
82
- * Removes the mask from a formatted value, without needing a mounted element.
83
- * Useful for sanitizing input before sending it to the backend.
84
- *
85
- * @param value - The masked value to unformat
86
- * @param mask - The mask pattern
87
- * @param options - Optional configuration options
88
- * @returns The raw, unmasked value
89
- */
90
- declare function unformatWithMask(value: string, mask: Mask, options?: Options): string;
91
- //#endregion
92
71
  export { type Input, type Mask, type Options, type TanStackFormInputProps, type UnmaskedValueApi, type UseFormRegister, type UseFormRegisterReturn, type UseMaskInputReturn, type UseTanStackFormMaskReturn, formatWithMask, unformatWithMask, useHookFormMask, useMaskInput, useTanStackFormMask, withHookFormMask, withMask, withTanStackFormMask };
93
72
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./withMask-DlC13MV7.mjs";import{useCallback as u,useEffect as d,useLayoutEffect as f,useMemo as p,useRef as m}from"react";function h(...e){let{length:t}=e,n=t;for(;n>0;)if(--n,typeof e[n]!=`function`)throw TypeError(`Expected a function`);return(...n)=>{let r=0,i=t?e[r].apply(void 0,n):n[0];for(;r+1<t;)r+=1,i=e[r].call(void 0,i);return i}}function g(n){let{mask:i,register:a,options:o}=n,s=m(null),f=m(i),p=m(o),h=u(()=>e(s.current),[]),g=u(e=>{if(!e){s.current=null;return}s.current=l(e),c(f.current,p.current)(s.current)},[]);return d(()=>{r||!s.current||!a||a(s.current)},[a]),r?t((()=>{}),()=>``):t(g,h)}function _(n){let r=m(new Map);return f(()=>{r.current.forEach(e=>{let t=e;!t.element||!t.latestRHFRef||t.latestRHFRef!==t.syncedRHFRef&&(t.latestRHFRef(t.element),t.syncedRHFRef=t.latestRHFRef)})}),p(()=>(r.current=new Map,(o,c,l)=>{if(!n)throw Error(`registerFn is required`);let u=n(o,l),{ref:d}=u,f=a(o,c),p=r.current.get(f);if(p)p.latestRHFRef=d;else{let e={element:null,latestRHFRef:d,syncedRHFRef:void 0,stableRef:null},t=t=>(e.element=t,t&&i(t,c,l),t),n=e.latestRHFRef?h(t=>(e.latestRHFRef?.(t),t),t):t;e.stableRef=(e=>{n(e)}),p=e,r.current.set(f,e)}let m={...u,ref:p.stableRef};return t(m,()=>e(p?.element??null)),s(m,d),m}),[n])}const v=new WeakMap;function y(n,r,o){let{ref:c}=n;if(!c){let a=null,l={...n,ref:(e=>{a=e,e&&i(e,r,o)})};return t(l,()=>e(a)),s(l,c),l}v.has(c)||v.set(c,new Map);let l=v.get(c),u=a(n.name??``,r);if(!l?.has(u)){let e=(t=>{e.currentElement=t,t&&i(t,r,o),c(t)});l?.set(u,e)}let d=l?.get(u),f={...n,ref:d};return t(f,()=>e(d?.currentElement??null)),s(f,c),f}function b(){return p(()=>(e,t,n)=>y(t,e,n),[])}const x=new WeakMap;function S(n,r,o){let{ref:c}=n;if(!c){let e={...n,ref:null};return t(e,()=>``),s(e,c),e}x.has(c)||x.set(c,new Map);let l=x.get(c),u=a(n.name,r);if(!l?.has(u)){let e=(t=>(e.currentElement=t,t&&i(t,r,o),c(t)));l?.set(u,e)}let d=l?.get(u),f={...n,ref:d};return t(f,()=>e(d?.currentElement??null)),s(f,c),f}export{o as formatWithMask,n as unformatWithMask,_ as useHookFormMask,g as useMaskInput,b as useTanStackFormMask,S as withHookFormMask,c as withMask,y as withTanStackFormMask};
1
+ import{a as e,c as t,h as n,i as r,n as i,o as a,s as o,t as s,u as c}from"./core-CNGYEIpO.mjs";import{t as l}from"./withMask-DOmJHTJ4.mjs";import{useCallback as u,useEffect as d,useLayoutEffect as f,useMemo as p,useRef as m}from"react";function h(...e){let{length:t}=e,n=t;for(;n>0;)if(--n,typeof e[n]!=`function`)throw TypeError(`Expected a function`);return(...n)=>{let r=0,i=t?e[r].apply(void 0,n):n[0];for(;r+1<t;)r+=1,i=e[r].call(void 0,i);return i}}function g(r){let{mask:i,register:a,options:o}=r,s=m(null),f=m(i),p=m(o),h=u(()=>e(s.current),[]),g=u(e=>{if(!e){s.current=null;return}s.current=n(e),l(f.current,p.current)(s.current)},[]);return d(()=>{c||!s.current||!a||a(s.current)},[a]),c?t((()=>{}),()=>``):t(g,h)}function _(n){let r=m(new Map);return f(()=>{r.current.forEach(e=>{let t=e;!t.element||!t.latestRHFRef||t.latestRHFRef!==t.syncedRHFRef&&(t.latestRHFRef(t.element),t.syncedRHFRef=t.latestRHFRef)})}),p(()=>(r.current=new Map,(i,c,l)=>{if(!n)throw Error(`registerFn is required`);let u=n(i,l),{ref:d}=u,f=a(i,c),p=r.current.get(f);if(p)p.latestRHFRef=d;else{let e={element:null,latestRHFRef:d,syncedRHFRef:void 0,stableRef:null},t=t=>(e.element=t,t&&s(t,c,l),t),n=e.latestRHFRef?h(t=>(e.latestRHFRef?.(t),t),t):t;e.stableRef=(e=>{n(e)}),p=e,r.current.set(f,e)}let m={...u,ref:p.stableRef};return t(m,()=>e(p?.element??null)),o(m,d),m}),[n])}const v=new WeakMap;function y(n,r,i){let{ref:c}=n;if(!c){let a=null,l={...n,ref:(e=>{a=e,e&&s(e,r,i)})};return t(l,()=>e(a)),o(l,c),l}v.has(c)||v.set(c,new Map);let l=v.get(c),u=a(n.name??``,r);if(!l?.has(u)){let e=(t=>{e.currentElement=t,t&&s(t,r,i),c(t)});l?.set(u,e)}let d=l?.get(u),f={...n,ref:d};return t(f,()=>e(d?.currentElement??null)),o(f,c),f}function b(){return p(()=>(e,t,n)=>y(t,e,n),[])}const x=new WeakMap;function S(n,r,i){let{ref:c}=n;if(!c){let e={...n,ref:null};return t(e,()=>``),o(e,c),e}x.has(c)||x.set(c,new Map);let l=x.get(c),u=a(n.name,r);if(!l?.has(u)){let e=(t=>(e.currentElement=t,t&&s(t,r,i),c(t)));l?.set(u,e)}let d=l?.get(u),f={...n,ref:d};return t(f,()=>e(d?.currentElement??null)),o(f,c),f}export{i as formatWithMask,r as unformatWithMask,_ as useHookFormMask,g as useMaskInput,b as useTanStackFormMask,S as withHookFormMask,l as withMask,y as withTanStackFormMask};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["refCache"],"sources":["../src/utils/flow.ts","../src/api/useMaskInput.ts","../src/api/useHookFormMask.ts","../src/api/withTanStackFormMask.ts","../src/api/useTanStackFormMask.ts","../src/api/withHookFormMask.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\nexport default function flow(...funcs: Function[]): Function {\n const { length } = funcs;\n let index = length;\n while (index > 0) {\n index -= 1;\n if (typeof funcs[index] !== 'function') {\n throw new TypeError('Expected a function');\n }\n }\n return (...args: Function[]) => {\n let i = 0;\n let result = length ? funcs[i].apply(undefined, args) : args[0];\n while (i + 1 < length) {\n i += 1;\n result = funcs[i].call(undefined, result);\n }\n return result;\n };\n}\n","import {\n useCallback, useEffect, useRef,\n} from 'react';\n\nimport { resolveInputRef } from '../core';\nimport withMask from './withMask';\nimport isServer from '../utils/isServer';\nimport { getUnmaskedValue, setUnmaskedValue } from '../utils';\n\nimport type {\n Input, Mask, Options, UseMaskInputReturn,\n} from '../types';\n\ninterface UseMaskInputOptions {\n mask: Mask;\n register?: (element: HTMLElement) => void;\n options?: Options;\n}\n\n/**\n * React hook for applying input masks to form elements.\n * Works with Ant Design and other wrapped components too.\n *\n * @param props - Configuration object\n * @param props.mask - The mask pattern to apply\n * @param props.register - Optional callback that receives the element\n * @param props.options - Optional mask configuration options\n * @returns A ref callback function to attach to the input element\n */\nexport default function useMaskInput(props: UseMaskInputOptions): UseMaskInputReturn {\n const { mask, register, options } = props;\n const ref = useRef<HTMLInputElement | null>(null);\n const maskRef = useRef(mask);\n const optionsRef = useRef(options);\n const unmaskedValue = useCallback(() => getUnmaskedValue(ref.current), []);\n\n const refCallback = useCallback((input: Input | null): void => {\n if (!input) {\n ref.current = null;\n return;\n }\n\n ref.current = resolveInputRef(input);\n withMask(maskRef.current, optionsRef.current)(ref.current);\n }, []);\n\n useEffect(() => {\n if (isServer || !ref.current || !register) return;\n register(ref.current);\n }, [register]);\n\n if (isServer) {\n const noop = (() => {\n // server doesn't have dom, so just do nothing\n }) as unknown as UseMaskInputReturn;\n\n return setUnmaskedValue(noop, () => '');\n }\n\n return setUnmaskedValue(refCallback, unmaskedValue);\n}\n","import { useLayoutEffect, useMemo, useRef } from 'react';\n\nimport { applyMaskToElement } from '../core';\nimport {\n flow, getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type {\n FieldValues, Path,\n RegisterOptions,\n UseFormRegister,\n} from 'react-hook-form';\n\nimport type { Mask, Options, UseHookFormMaskReturn } from '../types';\n\ninterface CacheEntry {\n stableRef: RefCallback<HTMLElement | null>;\n element: HTMLElement | null;\n latestRHFRef?: RefCallback<HTMLElement | null>;\n syncedRHFRef?: RefCallback<HTMLElement | null>;\n}\n\n/**\n * Creates a masked version of React Hook Form's register function.\n * Takes react-hook-form's register and adds automatic masking. Like an upgrade.\n *\n * @template T - The form data type\n * @template D - The register options type\n * @param registerFn - The register function from useForm hook\n * @returns A function that registers a field with mask support\n */\nexport default function useHookFormMask<\n T extends FieldValues, D extends RegisterOptions,\n>(registerFn: UseFormRegister<T>): ((fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D) => UseHookFormMaskReturn<T>) {\n const entryCacheRef = useRef(new Map<string, CacheEntry>());\n\n useLayoutEffect(() => {\n entryCacheRef.current.forEach((entry) => {\n const currentEntry = entry;\n if (!currentEntry.element || !currentEntry.latestRHFRef) return;\n\n // After reset(), RHF gives us a new ref callback. React won't call it\n // because our outward ref identity stays stable, so we replay it here.\n if (currentEntry.latestRHFRef !== currentEntry.syncedRHFRef) {\n currentEntry.latestRHFRef(currentEntry.element);\n currentEntry.syncedRHFRef = currentEntry.latestRHFRef;\n }\n });\n });\n\n return useMemo(() => {\n // registerFn identity changed, so drop cached refs bound to the previous\n // register lifecycle.\n entryCacheRef.current = new Map<string, CacheEntry>();\n\n return (fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D): UseHookFormMaskReturn<T> => {\n if (!registerFn) throw new Error('registerFn is required');\n\n const registerReturn = registerFn(fieldName, options as Options);\n const { ref } = registerReturn as UseHookFormMaskReturn<T>;\n\n const cacheKey = makeMaskCacheKey(fieldName, mask);\n\n let entry = entryCacheRef.current.get(cacheKey);\n if (!entry) {\n const nextEntry: CacheEntry = {\n element: null,\n latestRHFRef: ref,\n syncedRHFRef: undefined,\n stableRef: null as unknown as RefCallback<HTMLElement | null>,\n };\n\n const applyMaskToRef = (_ref: HTMLElement | null) => {\n nextEntry.element = _ref;\n if (_ref) applyMaskToElement(_ref, mask, options as Options);\n return _ref;\n };\n\n // RHF must run first: it writes the field's predefined value onto the\n // element. If we masked before that, Inputmask would initialise with an\n // empty buffer and RHF's later value assignment would leave its internal\n // state out of sync with the DOM, swallowing the first onChange after a\n // select-all + delete (#193). Masking after RHF seeds Inputmask with the\n // current value, keeping its buffer in sync from the start.\n const syncRHFRef = (_ref: HTMLElement | null) => {\n nextEntry.latestRHFRef?.(_ref);\n return _ref;\n };\n\n const composedRef = nextEntry.latestRHFRef\n ? flow(syncRHFRef, applyMaskToRef)\n : applyMaskToRef;\n\n // React 19 treats a ref callback's return value as a cleanup function,\n // so the composed callback must return void — never the resolved element.\n nextEntry.stableRef = ((_ref: HTMLElement | null): void => {\n composedRef(_ref);\n }) as RefCallback<HTMLElement | null>;\n\n entry = nextEntry;\n entryCacheRef.current.set(cacheKey, nextEntry);\n } else {\n entry.latestRHFRef = ref;\n }\n\n const result = {\n ...registerReturn,\n ref: entry.stableRef,\n } as UseHookFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(entry?.element ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n };\n }, [registerFn]);\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\n\nimport type {\n Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances TanStack Form-compatible input props with mask support.\n * Works with objects returned by field.getInputProps().\n */\nexport default function withTanStackFormMask<T extends TanStackFormInputProps>(\n inputProps: T,\n mask: Mask,\n options?: Options,\n): UseTanStackFormMaskReturn<T> {\n const { ref } = inputProps;\n\n if (!ref) {\n let currentElement: HTMLElement | null = null;\n const result = {\n ...inputProps,\n ref: ((input: HTMLElement | null) => {\n currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n }) as RefCallback<HTMLElement | null>,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(currentElement));\n\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(inputProps.name ?? '', mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...inputProps,\n ref: maskedRef,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n return result;\n}\n","import { useMemo } from 'react';\n\nimport withTanStackFormMask from './withTanStackFormMask';\n\nimport type { Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn } from '../types';\n\n/**\n * Creates a helper to mask TanStack Form-compatible input props.\n * Designed for objects returned by field.getInputProps().\n */\nexport default function useTanStackFormMask(): <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n) => UseTanStackFormMaskReturn<T> {\n return useMemo(\n () => <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n ): UseTanStackFormMaskReturn<T> => withTanStackFormMask(inputProps, mask, options),\n [],\n );\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type { FieldValues } from 'react-hook-form';\n\nimport type {\n Mask, Options, UseFormRegisterReturn, UseHookFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances a React Hook Form register return object with mask support.\n * Takes an already registered field and adds mask to it.\n * Useful when you registered the field before.\n *\n * @param register - The register return object from React Hook Form\n * @param mask - The mask pattern to apply\n * @param options - Optional mask configuration options\n * @returns A new register return object with mask applied\n */\nexport default function withHookFormMask(\n register: UseFormRegisterReturn,\n mask: Mask,\n options?: Options,\n): UseHookFormMaskReturn<FieldValues> {\n const { ref } = register as UseHookFormMaskReturn<FieldValues>;\n\n // null ref — nothing to cache, return as-is.\n if (!ref) {\n const result = {\n ...register,\n ref: null as unknown as RefCallback<HTMLElement | null>,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => '');\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(register.name, mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n return ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...register,\n ref: maskedRef,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["refCache"],"sources":["../src/utils/flow.ts","../src/api/useMaskInput.ts","../src/api/useHookFormMask.ts","../src/api/withTanStackFormMask.ts","../src/api/useTanStackFormMask.ts","../src/api/withHookFormMask.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-function-type */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\nexport default function flow(...funcs: Function[]): Function {\n const { length } = funcs;\n let index = length;\n while (index > 0) {\n index -= 1;\n if (typeof funcs[index] !== 'function') {\n throw new TypeError('Expected a function');\n }\n }\n return (...args: Function[]) => {\n let i = 0;\n let result = length ? funcs[i].apply(undefined, args) : args[0];\n while (i + 1 < length) {\n i += 1;\n result = funcs[i].call(undefined, result);\n }\n return result;\n };\n}\n","import {\n useCallback, useEffect, useRef,\n} from 'react';\n\nimport { resolveInputRef } from '../core';\nimport withMask from './withMask';\nimport isServer from '../utils/isServer';\nimport { getUnmaskedValue, setUnmaskedValue } from '../utils';\n\nimport type {\n Input, Mask, Options, UseMaskInputReturn,\n} from '../types';\n\ninterface UseMaskInputOptions {\n mask: Mask;\n register?: (element: HTMLElement) => void;\n options?: Options;\n}\n\n/**\n * React hook for applying input masks to form elements.\n * Works with Ant Design and other wrapped components too.\n *\n * @param props - Configuration object\n * @param props.mask - The mask pattern to apply\n * @param props.register - Optional callback that receives the element\n * @param props.options - Optional mask configuration options\n * @returns A ref callback function to attach to the input element\n */\nexport default function useMaskInput(props: UseMaskInputOptions): UseMaskInputReturn {\n const { mask, register, options } = props;\n const ref = useRef<HTMLInputElement | null>(null);\n const maskRef = useRef(mask);\n const optionsRef = useRef(options);\n const unmaskedValue = useCallback(() => getUnmaskedValue(ref.current), []);\n\n const refCallback = useCallback((input: Input | null): void => {\n if (!input) {\n ref.current = null;\n return;\n }\n\n ref.current = resolveInputRef(input);\n withMask(maskRef.current, optionsRef.current)(ref.current);\n }, []);\n\n useEffect(() => {\n if (isServer || !ref.current || !register) return;\n register(ref.current);\n }, [register]);\n\n if (isServer) {\n const noop = (() => {\n // server doesn't have dom, so just do nothing\n }) as unknown as UseMaskInputReturn;\n\n return setUnmaskedValue(noop, () => '');\n }\n\n return setUnmaskedValue(refCallback, unmaskedValue);\n}\n","import { useLayoutEffect, useMemo, useRef } from 'react';\n\nimport { applyMaskToElement } from '../core';\nimport {\n flow, getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type {\n FieldValues, Path,\n RegisterOptions,\n UseFormRegister,\n} from 'react-hook-form';\n\nimport type { Mask, Options, UseHookFormMaskReturn } from '../types';\n\ninterface CacheEntry {\n stableRef: RefCallback<HTMLElement | null>;\n element: HTMLElement | null;\n latestRHFRef?: RefCallback<HTMLElement | null>;\n syncedRHFRef?: RefCallback<HTMLElement | null>;\n}\n\n/**\n * Creates a masked version of React Hook Form's register function.\n * Takes react-hook-form's register and adds automatic masking. Like an upgrade.\n *\n * @template T - The form data type\n * @template D - The register options type\n * @param registerFn - The register function from useForm hook\n * @returns A function that registers a field with mask support\n */\nexport default function useHookFormMask<\n T extends FieldValues, D extends RegisterOptions,\n>(registerFn: UseFormRegister<T>): ((fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D) => UseHookFormMaskReturn<T>) {\n const entryCacheRef = useRef(new Map<string, CacheEntry>());\n\n useLayoutEffect(() => {\n entryCacheRef.current.forEach((entry) => {\n const currentEntry = entry;\n if (!currentEntry.element || !currentEntry.latestRHFRef) return;\n\n // After reset(), RHF gives us a new ref callback. React won't call it\n // because our outward ref identity stays stable, so we replay it here.\n if (currentEntry.latestRHFRef !== currentEntry.syncedRHFRef) {\n currentEntry.latestRHFRef(currentEntry.element);\n currentEntry.syncedRHFRef = currentEntry.latestRHFRef;\n }\n });\n });\n\n return useMemo(() => {\n // registerFn identity changed, so drop cached refs bound to the previous\n // register lifecycle.\n entryCacheRef.current = new Map<string, CacheEntry>();\n\n return (fieldName: Path<T>, mask: Mask, options?: (\n D & Options) | Options | D): UseHookFormMaskReturn<T> => {\n if (!registerFn) throw new Error('registerFn is required');\n\n const registerReturn = registerFn(fieldName, options as Options);\n const { ref } = registerReturn as UseHookFormMaskReturn<T>;\n\n const cacheKey = makeMaskCacheKey(fieldName, mask);\n\n let entry = entryCacheRef.current.get(cacheKey);\n if (!entry) {\n const nextEntry: CacheEntry = {\n element: null,\n latestRHFRef: ref,\n syncedRHFRef: undefined,\n stableRef: null as unknown as RefCallback<HTMLElement | null>,\n };\n\n const applyMaskToRef = (_ref: HTMLElement | null) => {\n nextEntry.element = _ref;\n if (_ref) applyMaskToElement(_ref, mask, options as Options);\n return _ref;\n };\n\n // RHF must run first: it writes the field's predefined value onto the\n // element. If we masked before that, Inputmask would initialise with an\n // empty buffer and RHF's later value assignment would leave its internal\n // state out of sync with the DOM, swallowing the first onChange after a\n // select-all + delete (#193). Masking after RHF seeds Inputmask with the\n // current value, keeping its buffer in sync from the start.\n const syncRHFRef = (_ref: HTMLElement | null) => {\n nextEntry.latestRHFRef?.(_ref);\n return _ref;\n };\n\n const composedRef = nextEntry.latestRHFRef\n ? flow(syncRHFRef, applyMaskToRef)\n : applyMaskToRef;\n\n // React 19 treats a ref callback's return value as a cleanup function,\n // so the composed callback must return void — never the resolved element.\n nextEntry.stableRef = ((_ref: HTMLElement | null): void => {\n composedRef(_ref);\n }) as RefCallback<HTMLElement | null>;\n\n entry = nextEntry;\n entryCacheRef.current.set(cacheKey, nextEntry);\n } else {\n entry.latestRHFRef = ref;\n }\n\n const result = {\n ...registerReturn,\n ref: entry.stableRef,\n } as UseHookFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(entry?.element ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n };\n }, [registerFn]);\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\n\nimport type {\n Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances TanStack Form-compatible input props with mask support.\n * Works with objects returned by field.getInputProps().\n */\nexport default function withTanStackFormMask<T extends TanStackFormInputProps>(\n inputProps: T,\n mask: Mask,\n options?: Options,\n): UseTanStackFormMaskReturn<T> {\n const { ref } = inputProps;\n\n if (!ref) {\n let currentElement: HTMLElement | null = null;\n const result = {\n ...inputProps,\n ref: ((input: HTMLElement | null) => {\n currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n }) as RefCallback<HTMLElement | null>,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(currentElement));\n\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(inputProps.name ?? '', mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...inputProps,\n ref: maskedRef,\n } as unknown as UseTanStackFormMaskReturn<T>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n return result;\n}\n","import { useMemo } from 'react';\n\nimport withTanStackFormMask from './withTanStackFormMask';\n\nimport type { Mask, Options, TanStackFormInputProps, UseTanStackFormMaskReturn } from '../types';\n\n/**\n * Creates a helper to mask TanStack Form-compatible input props.\n * Designed for objects returned by field.getInputProps().\n */\nexport default function useTanStackFormMask(): <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n) => UseTanStackFormMaskReturn<T> {\n return useMemo(\n () => <T extends TanStackFormInputProps>(\n mask: Mask,\n inputProps: T,\n options?: Options,\n ): UseTanStackFormMaskReturn<T> => withTanStackFormMask(inputProps, mask, options),\n [],\n );\n}\n","import { applyMaskToElement } from '../core';\nimport {\n getUnmaskedValue, makeMaskCacheKey, setPrevRef, setUnmaskedValue,\n} from '../utils';\n\nimport type { RefCallback } from 'react';\nimport type { FieldValues } from 'react-hook-form';\n\nimport type {\n Mask, Options, UseFormRegisterReturn, UseHookFormMaskReturn,\n} from '../types';\n\ntype MaskedRefCallback = RefCallback<HTMLElement | null> & {\n currentElement?: HTMLElement | null;\n};\n\nconst refCache = new WeakMap<\n RefCallback<HTMLElement | null>,\n Map<string, RefCallback<HTMLElement | null>>\n>();\n\n/**\n * Enhances a React Hook Form register return object with mask support.\n * Takes an already registered field and adds mask to it.\n * Useful when you registered the field before.\n *\n * @param register - The register return object from React Hook Form\n * @param mask - The mask pattern to apply\n * @param options - Optional mask configuration options\n * @returns A new register return object with mask applied\n */\nexport default function withHookFormMask(\n register: UseFormRegisterReturn,\n mask: Mask,\n options?: Options,\n): UseHookFormMaskReturn<FieldValues> {\n const { ref } = register as UseHookFormMaskReturn<FieldValues>;\n\n // null ref — nothing to cache, return as-is.\n if (!ref) {\n const result = {\n ...register,\n ref: null as unknown as RefCallback<HTMLElement | null>,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => '');\n setPrevRef(result, ref);\n return result;\n }\n\n if (!refCache.has(ref)) {\n refCache.set(ref, new Map());\n }\n const maskCache = refCache.get(ref);\n const cacheKey = makeMaskCacheKey(register.name, mask);\n\n if (!maskCache?.has(cacheKey)) {\n const maskedRef = ((input: HTMLElement | null) => {\n maskedRef.currentElement = input;\n if (input) applyMaskToElement(input, mask, options);\n return ref(input);\n }) as MaskedRefCallback;\n\n maskCache?.set(cacheKey, maskedRef);\n }\n\n const maskedRef = maskCache?.get(cacheKey) as MaskedRefCallback | undefined;\n const result = {\n ...register,\n ref: maskedRef,\n } as UseHookFormMaskReturn<FieldValues>;\n setUnmaskedValue(result, () => getUnmaskedValue(maskedRef?.currentElement ?? null));\n\n setPrevRef(result, ref);\n\n return result;\n}\n"],"mappings":"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"}
package/dist/vue.cjs ADDED
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./core-BopfTGvA.cjs");function t(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&`mask`in e}function n(e){return t(e)?{mask:e.mask,options:e.options}:{mask:e}}function r(e,t){if(e===t)return!0;if(!e||!t)return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.is(e[n],t[n]))}function i(t,i){let a=n(t),o=n(i);return e.o(``,a.mask)===e.o(``,o.mask)&&r(a.options,o.options)}function a(t,r){if(e.u||!t)return;let{mask:i,options:a}=n(r);if(i==null){t.inputmask?.remove?.();return}e.t(t,i,a)}function o(t){if(!t)return null;if(e.m(t))return e.p(t);let{$el:n}=t;return e.m(n)?e.p(n):null}const s={mounted(e,t){a(o(e),t.value)},updated(e,t){i(t.value,t.oldValue)||a(o(e),t.value)},unmounted(e){o(e)?.inputmask?.remove?.()},getSSRProps:()=>({})};function c(t,n){if(e.u)return{maskRef:()=>{},unmaskedValue:()=>``};let r=null;return{maskRef:e=>{r=o(e),a(r,{mask:t,options:n})},unmaskedValue:()=>e.a(r)}}exports.formatWithMask=e.n,exports.unformatWithMask=e.i,exports.useMaskInput=c,exports.vMaskInput=s;
2
+ //# sourceMappingURL=vue.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.cjs","names":["makeMaskCacheKey","isServer","isHTMLElement","findInputElement","isServer","getUnmaskedValue"],"sources":["../src/vue/applyMask.ts","../src/vue/resolveVueElement.ts","../src/vue/directive.ts","../src/vue/useMaskInput.ts"],"sourcesContent":["import { applyMaskToElement } from '../core';\nimport { makeMaskCacheKey } from '../utils';\nimport isServer from '../utils/isServer';\n\nimport type { Mask, Options, VueMaskBinding, VueMaskConfig } from './types';\n\ntype MaskedElement = HTMLElement & {\n inputmask?: { remove?: () => void };\n};\n\n/**\n * Single implementation both Vue surfaces route through, so the directive and\n * the composable cannot drift apart on what a given mask means.\n */\n\nfunction isConfig(binding: VueMaskBinding): binding is VueMaskConfig {\n return (\n typeof binding === 'object'\n && binding !== null\n && !Array.isArray(binding)\n && 'mask' in binding\n );\n}\n\n/** Unpacks the two accepted binding shapes into a mask and its options. */\nexport function normalizeBinding(binding: VueMaskBinding): {\n mask: Mask;\n options?: Options;\n} {\n if (isConfig(binding)) {\n return { mask: binding.mask, options: binding.options };\n }\n\n return { mask: binding as Mask };\n}\n\n/**\n * Shallow equality over mask options.\n *\n * ponytail: shallow on purpose. An options object mutated in place, or one\n * holding functions, won't compare equal-then-changed correctly — but deep\n * comparison on every re-render is exactly the cost this guard exists to\n * avoid. Documented as \"replace options, don't mutate them\".\n */\nfunction sameOptions(a?: Options, b?: Options): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a) as (keyof Options)[];\n const keysB = Object.keys(b) as (keyof Options)[];\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every((key) => Object.is(a[key], b[key]));\n}\n\n/**\n * True when two bindings mean the same mask, so an unrelated re-render doesn't\n * rebuild Inputmask's buffer and drop the caret to the end mid-typing.\n *\n * Compares structurally, not by identity: an inline `v-mask-input=\"{ mask: 'cpf' }\"`\n * allocates a fresh object every render and would otherwise never look equal.\n */\nexport function sameBinding(a: VueMaskBinding, b: VueMaskBinding): boolean {\n const left = normalizeBinding(a);\n const right = normalizeBinding(b);\n\n if (makeMaskCacheKey('', left.mask) !== makeMaskCacheKey('', right.mask)) {\n return false;\n }\n\n return sameOptions(left.options, right.options);\n}\n\n/**\n * Applies a binding's mask to an already-resolved element.\n *\n * A null mask is not merely \"do nothing\": it has to tear down whatever mask is\n * already on the element. A binding is reactive, so `v-mask-input=\"on ? 'cpf' : null\"`\n * turns the mask off, and simply returning early would leave the element still\n * formatting as a CPF.\n *\n * @param element - The element to mask\n * @param binding - Mask, or `{ mask, options }`\n */\nexport default function applyMask(\n element: HTMLElement | null,\n binding: VueMaskBinding,\n): void {\n if (isServer || !element) return;\n\n const { mask, options } = normalizeBinding(binding);\n\n if (mask === null || mask === undefined) {\n (element as MaskedElement).inputmask?.remove?.();\n return;\n }\n\n applyMaskToElement(element, mask, options);\n}\n","import { findInputElement, isHTMLElement } from '../core/elementResolver';\n\nimport type { MaskRefTarget } from './types';\n\n/**\n * Resolves whatever Vue hands us into the element that should carry the mask.\n *\n * A directive always receives a DOM element. A `:ref` on a component receives\n * the component's public instance instead, so the element has to be dug out of\n * `$el` first. Either way the existing `findInputElement` does the final\n * wrapper search, which is the same code path that makes Ant Design work on the\n * React side.\n *\n * Fragment-root components resolve to `null` on purpose: their `$el` is a text\n * anchor node, and Vue itself refuses this case for directives\n * (\"Runtime directive used on component with non-element root node\"). Walking\n * up to `parentElement` could just as easily find a sibling input as the\n * intended one.\n *\n * @param target - Element, component public instance, or null\n * @returns The element to mask, or null if there isn't one\n */\nexport default function resolveVueElement(target: MaskRefTarget): HTMLElement | null {\n if (!target) return null;\n\n if (isHTMLElement(target)) {\n return findInputElement(target);\n }\n\n const { $el } = target as { $el?: unknown };\n if (!isHTMLElement($el)) return null;\n\n return findInputElement($el);\n}\n","import applyMask, { sameBinding } from './applyMask';\nimport resolveVueElement from './resolveVueElement';\n\nimport type { ObjectDirective } from 'vue';\n\nimport type { VueMaskBinding } from './types';\n\ntype MaskedElement = HTMLElement & {\n inputmask?: { remove?: () => void };\n};\n\n/**\n * `v-mask-input` — the only thing in the Vue entry that applies a mask.\n *\n * Getting real lifecycle hooks is why this, and not the composable, is the\n * primitive: the React surface has no equivalent of `unmounted`, which is why\n * it never tears Inputmask down.\n *\n * Note there is no `v-model` handling here, and none is needed. Inputmask\n * replaces the element's `value` property with its own accessor, so `v-model`\n * reads and writes through the engine rather than around it — including\n * returning the unmasked value under `autoUnmask`.\n *\n * @example\n * ```vue\n * <script setup>\n * import { vMaskInput } from 'use-mask-input/vue'\n * </script>\n *\n * <template>\n * <input v-mask-input=\"'cpf'\" />\n * <input v-mask-input=\"{ mask: 'currency', options: { prefix: 'R$ ' } }\" />\n * </template>\n * ```\n */\nconst vMaskInput: ObjectDirective<HTMLElement, VueMaskBinding> = {\n mounted(el, binding) {\n applyMask(resolveVueElement(el), binding.value);\n },\n\n updated(el, binding) {\n // Every parent re-render lands here. Re-masking an unchanged binding would\n // rebuild the buffer and send the caret to the end while the user types.\n if (sameBinding(binding.value, binding.oldValue as VueMaskBinding)) return;\n\n applyMask(resolveVueElement(el), binding.value);\n },\n\n unmounted(el) {\n const target = resolveVueElement(el) as MaskedElement | null;\n target?.inputmask?.remove?.();\n },\n\n // Without this, @vue/server-renderer warns about an unhandled custom\n // directive. There is nothing to render server-side.\n getSSRProps: () => ({}),\n};\n\nexport default vMaskInput;\n","import applyMask from './applyMask';\nimport resolveVueElement from './resolveVueElement';\nimport { getUnmaskedValue } from '../utils';\nimport isServer from '../utils/isServer';\n\nimport type {\n MaskRefTarget, Mask, Options, UseMaskInputReturn,\n} from './types';\n\n/**\n * Composable form, for imperative use and for reading the raw value when\n * `autoUnmask` is off.\n *\n * Narrower than the directive on purpose: wrapper components (PrimeVue,\n * Element Plus, Ant Design Vue) are already covered by `v-mask-input`, because\n * Vue applies directives to a component's root element and the mask engine\n * searches inside it. Reach for this when you need `unmaskedValue()` or a ref\n * you can hold.\n *\n * @param mask - The mask pattern or alias\n * @param options - Optional mask configuration options\n * @returns A ref callback to bind, and an unmasked-value accessor\n *\n * @example\n * ```vue\n * <script setup>\n * import { useMaskInput } from 'use-mask-input/vue'\n * const { maskRef, unmaskedValue } = useMaskInput('cpf')\n * function submit() { console.log(unmaskedValue()) }\n * </script>\n *\n * <template><input :ref=\"maskRef\" /></template>\n * ```\n */\nexport default function useMaskInput(mask: Mask, options?: Options): UseMaskInputReturn {\n if (isServer) {\n return {\n maskRef: () => {\n // server doesn't have dom, so just do nothing\n },\n unmaskedValue: () => '',\n };\n }\n\n let element: HTMLElement | null = null;\n\n const maskRef = (target: MaskRefTarget): void => {\n element = resolveVueElement(target);\n applyMask(element, { mask, options });\n };\n\n return {\n maskRef,\n unmaskedValue: () => getUnmaskedValue(element),\n };\n}\n"],"mappings":"0GAeA,SAAS,EAAS,EAAmD,CACnE,OACE,OAAO,GAAY,YAChB,GACA,CAAC,MAAM,QAAQ,CAAO,GACtB,SAAU,CAEjB,CAGA,SAAgB,EAAiB,EAG/B,CAKA,OAJI,EAAS,CAAO,EACX,CAAE,KAAM,EAAQ,KAAM,QAAS,EAAQ,OAAQ,EAGjD,CAAE,KAAM,CAAgB,CACjC,CAUA,SAAS,EAAY,EAAa,EAAsB,CACtD,GAAI,IAAM,EAAG,MAAO,GACpB,GAAI,CAAC,GAAK,CAAC,EAAG,MAAO,GAErB,IAAM,EAAQ,OAAO,KAAK,CAAC,EACrB,EAAQ,OAAO,KAAK,CAAC,EAG3B,OAFI,EAAM,SAAW,EAAM,QAEpB,EAAM,MAAO,GAAQ,OAAO,GAAG,EAAE,GAAM,EAAE,EAAI,CAAC,CACvD,CASA,SAAgB,EAAY,EAAmB,EAA4B,CACzE,IAAM,EAAO,EAAiB,CAAC,EACzB,EAAQ,EAAiB,CAAC,EAMhC,OAJIA,EAAAA,EAAiB,GAAI,EAAK,IAAI,IAAMA,EAAAA,EAAiB,GAAI,EAAM,IAAI,GAIhE,EAAY,EAAK,QAAS,EAAM,OAAO,CAChD,CAaA,SAAwB,EACtB,EACA,EACM,CACN,GAAIC,EAAAA,GAAY,CAAC,EAAS,OAE1B,GAAM,CAAE,OAAM,WAAY,EAAiB,CAAO,EAElD,GAAI,GAAS,KAA4B,CACvC,EAA2B,WAAW,SAAS,EAC/C,MACF,CAEA,EAAA,EAAmB,EAAS,EAAM,CAAO,CAC3C,CC5EA,SAAwB,EAAkB,EAA2C,CACnF,GAAI,CAAC,EAAQ,OAAO,KAEpB,GAAIC,EAAAA,EAAc,CAAM,EACtB,OAAOC,EAAAA,EAAiB,CAAM,EAGhC,GAAM,CAAE,OAAQ,EAGhB,OAFKD,EAAAA,EAAc,CAAG,EAEfC,EAAAA,EAAiB,CAAG,EAFK,IAGlC,CCEA,MAAM,EAA2D,CAC/D,QAAQ,EAAI,EAAS,CACnB,EAAU,EAAkB,CAAE,EAAG,EAAQ,KAAK,CAChD,EAEA,QAAQ,EAAI,EAAS,CAGf,EAAY,EAAQ,MAAO,EAAQ,QAA0B,GAEjE,EAAU,EAAkB,CAAE,EAAG,EAAQ,KAAK,CAChD,EAEA,UAAU,EAAI,CAEZ,EADiC,CAC5B,CAAC,EAAE,WAAW,SAAS,CAC9B,EAIA,iBAAoB,CAAC,EACvB,ECtBA,SAAwB,EAAa,EAAY,EAAuC,CACtF,GAAIC,EAAAA,EACF,MAAO,CACL,YAAe,CAEf,EACA,kBAAqB,EACvB,EAGF,IAAI,EAA8B,KAOlC,MAAO,CACL,QANe,GAAgC,CAC/C,EAAU,EAAkB,CAAM,EAClC,EAAU,EAAS,CAAE,OAAM,SAAQ,CAAC,CACtC,EAIE,kBAAqBC,EAAAA,EAAiB,CAAO,CAC/C,CACF"}
package/dist/vue.d.cts ADDED
@@ -0,0 +1,92 @@
1
+ import { o as Mask, s as Options } from "./index-CqBLkcNO.cjs";
2
+ import { n as unformatWithMask, t as formatWithMask } from "./index-DAfluDSv.cjs";
3
+ import { ObjectDirective } from "vue";
4
+ //#region src/vue/types.d.ts
5
+ /** Object form of the directive binding, for when options are needed. */
6
+ interface VueMaskConfig {
7
+ mask: Mask;
8
+ options?: Options;
9
+ }
10
+ /**
11
+ * Everything `v-mask-input` accepts. A bare mask covers the common case;
12
+ * the object form adds options.
13
+ */
14
+ type VueMaskBinding = Mask | VueMaskConfig;
15
+ /**
16
+ * What Vue hands a `:ref` callback: a DOM element for a native tag, or the
17
+ * component's public instance for a component. `$el` is typed loosely because
18
+ * a fragment-root component exposes a text anchor node there, not an element.
19
+ */
20
+ type MaskRefTarget = Element | {
21
+ $el?: unknown;
22
+ } | null;
23
+ interface UseMaskInputReturn {
24
+ /** Bind with `:ref="maskRef"`. */
25
+ maskRef: (target: MaskRefTarget) => void;
26
+ /**
27
+ * Current unmasked value. Call this from event handlers and imperative code.
28
+ *
29
+ * NOT reactive: `{{ unmaskedValue() }}` in a template renders once and never
30
+ * updates, because reading the DOM registers no reactive dependency. For a
31
+ * value the template should track, bind `v-model` with `autoUnmask: true`.
32
+ */
33
+ unmaskedValue: () => string;
34
+ }
35
+ //#endregion
36
+ //#region src/vue/directive.d.ts
37
+ /**
38
+ * `v-mask-input` — the only thing in the Vue entry that applies a mask.
39
+ *
40
+ * Getting real lifecycle hooks is why this, and not the composable, is the
41
+ * primitive: the React surface has no equivalent of `unmounted`, which is why
42
+ * it never tears Inputmask down.
43
+ *
44
+ * Note there is no `v-model` handling here, and none is needed. Inputmask
45
+ * replaces the element's `value` property with its own accessor, so `v-model`
46
+ * reads and writes through the engine rather than around it — including
47
+ * returning the unmasked value under `autoUnmask`.
48
+ *
49
+ * @example
50
+ * ```vue
51
+ * <script setup>
52
+ * import { vMaskInput } from 'use-mask-input/vue'
53
+ * </script>
54
+ *
55
+ * <template>
56
+ * <input v-mask-input="'cpf'" />
57
+ * <input v-mask-input="{ mask: 'currency', options: { prefix: 'R$ ' } }" />
58
+ * </template>
59
+ * ```
60
+ */
61
+ declare const vMaskInput: ObjectDirective<HTMLElement, VueMaskBinding>;
62
+ //#endregion
63
+ //#region src/vue/useMaskInput.d.ts
64
+ /**
65
+ * Composable form, for imperative use and for reading the raw value when
66
+ * `autoUnmask` is off.
67
+ *
68
+ * Narrower than the directive on purpose: wrapper components (PrimeVue,
69
+ * Element Plus, Ant Design Vue) are already covered by `v-mask-input`, because
70
+ * Vue applies directives to a component's root element and the mask engine
71
+ * searches inside it. Reach for this when you need `unmaskedValue()` or a ref
72
+ * you can hold.
73
+ *
74
+ * @param mask - The mask pattern or alias
75
+ * @param options - Optional mask configuration options
76
+ * @returns A ref callback to bind, and an unmasked-value accessor
77
+ *
78
+ * @example
79
+ * ```vue
80
+ * <script setup>
81
+ * import { useMaskInput } from 'use-mask-input/vue'
82
+ * const { maskRef, unmaskedValue } = useMaskInput('cpf')
83
+ * function submit() { console.log(unmaskedValue()) }
84
+ * </script>
85
+ *
86
+ * <template><input :ref="maskRef" /></template>
87
+ * ```
88
+ */
89
+ declare function useMaskInput(mask: Mask, options?: Options): UseMaskInputReturn;
90
+ //#endregion
91
+ export { type Mask, type MaskRefTarget, type Options, type UseMaskInputReturn, type VueMaskBinding, type VueMaskConfig, formatWithMask, unformatWithMask, useMaskInput, vMaskInput };
92
+ //# sourceMappingURL=vue.d.cts.map
package/dist/vue.d.mts ADDED
@@ -0,0 +1,92 @@
1
+ import { o as Mask, s as Options } from "./index-CqBLkcNO.mjs";
2
+ import { n as unformatWithMask, t as formatWithMask } from "./index-DGAwRzYx.mjs";
3
+ import { ObjectDirective } from "vue";
4
+ //#region src/vue/types.d.ts
5
+ /** Object form of the directive binding, for when options are needed. */
6
+ interface VueMaskConfig {
7
+ mask: Mask;
8
+ options?: Options;
9
+ }
10
+ /**
11
+ * Everything `v-mask-input` accepts. A bare mask covers the common case;
12
+ * the object form adds options.
13
+ */
14
+ type VueMaskBinding = Mask | VueMaskConfig;
15
+ /**
16
+ * What Vue hands a `:ref` callback: a DOM element for a native tag, or the
17
+ * component's public instance for a component. `$el` is typed loosely because
18
+ * a fragment-root component exposes a text anchor node there, not an element.
19
+ */
20
+ type MaskRefTarget = Element | {
21
+ $el?: unknown;
22
+ } | null;
23
+ interface UseMaskInputReturn {
24
+ /** Bind with `:ref="maskRef"`. */
25
+ maskRef: (target: MaskRefTarget) => void;
26
+ /**
27
+ * Current unmasked value. Call this from event handlers and imperative code.
28
+ *
29
+ * NOT reactive: `{{ unmaskedValue() }}` in a template renders once and never
30
+ * updates, because reading the DOM registers no reactive dependency. For a
31
+ * value the template should track, bind `v-model` with `autoUnmask: true`.
32
+ */
33
+ unmaskedValue: () => string;
34
+ }
35
+ //#endregion
36
+ //#region src/vue/directive.d.ts
37
+ /**
38
+ * `v-mask-input` — the only thing in the Vue entry that applies a mask.
39
+ *
40
+ * Getting real lifecycle hooks is why this, and not the composable, is the
41
+ * primitive: the React surface has no equivalent of `unmounted`, which is why
42
+ * it never tears Inputmask down.
43
+ *
44
+ * Note there is no `v-model` handling here, and none is needed. Inputmask
45
+ * replaces the element's `value` property with its own accessor, so `v-model`
46
+ * reads and writes through the engine rather than around it — including
47
+ * returning the unmasked value under `autoUnmask`.
48
+ *
49
+ * @example
50
+ * ```vue
51
+ * <script setup>
52
+ * import { vMaskInput } from 'use-mask-input/vue'
53
+ * </script>
54
+ *
55
+ * <template>
56
+ * <input v-mask-input="'cpf'" />
57
+ * <input v-mask-input="{ mask: 'currency', options: { prefix: 'R$ ' } }" />
58
+ * </template>
59
+ * ```
60
+ */
61
+ declare const vMaskInput: ObjectDirective<HTMLElement, VueMaskBinding>;
62
+ //#endregion
63
+ //#region src/vue/useMaskInput.d.ts
64
+ /**
65
+ * Composable form, for imperative use and for reading the raw value when
66
+ * `autoUnmask` is off.
67
+ *
68
+ * Narrower than the directive on purpose: wrapper components (PrimeVue,
69
+ * Element Plus, Ant Design Vue) are already covered by `v-mask-input`, because
70
+ * Vue applies directives to a component's root element and the mask engine
71
+ * searches inside it. Reach for this when you need `unmaskedValue()` or a ref
72
+ * you can hold.
73
+ *
74
+ * @param mask - The mask pattern or alias
75
+ * @param options - Optional mask configuration options
76
+ * @returns A ref callback to bind, and an unmasked-value accessor
77
+ *
78
+ * @example
79
+ * ```vue
80
+ * <script setup>
81
+ * import { useMaskInput } from 'use-mask-input/vue'
82
+ * const { maskRef, unmaskedValue } = useMaskInput('cpf')
83
+ * function submit() { console.log(unmaskedValue()) }
84
+ * </script>
85
+ *
86
+ * <template><input :ref="maskRef" /></template>
87
+ * ```
88
+ */
89
+ declare function useMaskInput(mask: Mask, options?: Options): UseMaskInputReturn;
90
+ //#endregion
91
+ export { type Mask, type MaskRefTarget, type Options, type UseMaskInputReturn, type VueMaskBinding, type VueMaskConfig, formatWithMask, unformatWithMask, useMaskInput, vMaskInput };
92
+ //# sourceMappingURL=vue.d.mts.map
package/dist/vue.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{a as e,i as t,m as n,n as r,o as i,p as a,t as o,u as s}from"./core-CNGYEIpO.mjs";function c(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&`mask`in e}function l(e){return c(e)?{mask:e.mask,options:e.options}:{mask:e}}function u(e,t){if(e===t)return!0;if(!e||!t)return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.is(e[n],t[n]))}function d(e,t){let n=l(e),r=l(t);return i(``,n.mask)===i(``,r.mask)&&u(n.options,r.options)}function f(e,t){if(s||!e)return;let{mask:n,options:r}=l(t);if(n==null){e.inputmask?.remove?.();return}o(e,n,r)}function p(e){if(!e)return null;if(n(e))return a(e);let{$el:t}=e;return n(t)?a(t):null}const m={mounted(e,t){f(p(e),t.value)},updated(e,t){d(t.value,t.oldValue)||f(p(e),t.value)},unmounted(e){p(e)?.inputmask?.remove?.()},getSSRProps:()=>({})};function h(t,n){if(s)return{maskRef:()=>{},unmaskedValue:()=>``};let r=null;return{maskRef:e=>{r=p(e),f(r,{mask:t,options:n})},unmaskedValue:()=>e(r)}}export{r as formatWithMask,t as unformatWithMask,h as useMaskInput,m as vMaskInput};
2
+ //# sourceMappingURL=vue.mjs.map