@primereact/hooks 11.0.0-alpha.8 → 11.0.0-rc.1

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 (48) hide show
  1. package/LICENSE.md +45 -0
  2. package/README.md +34 -0
  3. package/index.d.ts +9 -0
  4. package/index.mjs +1 -1
  5. package/index.mjs.map +1 -1
  6. package/package.json +8 -12
  7. package/use-controlled-state/index.mjs +1 -1
  8. package/use-controlled-state/index.mjs.map +1 -1
  9. package/use-filter/_matchers.d.ts +23 -0
  10. package/use-filter/index.d.ts +94 -0
  11. package/use-filter/index.mjs +2 -0
  12. package/use-filter/index.mjs.map +1 -0
  13. package/use-hot-key/index.d.ts +25 -0
  14. package/use-hot-key/index.mjs +2 -0
  15. package/use-hot-key/index.mjs.map +1 -0
  16. package/use-is-mobile/index.d.ts +18 -0
  17. package/use-is-mobile/index.mjs +2 -0
  18. package/use-is-mobile/index.mjs.map +1 -0
  19. package/use-local-storage/index.d.ts +56 -0
  20. package/use-local-storage/index.mjs +2 -0
  21. package/use-local-storage/index.mjs.map +1 -0
  22. package/use-mask/index.d.ts +96 -67
  23. package/use-mask/index.mjs +1 -1
  24. package/use-mask/index.mjs.map +1 -1
  25. package/use-mounted/index.d.ts +36 -0
  26. package/use-mounted/index.mjs +2 -0
  27. package/use-mounted/index.mjs.map +1 -0
  28. package/use-number-formatter/index.d.ts +194 -0
  29. package/use-number-formatter/index.mjs +2 -0
  30. package/use-number-formatter/index.mjs.map +1 -0
  31. package/use-number-formatter/index.test.d.ts +0 -0
  32. package/use-presence/index.d.ts +1 -2
  33. package/use-presence/index.mjs +1 -1
  34. package/use-presence/index.mjs.map +1 -1
  35. package/use-props/index.d.ts +16 -11
  36. package/use-props/index.mjs +1 -1
  37. package/use-props/index.mjs.map +1 -1
  38. package/use-queue-task/index.d.ts +1 -0
  39. package/use-queue-task/index.mjs +2 -0
  40. package/use-queue-task/index.mjs.map +1 -0
  41. package/use-queue-task/index.test.d.ts +0 -0
  42. package/use-sortable-list/index.d.ts +43 -0
  43. package/use-sortable-list/index.mjs +2 -0
  44. package/use-sortable-list/index.mjs.map +1 -0
  45. package/use-tree-filter/index.d.ts +52 -0
  46. package/use-tree-filter/index.mjs +2 -0
  47. package/use-tree-filter/index.mjs.map +1 -0
  48. package/LICENSE +0 -21
@@ -1,109 +1,138 @@
1
- import * as React from 'react';
2
1
  /**
3
- * Event fired when the component's state changes.
2
+ * Event payload for `useMask` value/complete callbacks.
4
3
  */
5
- export interface UseMaskChangeEvent {
4
+ export interface UseMaskValueChangeEvent {
6
5
  /**
7
- * The value of the component.
6
+ * The DOM event that triggered the change, or `null` for programmatic
7
+ * updates (`setValue`, `reset`).
8
8
  */
9
- value: string | undefined;
9
+ originalEvent: Event | null;
10
+ /**
11
+ * Masked value (e.g. `"12/05/2026"`). Always in masked form.
12
+ */
13
+ value: string;
14
+ /**
15
+ * Unmasked (raw) value (e.g. `"12052026"`). Separators and placeholder
16
+ * characters are stripped.
17
+ */
18
+ rawValue: string;
19
+ /**
20
+ * Whether all required slots are filled.
21
+ */
22
+ isComplete: boolean;
10
23
  }
11
24
  /**
12
- * The options for the `useMask` hook.
25
+ * Options for the `useMask` hook.
13
26
  */
14
27
  export interface UseMaskOptions {
15
28
  /**
16
- * Mask pattern.
29
+ * Mask pattern. Built-in tokens:
30
+ * - `9` → [0-9]
31
+ * - `a` → [A-Za-z]
32
+ * - `A` → [A-Z]
33
+ * - `*` → [A-Za-z0-9]
34
+ * Append `?` to mark the remainder of the mask as optional. Extend with
35
+ * the `tokens` option.
17
36
  */
18
37
  mask: string;
19
38
  /**
20
- * Defines if model sets the raw unmasked value to bound value or the formatted mask value.
21
- * @default false
39
+ * Custom token map merged on top of the built-in tokens. Each token
40
+ * character is matched against the supplied RegExp.
41
+ * @example { '#': /[0-9]/, H: /[A-Fa-f0-9]/ }
22
42
  */
23
- unmask?: string;
43
+ tokens?: Record<string, RegExp>;
24
44
  /**
25
- * Placeholder character in mask, default is underscore.
26
- * @default _
45
+ * Controlled masked value. When provided, the hook operates in
46
+ * controlled mode.
27
47
  */
28
- slotChar?: string;
48
+ value?: string;
29
49
  /**
30
- * Clears the incomplete value on blur.
31
- * @default true
50
+ * Initial masked value for uncontrolled mode. Ignored when `value` is
51
+ * provided.
32
52
  */
33
- autoClear?: boolean;
53
+ defaultValue?: string;
54
+ /**
55
+ * Fires whenever the value changes (typing, paste, programmatic).
56
+ */
57
+ onValueChange?: (event: UseMaskValueChangeEvent) => void;
58
+ /**
59
+ * Fires when the value transitions to complete (all required slots
60
+ * filled). Re-fires if the value becomes incomplete and is completed
61
+ * again.
62
+ */
63
+ onComplete?: (event: UseMaskValueChangeEvent) => void;
64
+ /**
65
+ * Placeholder character for empty slots. Pass `null` to skip filling
66
+ * empty slots visually.
67
+ * @default '_'
68
+ */
69
+ slotChar?: string | null;
34
70
  /**
35
- * Whether the components are clickable or not.
71
+ * Whether to render the mask skeleton on focus.
36
72
  * @default false
37
73
  */
38
- readOnly?: boolean;
74
+ showMaskOnFocus?: boolean;
75
+ /**
76
+ * Always render the mask skeleton, regardless of focus state.
77
+ * @default false
78
+ */
79
+ alwaysShowMask?: boolean;
80
+ /**
81
+ * Clear an incomplete value on blur.
82
+ * @default true
83
+ */
84
+ autoClear?: boolean;
39
85
  /**
40
- * Callback function that is called when the value is changed.
41
- * @param event The event that triggered the change.
42
- * @param event.value The value of the component.
43
- * @returns void
86
+ * Transform every character before token validation (e.g. uppercase).
44
87
  */
45
- onMaskChange?: (event: UseMaskChangeEvent) => void;
88
+ transform?: (char: string) => string;
46
89
  /**
47
- * Reference to the mask element.
90
+ * Read-only mode. Typing is blocked; programmatic `setValue` still
91
+ * works.
92
+ * @default false
48
93
  */
49
- target: HTMLInputElement;
94
+ readOnly?: boolean;
50
95
  }
51
- export interface UseMaskExposes {
96
+ /**
97
+ * Return type of the `useMask` hook.
98
+ */
99
+ export interface UseMaskReturn {
52
100
  /**
53
- * Handles input events for the masked input field.
54
- * Processes character input and composition events while applying the mask pattern.
55
- * @param event - The form or composition event from the input element
101
+ * Ref callback for the target `<input>` (or `<textarea>`). Attaches
102
+ * native event listeners on mount and tears them down on unmount or
103
+ * when the ref switches to a new element.
56
104
  */
57
- onMaskInput: (event: React.FormEvent<HTMLInputElement> | React.CompositionEvent<HTMLInputElement>) => void;
105
+ ref: (element: HTMLInputElement | null) => void;
58
106
  /**
59
- * Handles keydown events for special key operations.
60
- * Manages backspace, delete, escape, and enter key behaviors.
61
- * @param event - The keyboard event from the input element
107
+ * Current masked value (always reflects what is in the input).
62
108
  */
63
- onMaskKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;
109
+ value: string;
64
110
  /**
65
- * Handles keypress events for character input validation.
66
- * Validates and places characters according to the mask pattern.
67
- * @param event - The keyboard event from the input element
111
+ * Current unmasked (raw) value.
68
112
  */
69
- onMaskKeyPress: (event: React.KeyboardEvent<HTMLInputElement>) => void;
113
+ rawValue: string;
70
114
  /**
71
- * Handles focus events when the input gains focus.
72
- * Initializes the mask display and sets the cursor position.
73
- * @param event - The focus event from the input element
115
+ * Whether all required slots are filled.
74
116
  */
75
- onMaskFocus: (event: React.FocusEvent<HTMLInputElement>) => void;
117
+ isComplete: boolean;
76
118
  /**
77
- * Handles blur events when the input loses focus.
78
- * Validates the final value and triggers change events if needed.
79
- * @param event - The focus event from the input element
119
+ * Programmatically set the masked value. The value is normalized
120
+ * through the mask before being applied.
80
121
  */
81
- onMaskBlur: (event: React.FocusEvent<HTMLInputElement>) => void;
122
+ setValue: (next: string) => void;
82
123
  /**
83
- * Handles paste events for clipboard content insertion.
84
- * Processes pasted content according to the mask pattern.
85
- * @param event - The clipboard event from the input element
124
+ * Reset the input to an empty mask skeleton.
86
125
  */
87
- onMaskPaste: (event: React.ClipboardEvent<HTMLInputElement>) => void;
126
+ reset: () => void;
88
127
  }
89
128
  /**
90
- * useMask hook is used to enter input in a certain format such as numeric, date, currency, email and phone.
91
- *
92
- * @param {UseMaskOptions} options - The options for the mask.
93
- * @returns {UseMaskExposes} - The exposed methods for the mask.
129
+ * React hook for masked text input. Attach the returned `ref` to any
130
+ * component that forwards a ref to a real `<input>` (e.g. `InputText`,
131
+ * `Textarea`, `DatePicker.Input`). The hook installs DOM event listeners
132
+ * directly on the element, so no other props need to be wired.
94
133
  *
95
134
  * @example
96
- * ```tsx
97
- * const { onMaskInput, onMaskKeyDown, onMaskKeyPress, onMaskFocus, onMaskBlur, onMaskPaste } = useMask({
98
- * mask: '99/99/9999',
99
- * onMaskChange: (event: UseMaskChangeEvent) => setValue(event.value ?? ''),
100
- * target: ref
101
- * });
102
- *
103
- * return (
104
- * <div className="card flex justify-center">
105
- * <InputText ref={ref} value={value} placeholder="99/99/9999" onInput={onMaskInput} onKeyDown={onMaskKeyDown} onKeyPress={onMaskKeyPress} onFocus={onMaskFocus} onBlur={onMaskBlur} onPaste={onMaskPaste} />
106
- * </div>
107
- * );
135
+ * const { ref, value, rawValue, isComplete } = useMask({ mask: '99/99/9999' });
136
+ * return <InputText ref={ref} placeholder="DD/MM/YYYY" />;
108
137
  */
109
- export declare function useMask(options: UseMaskOptions): UseMaskExposes;
138
+ export declare function useMask(options: UseMaskOptions): UseMaskReturn;
@@ -1,2 +1,2 @@
1
- import{useMountEffect as te}from"@primereact/hooks";import{getUserAgent as x}from"@primeuix/utils";import*as i from"react";function ue(j){let{mask:m,unmask:N,slotChar:L="_",autoClear:O=!0,readOnly:v=!1,onMaskChange:K,target:s}=j,o=i.useRef(0),a=i.useRef([]),l=i.useRef([]),k=i.useRef(null),h=i.useRef(0),w=i.useRef(!1),P=i.useRef(!1),T=i.useRef(null),M=i.useRef(null),S=i.useRef(0),H=i.useRef(null),I=i.useRef(null),A=i.useRef(null),q=e=>{"isComposing"in e&&e.isComposing||(w.current?X():D(e))},z=e=>{var b;if(v)return;let t=e.code,r,n,u,c=/iphone/i.test(x());if(I.current=s==null?void 0:s.value,t==="Backspace"||t==="Delete"||c&&t==="Escape"){if(r=f(),!r)return;n=r.begin,u=r.end,u-n===0&&(n=t!=="Delete"?Q(n):u=d(n-1),u=t==="Delete"?d(u):u),y(n,u),F(n,u-1),g(e.target.value),e.preventDefault()}else t==="Enter"?(s.blur(),g(e.target.value)):t==="Escape"&&(s&&(s.value=(b=T.current)!=null?b:""),f(0,p()),g(e.target.value),e.preventDefault())},J=e=>{var b;if(v)return;let t=e.code,r=f(),n,u,c;r&&(e.ctrlKey||e.altKey||e.metaKey||e.shiftKey||e.key==="CapsLock"||e.key==="Escape"||e.key==="Tab"||(t&&t!=="Enter"&&(r.end-r.begin!==0&&(y(r.begin,r.end),F(r.begin,r.end-1)),n=d(r.begin-1),n<o.current&&(u=e.key,(b=a.current[n])!=null&&b.test(u)&&(W(n),l.current[n]=u,E(),c=d(n),/android/i.test(x())?setTimeout(()=>{f(c)},0):f(c))),e.preventDefault()),g(e.target.value)))},Z=()=>{if(!v)if(H.current&&clearTimeout(H.current),P.current=!0,T.current=s.value,!s.value||s.value===k.current)requestAnimationFrame(()=>{s===document.activeElement&&f(0,0)});else{let e=p();H.current=setTimeout(()=>{s===document.activeElement&&(E(),e===(m==null?void 0:m.replace("?","").length)?f(0,e):f(e))},10)}},_=e=>{if(P.current=!1,p(),g(e.target.value),s.value!==T.current){let t=new Event("change",{bubbles:!0,cancelable:!1});s.dispatchEvent(t)}},G=e=>{D(e)},f=(e,t)=>{var u,c;let r=0,n=0;return typeof e=="number"?(r=e,n=typeof t=="number"?t:r,s.setSelectionRange(r,n)):s&&(r=(u=s.selectionStart)!=null?u:0,n=(c=s.selectionEnd)!=null?c:0),{begin:r,end:n}},R=e=>e<L.length?L.charAt(e):L.charAt(0),d=e=>{for(;++e<o.current&&!a.current[e];);return e},Q=e=>{for(;--e>=0&&!a.current[e];);return e},F=(e,t)=>{var u,c;let r,n;if(!(e<0)){for(r=e,n=d(t);r<o.current;r++)if(a.current[r]){if(n<o.current&&((u=a.current[r])!=null&&u.test(l.current[n])))l.current[r]=l.current[n],l.current[n]=R(n);else break;n=d(n)}E(),f(Math.max((c=M.current)!=null?c:0,e))}},W=e=>{var c;let t,r,n,u;for(t=e,r=R(e);t<o.current;t++)if(a.current[t])if(n=d(t),u=l.current[t],l.current[t]=r,n<o.current&&((c=a.current[n])!=null&&c.test(u)))r=u;else break},X=()=>{var r;let e=s.value,t=f();if(t)if(I.current&&I.current.length&&I.current.length>e.length){for(p(!0);t.begin>0&&!a.current[t.begin-1];)t.begin--;if(t.begin===0)for(;t.begin<((r=M.current)!=null?r:0)&&!a.current[t.begin];)t.begin++;f(t.begin,t.begin)}else{for(p(!0);t.begin<o.current&&!a.current[t.begin];)t.begin++;f(t.begin,t.begin)}},y=(e,t)=>{let r;for(r=e;r<t&&r<o.current;r++)a.current[r]&&(l.current[r]=R(r))},E=()=>{s&&(s.value=l.current.join(""))},p=(e=!1)=>{var b,C,V,B;let t=s.value,r=-1,n,u,c;for(n=0,c=0;n<o.current;n++){let U=a.current[n];if(U!==null){for(l.current[n]=R(n);c++<((b=t==null?void 0:t.length)!=null?b:0);)if(u=(C=t==null?void 0:t.charAt(c-1))!=null?C:"",U.test(u)){l.current[n]=u,r=n;break}if(c>((V=t==null?void 0:t.length)!=null?V:0)){y(n+1,o.current);break}}else l.current[n]===(t==null?void 0:t.charAt(c))&&c++,n<h.current&&(r=n)}return e?E():r+1<h.current?O||l.current.join("")===k.current?(s.value&&(s.value=""),y(0,o.current)):E():(E(),s&&(s.value=s.value.substring(0,r+1))),h.current?n:(B=M.current)!=null?B:0},D=e=>{let t=e.type==="paste";if(v||t)return;let r=p(!0);f(r),g(e.target.value)},Y=e=>{let t=[],r=e.split("");for(let n=0;n<r.length;n++){let u=r[n];a.current[n]&&u!==R(n)&&t.push(u)}return t.join("")},g=e=>{if(A.current===e)return;let t=N?Y(e):e,r=k.current!==t?t:"";A.current=e,s&&(s.value=r),K&&K({value:r})},$=(e=!0)=>{s&&(s.value==null?(s.value="",e&&g("")):(p(),setTimeout(()=>{s&&(E(),p(),e&&g(s.value))},10)),T.current=s.value)},ee=()=>{a.current=[],h.current=m?m.length:0,o.current=m?m.length:0,M.current=null;let e={9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},t=x();w.current=/chrome/i.test(t)&&/android/i.test(t);let r=m?m.split(""):"";for(let n=0;n<r.length;n++){let u=r[n];u==="?"?(o.current--,h.current=n):e[u]?(a.current.push(new RegExp(e[u])),M.current===null&&(M.current=a.current.length-1),n<h.current&&(S.current=a.current.length-1)):a.current.push(null)}l.current=[];for(let n=0;n<r.length;n++){let u=r[n];u!=="?"&&(e[u]?l.current.push(R(n)):l.current.push(u))}k.current=l.current.join(""),$(!1)};return te(()=>{ee()}),{onMaskInput:q,onMaskKeyDown:z,onMaskKeyPress:J,onMaskFocus:Z,onMaskBlur:_,onMaskPaste:G}}export{ue as useMask};
1
+ var xe=Object.defineProperty;var Oe=Object.getOwnPropertySymbols;var je=Object.prototype.hasOwnProperty,He=Object.prototype.propertyIsEnumerable;var Ie=(M,o,k)=>o in M?xe(M,o,{enumerable:!0,configurable:!0,writable:!0,value:k}):M[o]=k,J=(M,o)=>{for(var k in o||(o={}))je.call(o,k)&&Ie(M,k,o[k]);if(Oe)for(var k of Oe(o))He.call(o,k)&&Ie(M,k,o[k]);return M};import{getUserAgent as Q}from"@primeuix/utils";import*as c from"react";var Be={9:/[0-9]/,a:/[A-Za-z]/,A:/[A-Z]/,"*":/[A-Za-z0-9]/};function _e(M){let{mask:o,tokens:k,value:C,defaultValue:S,onValueChange:X,onComplete:Y,slotChar:$="_",showMaskOnFocus:ee=!1,alwaysShowMask:te=!1,autoClear:re=!0,transform:ne,readOnly:ue=!1}=M,P=c.useRef(X);P.current=X;let D=c.useRef(Y);D.current=Y;let B=c.useRef(ne);B.current=ne;let N=C!==void 0,[Se,Ae]=c.useState(S!=null?S:""),O=N?C!=null?C:"":Se,ce=c.useCallback(e=>{N||Ae(e)},[N]),g=c.useRef(null),d=c.useRef(0),i=c.useRef([]),p=c.useRef([]),L=c.useRef(""),I=c.useRef(0),se=c.useRef(!1),Z=c.useRef(!1),_=c.useRef(null),T=c.useRef(null),q=c.useRef(0),z=c.useRef(null),F=c.useRef(null),U=c.useRef(null),W=c.useRef(!1),ae=c.useRef(null),h=c.useRef({slotChar:$,showMaskOnFocus:ee,alwaysShowMask:te,autoClear:re,readOnly:ue,mask:o,userTokens:k});h.current={slotChar:$,showMaskOnFocus:ee,alwaysShowMask:te,autoClear:re,readOnly:ue,mask:o,userTokens:k};let v=c.useCallback(e=>{let r=h.current.slotChar;return r==null?"":e<r.length?r.charAt(e):r.charAt(0)},[]),l=c.useCallback((e,r)=>{var s,f;let n=g.current,t=0,u=0;return n?(typeof e=="number"?(t=e,u=typeof r=="number"?r:t,n.setSelectionRange(t,u)):(t=(s=n.selectionStart)!=null?s:0,u=(f=n.selectionEnd)!=null?f:0),{begin:t,end:u}):{begin:t,end:u}},[]),E=c.useCallback(e=>{for(;++e<d.current&&!i.current[e];);return e},[]),le=c.useCallback(e=>{for(;--e>=0&&!i.current[e];);return e},[]),G=c.useRef(!1),a=c.useCallback((e,r)=>{var u;let n=window.HTMLInputElement.prototype,t=(u=Object.getOwnPropertyDescriptor(n,"value"))==null?void 0:u.set;t?t.call(e,r):e.value=r},[]),oe=c.useCallback(e=>{G.current=!0;try{e.dispatchEvent(new Event("input",{bubbles:!0}))}finally{G.current=!1}},[]),w=c.useCallback(()=>{let e=g.current;e&&a(e,p.current.join(""))},[a]),V=c.useCallback((e,r)=>{for(let n=e;n<r&&n<d.current;n++)i.current[n]&&(p.current[n]=v(n))},[v]),x=c.useCallback((e,r)=>{var t,u;if(e<0)return;let n=E(r);for(let s=e;s<d.current;s++)if(i.current[s]){if(n<d.current&&((t=i.current[s])!=null&&t.test(p.current[n])))p.current[s]=p.current[n],p.current[n]=v(n);else break;n=E(n)}w(),l(Math.max((u=T.current)!=null?u:0,e))},[E,v,w,l]),ie=c.useCallback(e=>{var n;let r=v(e);for(let t=e;t<d.current;t++)if(i.current[t]){let u=E(t),s=p.current[t];if(p.current[t]=r,u<d.current&&((n=i.current[u])!=null&&n.test(s)))r=s;else break}},[v,E]),R=c.useCallback((e=!1)=>{var y,A,K,Le,Te;let r=g.current;if(!r)return(y=T.current)!=null?y:0;let n=r.value,t=-1,u,s,f;for(u=0,f=0;u<d.current;u++){let Ve=i.current[u];if(Ve!==null){for(p.current[u]=v(u);f++<((A=n==null?void 0:n.length)!=null?A:0);)if(s=(K=n==null?void 0:n.charAt(f-1))!=null?K:"",Ve.test(s)){p.current[u]=s,t=u;break}if(f>((Le=n==null?void 0:n.length)!=null?Le:0)){V(u+1,d.current);break}}else p.current[u]===(n==null?void 0:n.charAt(f))&&f++,u<I.current&&(t=u)}return e?w():t+1<I.current?h.current.autoClear||p.current.join("")===L.current?(r.value&&a(r,""),V(0,d.current)):w():(w(),a(r,r.value.substring(0,t+1))),I.current?u:(Te=T.current)!=null?Te:0},[v,V,w,a]),j=c.useCallback(e=>{let r=[],n=e.split("");for(let t=0;t<n.length;t++){let u=n[t];i.current[t]&&u!==v(t)&&r.push(u)}return r.join("")},[v]),H=c.useCallback(e=>{var n;let r=e.split("");for(let t=0;t<=q.current&&t<d.current;t++)if(i.current[t]){let u=r[t];if(!u||!((n=i.current[t])!=null&&n.test(u)))return!1}return!0},[]),b=c.useCallback(e=>{var A,K;let r=g.current;if(!r)return;let n=r.value,t=n===L.current,u=t?"":n;if(ae.current===u)return;ae.current=u,(e==null?void 0:e.type)!=="input"&&oe(r);let s=t?"":j(n),f=!t&&H(n),y={originalEvent:e,value:u,rawValue:s,isComplete:f};ce(u),(A=P.current)==null||A.call(P,y),f&&!W.current&&((K=D.current)==null||K.call(D,y)),W.current=f,U.current=n},[j,H,ce,oe]),fe=c.useCallback(e=>{if(h.current.readOnly||e.type==="paste")return;let r=R(!0);l(r),b(e)},[R,l,b]),Re=c.useCallback(e=>{var u;let r=g.current;if(!r)return;let n=r.value,t=l();if(t){if(F.current&&F.current.length&&F.current.length>n.length){for(R(!0);t.begin>0&&!i.current[t.begin-1];)t.begin--;if(t.begin===0)for(;t.begin<((u=T.current)!=null?u:0)&&!i.current[t.begin];)t.begin++;l(t.begin,t.begin)}else{for(R(!0);t.begin<d.current&&!i.current[t.begin];)t.begin++;l(t.begin,t.begin)}b(e)}},[l,R,b]),be=c.useCallback(e=>{g.current&&(G.current||"isComposing"in e&&e.isComposing||(se.current?Re(e):fe(e)))},[Re,fe]),ge=c.useCallback(e=>{var y;let r=g.current;if(!r||h.current.readOnly)return;let n=e.code,t,u,s,f=/iphone/i.test(Q());if(F.current=r.value,n==="Backspace"||n==="Delete"||f&&n==="Escape"){if(t=l(),!t)return;u=t.begin,s=t.end,s-u===0&&(u=n!=="Delete"?le(u):s=E(u-1),s=n==="Delete"?E(s):s),V(u,s),x(u,s-1),b(e),e.preventDefault()}else n==="Enter"?(r.blur(),b(e)):n==="Escape"&&(a(r,(y=_.current)!=null?y:""),l(0,R()),b(e),e.preventDefault())},[l,le,E,V,x,b,a,R]),pe=c.useCallback(e=>{var u;if(!g.current||h.current.readOnly)return;let n=e.code,t=l();if(t&&!(e.ctrlKey||e.altKey||e.metaKey||e.shiftKey||e.key==="CapsLock"||e.key==="Escape"||e.key==="Tab")){if(n&&n!=="Enter"){t.end-t.begin!==0&&(V(t.begin,t.end),x(t.begin,t.end-1));let s=E(t.begin-1);if(s<d.current){let f=e.key;if(B.current&&(f=B.current(f)),(u=i.current[s])!=null&&u.test(f)){ie(s),p.current[s]=f,w();let y=E(s);/android/i.test(Q())?setTimeout(()=>l(y),0):l(y)}}e.preventDefault()}b(e)}},[l,V,x,E,ie,w,b]),ke=c.useCallback(e=>{let r=g.current;if(!r||h.current.readOnly)return;z.current&&clearTimeout(z.current),Z.current=!0,_.current=r.value;let n=h.current.showMaskOnFocus||h.current.alwaysShowMask;if(!r.value||r.value===L.current)n&&a(r,L.current),requestAnimationFrame(()=>{var t,u;r===document.activeElement&&l((t=T.current)!=null?t:0,(u=T.current)!=null?u:0)});else{let t=R();z.current=setTimeout(()=>{var u;r===document.activeElement&&(w(),t===((u=h.current.mask)==null?void 0:u.replace("?","").length)?l(0,t):l(t))},10)}},[l,R,w,a]),de=c.useCallback(e=>{let r=g.current;r&&(Z.current=!1,R(),!h.current.alwaysShowMask&&r.value===L.current&&a(r,""),b(e),r.value!==_.current&&r.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!1})))},[R,b,a]),he=c.useCallback(e=>{!g.current||h.current.readOnly||setTimeout(()=>{let n=R(!0);l(n),b(e)},0)},[R,l,b]),me=c.useCallback(()=>{i.current=[],I.current=o?o.length:0,d.current=o?o.length:0,T.current=null,q.current=0;let e=J(J({},Be),k),r=Q();se.current=/chrome/i.test(r)&&/android/i.test(r);let n=o?o.split(""):[];for(let u=0;u<n.length;u++){let s=n[u];s==="?"?(d.current--,I.current=u):e[s]?(i.current.push(e[s]),T.current===null&&(T.current=i.current.length-1),u<I.current&&(q.current=i.current.length-1)):i.current.push(null)}p.current=[];for(let u=0;u<n.length;u++){let s=n[u];s!=="?"&&(e[s]?p.current.push(v(u)):p.current.push(s))}L.current=p.current.join("");let t=g.current;t&&!t.value&&h.current.alwaysShowMask&&a(t,L.current)},[o,k,v,a]);c.useEffect(()=>{me()},[me]),c.useEffect(()=>{let e=g.current;e&&C!==void 0&&C!==U.current&&(Z.current||(a(e,C),R(),U.current=e.value))},[C,a,R]);let ve=c.useRef(be);ve.current=be;let Ee=c.useRef(ge);Ee.current=ge;let ye=c.useRef(pe);ye.current=pe;let Ce=c.useRef(ke);Ce.current=ke;let we=c.useRef(de);we.current=de;let Me=c.useRef(he);Me.current=he;let m=c.useMemo(()=>({input:e=>ve.current(e),keydown:e=>Ee.current(e),keypress:e=>ye.current(e),focus:e=>Ce.current(e),blur:e=>we.current(e),paste:e=>Me.current(e)}),[]),Ke=c.useCallback(e=>{let r=g.current;r&&r!==e&&(r.removeEventListener("input",m.input),r.removeEventListener("keydown",m.keydown),r.removeEventListener("keypress",m.keypress),r.removeEventListener("focus",m.focus),r.removeEventListener("blur",m.blur),r.removeEventListener("paste",m.paste)),g.current=e,e&&e!==r&&(e.addEventListener("input",m.input),e.addEventListener("keydown",m.keydown),e.addEventListener("keypress",m.keypress),e.addEventListener("focus",m.focus),e.addEventListener("blur",m.blur),e.addEventListener("paste",m.paste),C?(a(e,C),R()):S&&!e.value?(a(e,S),R()):h.current.alwaysShowMask&&!e.value&&a(e,L.current))},[m]),Pe=c.useMemo(()=>O?j(O):"",[O,j]),De=c.useMemo(()=>O?H(O):!1,[O,H]),Fe=c.useCallback(e=>{let r=g.current;r&&(a(r,e!=null?e:""),R(!0),b(null))},[a,R,b]),Ue=c.useCallback(()=>{let e=g.current;e&&(a(e,""),V(0,d.current),h.current.alwaysShowMask&&a(e,L.current),U.current=e.value,W.current=!1,b(null))},[a,V,b]);return{ref:Ke,value:O,rawValue:Pe,isComplete:De,setValue:Fe,reset:Ue}}export{_e as useMask};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/use-mask/index.ts"],"sourcesContent":["import { useMountEffect } from '@primereact/hooks';\nimport { getUserAgent } from '@primeuix/utils';\nimport * as React from 'react';\n\n/**\n * Event fired when the component's state changes.\n */\nexport interface UseMaskChangeEvent {\n /**\n * The value of the component.\n */\n value: string | undefined;\n}\n\n/**\n * The options for the `useMask` hook.\n */\nexport interface UseMaskOptions {\n /**\n * Mask pattern.\n */\n mask: string;\n /**\n * Defines if model sets the raw unmasked value to bound value or the formatted mask value.\n * @default false\n */\n unmask?: string;\n /**\n * Placeholder character in mask, default is underscore.\n * @default _\n */\n slotChar?: string;\n /**\n * Clears the incomplete value on blur.\n * @default true\n */\n autoClear?: boolean;\n /**\n * Whether the components are clickable or not.\n * @default false\n */\n readOnly?: boolean;\n /**\n * Callback function that is called when the value is changed.\n * @param event The event that triggered the change.\n * @param event.value The value of the component.\n * @returns void\n */\n onMaskChange?: (event: UseMaskChangeEvent) => void;\n /**\n * Reference to the mask element.\n */\n target: HTMLInputElement;\n}\n\nexport interface UseMaskExposes {\n /**\n * Handles input events for the masked input field.\n * Processes character input and composition events while applying the mask pattern.\n * @param event - The form or composition event from the input element\n */\n onMaskInput: (event: React.FormEvent<HTMLInputElement> | React.CompositionEvent<HTMLInputElement>) => void;\n /**\n * Handles keydown events for special key operations.\n * Manages backspace, delete, escape, and enter key behaviors.\n * @param event - The keyboard event from the input element\n */\n onMaskKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n /**\n * Handles keypress events for character input validation.\n * Validates and places characters according to the mask pattern.\n * @param event - The keyboard event from the input element\n */\n onMaskKeyPress: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n /**\n * Handles focus events when the input gains focus.\n * Initializes the mask display and sets the cursor position.\n * @param event - The focus event from the input element\n */\n onMaskFocus: (event: React.FocusEvent<HTMLInputElement>) => void;\n /**\n * Handles blur events when the input loses focus.\n * Validates the final value and triggers change events if needed.\n * @param event - The focus event from the input element\n */\n onMaskBlur: (event: React.FocusEvent<HTMLInputElement>) => void;\n /**\n * Handles paste events for clipboard content insertion.\n * Processes pasted content according to the mask pattern.\n * @param event - The clipboard event from the input element\n */\n onMaskPaste: (event: React.ClipboardEvent<HTMLInputElement>) => void;\n}\n\n/**\n * useMask hook is used to enter input in a certain format such as numeric, date, currency, email and phone.\n *\n * @param {UseMaskOptions} options - The options for the mask.\n * @returns {UseMaskExposes} - The exposed methods for the mask.\n *\n * @example\n * ```tsx\n * const { onMaskInput, onMaskKeyDown, onMaskKeyPress, onMaskFocus, onMaskBlur, onMaskPaste } = useMask({\n * mask: '99/99/9999',\n * onMaskChange: (event: UseMaskChangeEvent) => setValue(event.value ?? ''),\n * target: ref\n * });\n *\n * return (\n * <div className=\"card flex justify-center\">\n * <InputText ref={ref} value={value} placeholder=\"99/99/9999\" onInput={onMaskInput} onKeyDown={onMaskKeyDown} onKeyPress={onMaskKeyPress} onFocus={onMaskFocus} onBlur={onMaskBlur} onPaste={onMaskPaste} />\n * </div>\n * );\n */\nexport function useMask(options: UseMaskOptions): UseMaskExposes {\n const { mask, unmask, slotChar = '_', autoClear = true, readOnly = false, onMaskChange, target } = options;\n\n const len = React.useRef(0);\n const tests = React.useRef<Array<RegExp | null>>([]);\n const buffer = React.useRef<string[]>([]);\n const defaultBuffer = React.useRef<string | null>(null);\n const partialPosition = React.useRef<number>(0);\n const androidChrome = React.useRef(false);\n const focus = React.useRef(false);\n const focusText = React.useRef<string | null>(null);\n const firstNonMaskPos = React.useRef<number | null>(null);\n const lastRequiredNonMaskPos = React.useRef<number>(0);\n const caretTimeoutId = React.useRef<NodeJS.Timeout | null>(null);\n const oldVal = React.useRef<string | null>(null);\n const currentVal = React.useRef<string | null>(null);\n\n const onMaskInput = (event: React.FormEvent<HTMLInputElement> | React.CompositionEvent<HTMLInputElement>) => {\n // Check if the event is part of a text composition process (e.g., for Asian languages).\n // If event.isComposing is true, it means the user is still composing text and the input is not finalized.\n if ('isComposing' in event && event.isComposing) {\n return;\n }\n\n if (androidChrome.current) handleAndroidInput();\n else handleInputChange(event);\n };\n\n const onMaskKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (readOnly) {\n return;\n }\n\n const k = event.code;\n let pos, begin, end;\n const iPhone = /iphone/i.test(getUserAgent());\n\n oldVal.current = target?.value as string;\n\n //backspace, delete, and escape get special treatment\n if (k === 'Backspace' || k === 'Delete' || (iPhone && k === 'Escape')) {\n pos = caret();\n\n if (!pos) {\n return;\n }\n\n begin = pos.begin;\n end = pos.end;\n\n if (end - begin === 0) {\n begin = k !== 'Delete' ? seekPrev(begin) : (end = seekNext(begin - 1));\n end = k === 'Delete' ? seekNext(end) : end;\n }\n\n clearBuffer(begin, end);\n shiftL(begin, end - 1);\n updateModelValue((event.target as HTMLInputElement).value);\n\n event.preventDefault();\n } else if (k === 'Enter') {\n // enter\n target.blur();\n updateModelValue((event.target as HTMLInputElement).value);\n } else if (k === 'Escape') {\n // escape\n if (target) {\n target.value = focusText.current ?? '';\n }\n\n caret(0, checkVal());\n updateModelValue((event.target as HTMLInputElement).value);\n event.preventDefault();\n }\n };\n\n const onMaskKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (readOnly) {\n return;\n }\n\n const k = event.code,\n pos = caret();\n let p: number, c: string, next: number;\n\n if (!pos) {\n return;\n }\n\n if (event.ctrlKey || event.altKey || event.metaKey || event.shiftKey || event.key === 'CapsLock' || event.key === 'Escape' || event.key === 'Tab') {\n //Ignore\n return;\n } else if (k && k !== 'Enter') {\n if (pos.end - pos.begin !== 0) {\n clearBuffer(pos.begin, pos.end);\n shiftL(pos.begin, pos.end - 1);\n }\n\n p = seekNext(pos.begin - 1);\n\n if (p < len.current) {\n c = event.key;\n\n if (tests.current[p]?.test(c)) {\n shiftR(p);\n\n buffer.current[p] = c;\n writeBuffer();\n next = seekNext(p);\n\n if (/android/i.test(getUserAgent())) {\n //Path for CSP Violation on FireFox OS 1.1\n const proxy = () => {\n caret(next);\n };\n\n setTimeout(proxy, 0);\n } else {\n caret(next);\n }\n }\n }\n\n event.preventDefault();\n }\n\n updateModelValue((event.target as HTMLInputElement).value);\n };\n\n const onMaskFocus = () => {\n if (readOnly) {\n return;\n }\n\n if (caretTimeoutId.current) {\n clearTimeout(caretTimeoutId.current as NodeJS.Timeout);\n }\n\n focus.current = true;\n focusText.current = target.value as string;\n\n if (!target.value || target.value === defaultBuffer.current) {\n requestAnimationFrame(() => {\n if (target === document.activeElement) {\n caret(0, 0);\n }\n });\n } else {\n const pos = checkVal();\n\n caretTimeoutId.current = setTimeout(() => {\n if (target !== document.activeElement) {\n return;\n }\n\n writeBuffer();\n\n if (pos === mask?.replace('?', '').length) {\n caret(0, pos);\n } else {\n caret(pos);\n }\n }, 10);\n }\n };\n\n const onMaskBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n focus.current = false;\n checkVal();\n updateModelValue(event.target.value);\n\n if (target.value !== focusText.current) {\n const e = new Event('change', { bubbles: true, cancelable: false });\n\n target.dispatchEvent(e);\n }\n };\n\n const onMaskPaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n handleInputChange(event);\n };\n\n const caret = (first?: number, last?: number): { begin: number; end: number } | undefined => {\n let begin = 0,\n end = 0;\n\n if (typeof first === 'number') {\n begin = first;\n end = typeof last === 'number' ? last : begin;\n\n target.setSelectionRange(begin, end);\n } else {\n if (target) {\n begin = target.selectionStart ?? 0;\n end = target.selectionEnd ?? 0;\n }\n }\n\n return { begin, end };\n };\n\n const getPlaceholder = (i: number) => {\n if (i < slotChar.length) {\n return slotChar.charAt(i);\n }\n\n return slotChar.charAt(0);\n };\n\n const seekNext = (pos: number) => {\n while (++pos < len.current && !tests.current[pos]);\n\n return pos;\n };\n\n const seekPrev = (pos: number) => {\n while (--pos >= 0 && !tests.current[pos]);\n\n return pos;\n };\n\n const shiftL = (begin: number, end: number) => {\n let i, j;\n\n if (begin < 0) {\n return;\n }\n\n for (i = begin, j = seekNext(end); i < len.current; i++) {\n if (tests.current[i]) {\n if (j < len.current && tests.current[i]?.test(buffer.current[j])) {\n buffer.current[i] = buffer.current[j];\n buffer.current[j] = getPlaceholder(j);\n } else {\n break;\n }\n\n j = seekNext(j);\n }\n }\n\n writeBuffer();\n caret(Math.max(firstNonMaskPos.current ?? 0, begin));\n };\n\n const shiftR = (pos: number) => {\n let i, c, j, t;\n\n for (i = pos, c = getPlaceholder(pos); i < len.current; i++) {\n if (tests.current[i]) {\n j = seekNext(i);\n t = buffer.current[i];\n buffer.current[i] = c;\n\n if (j < len.current && tests.current[j]?.test(t)) {\n c = t;\n } else {\n break;\n }\n }\n }\n };\n\n const handleAndroidInput = () => {\n const curVal = target.value as string;\n const pos = caret();\n\n if (!pos) {\n return;\n }\n\n if (oldVal.current && oldVal.current.length && oldVal.current.length > curVal.length) {\n // a deletion or backspace happened\n checkVal(true);\n while (pos.begin > 0 && !tests.current[pos.begin - 1]) pos.begin--;\n\n if (pos.begin === 0) {\n while (pos.begin < (firstNonMaskPos.current ?? 0) && !tests.current[pos.begin]) pos.begin++;\n }\n\n caret(pos.begin, pos.begin);\n } else {\n checkVal(true);\n while (pos.begin < len.current && !tests.current[pos.begin]) pos.begin++;\n\n caret(pos.begin, pos.begin);\n }\n };\n\n const clearBuffer = (start: number, end: number) => {\n let i;\n\n for (i = start; i < end && i < len.current; i++) {\n if (tests.current[i]) {\n buffer.current[i] = getPlaceholder(i);\n }\n }\n };\n\n const writeBuffer = () => {\n if (target) {\n target.value = buffer.current.join('');\n }\n };\n\n const checkVal = (allow = false): number => {\n //try to place characters where they belong\n const test = target.value;\n let lastMatch = -1,\n i,\n c,\n pos;\n\n for (i = 0, pos = 0; i < len.current; i++) {\n const currentTest = tests.current[i];\n\n if (currentTest !== null) {\n buffer.current[i] = getPlaceholder(i);\n\n while (pos++ < (test?.length ?? 0)) {\n c = test?.charAt(pos - 1) ?? '';\n\n if (currentTest.test(c)) {\n buffer.current[i] = c;\n lastMatch = i;\n break;\n }\n }\n\n if (pos > (test?.length ?? 0)) {\n clearBuffer(i + 1, len.current);\n break;\n }\n } else {\n if (buffer.current[i] === test?.charAt(pos)) {\n pos++;\n }\n\n if (i < partialPosition.current) {\n lastMatch = i;\n }\n }\n }\n\n if (allow) {\n writeBuffer();\n } else if (lastMatch + 1 < partialPosition.current) {\n if (autoClear || buffer.current.join('') === defaultBuffer.current) {\n // Invalid value. Remove it and replace it with the\n // mask, which is the default behavior.\n if (target.value) {\n target.value = '';\n }\n\n clearBuffer(0, len.current);\n } else {\n // Invalid value, but we opt to show the value to the\n // user and allow them to correct their mistake.\n writeBuffer();\n }\n } else {\n writeBuffer();\n\n if (target) {\n target.value = target.value.substring(0, lastMatch + 1);\n }\n }\n\n return partialPosition.current ? i : (firstNonMaskPos.current ?? 0);\n };\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement> | React.ClipboardEvent<HTMLInputElement>) => {\n const isPasteEvent = event.type === 'paste';\n\n if (readOnly || isPasteEvent) {\n return;\n }\n\n const pos = checkVal(true);\n\n caret(pos);\n updateModelValue((event.target as HTMLInputElement).value);\n };\n\n const unmaskValue = (value: string) => {\n const unmaskedBuffer = [];\n const thisbuffer = value.split('');\n\n for (let i = 0; i < thisbuffer.length; i++) {\n const c = thisbuffer[i];\n\n if (tests.current[i] && c !== getPlaceholder(i)) {\n unmaskedBuffer.push(c);\n }\n }\n\n return unmaskedBuffer.join('');\n };\n\n const updateModelValue = (value: string) => {\n if (currentVal.current === value) return;\n\n const val = unmask ? unmaskValue(value) : value;\n const finalValue = defaultBuffer.current !== val ? val : '';\n\n currentVal.current = value;\n\n if (target) {\n target.value = finalValue;\n }\n\n // Call the onMaskChange callback to update React state\n if (onMaskChange) {\n onMaskChange({ value: finalValue });\n }\n };\n\n const updateValue = (updateModel = true) => {\n if (target) {\n if (target.value == null) {\n target.value = '';\n\n if (updateModel) {\n updateModelValue('');\n }\n } else {\n checkVal();\n\n setTimeout(() => {\n if (target) {\n writeBuffer();\n checkVal();\n\n if (updateModel) updateModelValue(target.value);\n }\n }, 10);\n }\n\n focusText.current = target.value;\n }\n };\n\n const initMask = () => {\n tests.current = [];\n partialPosition.current = mask ? mask.length : 0;\n len.current = mask ? mask.length : 0;\n firstNonMaskPos.current = null;\n const defs = {\n 9: '[0-9]',\n a: '[A-Za-z]',\n '*': '[A-Za-z0-9]'\n } as Record<string, string>;\n\n const ua = getUserAgent();\n\n androidChrome.current = /chrome/i.test(ua) && /android/i.test(ua);\n\n const maskTokens = mask ? mask.split('') : '';\n\n for (let i = 0; i < maskTokens.length; i++) {\n const c = maskTokens[i];\n\n if (c === '?') {\n len.current--;\n partialPosition.current = i;\n } else if (defs[c]) {\n tests.current.push(new RegExp(defs[c]));\n\n if (firstNonMaskPos.current === null) {\n firstNonMaskPos.current = tests.current.length - 1;\n }\n\n if (i < partialPosition.current) {\n lastRequiredNonMaskPos.current = tests.current.length - 1;\n }\n } else {\n tests.current.push(null);\n }\n }\n\n buffer.current = [];\n\n for (let i = 0; i < maskTokens.length; i++) {\n const c = maskTokens[i];\n\n if (c !== '?') {\n if (defs[c]) buffer.current.push(getPlaceholder(i));\n else buffer.current.push(c);\n }\n }\n\n defaultBuffer.current = buffer.current.join('');\n\n updateValue(false);\n };\n\n useMountEffect(() => {\n initMask();\n });\n\n return {\n onMaskInput,\n onMaskKeyDown,\n onMaskKeyPress,\n onMaskFocus,\n onMaskBlur,\n onMaskPaste\n };\n}\n"],"mappings":"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","names":["useMountEffect","getUserAgent","React","useMask","options","mask","unmask","slotChar","autoClear","readOnly","onMaskChange","target","len","tests","buffer","defaultBuffer","partialPosition","androidChrome","focus","focusText","firstNonMaskPos","lastRequiredNonMaskPos","caretTimeoutId","oldVal","currentVal","onMaskInput","event","handleAndroidInput","handleInputChange","onMaskKeyDown","_a","k","pos","begin","end","iPhone","caret","seekPrev","seekNext","clearBuffer","shiftL","updateModelValue","checkVal","onMaskKeyPress","p","c","next","shiftR","writeBuffer","onMaskFocus","onMaskBlur","e","onMaskPaste","first","last","_b","getPlaceholder","i","j","t","curVal","start","allow","_c","_d","test","lastMatch","currentTest","isPasteEvent","unmaskValue","value","unmaskedBuffer","thisbuffer","val","finalValue","updateValue","updateModel","initMask","defs","ua","maskTokens"]}
1
+ {"version":3,"sources":["../../src/use-mask/index.ts"],"sourcesContent":["import { getUserAgent } from '@primeuix/utils';\nimport * as React from 'react';\n\n/**\n * Event payload for `useMask` value/complete callbacks.\n */\nexport interface UseMaskValueChangeEvent {\n /**\n * The DOM event that triggered the change, or `null` for programmatic\n * updates (`setValue`, `reset`).\n */\n originalEvent: Event | null;\n /**\n * Masked value (e.g. `\"12/05/2026\"`). Always in masked form.\n */\n value: string;\n /**\n * Unmasked (raw) value (e.g. `\"12052026\"`). Separators and placeholder\n * characters are stripped.\n */\n rawValue: string;\n /**\n * Whether all required slots are filled.\n */\n isComplete: boolean;\n}\n\n/**\n * Options for the `useMask` hook.\n */\nexport interface UseMaskOptions {\n /**\n * Mask pattern. Built-in tokens:\n * - `9` → [0-9]\n * - `a` → [A-Za-z]\n * - `A` → [A-Z]\n * - `*` → [A-Za-z0-9]\n * Append `?` to mark the remainder of the mask as optional. Extend with\n * the `tokens` option.\n */\n mask: string;\n /**\n * Custom token map merged on top of the built-in tokens. Each token\n * character is matched against the supplied RegExp.\n * @example { '#': /[0-9]/, H: /[A-Fa-f0-9]/ }\n */\n tokens?: Record<string, RegExp>;\n /**\n * Controlled masked value. When provided, the hook operates in\n * controlled mode.\n */\n value?: string;\n /**\n * Initial masked value for uncontrolled mode. Ignored when `value` is\n * provided.\n */\n defaultValue?: string;\n /**\n * Fires whenever the value changes (typing, paste, programmatic).\n */\n onValueChange?: (event: UseMaskValueChangeEvent) => void;\n /**\n * Fires when the value transitions to complete (all required slots\n * filled). Re-fires if the value becomes incomplete and is completed\n * again.\n */\n onComplete?: (event: UseMaskValueChangeEvent) => void;\n /**\n * Placeholder character for empty slots. Pass `null` to skip filling\n * empty slots visually.\n * @default '_'\n */\n slotChar?: string | null;\n /**\n * Whether to render the mask skeleton on focus.\n * @default false\n */\n showMaskOnFocus?: boolean;\n /**\n * Always render the mask skeleton, regardless of focus state.\n * @default false\n */\n alwaysShowMask?: boolean;\n /**\n * Clear an incomplete value on blur.\n * @default true\n */\n autoClear?: boolean;\n /**\n * Transform every character before token validation (e.g. uppercase).\n */\n transform?: (char: string) => string;\n /**\n * Read-only mode. Typing is blocked; programmatic `setValue` still\n * works.\n * @default false\n */\n readOnly?: boolean;\n}\n\n/**\n * Return type of the `useMask` hook.\n */\nexport interface UseMaskReturn {\n /**\n * Ref callback for the target `<input>` (or `<textarea>`). Attaches\n * native event listeners on mount and tears them down on unmount or\n * when the ref switches to a new element.\n */\n ref: (element: HTMLInputElement | null) => void;\n /**\n * Current masked value (always reflects what is in the input).\n */\n value: string;\n /**\n * Current unmasked (raw) value.\n */\n rawValue: string;\n /**\n * Whether all required slots are filled.\n */\n isComplete: boolean;\n /**\n * Programmatically set the masked value. The value is normalized\n * through the mask before being applied.\n */\n setValue: (next: string) => void;\n /**\n * Reset the input to an empty mask skeleton.\n */\n reset: () => void;\n}\n\nconst DEFAULT_TOKENS: Record<string, RegExp> = {\n '9': /[0-9]/,\n a: /[A-Za-z]/,\n A: /[A-Z]/,\n '*': /[A-Za-z0-9]/\n};\n\n/**\n * React hook for masked text input. Attach the returned `ref` to any\n * component that forwards a ref to a real `<input>` (e.g. `InputText`,\n * `Textarea`, `DatePicker.Input`). The hook installs DOM event listeners\n * directly on the element, so no other props need to be wired.\n *\n * @example\n * const { ref, value, rawValue, isComplete } = useMask({ mask: '99/99/9999' });\n * return <InputText ref={ref} placeholder=\"DD/MM/YYYY\" />;\n */\nexport function useMask(options: UseMaskOptions): UseMaskReturn {\n const { mask, tokens: userTokens, value: controlledValue, defaultValue, onValueChange, onComplete, slotChar = '_', showMaskOnFocus = false, alwaysShowMask = false, autoClear = true, transform, readOnly = false } = options;\n\n // Latest callback refs so handlers always see the freshest values\n // without forcing the listener registration to re-run on every render.\n const onValueChangeRef = React.useRef(onValueChange);\n\n onValueChangeRef.current = onValueChange;\n const onCompleteRef = React.useRef(onComplete);\n\n onCompleteRef.current = onComplete;\n const transformRef = React.useRef(transform);\n\n transformRef.current = transform;\n\n // Controlled / uncontrolled hybrid state. The hook owns an internal\n // string that mirrors the masked DOM value. When the consumer passes\n // `value` we operate in controlled mode and ignore internal state for\n // the public `value` field. Internal state still drives derived\n // outputs (`rawValue`, `isComplete`) when uncontrolled.\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = React.useState<string>(defaultValue ?? '');\n const value = isControlled ? (controlledValue ?? '') : internalValue;\n const setStateValue = React.useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next);\n },\n [isControlled]\n );\n\n // ---------------------------------------------------------------------\n // Mask engine state — preserved from the previous implementation. These\n // refs hold the parsed mask metadata and the live character buffer.\n // ---------------------------------------------------------------------\n const targetRef = React.useRef<HTMLInputElement | null>(null);\n const len = React.useRef(0);\n const tests = React.useRef<Array<RegExp | null>>([]);\n const buffer = React.useRef<string[]>([]);\n const defaultBuffer = React.useRef<string>('');\n const partialPosition = React.useRef<number>(0);\n const androidChrome = React.useRef(false);\n const focus = React.useRef(false);\n const focusText = React.useRef<string | null>(null);\n const firstNonMaskPos = React.useRef<number | null>(null);\n const lastRequiredNonMaskPos = React.useRef<number>(0);\n const caretTimeoutId = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const oldVal = React.useRef<string | null>(null);\n const currentVal = React.useRef<string | null>(null);\n const wasComplete = React.useRef(false);\n const lastEmittedValue = React.useRef<string | null>(null);\n\n // Cached options so handlers don't capture stale closures when options\n // change between renders.\n const optsRef = React.useRef({ slotChar, showMaskOnFocus, alwaysShowMask, autoClear, readOnly, mask, userTokens });\n\n optsRef.current = { slotChar, showMaskOnFocus, alwaysShowMask, autoClear, readOnly, mask, userTokens };\n\n // ---------------------------------------------------------------------\n // Helpers (all read `targetRef.current` lazily so a ref swap is safe).\n // ---------------------------------------------------------------------\n\n const getPlaceholder = React.useCallback((i: number) => {\n const sc = optsRef.current.slotChar;\n\n if (sc == null) return '';\n\n if (i < sc.length) return sc.charAt(i);\n\n return sc.charAt(0);\n }, []);\n\n const caret = React.useCallback((first?: number, last?: number): { begin: number; end: number } | undefined => {\n const target = targetRef.current;\n let begin = 0;\n let end = 0;\n\n if (!target) return { begin, end };\n\n if (typeof first === 'number') {\n begin = first;\n end = typeof last === 'number' ? last : begin;\n target.setSelectionRange(begin, end);\n } else {\n begin = target.selectionStart ?? 0;\n end = target.selectionEnd ?? 0;\n }\n\n return { begin, end };\n }, []);\n\n const seekNext = React.useCallback((pos: number) => {\n while (++pos < len.current && !tests.current[pos]);\n\n return pos;\n }, []);\n\n const seekPrev = React.useCallback((pos: number) => {\n while (--pos >= 0 && !tests.current[pos]);\n\n return pos;\n }, []);\n\n // Track whether we're currently writing to the DOM ourselves, so the\n // resulting `input` event doesn't re-enter our own handler chain.\n const internalWrite = React.useRef(false);\n\n // DOM value setter using React's native value setter so React's\n // `_valueTracker` stays in sync. Note: this only mutates the DOM —\n // it intentionally does NOT dispatch an `input` event. We dispatch\n // exactly once per user-visible change (see `notifyReact` below)\n // to avoid firing React `onChange` mid-operation and to keep\n // downstream consumers (e.g. DatePicker.Input parsing the value)\n // from seeing intermediate buffer states.\n const setNativeValue = React.useCallback((target: HTMLInputElement, next: string) => {\n const proto = window.HTMLInputElement.prototype;\n const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;\n\n if (setter) setter.call(target, next);\n else target.value = next;\n }, []);\n\n // Notify React (and any other React-side onChange listeners) that\n // the input value has changed. Wraps the dispatch in `internalWrite`\n // so our own native `input` listener doesn't re-process the event.\n const notifyReact = React.useCallback((target: HTMLInputElement) => {\n internalWrite.current = true;\n try {\n target.dispatchEvent(new Event('input', { bubbles: true }));\n } finally {\n internalWrite.current = false;\n }\n }, []);\n\n const writeBuffer = React.useCallback(() => {\n const target = targetRef.current;\n\n if (!target) return;\n setNativeValue(target, buffer.current.join(''));\n }, [setNativeValue]);\n\n const clearBuffer = React.useCallback(\n (start: number, end: number) => {\n for (let i = start; i < end && i < len.current; i++) {\n if (tests.current[i]) buffer.current[i] = getPlaceholder(i);\n }\n },\n [getPlaceholder]\n );\n\n const shiftL = React.useCallback(\n (begin: number, end: number) => {\n if (begin < 0) return;\n\n let j = seekNext(end);\n\n for (let i = begin; i < len.current; i++) {\n if (tests.current[i]) {\n if (j < len.current && tests.current[i]?.test(buffer.current[j])) {\n buffer.current[i] = buffer.current[j];\n buffer.current[j] = getPlaceholder(j);\n } else {\n break;\n }\n\n j = seekNext(j);\n }\n }\n\n writeBuffer();\n caret(Math.max(firstNonMaskPos.current ?? 0, begin));\n },\n [seekNext, getPlaceholder, writeBuffer, caret]\n );\n\n const shiftR = React.useCallback(\n (pos: number) => {\n let c = getPlaceholder(pos);\n\n for (let i = pos; i < len.current; i++) {\n if (tests.current[i]) {\n const j = seekNext(i);\n const t = buffer.current[i];\n\n buffer.current[i] = c;\n\n if (j < len.current && tests.current[j]?.test(t)) {\n c = t;\n } else {\n break;\n }\n }\n }\n },\n [getPlaceholder, seekNext]\n );\n\n const checkVal = React.useCallback(\n (allow = false): number => {\n const target = targetRef.current;\n\n if (!target) return firstNonMaskPos.current ?? 0;\n\n const test = target.value;\n let lastMatch = -1;\n let i: number;\n let c: string;\n let pos: number;\n\n for (i = 0, pos = 0; i < len.current; i++) {\n const currentTest = tests.current[i];\n\n if (currentTest !== null) {\n buffer.current[i] = getPlaceholder(i);\n\n while (pos++ < (test?.length ?? 0)) {\n c = test?.charAt(pos - 1) ?? '';\n\n if (currentTest.test(c)) {\n buffer.current[i] = c;\n lastMatch = i;\n break;\n }\n }\n\n if (pos > (test?.length ?? 0)) {\n clearBuffer(i + 1, len.current);\n break;\n }\n } else {\n if (buffer.current[i] === test?.charAt(pos)) pos++;\n\n if (i < partialPosition.current) lastMatch = i;\n }\n }\n\n if (allow) {\n writeBuffer();\n } else if (lastMatch + 1 < partialPosition.current) {\n if (optsRef.current.autoClear || buffer.current.join('') === defaultBuffer.current) {\n if (target.value) setNativeValue(target, '');\n clearBuffer(0, len.current);\n } else {\n writeBuffer();\n }\n } else {\n writeBuffer();\n setNativeValue(target, target.value.substring(0, lastMatch + 1));\n }\n\n return partialPosition.current ? i! : (firstNonMaskPos.current ?? 0);\n },\n [getPlaceholder, clearBuffer, writeBuffer, setNativeValue]\n );\n\n const unmaskValue = React.useCallback(\n (masked: string) => {\n const out: string[] = [];\n const chars = masked.split('');\n\n for (let i = 0; i < chars.length; i++) {\n const c = chars[i];\n\n if (tests.current[i] && c !== getPlaceholder(i)) {\n out.push(c);\n }\n }\n\n return out.join('');\n },\n [getPlaceholder]\n );\n\n const computeIsComplete = React.useCallback((maskedValue: string) => {\n // Complete when the buffer up to lastRequiredNonMaskPos has no\n // placeholders in its required slots.\n const chars = maskedValue.split('');\n\n for (let i = 0; i <= lastRequiredNonMaskPos.current && i < len.current; i++) {\n if (tests.current[i]) {\n const c = chars[i];\n\n if (!c || !tests.current[i]?.test(c)) return false;\n }\n }\n\n return true;\n }, []);\n\n // Single source of truth for emitting changes. Reads the current DOM\n // value, notifies React (so onChange handlers fire), derives\n // rawValue/isComplete, syncs internal state, and fires user callbacks.\n const emitChange = React.useCallback(\n (originalEvent: Event | null) => {\n const target = targetRef.current;\n\n if (!target) return;\n\n const masked = target.value;\n const isDefault = masked === defaultBuffer.current;\n const reported = isDefault ? '' : masked;\n\n if (lastEmittedValue.current === reported) return;\n lastEmittedValue.current = reported;\n\n // Notify React-side `onChange` handlers (e.g. DatePicker.Input's\n // parser) that the DOM value has changed. The flag `internalWrite`\n // prevents our own listener from re-processing this dispatch.\n // We only dispatch when the originating event was NOT a native\n // `input` event — for those, React already gets the change via\n // the original event.\n if (originalEvent?.type !== 'input') {\n notifyReact(target);\n }\n\n const rawValue = isDefault ? '' : unmaskValue(masked);\n const complete = !isDefault && computeIsComplete(masked);\n const eventPayload: UseMaskValueChangeEvent = {\n originalEvent,\n value: reported,\n rawValue,\n isComplete: complete\n };\n\n // Mirror DOM into hook's internal state (no-op in controlled mode).\n setStateValue(reported);\n\n onValueChangeRef.current?.(eventPayload);\n\n if (complete && !wasComplete.current) {\n onCompleteRef.current?.(eventPayload);\n }\n\n wasComplete.current = complete;\n currentVal.current = masked;\n },\n [unmaskValue, computeIsComplete, setStateValue, notifyReact]\n );\n\n // ---------------------------------------------------------------------\n // Event handlers — invoked from native DOM listeners installed in the\n // ref callback below.\n // ---------------------------------------------------------------------\n\n const handleInputChange = React.useCallback(\n (event: Event) => {\n if (optsRef.current.readOnly) return;\n if (event.type === 'paste') return;\n\n const pos = checkVal(true);\n\n caret(pos);\n emitChange(event);\n },\n [checkVal, caret, emitChange]\n );\n\n const handleAndroidInput = React.useCallback(\n (event: Event) => {\n const target = targetRef.current;\n\n if (!target) return;\n\n const curVal = target.value;\n const pos = caret();\n\n if (!pos) return;\n\n if (oldVal.current && oldVal.current.length && oldVal.current.length > curVal.length) {\n checkVal(true);\n while (pos.begin > 0 && !tests.current[pos.begin - 1]) pos.begin--;\n\n if (pos.begin === 0) {\n while (pos.begin < (firstNonMaskPos.current ?? 0) && !tests.current[pos.begin]) pos.begin++;\n }\n\n caret(pos.begin, pos.begin);\n } else {\n checkVal(true);\n while (pos.begin < len.current && !tests.current[pos.begin]) pos.begin++;\n caret(pos.begin, pos.begin);\n }\n\n emitChange(event);\n },\n [caret, checkVal, emitChange]\n );\n\n const onInput = React.useCallback(\n (event: Event) => {\n const target = targetRef.current;\n\n if (!target) return;\n // Ignore our own re-dispatched input events — they exist only to\n // notify React listeners (e.g. DatePicker.Input's onChange parse).\n if (internalWrite.current) return;\n\n if ('isComposing' in event && (event as InputEvent).isComposing) return;\n\n if (androidChrome.current) handleAndroidInput(event);\n else handleInputChange(event);\n },\n [handleAndroidInput, handleInputChange]\n );\n\n const onKeyDown = React.useCallback(\n (event: KeyboardEvent) => {\n const target = targetRef.current;\n\n if (!target || optsRef.current.readOnly) return;\n\n const k = event.code;\n let pos: { begin: number; end: number } | undefined;\n let begin: number;\n let end: number;\n const iPhone = /iphone/i.test(getUserAgent());\n\n oldVal.current = target.value;\n\n if (k === 'Backspace' || k === 'Delete' || (iPhone && k === 'Escape')) {\n pos = caret();\n\n if (!pos) return;\n\n begin = pos.begin;\n end = pos.end;\n\n if (end - begin === 0) {\n begin = k !== 'Delete' ? seekPrev(begin) : (end = seekNext(begin - 1));\n end = k === 'Delete' ? seekNext(end) : end;\n }\n\n clearBuffer(begin, end);\n shiftL(begin, end - 1);\n emitChange(event);\n\n event.preventDefault();\n } else if (k === 'Enter') {\n target.blur();\n emitChange(event);\n } else if (k === 'Escape') {\n setNativeValue(target, focusText.current ?? '');\n caret(0, checkVal());\n emitChange(event);\n event.preventDefault();\n }\n },\n [caret, seekPrev, seekNext, clearBuffer, shiftL, emitChange, setNativeValue, checkVal]\n );\n\n const onKeyPress = React.useCallback(\n (event: KeyboardEvent) => {\n const target = targetRef.current;\n\n if (!target || optsRef.current.readOnly) return;\n\n const k = event.code;\n const pos = caret();\n\n if (!pos) return;\n\n if (event.ctrlKey || event.altKey || event.metaKey || event.shiftKey || event.key === 'CapsLock' || event.key === 'Escape' || event.key === 'Tab') {\n return;\n }\n\n if (k && k !== 'Enter') {\n if (pos.end - pos.begin !== 0) {\n clearBuffer(pos.begin, pos.end);\n shiftL(pos.begin, pos.end - 1);\n }\n\n const p = seekNext(pos.begin - 1);\n\n if (p < len.current) {\n let c = event.key;\n\n if (transformRef.current) c = transformRef.current(c);\n\n if (tests.current[p]?.test(c)) {\n shiftR(p);\n buffer.current[p] = c;\n writeBuffer();\n const next = seekNext(p);\n\n if (/android/i.test(getUserAgent())) {\n setTimeout(() => caret(next), 0);\n } else {\n caret(next);\n }\n }\n }\n\n event.preventDefault();\n }\n\n emitChange(event);\n },\n [caret, clearBuffer, shiftL, seekNext, shiftR, writeBuffer, emitChange]\n );\n\n const onFocus = React.useCallback(\n (_event: FocusEvent) => {\n const target = targetRef.current;\n\n if (!target || optsRef.current.readOnly) return;\n if (caretTimeoutId.current) clearTimeout(caretTimeoutId.current);\n focus.current = true;\n focusText.current = target.value;\n\n const shouldShowSkeleton = optsRef.current.showMaskOnFocus || optsRef.current.alwaysShowMask;\n\n if (!target.value || target.value === defaultBuffer.current) {\n if (shouldShowSkeleton) {\n setNativeValue(target, defaultBuffer.current);\n }\n\n requestAnimationFrame(() => {\n if (target === document.activeElement) {\n caret(firstNonMaskPos.current ?? 0, firstNonMaskPos.current ?? 0);\n }\n });\n } else {\n const pos = checkVal();\n\n caretTimeoutId.current = setTimeout(() => {\n if (target !== document.activeElement) return;\n writeBuffer();\n\n if (pos === optsRef.current.mask?.replace('?', '').length) {\n caret(0, pos);\n } else {\n caret(pos);\n }\n }, 10);\n }\n },\n [caret, checkVal, writeBuffer, setNativeValue]\n );\n\n const onBlur = React.useCallback(\n (event: FocusEvent) => {\n const target = targetRef.current;\n\n if (!target) return;\n focus.current = false;\n checkVal();\n\n if (!optsRef.current.alwaysShowMask && target.value === defaultBuffer.current) {\n setNativeValue(target, '');\n }\n\n emitChange(event);\n\n if (target.value !== focusText.current) {\n target.dispatchEvent(new Event('change', { bubbles: true, cancelable: false }));\n }\n },\n [checkVal, emitChange, setNativeValue]\n );\n\n const onPaste = React.useCallback(\n (event: Event) => {\n const target = targetRef.current;\n\n if (!target || optsRef.current.readOnly) return;\n\n // Defer to next tick so the pasted content is already in the input,\n // then run a full revalidation through checkVal(true).\n setTimeout(() => {\n const pos = checkVal(true);\n\n caret(pos);\n emitChange(event);\n }, 0);\n },\n [checkVal, caret, emitChange]\n );\n\n // ---------------------------------------------------------------------\n // Mask initialization: parses the pattern into the tests/buffer refs\n // and writes the initial value into the bound input (if any).\n // ---------------------------------------------------------------------\n const initMask = React.useCallback(() => {\n tests.current = [];\n partialPosition.current = mask ? mask.length : 0;\n len.current = mask ? mask.length : 0;\n firstNonMaskPos.current = null;\n lastRequiredNonMaskPos.current = 0;\n\n const tokenMap: Record<string, RegExp> = { ...DEFAULT_TOKENS, ...userTokens };\n const ua = getUserAgent();\n\n androidChrome.current = /chrome/i.test(ua) && /android/i.test(ua);\n\n const maskTokens = mask ? mask.split('') : [];\n\n for (let i = 0; i < maskTokens.length; i++) {\n const c = maskTokens[i];\n\n if (c === '?') {\n len.current--;\n partialPosition.current = i;\n } else if (tokenMap[c]) {\n tests.current.push(tokenMap[c]);\n\n if (firstNonMaskPos.current === null) {\n firstNonMaskPos.current = tests.current.length - 1;\n }\n\n if (i < partialPosition.current) {\n lastRequiredNonMaskPos.current = tests.current.length - 1;\n }\n } else {\n tests.current.push(null);\n }\n }\n\n buffer.current = [];\n\n for (let i = 0; i < maskTokens.length; i++) {\n const c = maskTokens[i];\n\n if (c !== '?') {\n if (tokenMap[c]) buffer.current.push(getPlaceholder(i));\n else buffer.current.push(c);\n }\n }\n\n defaultBuffer.current = buffer.current.join('');\n\n const target = targetRef.current;\n\n if (target) {\n // Seed initial skeleton only when alwaysShowMask is on AND\n // the input has no value yet. Initial controlled/defaultValue\n // sync is handled by the dedicated effect below — keeping\n // `initMask` independent of `value` prevents it from\n // re-running on every keystroke (which would re-write the\n // DOM and fight user typing).\n if (!target.value && optsRef.current.alwaysShowMask) {\n setNativeValue(target, defaultBuffer.current);\n }\n }\n }, [mask, userTokens, getPlaceholder, setNativeValue]);\n\n // Re-init when mask or tokens change.\n React.useEffect(() => {\n initMask();\n }, [initMask]);\n\n // ---------------------------------------------------------------------\n // Sync controlled value -> input. When the consumer changes `value`\n // externally we must reflect it in the DOM.\n // ---------------------------------------------------------------------\n React.useEffect(() => {\n const target = targetRef.current;\n\n if (!target) return;\n if (controlledValue === undefined) return;\n if (controlledValue === currentVal.current) return;\n if (focus.current) return; // Don't fight the user while typing.\n\n setNativeValue(target, controlledValue);\n checkVal();\n currentVal.current = target.value;\n }, [controlledValue, setNativeValue, checkVal]);\n\n // ---------------------------------------------------------------------\n // Ref callback: install / tear down native listeners on the target.\n //\n // The callback has a STABLE identity (`useCallback` with no deps) so\n // React doesn't tear down and re-attach listeners on every render.\n // Listeners themselves are stable refs to the latest handlers via\n // the `*Handler` indirections below.\n // ---------------------------------------------------------------------\n const onInputRef = React.useRef(onInput);\n\n onInputRef.current = onInput;\n const onKeyDownRef = React.useRef(onKeyDown);\n\n onKeyDownRef.current = onKeyDown;\n const onKeyPressRef = React.useRef(onKeyPress);\n\n onKeyPressRef.current = onKeyPress;\n const onFocusRef = React.useRef(onFocus);\n\n onFocusRef.current = onFocus;\n const onBlurRef = React.useRef(onBlur);\n\n onBlurRef.current = onBlur;\n const onPasteRef = React.useRef(onPaste);\n\n onPasteRef.current = onPaste;\n\n // Stable trampoline handlers that delegate to the latest refs.\n const stableHandlers = React.useMemo(\n () => ({\n input: (e: Event) => onInputRef.current(e),\n keydown: (e: KeyboardEvent) => onKeyDownRef.current(e),\n keypress: (e: KeyboardEvent) => onKeyPressRef.current(e),\n focus: (e: FocusEvent) => onFocusRef.current(e),\n blur: (e: FocusEvent) => onBlurRef.current(e),\n paste: (e: Event) => onPasteRef.current(e)\n }),\n []\n );\n\n const refCallback = React.useCallback(\n (element: HTMLInputElement | null) => {\n const previous = targetRef.current;\n\n if (previous && previous !== element) {\n previous.removeEventListener('input', stableHandlers.input);\n previous.removeEventListener('keydown', stableHandlers.keydown);\n previous.removeEventListener('keypress', stableHandlers.keypress);\n previous.removeEventListener('focus', stableHandlers.focus);\n previous.removeEventListener('blur', stableHandlers.blur);\n previous.removeEventListener('paste', stableHandlers.paste);\n }\n\n targetRef.current = element;\n\n if (element && element !== previous) {\n element.addEventListener('input', stableHandlers.input);\n element.addEventListener('keydown', stableHandlers.keydown);\n element.addEventListener('keypress', stableHandlers.keypress);\n element.addEventListener('focus', stableHandlers.focus);\n element.addEventListener('blur', stableHandlers.blur);\n element.addEventListener('paste', stableHandlers.paste);\n\n // Seed the freshly-bound element. Use `controlledValue`\n // (not `value`) so the seed only happens for an externally\n // supplied controlled value; uncontrolled internal state\n // changes are handled by the user's typing and shouldn't\n // re-seed mid-stream.\n if (controlledValue) {\n setNativeValue(element, controlledValue);\n checkVal();\n } else if (defaultValue && !element.value) {\n setNativeValue(element, defaultValue);\n checkVal();\n } else if (optsRef.current.alwaysShowMask && !element.value) {\n setNativeValue(element, defaultBuffer.current);\n }\n }\n },\n // Intentionally NO `value`/`controlledValue` deps — see comment\n // above. The setter closures below read fresh values from refs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [stableHandlers]\n );\n\n // ---------------------------------------------------------------------\n // Derived public outputs.\n // ---------------------------------------------------------------------\n const rawValue = React.useMemo(() => (value ? unmaskValue(value) : ''), [value, unmaskValue]);\n const isComplete = React.useMemo(() => (value ? computeIsComplete(value) : false), [value, computeIsComplete]);\n\n const setValue = React.useCallback(\n (next: string) => {\n const target = targetRef.current;\n\n if (!target) return;\n setNativeValue(target, next ?? '');\n checkVal(true);\n emitChange(null);\n },\n [setNativeValue, checkVal, emitChange]\n );\n\n const reset = React.useCallback(() => {\n const target = targetRef.current;\n\n if (!target) return;\n setNativeValue(target, '');\n clearBuffer(0, len.current);\n\n if (optsRef.current.alwaysShowMask) {\n setNativeValue(target, defaultBuffer.current);\n }\n\n currentVal.current = target.value;\n wasComplete.current = false;\n emitChange(null);\n }, [setNativeValue, clearBuffer, emitChange]);\n\n return {\n ref: refCallback,\n value,\n rawValue,\n isComplete,\n setValue,\n reset\n };\n}\n"],"mappings":"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","names":["getUserAgent","React","DEFAULT_TOKENS","useMask","options","mask","userTokens","controlledValue","defaultValue","onValueChange","onComplete","slotChar","showMaskOnFocus","alwaysShowMask","autoClear","transform","readOnly","onValueChangeRef","onCompleteRef","transformRef","isControlled","internalValue","setInternalValue","value","setStateValue","next","targetRef","len","tests","buffer","defaultBuffer","partialPosition","androidChrome","focus","focusText","firstNonMaskPos","lastRequiredNonMaskPos","caretTimeoutId","oldVal","currentVal","wasComplete","lastEmittedValue","optsRef","getPlaceholder","i","sc","caret","first","last","_a","_b","target","begin","end","seekNext","pos","seekPrev","internalWrite","setNativeValue","proto","setter","notifyReact","writeBuffer","clearBuffer","start","shiftL","j","shiftR","c","t","checkVal","allow","_c","_d","_e","test","lastMatch","currentTest","unmaskValue","masked","out","chars","computeIsComplete","maskedValue","emitChange","originalEvent","isDefault","reported","rawValue","complete","eventPayload","handleInputChange","event","handleAndroidInput","curVal","onInput","onKeyDown","k","iPhone","getUserAgent","onKeyPress","p","onFocus","_event","shouldShowSkeleton","onBlur","onPaste","initMask","tokenMap","__spreadValues","ua","maskTokens","onInputRef","onKeyDownRef","onKeyPressRef","onFocusRef","onBlurRef","onPasteRef","stableHandlers","refCallback","element","previous","isComplete","setValue","reset"]}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Options for the useMounted hook.
3
+ */
4
+ export interface UseMountedOptions {
5
+ /**
6
+ * Callback invoked when the component transitions to mounted state.
7
+ */
8
+ onMounted?: () => void;
9
+ /**
10
+ * Callback invoked when the component transitions to unmounted state
11
+ * or when the component is destroyed while mounted.
12
+ */
13
+ onUnmounted?: () => void;
14
+ }
15
+ /**
16
+ * Custom hook that tracks whether a component is mounted on the client.
17
+ * Provides SSR-safe mounting detection with optional lifecycle callbacks.
18
+ *
19
+ * @param {UseMountedOptions} options configuration options
20
+ * @returns {boolean} whether the component is currently mounted
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const MyComponent = () => {
25
+ * const mounted = useMounted({
26
+ * onMounted: () => console.log('Mounted'),
27
+ * onUnmounted: () => console.log('Unmounted')
28
+ * });
29
+ *
30
+ * if (!mounted) return null;
31
+ *
32
+ * return <div>Content</div>;
33
+ * };
34
+ * ```
35
+ */
36
+ export declare function useMounted(options?: UseMountedOptions): boolean;
@@ -0,0 +1,2 @@
1
+ import*as t from"react";function a(e={}){let[d,r]=t.useState(!1);return t.useEffect(()=>{var u;return r(!0),(u=e.onMounted)==null||u.call(e),()=>{var n;(n=e.onUnmounted)==null||n.call(e)}},[]),d}export{a as useMounted};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/use-mounted/index.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * Options for the useMounted hook.\n */\nexport interface UseMountedOptions {\n /**\n * Callback invoked when the component transitions to mounted state.\n */\n onMounted?: () => void;\n /**\n * Callback invoked when the component transitions to unmounted state\n * or when the component is destroyed while mounted.\n */\n onUnmounted?: () => void;\n}\n\n/**\n * Custom hook that tracks whether a component is mounted on the client.\n * Provides SSR-safe mounting detection with optional lifecycle callbacks.\n *\n * @param {UseMountedOptions} options configuration options\n * @returns {boolean} whether the component is currently mounted\n *\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const mounted = useMounted({\n * onMounted: () => console.log('Mounted'),\n * onUnmounted: () => console.log('Unmounted')\n * });\n *\n * if (!mounted) return null;\n *\n * return <div>Content</div>;\n * };\n * ```\n */\nexport function useMounted(options: UseMountedOptions = {}): boolean {\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n\n options.onMounted?.();\n\n return () => {\n options.onUnmounted?.();\n };\n }, []);\n\n return mounted;\n}\n"],"mappings":"AAAA,UAAYA,MAAW,QAsChB,SAASC,EAAWC,EAA6B,CAAC,EAAY,CACjE,GAAM,CAACC,EAASC,CAAU,EAAU,WAAS,EAAK,EAElD,OAAM,YAAU,IAAM,CAzC1B,IAAAC,EA0CQ,OAAAD,EAAW,EAAI,GAEfC,EAAAH,EAAQ,YAAR,MAAAG,EAAA,KAAAH,GAEO,IAAM,CA9CrB,IAAAG,GA+CYA,EAAAH,EAAQ,cAAR,MAAAG,EAAA,KAAAH,EACJ,CACJ,EAAG,CAAC,CAAC,EAEEC,CACX","names":["React","useMounted","options","mounted","setMounted","_a"]}