raqam 0.4.0 → 0.4.2
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.
- package/README.md +9 -7
- package/dist/chunk-NIPT3LT6.js +2 -0
- package/dist/chunk-NIPT3LT6.js.map +1 -0
- package/dist/chunk-PM3EDICU.cjs +2 -0
- package/dist/chunk-PM3EDICU.cjs.map +1 -0
- package/dist/chunk-XCKMM244.cjs +2 -0
- package/dist/chunk-XCKMM244.cjs.map +1 -0
- package/dist/chunk-YKK5OGE4.js +2 -0
- package/dist/chunk-YKK5OGE4.js.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +49 -49
- package/dist/core.d.ts +49 -49
- package/dist/core.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -1
- package/dist/locales/index.d.cts +1 -1
- package/dist/locales/index.d.ts +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +62 -63
- package/dist/react.d.ts +62 -63
- package/dist/react.js +1 -1
- package/package.json +31 -31
- package/dist/chunk-G7ACJUKH.js +0 -2
- package/dist/chunk-G7ACJUKH.js.map +0 -1
- package/dist/chunk-GAKIDRGS.cjs +0 -2
- package/dist/chunk-GAKIDRGS.cjs.map +0 -1
- package/dist/chunk-P6AWGQPY.js +0 -2
- package/dist/chunk-P6AWGQPY.js.map +0 -1
- package/dist/chunk-YUKLLK4G.cjs +0 -2
- package/dist/chunk-YUKLLK4G.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Raqam 🔢
|
|
2
|
+
|
|
3
|
+
<img src="https://raw.githubusercontent.com/47vigen/raqam/main/assets/raqam-poster.jpg" alt="raqam — the definitive React number input" width="100%" />
|
|
2
4
|
|
|
3
5
|
**The definitive React number input: live formatting, full i18n, headless, accessible.**
|
|
4
6
|
|
|
@@ -16,7 +18,7 @@
|
|
|
16
18
|
| Truly headless | ✅ | ✅ | ❌ | ✅ |
|
|
17
19
|
| i18n digit input (Persian ۱۲۳, Arabic ١٢٣…) | ❌ | ✅ | ❌ | ✅ |
|
|
18
20
|
| WAI-ARIA spinbutton | ✅ | ✅✅ | ⚠️ | ✅✅ |
|
|
19
|
-
| Bundle size | ~10 KB | ~30 KB | ~60 KB | **~2.
|
|
21
|
+
| Bundle size | ~10 KB | ~30 KB | ~60 KB | **~2.2 KB core** |
|
|
20
22
|
|
|
21
23
|
No existing package combines all four. raqam does.
|
|
22
24
|
|
|
@@ -303,7 +305,7 @@ State management hook — returns `NumberFieldState`.
|
|
|
303
305
|
| `required` | `boolean` | `false` | Mark the field as required |
|
|
304
306
|
|
|
305
307
|
Also accepts `maximumFractionDigits`, `minimumFractionDigits`, `formatValue`,
|
|
306
|
-
and `parseValue` — see the [full options reference](https://raqam.
|
|
308
|
+
and `parseValue` — see the [full options reference](https://raqam.47vigen.com/docs/api/use-number-field-state).
|
|
307
309
|
|
|
308
310
|
### `useNumberField(props, state, inputRef)`
|
|
309
311
|
|
|
@@ -318,7 +320,7 @@ every `useNumberFieldState` option plus the behavior-only props below:
|
|
|
318
320
|
| `stepHoldInterval` | `number` | `200` | Press-and-hold repeat interval (ms) |
|
|
319
321
|
| `label` / `name` / `id` / `aria-*` | `string` | — | Labelling, form name, and id wiring |
|
|
320
322
|
|
|
321
|
-
→ Full reference: [`useNumberField`](https://raqam.
|
|
323
|
+
→ Full reference: [`useNumberField`](https://raqam.47vigen.com/docs/api/use-number-field).
|
|
322
324
|
|
|
323
325
|
### `NumberField.Root` extra props
|
|
324
326
|
|
|
@@ -368,9 +370,9 @@ Measured min + brotli (including dependencies), enforced in CI via
|
|
|
368
370
|
|
|
369
371
|
| Entry | Size | CI budget |
|
|
370
372
|
|-------|------|-----------|
|
|
371
|
-
| `raqam/core` | ~2.
|
|
372
|
-
| `raqam` (hooks + components) | ~9.
|
|
373
|
-
| `raqam/react` | ~9.
|
|
373
|
+
| `raqam/core` | ~2.23 KB | 2.5 KB |
|
|
374
|
+
| `raqam` (hooks + components) | ~9.62 KB | 12 KB |
|
|
375
|
+
| `raqam/react` | ~9.42 KB | 10 KB |
|
|
374
376
|
| `raqam/locales/fa` | 196 B | 0.3 KB |
|
|
375
377
|
|
|
376
378
|
## 📄 License
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {c,d,e,b as b$1}from'./chunk-YKK5OGE4.js';import {b,c as c$1}from'./chunk-4GNLVHAM.js';import at,{createContext,forwardRef,useRef,useMemo,useCallback,useState,useId,useEffect,useContext,useLayoutEffect}from'react';import {jsx}from'react/jsx-runtime';var nt=createContext(null);function X(){let t=useContext(nt);if(!t)throw typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production"?new Error("[raqam] NumberField sub-components must be used inside <NumberField.Root>."):new Error("[raqam] <NumberField.Root> missing");return t}function rt(t,e={}){let{delay:r=400,interval:n=200,disabled:i=false}=e,o=useRef(t);useEffect(()=>{o.current=t;});let l=useRef(r);useEffect(()=>{l.current=r;});let a=useRef(n);useEffect(()=>{a.current=n;});let v=useRef(i);useEffect(()=>{v.current=i;});let g=useRef(null),I=useRef(null),L=useRef(false),R=useCallback(()=>{L.current=false,g.current!==null&&(clearTimeout(g.current),g.current=null),I.current!==null&&(clearTimeout(I.current),I.current=null);},[]),F=useCallback(C=>{if(!L.current||v.current){R();return}o.current();let B=Math.max(50,Math.floor(C/2));I.current=setTimeout(()=>{F(B);},C);},[R]),x=useCallback(C=>{i||C.button!==0&&C.pointerType==="mouse"||(o.current(),L.current=true,g.current=setTimeout(()=>{F(a.current);},l.current));},[i,F]),D=useCallback(C=>{C.preventDefault(),R();},[R]),M=useCallback(C=>{R();},[R]),re=useCallback(C=>{R();},[R]),q=useCallback(C=>{R();},[R]);return useEffect(()=>{i&&R();},[i,R]),useEffect(()=>R,[R]),{onPointerDown:x,onPointerUp:D,onPointerLeave:M,onPointerCancel:re,onLostPointerCapture:q}}var lt=typeof window<"u"?useLayoutEffect:useEffect;function st(t){return t.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&")}function ct(){let t=useRef(0),[e,r]=useState(false),n=useCallback(i=>{i?(t.current+=1,r(true)):t.current>0&&(t.current-=1,t.current===0&&r(false));},[]);return [e,n]}function dt(t){let e=t?.getRootNode();return e&&"activeElement"in e?e.activeElement:typeof document<"u"?document.activeElement:null}var At={k:1e3,thousand:1e3,m:1e6,million:1e6,b:1e9,billion:1e9,t:1e12,trillion:1e12};function Ot(t){if(t.length>256)return null;let e=t.replace(/\s+/g,"");if(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)[eE][+-]?\d+$/.test(e)){let n=Number(e);return Number.isFinite(n)?n:null}let r=e.match(/^([+-]?(?:\d+(?:\.\d*)?|\.\d+))(k|m|b|t|thousand|million|billion|trillion)$/i);if(r){let n=Number(r[1])*At[r[2].toLowerCase()];return Number.isFinite(n)?n:null}return null}function mt(t,e$1,r){let{locale:n,formatOptions:i,minValue:o,maxValue:l,allowNegative:a=true,allowDecimal:v=true,allowMouseWheel:g=false,liveFormat:I=true,prefix:L,suffix:R,name:F,disabled:x,readOnly:D,required:M,onFocus:re,onBlur:q,maximumFractionDigits:C,minimumFractionDigits:B,fixedDecimalScale:H,copyBehavior:u="formatted",stepHoldDelay:W=400,stepHoldInterval:j=200,incrementLabel:se="Increase",decrementLabel:ie="Decrease",formatValue:E,parseValue:_,onValueCommitted:O}=t,G=Number.isFinite(o)?o:void 0,J=Number.isFinite(l)?l:void 0,K=i?.notation,ce=I&&K!=="compact"&&K!=="scientific"&&K!=="engineering",ve=JSON.stringify(i),{step:ae=1,largeStep:U=ae*10,smallStep:Me=ae*.1}=e$1.options,ge=useId(),Re=t.id??`raqam-${ge}`,Se=`${Re}-label`,Te=`${Re}-description`,Ce=`${Re}-error`,{effMinFrac:we,effMaxFrac:Le,effFixedScale:Ae}=c({allowDecimal:v,minimumFractionDigits:B,maximumFractionDigits:C,fixedDecimalScale:H}),N=useMemo(()=>d({locale:n,formatOptions:i,prefix:L,suffix:R,minimumFractionDigits:we,maximumFractionDigits:Le,fixedDecimalScale:Ae}),[n,ve,L,R,we,Le,Ae]),qe=i?.style==="percent",Oe=v?qe?20:Le:0,Q=useMemo(()=>d({locale:n,formatOptions:i,prefix:L,suffix:R,minimumFractionDigits:0,maximumFractionDigits:Oe,fixedDecimalScale:false}),[n,ve,L,R,Oe]),$=useMemo(()=>e({locale:n,formatOptions:i,allowNegative:a,allowDecimal:v,prefix:L,suffix:R}),[n,ve,a,v,L,R]),de=useCallback((s,f)=>{let y=N.getLocaleInfo(),d$1=f.lastIndexOf(y.decimalSeparator);if(d$1===-1&&y.decimalSeparator!=="."&&y.groupingSeparator!=="."&&(d$1=f.lastIndexOf(".")),d$1===-1||!/\d/.test(b(f.slice(0,d$1))))return null;let S=b(f.slice(d$1+1)).match(/^\d+/);if(!S)return null;let m=Math.min(S[0].length,Le??20,20);return m===0?null:d({locale:n,formatOptions:i,prefix:L,suffix:R,minimumFractionDigits:m,maximumFractionDigits:m}).format(s)},[N,n,ve,L,R,Le]),w=useRef(null),ke=useRef(e$1);ke.current=e$1,lt(()=>{w.current!==null&&r.current&&dt(r.current)===r.current&&(r.current.setSelectionRange(w.current,w.current),w.current=null);},[e$1.inputValue,r]),useEffect(()=>{let s=r.current;if(!s||!g)return;let f=y=>{if(x||D||dt(s)!==s)return;y.preventDefault();let d=ke.current;d._setLastChangeReason("wheel"),y.deltaY<0?d.increment():d.decrement();};return s.addEventListener("wheel",f,{passive:false}),()=>s.removeEventListener("wheel",f)},[g,x,D,r]);let Z=useRef(false),_e=useCallback(()=>{Z.current=true;},[]),Ve=useCallback(s=>{Z.current=false;let f=s.currentTarget.value,y=N.getLocaleInfo(),d=b(f),S,m;if(_){let p=_(d);m=p.value,p.isIntermediate?S=d:p.value!==null&&E?S=E(p.value):p.value!==null?S=N.format(p.value):S=d,w.current=S.length;}else if(ce){let p=$.parse(d);p.isIntermediate?S=c$1(d,y.zero):p.value!==null?S=E?E(p.value):Q.format(p.value):S=d===""?"":d,w.current=b$1(f,f.length,S,y,"insertCompositionText");}else S=d,w.current=d.length;e$1._setLastChangeReason("input"),e$1.setInputValue(S,m);},[N,Q,$,ce,e$1,E,_]),Be=useCallback(s=>{let f=s.target.value,y=s.target.selectionStart??f.length,d=s.nativeEvent.inputType,S=N.getLocaleInfo();if(Z.current){e$1.setInputValue(f);return}let m=b(f);a||(m=m.split("-").join("").split(S.minusSign).join("")),v?S.decimalSeparator!=="."&&S.groupingSeparator!=="."&&(m=m.replace(/\./g,(A,b,P)=>/\d/.test(P[b-1]??"")||/\d/.test(P[b+1]??"")?S.decimalSeparator:".")):m=m.split(".").join("").split(S.decimalSeparator).join("");let p,fe;if(_){let A=_(m);fe=A.value,A.isIntermediate?p=m:A.value!==null?p=E?E(A.value):N.format(A.value):m===""?p="":p=m,w.current=p.length;}else if(ce){let A=$.parse(m);if(A.isIntermediate)p=(!E&&A.value!==null?de(A.value,m):null)??c$1(m,S.zero);else if(A.value!==null)if(E)p=E(A.value);else {p=Q.format(A.value);let b=$.parse(p).value;fe=b!==null&&Number.isFinite(b)&&Q.format(b)===p?b:A.value;}else m===""||!/\d/.test(m)?p="":p=m;E?w.current=p.length:w.current=b$1(f,y,p,S,d);}else p=m,w.current=y;e$1._setLastChangeReason(p===""?"clear":"input"),e$1.setInputValue(p,fe);},[N,Q,$,ce,e$1,E,_,de]),me=useCallback(s=>{s.preventDefault();let f=s.clipboardData.getData("text/plain");if(!f||f.length>1e3)return;let y=f.replace(/[€$£¥₹₺₽﷼฿₩¢₦₨₪₫₱]/g,"").trim(),d=b(y);if(!a){let P=N.getLocaleInfo();d=d.split("-").join("").split(P.minusSign).join("");}if(!v){let P=N.getLocaleInfo();d=d.split(".").join("").split(P.decimalSeparator).join("");}if(e$1._setLastChangeReason("paste"),_){let P=_(d);if(P.value!==null){let k=E?E(P.value):N.format(P.value);e$1.setInputValue(k,P.value),w.current=k.length;}return}let S=Ot(d);if(S!==null){let k=i?.style==="percent"?S/100:S,he=E?E(k):N.format(k);e$1.setInputValue(he,k),w.current=he.length;return}let m=$.parse(d);if(m.value!==null){let P=N.format(m.value);e$1.setInputValue(P,m.value),w.current=P.length;return}let p=N.getLocaleInfo(),fe=new RegExp(`[^0-9${st(p.decimalSeparator)}${st(p.minusSign)}-]`,"g"),A=d.replace(fe,""),b$1=$.parse(A);if(b$1.value!==null){let P=N.format(b$1.value);e$1.setInputValue(P,b$1.value),w.current=P.length;}},[$,N,e$1,E,_]),We=useCallback(s=>{if(u==="formatted")return;s.preventDefault();let f=String(e$1.numberValue??"");s.clipboardData.setData("text/plain",f);},[u,e$1.numberValue]),ee=useCallback(s=>{if(u==="formatted")return;s.preventDefault();let f=String(e$1.numberValue??"");s.clipboardData.setData("text/plain",f),e$1._setLastChangeReason("clear"),e$1.setInputValue("");},[u,e$1]),Ge=useCallback(s=>{if(x||D)return;let f=s.key;if(!s.metaKey&&!s.ctrlKey&&!s.altKey&&v){let y=N.getLocaleInfo();if(f===y.decimalSeparator||f==="."&&y.decimalSeparator!=="."&&y.groupingSeparator!=="."){let S=r.current;if(S){let m=S.value.indexOf(y.decimalSeparator);if(m!==-1){s.preventDefault(),S.setSelectionRange(m+1,m+1);return}}}}if(f==="Backspace"&&!s.shiftKey&&!s.altKey&&!s.metaKey&&!s.ctrlKey){let y=r.current;if(y){let d=y.selectionStart??0,S=y.selectionEnd??d,m=y.value,p=N.getLocaleInfo();if(d===S&&d>=2&&m[d-1]===p.groupingSeparator){s.preventDefault();let b=m.slice(0,d-2)+m.slice(d),P=$.parse(b);e$1._setLastChangeReason("input");let k;P.value!==null?(k=de(P.value,b)??Q.format(P.value),e$1.setInputValue(k,P.value)):(k=b,b===""&&e$1._setLastChangeReason("clear"),e$1.setInputValue(b)),w.current=b$1(b,d-2,k,p,"deleteContentBackward");return}let fe=b=>b!==void 0&&/\p{Nd}/u.test(b),A=b=>b!==void 0&&!fe(b)&&b!==p.decimalSeparator&&b!==p.minusSign&&b!=="-";if(d===S&&d===m.length&&d>=1&&A(m[d-1])){let b=d;for(;b>0&&A(m[b-1]);)b--;if(b>0&&fe(m[b-1])){s.preventDefault();let P=m.slice(0,b-1)+m.slice(b),k=$.parse(P);e$1._setLastChangeReason("input");let he;k.value!==null&&/\p{Nd}/u.test(P)?(he=de(k.value,P)??Q.format(k.value),e$1.setInputValue(he,k.value)):(he="",e$1._setLastChangeReason("clear"),e$1.setInputValue("")),w.current=b$1(P,b-1,he,p,"deleteContentBackward");return}}}}if(f==="ArrowUp"||f==="ArrowDown"){s.preventDefault();let y=f==="ArrowUp"?1:-1;e$1._setLastChangeReason("keyboard"),s.shiftKey?y>0?e$1.increment(U):e$1.decrement(U):s.metaKey||s.ctrlKey?y>0?e$1.increment(Me):e$1.decrement(Me):y>0?e$1.increment():e$1.decrement();return}if(f==="PageUp"){s.preventDefault(),e$1._setLastChangeReason("keyboard"),e$1.increment(U);return}if(f==="PageDown"){s.preventDefault(),e$1._setLastChangeReason("keyboard"),e$1.decrement(U);return}if(f==="Home"){G!==void 0&&(s.preventDefault(),e$1._setLastChangeReason("keyboard"),e$1.decrementToMin());return}if(f==="End"){J!==void 0&&(s.preventDefault(),e$1._setLastChangeReason("keyboard"),e$1.incrementToMax());return}if(f==="Enter"){e$1._setLastChangeReason("blur");let y=e$1.commit();O?.(y,{reason:"keyboard"});return}},[x,D,e$1,U,Me,G,J,N,Q,$,r,v,de,O]),ue=useCallback(s=>{e$1.setIsFocused(false),e$1._setLastChangeReason("blur");let f=e$1.commit();O?.(f,{reason:"blur"}),q?.(s);},[e$1,q,O]),Xe=useCallback(s=>{e$1.setIsFocused(true),re?.(s);},[e$1,re]),Je=rt(()=>{e$1._setLastChangeReason("increment"),e$1.increment();},{delay:W,interval:j,disabled:x||!e$1.canIncrement}),Qe=rt(()=>{e$1._setLastChangeReason("decrement"),e$1.decrement();},{delay:W,interval:j,disabled:x||!e$1.canDecrement}),Ze=useMemo(()=>{if(e$1.numberValue!=null)return E?E(e$1.numberValue):N.format(e$1.numberValue)},[e$1.numberValue,N,E]),je=N.getLocaleInfo(),De=e$1.numberValue!==null&&(G!==void 0&&e$1.numberValue<G||J!==void 0&&e$1.numberValue>J)||e$1.validationState==="invalid",[et,c$2]=ct(),h=t["aria-labelledby"]??(t["aria-label"]?void 0:et?Se:void 0),[V,T]=ct(),oe=[t["aria-describedby"],V?Te:null].filter(Boolean).join(" ")||void 0,Ee={id:Se,htmlFor:Re,ref:c$2},Pt={role:"group","aria-labelledby":h},Tt={id:Re,type:"text",inputMode:"decimal",role:"spinbutton",autoComplete:"off",autoCorrect:"off",spellCheck:false,"aria-label":t["aria-label"],"aria-labelledby":h,"aria-describedby":oe,"aria-valuenow":e$1.numberValue??void 0,"aria-valuemin":G,"aria-valuemax":J,"aria-valuetext":Ze,"aria-disabled":x||void 0,"aria-readonly":D||void 0,"aria-required":M||void 0,"aria-invalid":De?true:void 0,"aria-errormessage":De&&e$1.validationError?Ce:void 0,disabled:x,readOnly:D,required:M,value:e$1.inputValue,onChange:Be,onKeyDown:Ge,onBlur:ue,onFocus:Xe,onPaste:me,onCopy:u!=="formatted"?We:void 0,onCut:u!=="formatted"?ee:void 0,onCompositionStart:_e,onCompositionEnd:Ve,style:je.isRTL?{direction:"ltr",textAlign:"right",unicodeBidi:"plaintext"}:void 0,"data-disabled":x?"":void 0,"data-readonly":D?"":void 0,"data-required":M?"":void 0,"data-invalid":De?"":void 0,"data-rtl":je.isRTL?"":void 0},Ft=F?{type:"hidden",name:F,value:e$1.numberValue??"","aria-hidden":true}:null,xt={type:"button",tabIndex:-1,"aria-label":se,disabled:x||!e$1.canIncrement,...Je,"data-disabled":x||!e$1.canIncrement?"":void 0},Nt={type:"button",tabIndex:-1,"aria-label":ie,disabled:x||!e$1.canDecrement,...Qe,"data-disabled":x||!e$1.canDecrement?"":void 0};return {labelProps:Ee,groupProps:Pt,inputProps:Tt,hiddenInputProps:Ft,incrementButtonProps:xt,decrementButtonProps:Nt,descriptionProps:{id:Te,ref:T},errorMessageProps:{id:Ce,role:"alert","aria-live":"polite"}}}function ft({value:t,defaultValue:e,onChange:r}){let n=t!==void 0,i=useRef(n);typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production"&&i.current!==n&&console.warn("[raqam] Switching between controlled and uncontrolled. Pick one and keep it.");let[o,l]=useState(e),a=useCallback(v=>{let g=typeof v=="function"?v(n?t:o):v;n||l(g),r?.(g);},[n,t,o,r]);return [n?t:o,a]}function it(t,e,r){let n=t;return e!==void 0&&Number.isFinite(e)&&(n=Math.max(n,e)),r!==void 0&&Number.isFinite(r)&&(n=Math.min(n,r)),n}function pt(t,e){let r=Math.max(bt(t),bt(e));if(r>15)return t+e;let n=10**r,i=t*n,o=e*n;return !Number.isSafeInteger(Math.round(i))||!Number.isSafeInteger(Math.round(o))?t+e:Math.round(i+o)/n}function bt(t){if(!Number.isFinite(t))return 0;let e=String(t),r=e.indexOf("e");if(r!==-1){let i=Number(e.slice(r+1)),o=e.indexOf("."),l=o===-1?0:r-o-1;return Math.max(0,l-i)}let n=e.indexOf(".");return n===-1?0:e.length-n-1}function vt(t){let{locale:e$1,formatOptions:r,minValue:n,maxValue:i,step:o=1,largeStep:l,smallStep:a,allowNegative:v=true,allowDecimal:g=true,maximumFractionDigits:I,minimumFractionDigits:L,fixedDecimalScale:R,clampBehavior:F="blur",prefix:x,suffix:D,allowOutOfRange:M=false,validate:re,onRawChange:q,formatValue:C}=t,B=Number.isFinite(o)&&o>0?o:1,H=Number.isFinite(n)?n:void 0,u=Number.isFinite(i)?i:void 0,{effMinFrac:W,effMaxFrac:j,effFixedScale:se}=c({allowDecimal:g,minimumFractionDigits:L,maximumFractionDigits:I,fixedDecimalScale:R}),ie=JSON.stringify(r??{}),E=useMemo(()=>d({locale:e$1,formatOptions:r,prefix:x,suffix:D,minimumFractionDigits:W,maximumFractionDigits:j,fixedDecimalScale:se}),[e$1,ie,x,D,W,j,se]),_=useMemo(()=>e({locale:e$1,formatOptions:r,allowNegative:v,allowDecimal:g,prefix:x,suffix:D}),[e$1,ie,v,g,x,D]),[O,G]=ft({value:t.value,defaultValue:t.defaultValue??null,onChange:t.onChange}),J=useRef(t.value??t.defaultValue??null),K=useCallback(c=>C?C(Object.is(c,-0)?0:c):E.format(Object.is(c,-0)?0:c),[E,C]),ce=useMemo(()=>t.defaultValue!=null?K(t.defaultValue):t.value!=null?K(t.value):"",[]),[ve,ae]=useState(ce),U=useRef(ce),Me=useCallback(()=>U.current,[]),ge=useRef(ce),[Re,Se]=useState(t.defaultValue!=null?String(t.defaultValue):null),Te=useCallback(c=>{if(!re)return {validationState:"valid",validationError:null};let h=re(c);return h===false?{validationState:"invalid",validationError:null}:typeof h=="string"?{validationState:"invalid",validationError:h}:{validationState:"valid",validationError:null}},[re]),Ce=useMemo(()=>{let c=t.defaultValue??t.value??null;return Te(c??null)},[]),[we,Le]=useState(Ce.validationState),[Ae,N]=useState(Ce.validationError),[qe,Oe]=useState(false),[Q,$]=useState(false),de=useRef("input"),w=useCallback(c=>{de.current=c;},[]),ke=useCallback(()=>de.current,[]),Z=t.value,_e=useRef(Z);if(!Object.is(_e.current,Z)&&(_e.current=Z,!Object.is(Z,J.current))){J.current=Z;let c=Object.is(Z,-0)?0:Z,h=c!=null&&Number.isFinite(c),V=h?K(c):"";ge.current=V,U.current=V,ae(V),Se(h?String(c):null);}let Ve=`${e$1??""}|${ie}|${x??""}|${D??""}|${W??""}|${j??""}|${se??""}`,Be=useRef(Ve);if(Be.current!==Ve&&(Be.current=Ve,O!=null&&Number.isFinite(O)&&!Q)){let c=K(O);c!==ve&&(ae(c),ge.current=c,U.current=c);}let me=useCallback(c=>{let{validationState:h,validationError:V}=Te(c);Le(h),N(V);},[Te]),We=useCallback((c,h)=>{let V=_.parse(c),T=h!==void 0?h:V.value;if(F==="strict"&&!M&&T!==null&&(H!==void 0&&T<H||u!==void 0&&T>u))return;U.current=c,ae(c),J.current=T,G(T);let oe=null;if(T!==null){let Ee=_.strip(c);/\d/.test(Ee)&&Number(Ee)===T?oe=T===0&&Ee.startsWith("-")?Ee.slice(1):Ee:oe=String(T);}Se(oe),q?.(oe),me(T);},[_,F,M,H,u,G,q,me]),ee=useCallback(c=>{let h=c!==null&&!Number.isFinite(c)?null:c,V=h!=null?K(h):"";if(U.current=V,J.current=h,G(h),ae(V),ge.current=V,h!=null){let T=String(h);Se(T),q?.(T);}else Se(null),q?.(null);me(h);},[K,G,q,me]),Ge=useCallback(()=>{if(O==null||!Number.isFinite(O))return U.current="",ae(""),ge.current="",null;let c=O;F==="blur"&&!M&&(c=it(O,H,u)),Object.is(c,-0)&&(c=0);let h=K(c);U.current=h,ae(h),ge.current=h;let V=c;if(!C){let T=_.parse(h).value;T!==null&&Number.isFinite(T)&&K(T)===h&&(V=T);}return V!==O&&(J.current=V,G(V)),me(V),V},[O,F,M,H,u,_,K,C,G,me]),ue=O!=null&&Number.isFinite(O)?O:null,Xe=Number.isFinite(l)&&l>0?l:B*10,Je=Number.isFinite(a)&&a>0?a:B*.1,Qe=!t.disabled&&!t.readOnly&&(M||u===void 0||(ue??Number.NEGATIVE_INFINITY)<u),Ze=!t.disabled&&!t.readOnly&&(M||H===void 0||(ue??Number.POSITIVE_INFINITY)>H),je=useCallback(c=>{let T=pt(ue??0,c??B),oe=M?T:it(T,H,u);ee(oe);},[ue,B,H,u,M,ee]),ut=useCallback(c=>{let T=pt(ue??0,-(c??B)),oe=M?T:it(T,H,u);ee(oe);},[ue,B,H,u,M,ee]),De=useCallback(()=>{u!==void 0&&ee(u);},[u,ee]),et=useCallback(()=>{H!==void 0&&ee(H);},[H,ee]);return {inputValue:ve,numberValue:ue,rawValue:Re,canIncrement:Qe,canDecrement:Ze,isScrubbing:qe,setIsScrubbing:Oe,isFocused:Q,setIsFocused:$,validationState:we,validationError:Ae,_setLastChangeReason:w,_getLastChangeReason:ke,_getLatestDisplay:Me,setInputValue:We,setNumberValue:ee,commit:Ge,increment:je,decrement:ut,incrementToMax:De,decrementToMin:et,options:{...t,step:B,largeStep:Xe,smallStep:Je,minValue:H,maxValue:u}}}function St(t,e={}){let{direction:r="horizontal",pixelSensitivity:n=4,label:i="Scrub to change value"}=e,[o,l]=useState(false),a=useRef(t);a.current=t;let v=useRef(r);v.current=r;let g=useRef(n);g.current=n;let I=useRef(false),L=useRef(0),R=useRef(null),F=useRef({x:0,y:0}),[x,D]=useState({x:0,y:0}),M=useRef(u=>{if(!I.current)return;let W=F.current.x+u.movementX,j=F.current.y+u.movementY;F.current={x:W,y:j},D({x:W,y:j});let se=v.current,ie=0;se==="horizontal"?ie=u.movementX:se==="vertical"?ie=-u.movementY:ie=Math.abs(u.movementX)>=Math.abs(u.movementY)?u.movementX:-u.movementY,L.current+=ie;let E=Math.max(1,g.current);for((L.current>=E||L.current<=-E)&&a.current._setLastChangeReason("scrub");L.current>=E;)a.current.increment(),L.current-=E;for(;L.current<=-E;)a.current.decrement(),L.current+=E;}),re=useRef(()=>{document.pointerLockElement===R.current?(I.current=true,L.current=0,l(true),a.current.setIsScrubbing(true),document.addEventListener("mousemove",M.current)):(I.current=false,L.current=0,document.removeEventListener("mousemove",M.current),l(false),a.current.setIsScrubbing(false));});useEffect(()=>{let u=re.current;return document.addEventListener("pointerlockchange",u),()=>{document.removeEventListener("pointerlockchange",u),document.removeEventListener("mousemove",M.current),typeof document.exitPointerLock=="function"&&document.pointerLockElement&&document.pointerLockElement===R.current&&document.exitPointerLock(),I.current&&(I.current=false,L.current=0,a.current.setIsScrubbing(false));}},[]);let q=useCallback(u=>{if(a.current.options.disabled||a.current.options.readOnly||u.button!==0)return;let W=u.currentTarget;R.current=W,F.current={x:u.clientX,y:u.clientY},D({x:u.clientX,y:u.clientY});let j=W.requestPointerLock();j&&typeof j.then=="function"&&j.catch(()=>{R.current=null;});},[]),C=useCallback(u=>{a.current.options.disabled||a.current.options.readOnly||(u.key==="ArrowRight"||u.key==="ArrowUp"?(u.preventDefault(),a.current._setLastChangeReason("scrub"),a.current.increment()):(u.key==="ArrowLeft"||u.key==="ArrowDown")&&(u.preventDefault(),a.current._setLastChangeReason("scrub"),a.current.decrement()));},[]),B=r==="horizontal"?"ew-resize":r==="vertical"?"ns-resize":"move",H={role:"slider",tabIndex:t.options.disabled?-1:0,style:{cursor:t.options.disabled?void 0:B,userSelect:"none",WebkitUserSelect:"none"},"aria-label":i,"aria-valuenow":t.numberValue??void 0,"aria-valuemin":t.options.minValue,"aria-valuemax":t.options.maxValue,"aria-valuetext":t.inputValue||void 0,"aria-disabled":t.options.disabled?true:void 0,"data-scrubbing":o?"":void 0,onPointerDown:q,onKeyDown:C};return {isScrubbing:o,scrubAreaProps:H,virtualCursor:x}}function be(t,e,r,n){if(!e)return t;let i={...t.props};if(n!=null&&(i.ref=n),typeof e=="function")return e(i,r);let o=Object.assign({},i,e.props);return n!=null&&(o.ref=n),at.cloneElement(e,o)}var Et=Number.parseInt(at.version,10)>=19,Kt=Et;function Ut(t){return Et?t.props.ref:t.ref}function ht(...t){let e=n=>{let i=[];for(let o of t)if(o!=null)if(typeof o=="function"){let l=o(n);i.push(typeof l=="function"?l:()=>o(null));}else o.current=n,i.push(()=>{o.current=null;});return i};if(Kt)return n=>{let i=e(n);return ()=>{for(let o of i)o();}};let r=[];return n=>{for(let i of r)i();r=n==null?[]:e(n);}}function $t(t,e){let{options:r}=t;return {"data-disabled":r.disabled?"":void 0,"data-readonly":r.readOnly?"":void 0,"data-required":r.required?"":void 0,"data-scrubbing":t.isScrubbing?"":void 0,"data-focused":t.isFocused?"":void 0,"data-invalid":e?"":void 0}}var zt=new Set(["className","style","id","tabIndex","title","role","aria-label","data-testid","onClick","onMouseEnter","onMouseLeave"]);function Yt(t){let e={},r={};for(let[n,i]of Object.entries(t))zt.has(n)||n.startsWith("data-")||n.startsWith("aria-")?r[n]=i:e[n]=i;return {fieldProps:e,divProps:r}}var qt=forwardRef(function({children:e,onValueChange:r,onValueCommitted:n,...i},o){let l=useRef(null),{fieldProps:a,divProps:v}=Yt(i),g=a,I=useRef(r);I.current=r;let L=useRef(null),R={...g,onValueCommitted:n,onChange:M=>{g.onChange?.(M),I.current&&L.current&&I.current(M,{reason:L.current._getLastChangeReason(),formattedValue:L.current._getLatestDisplay()});}},F=vt(R);L.current=F;let x=mt(R,F,l),D=F.validationState==="invalid"||F.numberValue!==null&&(g.minValue!==void 0&&F.numberValue<g.minValue||g.maxValue!==void 0&&F.numberValue>g.maxValue);return jsx(nt.Provider,{value:{state:F,aria:x,inputRef:l,props:R},children:jsx("div",{ref:o,...v,...$t(F,D),children:e})})}),Wt=forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),{ref:a,...v}=o.labelProps,g=at.isValidElement(e)?Ut(e):void 0,I=useMemo(()=>ht(i,a,g),[i,a,g]),L=jsx("label",{ref:I,...v,...n,children:r});return be(L,e,l,I)}),Gt=forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),a=jsx("div",{ref:i,...o.groupProps,...n,children:r});return be(a,e,l)}),Xt=forwardRef(function({render:e,...r},n){let{aria:i,state:o,inputRef:l}=X(),a=[r["aria-describedby"],i.inputProps["aria-describedby"]].filter(Boolean).join(" ")||void 0,v=jsx("input",{ref:l,...i.inputProps,...r,"aria-describedby":a});return be(v,e,o)}),Jt=forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),a=jsx("button",{ref:i,...o.incrementButtonProps,...n,children:r??"+"});return be(a,e,l)}),Qt=forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),a=jsx("button",{ref:i,...o.decrementButtonProps,...n,children:r??"\u2212"});return be(a,e,l)}),Zt=function(){let{aria:e}=X();return e.hiddenInputProps?jsx("input",{...e.hiddenInputProps}):null},en=forwardRef(function({render:e,children:r,direction:n="horizontal",pixelSensitivity:i=4,label:o,...l},a){let{state:v}=X(),{scrubAreaProps:g}=St(v,{direction:n,pixelSensitivity:i,label:o}),I=jsx("span",{ref:a,...g,...l,children:r});return be(I,e,v)}),tn=forwardRef(function({render:e,children:r,style:n,...i},o){let{state:l}=X();if(!l.isScrubbing)return null;let a=jsx("span",{ref:o,style:{position:"fixed",pointerEvents:"none",zIndex:9999,...n},...i,children:r});return be(a,e,l)}),nn=forwardRef(function({children:e,...r},n){let{aria:i}=X(),{ref:o,...l}=i.descriptionProps,a=useMemo(()=>ht(n,o),[n,o]);return jsx("p",{ref:a,...l,...r,children:e})}),rn=forwardRef(function({children:e,...r},n){let{aria:i,state:o}=X(),l=e??o.validationError??null;return l?jsx("p",{ref:n,...i.errorMessageProps,...r,children:l}):null}),on=forwardRef(function({render:e,style:r,...n},i){let{state:o,aria:l}=X(),a=l.inputProps.style!=null,v=a?{direction:"ltr",textAlign:"right",unicodeBidi:"plaintext",...r}:{unicodeBidi:"isolate",...r},g=jsx("span",{ref:i,"aria-hidden":"true","data-rtl":a?"":void 0,style:v,...n,children:o.inputValue});return be(g,e,o)}),An={Root:qt,Label:Wt,Group:Gt,Input:Xt,Increment:Jt,Decrement:Qt,HiddenInput:Zt,ScrubArea:en,ScrubAreaCursor:tn,Description:nn,ErrorMessage:rn,Formatted:on};function jn(t,e={}){let{locale:r,formatOptions:n,prefix:i,suffix:o,minimumFractionDigits:l,maximumFractionDigits:a,fixedDecimalScale:v}=e,g=useMemo(()=>d({locale:r,formatOptions:n,prefix:i,suffix:o,minimumFractionDigits:l,maximumFractionDigits:a,fixedDecimalScale:v}),[r,JSON.stringify(n),i,o,l,a,v]);return useMemo(()=>t==null?"":g.format(t),[t,g])}export{nt as a,X as b,rt as c,mt as d,ft as e,vt as f,St as g,An as h,jn as i};//# sourceMappingURL=chunk-NIPT3LT6.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-NIPT3LT6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/context.ts","../src/react/usePressAndHold.ts","../src/react/useIsomorphicLayoutEffect.ts","../src/react/useNumberField.ts","../src/react/useControllableState.ts","../src/react/useNumberFieldState.ts","../src/react/useScrubArea.ts","../src/react/NumberField.tsx","../src/react/useNumberFieldFormat.ts"],"names":["NumberFieldContext","createContext","useNumberFieldContext","ctx","useContext","usePressAndHold","callback","options","delay","interval","disabled","callbackRef","useRef","useEffect","delayRef","intervalRef","disabledRef","delayTimerRef","repeatTimerRef","isHeldRef","clearTimers","useCallback","scheduleRepeat","currentInterval","nextInterval","onPointerDown","e","onPointerUp","onPointerLeave","onPointerCancel","onLostPointerCapture","useIsomorphicLayoutEffect","useLayoutEffect","escapeRegex","s","useMountedFlag","countRef","mounted","setMounted","useState","ref","node","activeElementWithin","root","MAGNITUDE_MULTIPLIERS","parseSpecialNotation","t","m","useNumberField","props","state","inputRef","locale","formatOptions","rawMinValue","rawMaxValue","allowNegative","allowDecimal","allowMouseWheel","rawLiveFormat","prefix","suffix","name","readOnly","required","onFocus","onBlur","maximumFractionDigits","minimumFractionDigits","fixedDecimalScale","copyBehavior","stepHoldDelay","stepHoldInterval","incrementLabel","decrementLabel","customFormatValue","customParseValue","onValueCommitted","minValue","maxValue","notation","liveFormat","formatOptionsKey","step","largeStep","smallStep","autoId","useId","inputId","labelId","descriptionId","errorId","effMinFrac","effMaxFrac","effFixedScale","resolveEffectiveFractions","formatter","useMemo","createFormatter","isPercentStyle","liveMaxFrac","liveFormatter","parser","createParser","formatGroupedFraction","value","source","info","decIdx","normalizeDigits","fracMatch","fracLen","pendingCursor","stateRef","el","handler","isComposing","handleCompositionStart","handleCompositionEnd","composedValue","normalized","displayValue","composedKnownValue","result","localizeDigits","computeNewCursorPosition","handleChange","rawInputValue","cursorPos","inputType","_m","offset","str","knownValue","rt","handlePaste","text","stripped","li","formatted","special","sval","localeInfo","allowedCharsPattern","stripped2","result2","handleCopy","handleCut","handleKeyDown","key","input","decPos","cursor","selEnd","currentValue","rawEdited","parseResult","nextDisplay","isDigitChar","ch","isAffordanceChar","i","direction","committed","handleBlur","handleFocus","incrementHold","decrementHold","ariaValueText","isInvalid","hasLabel","labelRef","ariaLabelledBy","hasDescription","descriptionRef","ariaDescribedBy","labelProps","groupProps","inputProps","hiddenInputProps","incrementButtonProps","decrementButtonProps","useControllableState","defaultValue","onChange","isControlled","wasControlled","internalValue","setInternalValue","set","next","nextValue","clamp","min","max","v","preciseAdd","a","b","precision","decimalPlaces","factor","sa","sb","n","eIdx","exp","dotIdx","idx","useNumberFieldState","rawStep","rawLargeStep","rawSmallStep","clampBehavior","allowOutOfRange","validate","onRawChange","numberValue","setNumberValue","lastEmittedRef","formatDisplay","initialDisplay","inputValue","setInputValueRaw","latestDisplayRef","_getLatestDisplay","lastFormattedRef","rawValue","setRawValueState","runValidation","val","initialValidation","initVal","validationState","setValidationState","validationError","setValidationError","isScrubbing","setIsScrubbing","isFocused","setIsFocused","lastChangeReasonRef","_setLastChangeReason","reason","_getLastChangeReason","externalValue","prevExternalValueRef","ev","finite","formatKey","prevFormatKeyRef","applyValidation","vs","ve","setInputValue","parsed","raw","setNumericValue","rawVal","rawStr","commit","clamped","reparsed","safeNumberValue","resolvedLargeStep","resolvedSmallStep","canIncrement","canDecrement","increment","amount","decrement","incrementToMax","decrementToMin","useScrubArea","pixelSensitivity","label","setIsScrubbingLocal","directionRef","sensitivityRef","isScrubbingRef","accumulatorRef","elementRef","virtualCursorRef","virtualCursor","setVirtualCursor","stableMouseMove","nx","ny","dir","delta","sensitivity","stablePointerLockChange","onKeyDown","cursorStyle","scrubAreaProps","renderWith","defaultElement","render","forwardedRef","baseProps","merged","React","REF_IN_PROPS","SUPPORTS_REF_CLEANUP","getElementRef","mergeRefs","refs","attach","cleanups","cleanup","stateDataAttrs","DIV_ONLY_KEYS","splitProps","fieldProps","divProps","Root","forwardRef","children","onValueChange","allProps","onValueChangeRef","wrappedProps","aria","jsx","Label","rest","renderRef","mergedRef","Group","Input","_ref","describedBy","Increment","Decrement","HiddenInput","ScrubArea","ScrubAreaCursor","style","Description","descRef","descriptionProps","ErrorMessage","content","Formatted","isRTL","mergedStyle","NumberField","useNumberFieldFormat"],"mappings":"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","file":"chunk-NIPT3LT6.js","sourcesContent":["import type { RefObject } from \"react\";\nimport { createContext, useContext } from \"react\";\nimport type { NumberFieldAria, NumberFieldState, UseNumberFieldProps } from \"../core/types.js\";\n\n// Locally declared so the dev-only gate type-checks without @types/node.\ndeclare const process: { env?: Record<string, string | undefined> } | undefined;\n\nexport interface NumberFieldContextValue {\n state: NumberFieldState;\n aria: NumberFieldAria;\n inputRef: RefObject<HTMLInputElement | null>;\n props: UseNumberFieldProps;\n}\n\nexport const NumberFieldContext = createContext<NumberFieldContextValue | null>(null);\n\n/**\n * Hook for sub-components to access the NumberField context.\n * Throws if used outside NumberField.Root.\n */\nexport function useNumberFieldContext(): NumberFieldContextValue {\n const ctx = useContext(NumberFieldContext);\n if (!ctx) {\n // Full guidance in dev; production bundlers strip the guarded branch and ship\n // only the short identifiable message below. The `typeof process` /\n // `process.env` guards keep it crash-safe under raw-browser ESM and partial\n // `process` shims; both sit on the eliminated side of the NODE_ENV token.\n if (typeof process !== \"undefined\" && process.env && process.env.NODE_ENV !== \"production\") {\n throw new Error(\"[raqam] NumberField sub-components must be used inside <NumberField.Root>.\");\n }\n throw new Error(\"[raqam] <NumberField.Root> missing\");\n }\n return ctx;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\n\nexport interface UsePressAndHoldOptions {\n /** Milliseconds before repeating starts (default: 400) */\n delay?: number;\n /** Initial milliseconds between repeats — halves each tick, floors at 50 (default: 200) */\n interval?: number;\n /** Whether the element is disabled */\n disabled?: boolean;\n}\n\nexport interface PressAndHoldProps {\n onPointerDown: (e: React.PointerEvent) => void;\n onPointerUp: (e: React.PointerEvent) => void;\n onPointerLeave: (e: React.PointerEvent) => void;\n onPointerCancel: (e: React.PointerEvent) => void;\n onLostPointerCapture: (e: React.PointerEvent) => void;\n}\n\n/**\n * Returns pointer event handlers that call `callback` immediately on press,\n * then repeatedly with accelerating frequency while held down.\n *\n * Acceleration schedule (default settings):\n * immediate → 400ms wait → 200ms → 100ms → 50ms (floor, stays until release)\n *\n * All timing is handled via refs — zero state updates, zero re-renders.\n */\nexport function usePressAndHold(\n callback: () => void,\n options: UsePressAndHoldOptions = {}\n): PressAndHoldProps {\n const { delay = 400, interval = 200, disabled = false } = options;\n\n // Stable refs so handlers don't re-create on every render\n const callbackRef = useRef(callback);\n useEffect(() => {\n callbackRef.current = callback;\n });\n\n const delayRef = useRef(delay);\n useEffect(() => {\n delayRef.current = delay;\n });\n\n const intervalRef = useRef(interval);\n useEffect(() => {\n intervalRef.current = interval;\n });\n\n // Track disabled in a ref so an in-flight repeat loop can stop the instant the\n // control becomes disabled (e.g. the value hits min/max) — a disabled <button>\n // stops dispatching the pointerup/leave that would normally clear the timer.\n const disabledRef = useRef(disabled);\n useEffect(() => {\n disabledRef.current = disabled;\n });\n\n // Timer handle refs (null = no active timer)\n const delayTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const repeatTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isHeldRef = useRef(false);\n\n const clearTimers = useCallback(() => {\n isHeldRef.current = false;\n if (delayTimerRef.current !== null) {\n clearTimeout(delayTimerRef.current);\n delayTimerRef.current = null;\n }\n if (repeatTimerRef.current !== null) {\n clearTimeout(repeatTimerRef.current);\n repeatTimerRef.current = null;\n }\n }, []);\n\n // Recursive accelerating repeat\n const scheduleRepeat = useCallback(\n (currentInterval: number) => {\n if (!isHeldRef.current || disabledRef.current) {\n clearTimers();\n return;\n }\n callbackRef.current();\n const nextInterval = Math.max(50, Math.floor(currentInterval / 2));\n repeatTimerRef.current = setTimeout(() => {\n scheduleRepeat(nextInterval);\n }, currentInterval);\n },\n [clearTimers]\n );\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (disabled) return;\n // Only primary button (left mouse / single touch / pen)\n if (e.button !== 0 && e.pointerType === \"mouse\") return;\n\n // Fire immediately\n callbackRef.current();\n isHeldRef.current = true;\n\n // After initial delay, start accelerating repeats\n delayTimerRef.current = setTimeout(() => {\n scheduleRepeat(intervalRef.current);\n }, delayRef.current);\n },\n [disabled, scheduleRepeat]\n );\n\n const onPointerUp = useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n clearTimers();\n },\n [clearTimers]\n );\n\n const onPointerLeave = useCallback(\n (e: React.PointerEvent) => {\n void e;\n clearTimers();\n },\n [clearTimers]\n );\n\n // Touch interruptions (scroll/gesture) and pointer-capture loss must also stop\n // the repeat — otherwise the timer keeps firing with no release event.\n const onPointerCancel = useCallback(\n (e: React.PointerEvent) => {\n void e;\n clearTimers();\n },\n [clearTimers]\n );\n\n const onLostPointerCapture = useCallback(\n (e: React.PointerEvent) => {\n void e;\n clearTimers();\n },\n [clearTimers]\n );\n\n // Stop an in-flight repeat as soon as the control becomes disabled — a disabled\n // <button> no longer fires pointerup/leave, so the loop would otherwise run on.\n useEffect(() => {\n if (disabled) clearTimers();\n }, [disabled, clearTimers]);\n\n // Safety: clear on unmount\n useEffect(() => clearTimers, [clearTimers]);\n\n return { onPointerDown, onPointerUp, onPointerLeave, onPointerCancel, onLostPointerCapture };\n}\n","\"use client\";\n\nimport { useEffect, useLayoutEffect } from \"react\";\n\n/**\n * `useLayoutEffect` in the browser, `useEffect` on the server — avoids React's\n * \"useLayoutEffect does nothing on the server\" warning for SSR consumers while\n * keeping synchronous cursor restoration on the client.\n */\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","\"use client\";\n\nimport { useCallback, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { computeNewCursorPosition } from \"../core/cursor.js\";\nimport { createFormatter, resolveEffectiveFractions } from \"../core/formatter.js\";\nimport { localizeDigits, normalizeDigits } from \"../core/normalizer.js\";\nimport { createParser } from \"../core/parser.js\";\nimport type { NumberFieldAria, NumberFieldState, UseNumberFieldProps } from \"../core/types.js\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect.js\";\nimport { usePressAndHold } from \"./usePressAndHold.js\";\n\n// ── Tiny helper to safely escape regex special chars (including hyphen) ──────\n\nfunction escapeRegex(s: string): string {\n // The hyphen is kept last in the character class so it reads as a literal\n // rather than a range indicator, no escape needed.\n return s.replace(/[.*+?^${}()|[\\]\\\\-]/g, \"\\\\$&\");\n}\n\n/**\n * Track whether at least one element registered through the returned ref\n * callback is currently mounted. Lets `aria-labelledby` / `aria-describedby`\n * point at the label / description only while one truly exists — for any render\n * path (built-in component, custom primitive, or headless) — instead of\n * dangling at an element that isn't rendered. Ref-counted so multiple mounts and\n * StrictMode's double-invoke settle to the correct flag.\n */\nfunction useMountedFlag(): [boolean, React.RefCallback<HTMLElement>] {\n const countRef = useRef(0);\n const [mounted, setMounted] = useState(false);\n const ref = useCallback<React.RefCallback<HTMLElement>>((node) => {\n if (node) {\n countRef.current += 1;\n setMounted(true);\n } else if (countRef.current > 0) {\n countRef.current -= 1;\n if (countRef.current === 0) setMounted(false);\n }\n }, []);\n return [mounted, ref];\n}\n\n/**\n * The focused element resolved through the node's *root* — `document` in the\n * light DOM, or the containing `ShadowRoot` when the field is inside a shadow\n * tree (where `document.activeElement` only reports the host). Falls back to\n * `document.activeElement` when no node is available.\n */\nfunction activeElementWithin(node: Element | null): Element | null {\n const root = node?.getRootNode() as Document | ShadowRoot | undefined;\n if (root && \"activeElement\" in root) return root.activeElement;\n return typeof document !== \"undefined\" ? document.activeElement : null;\n}\n\n// Magnitude suffixes for compact-notation paste (\"1.5K\", \"3.4M\"). Module-scoped\n// so it isn't rebuilt on every paste.\nconst MAGNITUDE_MULTIPLIERS: Record<string, number> = {\n k: 1e3,\n thousand: 1e3,\n m: 1e6,\n million: 1e6,\n b: 1e9,\n billion: 1e9,\n t: 1e12,\n trillion: 1e12,\n};\n\n/**\n * Parse scientific (\"1e3\", \"1.23E4\") and compact (\"1.5K\", \"3.4M\") notation that\n * the plain locale parser cannot handle. Used on paste so values copied from\n * spreadsheets / dashboards round-trip instead of being mangled by char-strip.\n * Returns null when `s` is not one of these forms.\n */\nfunction parseSpecialNotation(s: string): number | null {\n // Bound length before the regexes (this runs on attacker-controllable paste\n // text). The patterns are also de-ambiguated below so they match in linear\n // time — together this closes the ReDoS on the paste path.\n if (s.length > 256) return null;\n const t = s.replace(/\\s+/g, \"\");\n // Note the de-ambiguated mantissa `\\d+(?:\\.\\d*)?|\\.\\d+` (no overlapping\n // `\\d+\\.?\\d*` alternation) — the old form backtracked quadratically on a long\n // failing input.\n if (/^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)[eE][+-]?\\d+$/.test(t)) {\n const n = Number(t);\n return Number.isFinite(n) ? n : null;\n }\n const m = t.match(/^([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+))(k|m|b|t|thousand|million|billion|trillion)$/i);\n if (m) {\n const n = Number(m[1]) * MAGNITUDE_MULTIPLIERS[m[2].toLowerCase()]!;\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\nexport function useNumberField(\n props: UseNumberFieldProps,\n state: NumberFieldState,\n inputRef: React.RefObject<HTMLInputElement | null>\n): NumberFieldAria {\n const {\n locale,\n formatOptions,\n minValue: rawMinValue,\n maxValue: rawMaxValue,\n allowNegative = true,\n allowDecimal = true,\n allowMouseWheel = false,\n liveFormat: rawLiveFormat = true,\n prefix,\n suffix,\n name,\n disabled,\n readOnly,\n required,\n onFocus,\n onBlur,\n maximumFractionDigits,\n minimumFractionDigits,\n fixedDecimalScale,\n copyBehavior = \"formatted\",\n stepHoldDelay = 400,\n stepHoldInterval = 200,\n incrementLabel = \"Increase\",\n decrementLabel = \"Decrease\",\n formatValue: customFormatValue,\n parseValue: customParseValue,\n onValueCommitted,\n } = props; // formatValue/parseValue are on UseNumberFieldStateOptions (inherited)\n\n // Drop non-finite bounds (mirrors useNumberFieldState) so aria-valuemin/max\n // never render \"NaN\"/\"Infinity\" and out-of-range / Home / End never act on a\n // bad bound.\n const minValue = Number.isFinite(rawMinValue) ? rawMinValue : undefined;\n const maxValue = Number.isFinite(rawMaxValue) ? rawMaxValue : undefined;\n\n // Compact/scientific/engineering notation produce formatted strings (\"2.5K\",\n // \"1.5E3\") whose suffix/exponent characters collide with continued typing, so\n // we keep the raw typed digits live and only format on blur/commit.\n const notation = formatOptions?.notation;\n const liveFormat =\n rawLiveFormat &&\n notation !== \"compact\" &&\n notation !== \"scientific\" &&\n notation !== \"engineering\";\n\n // Serialize formatOptions once per render — it feeds four useMemo dependency\n // arrays below and JSON.stringify is not free for non-trivial option objects.\n const formatOptionsKey = JSON.stringify(formatOptions);\n\n const { step = 1, largeStep = step * 10, smallStep = step * 0.1 } = state.options;\n\n const autoId = useId();\n const inputId = props.id ?? `raqam-${autoId}`;\n const labelId = `${inputId}-label`;\n const descriptionId = `${inputId}-description`;\n const errorId = `${inputId}-error`;\n\n // ── Formatter & parser (kept in sync with state's) ──────────────────────\n // Same effective-fraction resolution as the state hook, via one shared helper,\n // so the live-typing and on-commit displays can never drift apart.\n const { effMinFrac, effMaxFrac, effFixedScale } = resolveEffectiveFractions({\n allowDecimal,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n });\n\n const formatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: effMinFrac,\n maximumFractionDigits: effMaxFrac,\n fixedDecimalScale: effFixedScale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, prefix, suffix, effMinFrac, effMaxFrac, effFixedScale]\n );\n\n // Live-typing formatter: keeps grouping + currency symbol but drops the\n // minimum-fraction *padding* (\".00\") so currency / fixedDecimalScale fields\n // group correctly while typing and never accumulate padding zeros. The full\n // `formatter` (with padding) is applied on commit/blur.\n //\n // Percent fields default to maximumFractionDigits:0, which would round away\n // the fraction the user is typing (\"12.5\" → \"13%\") and — because the rounded\n // string is shorter — corrupt the next keystroke. Give the percent live\n // formatter room so typing never rounds; commit() rounds to the real scale.\n const isPercentStyle = formatOptions?.style === \"percent\";\n const liveMaxFrac = allowDecimal ? (isPercentStyle ? 20 : effMaxFrac) : 0;\n const liveFormatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: 0,\n maximumFractionDigits: liveMaxFrac,\n fixedDecimalScale: false,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, prefix, suffix, liveMaxFrac]\n );\n\n const parser = useMemo(\n () =>\n createParser({\n locale,\n formatOptions,\n allowNegative,\n allowDecimal,\n prefix,\n suffix,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, allowNegative, allowDecimal, prefix, suffix]\n );\n\n // Re-format `value` so its integer part groups while the EXACT typed fraction\n // (incl. trailing zeros) from `source` is preserved. Returns null when there is\n // no integer part (leading-dot \".5\" — keep it raw to avoid a \"0\" prepend that\n // would shift the caret) or no fraction (trailing dot). Used by the typing path\n // and the grouping-comma / trailing-affordance backspace paths so they all\n // preserve typed trailing zeros consistently.\n const formatGroupedFraction = useCallback(\n (value: number, source: string): string | null => {\n const info = formatter.getLocaleInfo();\n let decIdx = source.lastIndexOf(info.decimalSeparator);\n // Fall back to an ASCII \".\" only when it stands in for the decimal point\n // (not when \".\" is the grouping separator, e.g. de-DE — see Fix J).\n if (decIdx === -1 && info.decimalSeparator !== \".\" && info.groupingSeparator !== \".\") {\n decIdx = source.lastIndexOf(\".\");\n }\n if (decIdx === -1) return null;\n if (!/\\d/.test(normalizeDigits(source.slice(0, decIdx)))) return null; // leading dot\n const fracMatch = normalizeDigits(source.slice(decIdx + 1)).match(/^\\d+/);\n if (!fracMatch) return null; // trailing dot\n const fracLen = Math.min(fracMatch[0].length, effMaxFrac ?? 20, 20);\n if (fracLen === 0) return null;\n return createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: fracLen,\n maximumFractionDigits: fracLen,\n }).format(value);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [formatter, locale, formatOptionsKey, prefix, suffix, effMaxFrac]\n );\n\n // ── Cursor engine ────────────────────────────────────────────────────────\n const pendingCursor = useRef<number | null>(null);\n\n // Stable handle to the latest state so listeners/effects that only *invoke*\n // state methods don't have to list the (per-render fresh) `state` object as a\n // dependency — keeps the native wheel listener from re-subscribing every render.\n const stateRef = useRef(state);\n stateRef.current = state;\n\n // Restore cursor synchronously after React commits the new value to DOM\n useIsomorphicLayoutEffect(() => {\n if (\n pendingCursor.current !== null &&\n inputRef.current &&\n activeElementWithin(inputRef.current) === inputRef.current\n ) {\n inputRef.current.setSelectionRange(pendingCursor.current, pendingCursor.current);\n pendingCursor.current = null;\n }\n // Run after every inputValue change\n }, [state.inputValue, inputRef]);\n\n // ── Mouse wheel (non-passive native listener) ────────────────────────────\n // React's synthetic onWheel is passive in React 17+; it cannot call\n // preventDefault(). We must attach a native, non-passive listener instead.\n useEffect(() => {\n const el = inputRef.current;\n if (!el || !allowMouseWheel) return;\n\n const handler = (e: WheelEvent) => {\n if (disabled || readOnly) return;\n if (activeElementWithin(el) !== el) return;\n e.preventDefault();\n const s = stateRef.current;\n s._setLastChangeReason(\"wheel\");\n if (e.deltaY < 0) {\n s.increment();\n } else {\n s.decrement();\n }\n };\n\n el.addEventListener(\"wheel\", handler, { passive: false });\n return () => el.removeEventListener(\"wheel\", handler);\n }, [allowMouseWheel, disabled, readOnly, inputRef]);\n\n // ── IME Composition state ────────────────────────────────────────────────\n // During CJK IME input, partial composed characters must not trigger live\n // formatting. We suspend formatting during composition and resume on end.\n const isComposing = useRef(false);\n\n const handleCompositionStart = useCallback(() => {\n isComposing.current = true;\n }, []);\n\n const handleCompositionEnd = useCallback(\n (e: React.CompositionEvent<HTMLInputElement>) => {\n isComposing.current = false;\n // After composition ends, run the full format cycle on the composed value\n const composedValue = e.currentTarget.value;\n const info = formatter.getLocaleInfo();\n const normalized = normalizeDigits(composedValue);\n\n let displayValue: string;\n // Thread the custom parser's value through to state — otherwise the state\n // hook re-derives it with the BUILT-IN parser, discarding the custom result.\n let composedKnownValue: number | null | undefined;\n if (customParseValue) {\n const result = customParseValue(normalized);\n // Honor an explicit null too (a custom parser rejecting the composed\n // text), so the built-in parser can't re-derive a value for it.\n composedKnownValue = result.value;\n if (result.isIntermediate) {\n displayValue = normalized;\n } else if (result.value !== null && customFormatValue) {\n displayValue = customFormatValue(result.value);\n } else if (result.value !== null) {\n displayValue = formatter.format(result.value);\n } else {\n displayValue = normalized;\n }\n // Disable cursor engine for custom format/parse\n pendingCursor.current = displayValue.length;\n } else if (liveFormat) {\n const result = parser.parse(normalized);\n if (result.isIntermediate) {\n // Keep the still-typing display in the locale's native digit script.\n displayValue = localizeDigits(normalized, info.zero);\n } else if (result.value !== null) {\n displayValue = customFormatValue\n ? customFormatValue(result.value)\n : liveFormatter.format(result.value);\n } else {\n displayValue = normalized === \"\" ? \"\" : normalized;\n }\n pendingCursor.current = computeNewCursorPosition(\n composedValue,\n composedValue.length,\n displayValue,\n info,\n \"insertCompositionText\"\n );\n } else {\n displayValue = normalized;\n pendingCursor.current = normalized.length;\n }\n\n state._setLastChangeReason(\"input\");\n state.setInputValue(displayValue, composedKnownValue);\n },\n [formatter, liveFormatter, parser, liveFormat, state, customFormatValue, customParseValue]\n );\n\n // ── onChange handler ─────────────────────────────────────────────────────\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawInputValue = e.target.value;\n const cursorPos = e.target.selectionStart ?? rawInputValue.length;\n const inputType = (e.nativeEvent as InputEvent).inputType;\n const info = formatter.getLocaleInfo();\n\n // During IME composition, skip live formatting — just track the raw value\n if (isComposing.current) {\n state.setInputValue(rawInputValue);\n return;\n }\n\n // Normalise non-Latin digits\n let normalized = normalizeDigits(rawInputValue);\n\n // Drop characters disallowed by the constraint flags *live*, so the field\n // never shows an invalid string that gets wiped on blur. The minus / dot\n // keys simply do nothing instead of poisoning the value.\n if (!allowNegative) {\n normalized = normalized.split(\"-\").join(\"\").split(info.minusSign).join(\"\");\n }\n if (!allowDecimal) {\n normalized = normalized.split(\".\").join(\"\").split(info.decimalSeparator).join(\"\");\n } else if (info.decimalSeparator !== \".\" && info.groupingSeparator !== \".\") {\n // Latin-keyboard users type the ASCII \".\" as the decimal point even in\n // locales whose separator is non-ASCII (ar/fa: ٫). Map a \".\" that is part\n // of a number (adjacent to a digit) onto the locale separator so the value\n // parses and the caret engine (which only tracks the locale separator)\n // doesn't strand the dot. Dots inside a symbol (e.g. the Arabic currency\n // symbol \"ج.م.\") are NOT adjacent to digits, so they stay untouched.\n // Skipped entirely when \".\" is the grouping separator (e.g. de-DE).\n normalized = normalized.replace(/\\./g, (_m, offset: number, str: string) =>\n /\\d/.test(str[offset - 1] ?? \"\") || /\\d/.test(str[offset + 1] ?? \"\")\n ? info.decimalSeparator\n : \".\"\n );\n }\n\n let displayValue: string;\n let knownValue: number | null | undefined;\n\n // Custom parse/format escape hatch\n if (customParseValue) {\n const result = customParseValue(normalized);\n // Thread the custom parser's value through to state — including an\n // explicit null (a custom parser that rejects input). Otherwise the\n // state hook re-parses the display with the BUILT-IN parser and could\n // emit a number the custom parser deliberately rejected.\n knownValue = result.value;\n if (result.isIntermediate) {\n displayValue = normalized;\n } else if (result.value !== null) {\n displayValue = customFormatValue\n ? customFormatValue(result.value)\n : formatter.format(result.value);\n } else if (normalized === \"\") {\n displayValue = \"\";\n } else {\n displayValue = normalized;\n }\n // Can't predict cursor position with custom formatter — place at end\n pendingCursor.current = displayValue.length;\n } else if (liveFormat) {\n const result = parser.parse(normalized);\n\n if (result.isIntermediate) {\n // A trailing-zero decimal (e.g. \"12.50\") is intermediate, but its\n // integer part should still group live (insert \"99\" into \"$12.50\" must\n // show \"$9,912.50\"). Re-format preserving the typed fraction; lone \"-\",\n // trailing \".\" and leading \".\" keep the raw form.\n const grouped =\n !customFormatValue && result.value !== null\n ? formatGroupedFraction(result.value, normalized)\n : null;\n displayValue = grouped ?? localizeDigits(normalized, info.zero);\n } else if (result.value !== null) {\n if (customFormatValue) {\n displayValue = customFormatValue(result.value);\n } else {\n displayValue = liveFormatter.format(result.value);\n // The display will be re-parsed by setInputValue. For invertible\n // formats that round-trips (and rounds the value to the displayed\n // precision); for non-invertible notation (compact \"2.5K\",\n // scientific, unit) re-parsing destroys magnitude — so pass the\n // exact typed value through when the format does not round-trip.\n const rt = parser.parse(displayValue).value;\n knownValue =\n rt !== null && Number.isFinite(rt) && liveFormatter.format(rt) === displayValue\n ? rt\n : result.value;\n }\n } else if (normalized === \"\" || !/\\d/.test(normalized)) {\n // Empty, or only formatting affordances left (a lone \"%\", suffix, etc.\n // after deleting the last digit) — clear the field instead of stranding\n // the orphaned characters.\n displayValue = \"\";\n } else {\n // Invalid input — keep the raw normalised string so the user can\n // see what they typed (they'll get corrected on blur)\n displayValue = normalized;\n }\n\n if (customFormatValue) {\n // Custom format: can't predict cursor, place at end\n pendingCursor.current = displayValue.length;\n } else {\n // Compute and stash cursor position for the isomorphic layout effect\n pendingCursor.current = computeNewCursorPosition(\n rawInputValue,\n cursorPos,\n displayValue,\n info,\n inputType\n );\n }\n } else {\n // No live format — just pass through normalised digits\n displayValue = normalized;\n pendingCursor.current = cursorPos;\n }\n\n // An edit that empties the field reports the dedicated \"clear\" reason so\n // consumers can distinguish a deletion-to-empty from ordinary typing.\n state._setLastChangeReason(displayValue === \"\" ? \"clear\" : \"input\");\n state.setInputValue(displayValue, knownValue);\n },\n [\n formatter,\n liveFormatter,\n parser,\n liveFormat,\n state,\n customFormatValue,\n customParseValue,\n formatGroupedFraction,\n ]\n );\n\n // ── Paste handler ────────────────────────────────────────────────────────\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData(\"text/plain\");\n if (!text) return;\n // Discard absurdly long clipboard payloads up front — no legitimate number\n // is this long, and it bounds every downstream scan/regex on this\n // attacker-controllable input.\n if (text.length > 1000) return;\n\n // 1. Strip common currency symbols (global currencies)\n const stripped = text.replace(/[€$£¥₹₺₽﷼฿₩¢₦₨₪₫₱]/g, \"\").trim();\n\n // 2. Normalize non-Latin digits to ASCII\n let normalized = normalizeDigits(stripped);\n\n // Honour the constraint flags on paste too (drop minus / decimal).\n if (!allowNegative) {\n const li = formatter.getLocaleInfo();\n normalized = normalized.split(\"-\").join(\"\").split(li.minusSign).join(\"\");\n }\n if (!allowDecimal) {\n const li = formatter.getLocaleInfo();\n normalized = normalized.split(\".\").join(\"\").split(li.decimalSeparator).join(\"\");\n }\n\n state._setLastChangeReason(\"paste\");\n\n // Custom parse escape hatch\n if (customParseValue) {\n const result = customParseValue(normalized);\n if (result.value !== null) {\n const formatted = customFormatValue\n ? customFormatValue(result.value)\n : formatter.format(result.value);\n // Pass the known value so a non-invertible format (compact/scientific)\n // is not re-parsed into a wrong magnitude.\n state.setInputValue(formatted, result.value);\n pendingCursor.current = formatted.length;\n }\n return;\n }\n\n // 2.5 Scientific / compact notation (1e3, 1.23E4, 1.5K…) before the\n // locale parser, whose char-strip would otherwise mangle the e / K.\n const special = parseSpecialNotation(normalized);\n if (special !== null) {\n const isPercent = formatOptions?.style === \"percent\";\n const sval = isPercent ? special / 100 : special;\n const formatted = customFormatValue ? customFormatValue(sval) : formatter.format(sval);\n state.setInputValue(formatted, sval);\n pendingCursor.current = formatted.length;\n return;\n }\n\n // 3. Try parse with current locale parser\n const result = parser.parse(normalized);\n\n if (result.value !== null) {\n const formatted = formatter.format(result.value);\n state.setInputValue(formatted, result.value);\n pendingCursor.current = formatted.length;\n return;\n }\n\n // 4. Fallback: strip everything except digits, locale decimal, minus sign\n const localeInfo = formatter.getLocaleInfo();\n const allowedCharsPattern = new RegExp(\n `[^0-9${escapeRegex(localeInfo.decimalSeparator)}${escapeRegex(localeInfo.minusSign)}-]`,\n \"g\"\n );\n const stripped2 = normalized.replace(allowedCharsPattern, \"\");\n const result2 = parser.parse(stripped2);\n\n if (result2.value !== null) {\n const formatted = formatter.format(result2.value);\n state.setInputValue(formatted, result2.value);\n pendingCursor.current = formatted.length;\n }\n // If still invalid, silently discard — don't paste garbage into the field\n },\n [parser, formatter, state, customFormatValue, customParseValue]\n );\n\n // ── Copy / Cut handlers ──────────────────────────────────────────────────\n const handleCopy = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n if (copyBehavior === \"formatted\") return; // browser handles it natively\n\n e.preventDefault();\n const text = String(state.numberValue ?? \"\");\n e.clipboardData.setData(\"text/plain\", text);\n },\n [copyBehavior, state.numberValue]\n );\n\n const handleCut = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n if (copyBehavior === \"formatted\") return; // browser handles it\n\n e.preventDefault();\n const text = String(state.numberValue ?? \"\");\n e.clipboardData.setData(\"text/plain\", text);\n // Clear the field after cut — report the dedicated \"clear\" reason.\n state._setLastChangeReason(\"clear\");\n state.setInputValue(\"\");\n },\n [copyBehavior, state]\n );\n\n // ── Keyboard handler ─────────────────────────────────────────────────────\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n\n const key = e.key;\n\n // Smart backspace: when cursor is immediately after a grouping separator\n // (no selection active, no modifier keys), delete both the separator and\n // the preceding digit so the user can backspace through formatted numbers\n // without the comma \"blocking\" deletion.\n //\n // This must be handled in keydown — by the time onChange fires, the\n // browser has already removed the separator character, making it\n // impossible to detect what was deleted.\n // Smart decimal: when the user types the decimal separator but one already\n // exists in the formatted value (e.g. \"1.00\" with fixedDecimalScale),\n // move the cursor to just after the decimal separator instead of inserting\n // a duplicate. This enables the financial UX pattern:\n // \"1.00\" → type \".\" → cursor jumps after \".\" → type \"5\" → \"1.50\"\n // Same applies for negative values: \"-1.00\" → type \".\" → cursor after \".\"\n if (!e.metaKey && !e.ctrlKey && !e.altKey && allowDecimal) {\n const localeInfo = formatter.getLocaleInfo();\n // Match the locale's decimal separator key (e.g. \".\" for en-US, \",\" for\n // de-DE), plus the ASCII \".\" when it stands in for a non-ASCII separator\n // (ar/fa). Do NOT match \".\" when it is the grouping separator (de-DE).\n const isDecimalKey =\n key === localeInfo.decimalSeparator ||\n (key === \".\" &&\n localeInfo.decimalSeparator !== \".\" &&\n localeInfo.groupingSeparator !== \".\");\n if (isDecimalKey) {\n const input = inputRef.current;\n if (input) {\n const decPos = input.value.indexOf(localeInfo.decimalSeparator);\n if (decPos !== -1) {\n e.preventDefault();\n input.setSelectionRange(decPos + 1, decPos + 1);\n return;\n }\n }\n }\n }\n\n if (key === \"Backspace\" && !e.shiftKey && !e.altKey && !e.metaKey && !e.ctrlKey) {\n const input = inputRef.current;\n if (input) {\n const cursor = input.selectionStart ?? 0;\n const selEnd = input.selectionEnd ?? cursor;\n const currentValue = input.value;\n const info = formatter.getLocaleInfo();\n\n if (\n cursor === selEnd && // no text selection — single caret\n cursor >= 2 &&\n currentValue[cursor - 1] === info.groupingSeparator\n ) {\n e.preventDefault();\n // Remove the grouping separator (cursor-1) AND the digit before it (cursor-2)\n const rawEdited = currentValue.slice(0, cursor - 2) + currentValue.slice(cursor);\n const parseResult = parser.parse(rawEdited);\n\n state._setLastChangeReason(\"input\");\n let nextDisplay: string;\n if (parseResult.value !== null) {\n // Preserve typed trailing zeros; use the LIVE formatter (no\n // min-fraction padding) so editing matches the typing display.\n nextDisplay =\n formatGroupedFraction(parseResult.value, rawEdited) ??\n liveFormatter.format(parseResult.value);\n state.setInputValue(nextDisplay, parseResult.value);\n } else {\n // Empty or intermediate — store as-is (blur will clean up). If the\n // edit emptied the field, report the dedicated \"clear\" reason.\n nextDisplay = rawEdited;\n if (rawEdited === \"\") state._setLastChangeReason(\"clear\");\n state.setInputValue(rawEdited);\n }\n // Remap the caret through the cursor engine so re-grouping shifts\n // (e.g. \"1,234,567\" → \"123,567\") never leave it stranded after a comma.\n pendingCursor.current = computeNewCursorPosition(\n rawEdited,\n cursor - 2,\n nextDisplay,\n info,\n \"deleteContentBackward\"\n );\n return;\n }\n\n // Backspace over a trailing affordance (% sign, suffix like \" kg\") —\n // the browser would delete the affordance char, but the formatter\n // immediately re-appends it, so the field never changes. Instead delete\n // the digit that precedes the affordance run. Digit detection is\n // script-aware (\\p{Nd}) so it works for native digits (fa/ar) too.\n const isDigitChar = (ch: string | undefined): boolean =>\n ch !== undefined && /\\p{Nd}/u.test(ch);\n const isAffordanceChar = (ch: string | undefined): boolean =>\n ch !== undefined &&\n !isDigitChar(ch) &&\n ch !== info.decimalSeparator &&\n ch !== info.minusSign &&\n ch !== \"-\";\n if (\n cursor === selEnd &&\n cursor === currentValue.length &&\n cursor >= 1 &&\n isAffordanceChar(currentValue[cursor - 1])\n ) {\n // Walk back over the trailing affordance run to the last real char.\n let i = cursor;\n while (i > 0 && isAffordanceChar(currentValue[i - 1])) i--;\n if (i > 0 && isDigitChar(currentValue[i - 1])) {\n e.preventDefault();\n const rawEdited = currentValue.slice(0, i - 1) + currentValue.slice(i);\n const parseResult = parser.parse(rawEdited);\n state._setLastChangeReason(\"input\");\n let nextDisplay: string;\n if (parseResult.value !== null && /\\p{Nd}/u.test(rawEdited)) {\n // Use the LIVE formatter (no min-fraction padding) so the display\n // matches the typing path — never re-pad \".00\" mid-edit.\n nextDisplay =\n formatGroupedFraction(parseResult.value, rawEdited) ??\n liveFormatter.format(parseResult.value);\n state.setInputValue(nextDisplay, parseResult.value);\n } else {\n // No digits left — clear the field (don't strand the affordance).\n // Report the dedicated \"clear\" reason like the onChange path.\n nextDisplay = \"\";\n state._setLastChangeReason(\"clear\");\n state.setInputValue(\"\");\n }\n pendingCursor.current = computeNewCursorPosition(\n rawEdited,\n i - 1,\n nextDisplay,\n info,\n \"deleteContentBackward\"\n );\n return;\n }\n }\n }\n }\n\n if (key === \"ArrowUp\" || key === \"ArrowDown\") {\n e.preventDefault();\n const direction = key === \"ArrowUp\" ? 1 : -1;\n state._setLastChangeReason(\"keyboard\");\n if (e.shiftKey) {\n direction > 0 ? state.increment(largeStep) : state.decrement(largeStep);\n } else if (e.metaKey || e.ctrlKey) {\n direction > 0 ? state.increment(smallStep) : state.decrement(smallStep);\n } else {\n direction > 0 ? state.increment() : state.decrement();\n }\n return;\n }\n\n if (key === \"PageUp\") {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.increment(largeStep);\n return;\n }\n\n if (key === \"PageDown\") {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.decrement(largeStep);\n return;\n }\n\n if (key === \"Home\") {\n if (minValue !== undefined) {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.decrementToMin();\n }\n return;\n }\n\n if (key === \"End\") {\n if (maxValue !== undefined) {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.incrementToMax();\n }\n return;\n }\n\n if (key === \"Enter\") {\n state._setLastChangeReason(\"blur\");\n const committed = state.commit();\n onValueCommitted?.(committed, { reason: \"keyboard\" });\n return;\n }\n },\n [\n disabled,\n readOnly,\n state,\n largeStep,\n smallStep,\n minValue,\n maxValue,\n formatter,\n liveFormatter,\n parser,\n inputRef,\n allowDecimal,\n formatGroupedFraction,\n onValueCommitted,\n ]\n );\n\n // ── Blur handler ─────────────────────────────────────────────────────────\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n state.setIsFocused(false);\n state._setLastChangeReason(\"blur\");\n const committed = state.commit();\n onValueCommitted?.(committed, { reason: \"blur\" });\n onBlur?.(e);\n },\n [state, onBlur, onValueCommitted]\n );\n\n // ── Focus handler ────────────────────────────────────────────────────────\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n state.setIsFocused(true);\n onFocus?.(e);\n },\n [state, onFocus]\n );\n\n // ── Press-and-hold for increment/decrement buttons ───────────────────────\n const incrementHold = usePressAndHold(\n () => {\n state._setLastChangeReason(\"increment\");\n state.increment();\n },\n {\n delay: stepHoldDelay,\n interval: stepHoldInterval,\n disabled: disabled || !state.canIncrement,\n }\n );\n\n const decrementHold = usePressAndHold(\n () => {\n state._setLastChangeReason(\"decrement\");\n state.decrement();\n },\n {\n delay: stepHoldDelay,\n interval: stepHoldInterval,\n disabled: disabled || !state.canDecrement,\n }\n );\n\n // ── ARIA valuetext ───────────────────────────────────────────────────────\n const ariaValueText = useMemo(() => {\n if (state.numberValue == null) return undefined;\n return customFormatValue\n ? customFormatValue(state.numberValue)\n : formatter.format(state.numberValue);\n }, [state.numberValue, formatter, customFormatValue]);\n\n // ── RTL detection ────────────────────────────────────────────────────────\n const localeInfo = formatter.getLocaleInfo();\n\n // ── Out-of-range + validation detection (for aria-invalid + data-invalid) ─\n const isOutOfRange =\n state.numberValue !== null &&\n ((minValue !== undefined && state.numberValue < minValue) ||\n (maxValue !== undefined && state.numberValue > maxValue));\n\n const isInvalid = isOutOfRange || state.validationState === \"invalid\";\n\n // ── Prop maps ────────────────────────────────────────────────────────────\n\n // Track whether a label element is actually mounted. `labelProps.ref` (below)\n // registers/unregisters as it mounts, so `aria-labelledby` only points at the\n // label when it truly exists — for any render path (built-in component, custom\n // primitive, or fully headless), not just one that runs a specific effect.\n const [hasLabel, labelRef] = useMountedFlag();\n\n // Fall back to the internal label id only when the consumer hasn't supplied\n // their own accessible name AND a label is actually rendered. Defaulting to\n // `labelId` otherwise points `aria-labelledby` at a `<label>` that may not\n // exist (e.g. when only `aria-label` is passed), producing a dangling ref.\n const ariaLabelledBy =\n props[\"aria-labelledby\"] ?? (props[\"aria-label\"] ? undefined : hasLabel ? labelId : undefined);\n\n // Mirror the label registration for the description so the input's\n // aria-describedby points at <NumberField.Description> only while one is\n // actually mounted — avoiding a dangling reference (the same class of bug fixed\n // for aria-labelledby) when no description is rendered.\n const [hasDescription, descriptionRef] = useMountedFlag();\n\n // Combine the consumer's own aria-describedby with the internal description id\n // (when present) so the description is announced by assistive technology.\n const ariaDescribedBy =\n [props[\"aria-describedby\"], hasDescription ? descriptionId : null].filter(Boolean).join(\" \") ||\n undefined;\n\n const labelProps: NumberFieldAria[\"labelProps\"] = {\n id: labelId,\n htmlFor: inputId,\n ref: labelRef,\n };\n\n const groupProps: React.HTMLAttributes<HTMLDivElement> = {\n role: \"group\",\n \"aria-labelledby\": ariaLabelledBy,\n };\n\n const inputProps: React.InputHTMLAttributes<HTMLInputElement> = {\n id: inputId,\n type: \"text\",\n inputMode: \"decimal\",\n role: \"spinbutton\",\n autoComplete: \"off\",\n autoCorrect: \"off\",\n spellCheck: false,\n \"aria-label\": props[\"aria-label\"],\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-valuenow\": state.numberValue ?? undefined,\n \"aria-valuemin\": minValue,\n \"aria-valuemax\": maxValue,\n \"aria-valuetext\": ariaValueText,\n \"aria-disabled\": disabled || undefined,\n \"aria-readonly\": readOnly || undefined,\n \"aria-required\": required || undefined,\n \"aria-invalid\": isInvalid ? true : undefined,\n \"aria-errormessage\": isInvalid && state.validationError ? errorId : undefined,\n disabled,\n readOnly,\n required,\n value: state.inputValue,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onBlur: handleBlur,\n onFocus: handleFocus,\n onPaste: handlePaste,\n onCopy: copyBehavior !== \"formatted\" ? handleCopy : undefined,\n onCut: copyBehavior !== \"formatted\" ? handleCut : undefined,\n onCompositionStart: handleCompositionStart,\n onCompositionEnd: handleCompositionEnd,\n // RTL: keep the number LTR and align it to the right in RTL contexts.\n // unicodeBidi \"plaintext\" auto-detects each run's direction, so the digits\n // stay LTR while an RTL suffix / Arabic currency name falls to its natural\n // side (\"embed\" forced the whole field LTR, mis-ordering those affordances).\n style: localeInfo.isRTL\n ? { direction: \"ltr\", textAlign: \"right\", unicodeBidi: \"plaintext\" }\n : undefined,\n // Data attributes for CSS styling\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n \"data-required\": required ? \"\" : undefined,\n \"data-invalid\": isInvalid ? \"\" : undefined,\n \"data-rtl\": localeInfo.isRTL ? \"\" : undefined,\n } as React.InputHTMLAttributes<HTMLInputElement>;\n\n const hiddenInputProps: React.InputHTMLAttributes<HTMLInputElement> | null = name\n ? {\n type: \"hidden\",\n name,\n value: state.numberValue ?? \"\",\n \"aria-hidden\": true,\n }\n : null;\n\n const incrementButtonProps: React.ButtonHTMLAttributes<HTMLButtonElement> = {\n type: \"button\",\n tabIndex: -1,\n \"aria-label\": incrementLabel,\n disabled: disabled || !state.canIncrement,\n // Press-and-hold handlers replace simple onClick\n ...incrementHold,\n \"data-disabled\": disabled || !state.canIncrement ? \"\" : undefined,\n } as React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n const decrementButtonProps: React.ButtonHTMLAttributes<HTMLButtonElement> = {\n type: \"button\",\n tabIndex: -1,\n \"aria-label\": decrementLabel,\n disabled: disabled || !state.canDecrement,\n // Press-and-hold handlers replace simple onClick\n ...decrementHold,\n \"data-disabled\": disabled || !state.canDecrement ? \"\" : undefined,\n } as React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n const descriptionProps: NumberFieldAria[\"descriptionProps\"] = {\n id: descriptionId,\n ref: descriptionRef,\n };\n\n const errorMessageProps: React.HTMLAttributes<HTMLElement> = {\n id: errorId,\n role: \"alert\",\n \"aria-live\": \"polite\",\n } as React.HTMLAttributes<HTMLElement>;\n\n return {\n labelProps,\n groupProps,\n inputProps,\n hiddenInputProps,\n incrementButtonProps,\n decrementButtonProps,\n descriptionProps,\n errorMessageProps,\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\n// Locally declared so the dev-only gate type-checks without @types/node.\ndeclare const process: { env?: Record<string, string | undefined> } | undefined;\n\ninterface UseControllableStateOptions<T> {\n value?: T;\n defaultValue?: T;\n onChange?: (value: T) => void;\n}\n\ntype ControllableSetter<T> = (next: T | ((prev: T | undefined) => T)) => void;\n\n/**\n * Manages controlled vs uncontrolled state.\n * - If `value` is provided, the component is controlled.\n * - Otherwise it manages its own state starting from `defaultValue`.\n * Warns in dev mode if the component switches between controlled/uncontrolled.\n *\n * Overloads narrow the returned value to `T` (no `| undefined`) when a `value`\n * or `defaultValue` is supplied, so callers that guarantee one don't have to\n * null-check the result.\n */\nexport function useControllableState<T>(options: {\n value: T;\n defaultValue?: T;\n onChange?: (value: T) => void;\n}): [T, ControllableSetter<T>];\nexport function useControllableState<T>(options: {\n value?: T;\n defaultValue: T;\n onChange?: (value: T) => void;\n}): [T, ControllableSetter<T>];\nexport function useControllableState<T>(\n options: UseControllableStateOptions<T>\n): [T | undefined, ControllableSetter<T>];\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T | undefined, ControllableSetter<T>] {\n const isControlled = value !== undefined;\n const wasControlled = useRef(isControlled);\n\n // Dev-only warning. The `process.env.NODE_ENV !== \"production\"` token is\n // statically replaced and the branch eliminated by production bundlers that\n // define NODE_ENV (and by raqam's minified build), so this ships zero bytes in\n // production. The `typeof process` / `process.env` guards keep it crash-safe\n // under raw-browser ESM and partial `process` shims — this runs on every\n // render, so a throw here would break rendering, not just an error path.\n if (\n typeof process !== \"undefined\" &&\n process.env &&\n process.env.NODE_ENV !== \"production\" &&\n wasControlled.current !== isControlled\n ) {\n console.warn(\"[raqam] Switching between controlled and uncontrolled. Pick one and keep it.\");\n }\n\n const [internalValue, setInternalValue] = useState<T | undefined>(defaultValue);\n\n const set = useCallback(\n (next: T | ((prev: T | undefined) => T)) => {\n const nextValue =\n typeof next === \"function\"\n ? (next as (prev: T | undefined) => T)(isControlled ? value : internalValue)\n : next;\n\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [isControlled, value, internalValue, onChange]\n );\n\n return [isControlled ? value : internalValue, set];\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { createFormatter, resolveEffectiveFractions } from \"../core/formatter.js\";\nimport { createParser } from \"../core/parser.js\";\nimport type { ChangeReason, NumberFieldState, UseNumberFieldStateOptions } from \"../core/types.js\";\nimport { useControllableState } from \"./useControllableState.js\";\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction clamp(value: number, min?: number, max?: number): number {\n let v = value;\n // Ignore non-finite bounds (NaN/Infinity) — Math.max/Math.min would otherwise\n // return NaN and poison the committed value.\n if (min !== undefined && Number.isFinite(min)) v = Math.max(v, min);\n if (max !== undefined && Number.isFinite(max)) v = Math.min(v, max);\n return v;\n}\n\nfunction preciseAdd(a: number, b: number): number {\n // Float precision fix — avoids 0.1 + 0.2 = 0.30000000000000004. The scaling\n // trick is only valid while the scaled operands stay within Number.MAX_SAFE_\n // INTEGER (2^53). Fall back to plain addition when scaling would be unsafe:\n // - precision > 15: the operands can't be represented at that scale; capping\n // instead would round a tiny addend (e.g. 1e-20) to 0, dropping the step.\n // - scaled operand exceeds MAX_SAFE_INTEGER: rounding can drop the step or\n // move the value backwards.\n const precision = Math.max(decimalPlaces(a), decimalPlaces(b));\n if (precision > 15) return a + b;\n const factor = 10 ** precision;\n const sa = a * factor;\n const sb = b * factor;\n if (!Number.isSafeInteger(Math.round(sa)) || !Number.isSafeInteger(Math.round(sb))) {\n return a + b;\n }\n return Math.round(sa + sb) / factor;\n}\n\nfunction decimalPlaces(n: number): number {\n if (!Number.isFinite(n)) return 0;\n const s = String(n);\n // Exponential form (e.g. \"1e-7\", \"1.5e-7\") — String() uses it below 1e-6.\n const eIdx = s.indexOf(\"e\");\n if (eIdx !== -1) {\n const exp = Number(s.slice(eIdx + 1));\n const dotIdx = s.indexOf(\".\");\n const fracLen = dotIdx === -1 ? 0 : eIdx - dotIdx - 1;\n return Math.max(0, fracLen - exp);\n }\n const idx = s.indexOf(\".\");\n return idx === -1 ? 0 : s.length - idx - 1;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────────────────\n\nexport function useNumberFieldState(options: UseNumberFieldStateOptions): NumberFieldState {\n const {\n locale,\n formatOptions,\n minValue: rawMinValue,\n maxValue: rawMaxValue,\n step: rawStep = 1,\n largeStep: rawLargeStep,\n smallStep: rawSmallStep,\n allowNegative = true,\n allowDecimal = true,\n maximumFractionDigits,\n minimumFractionDigits,\n fixedDecimalScale,\n clampBehavior = \"blur\",\n prefix,\n suffix,\n allowOutOfRange = false,\n validate,\n onRawChange,\n formatValue: customFormatValue,\n } = options;\n\n // Sanitize numeric config. A non-finite/non-positive step would emit NaN or\n // Infinity through increment/decrement (or dead-end stepping for 0), and\n // non-finite bounds would poison clamp and the committed value. Drop bad\n // values to safe defaults / undefined.\n const step = Number.isFinite(rawStep) && rawStep > 0 ? rawStep : 1;\n const minValue = Number.isFinite(rawMinValue) ? rawMinValue : undefined;\n const maxValue = Number.isFinite(rawMaxValue) ? rawMaxValue : undefined;\n\n // When decimals are disallowed, fraction padding/scale is forced to 0 so\n // currency / fixedDecimalScale never pad \".00\" (which the dot-strip would then\n // re-read, exploding the value). Shared with useNumberField via one helper so\n // the editable and on-commit displays can never drift apart.\n const { effMinFrac, effMaxFrac, effFixedScale } = resolveEffectiveFractions({\n allowDecimal,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n });\n\n // Serialize formatOptions once per render — it feeds two useMemo dependency\n // arrays and the runtime-reformat key below, and JSON.stringify is not free\n // for non-trivial option objects.\n const formatOptionsKey = JSON.stringify(formatOptions ?? {});\n\n // ── Formatter & parser (re-created only when deps change) ──────────────────\n const formatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: effMinFrac,\n maximumFractionDigits: effMaxFrac,\n fixedDecimalScale: effFixedScale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, prefix, suffix, effMinFrac, effMaxFrac, effFixedScale]\n );\n\n const parser = useMemo(\n () =>\n createParser({\n locale,\n formatOptions,\n allowNegative,\n allowDecimal,\n prefix,\n suffix,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, allowNegative, allowDecimal, prefix, suffix]\n );\n\n // ── Controlled/uncontrolled numeric value ──────────────────────────────────\n const [numberValue, setNumberValue] = useControllableState<number | null>({\n value: options.value,\n defaultValue: options.defaultValue ?? null,\n onChange: options.onChange,\n });\n\n // Last numeric value we emitted ourselves — used to tell our own onChange echo\n // apart from a genuine external controlled-value change (see sync block below).\n const lastEmittedRef = useRef<number | null | undefined>(\n options.value ?? options.defaultValue ?? null\n );\n\n // ── Display string ─────────────────────────────────────────────────────────\n // Stored in local state — can transiently diverge from numberValue\n // (e.g. while typing \"1.\" which isn't a valid JS number yet)\n const formatDisplay = useCallback(\n (n: number): string =>\n // Normalise -0 so it never renders as \"-0\" on any path (mount included).\n customFormatValue\n ? customFormatValue(Object.is(n, -0) ? 0 : n)\n : formatter.format(Object.is(n, -0) ? 0 : n),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [formatter, customFormatValue]\n );\n\n const initialDisplay = useMemo(() => {\n if (options.defaultValue != null) {\n return formatDisplay(options.defaultValue);\n }\n if (options.value != null) {\n return formatDisplay(options.value);\n }\n return \"\";\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Only on mount\n\n const [inputValue, setInputValueRaw] = useState<string>(initialDisplay);\n\n // Mirror of the display string, updated SYNCHRONOUSLY before each setNumberValue\n // (which fires onChange). `inputValue` state only reflects the *previous* render\n // at onChange time, so consumers reading the formatted value via onValueChange\n // must read this ref to get the value that matches the just-emitted number.\n const latestDisplayRef = useRef<string>(initialDisplay);\n const _getLatestDisplay = useCallback((): string => latestDisplayRef.current, []);\n\n // Track last formatted value so we can sync controlled value changes\n const lastFormattedRef = useRef<string>(initialDisplay);\n\n // ── Raw value (precision-preserving string) ────────────────────────────────\n const [rawValue, setRawValueState] = useState<string | null>(\n options.defaultValue != null ? String(options.defaultValue) : null\n );\n\n // ── Validation state ───────────────────────────────────────────────────────\n const runValidation = useCallback(\n (\n val: number | null\n ): { validationState: \"valid\" | \"invalid\"; validationError: string | null } => {\n if (!validate) return { validationState: \"valid\", validationError: null };\n const result = validate(val);\n if (result === false) return { validationState: \"invalid\", validationError: null };\n if (typeof result === \"string\")\n return { validationState: \"invalid\", validationError: result };\n return { validationState: \"valid\", validationError: null };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [validate]\n );\n\n const initialValidation = useMemo(() => {\n const initVal = options.defaultValue ?? options.value ?? null;\n return runValidation(initVal != null ? initVal : null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Only on mount\n\n const [validationState, setValidationState] = useState<\"valid\" | \"invalid\">(\n initialValidation.validationState\n );\n const [validationError, setValidationError] = useState<string | null>(\n initialValidation.validationError\n );\n\n // ── isScrubbing / isFocused state ──────────────────────────────────────────\n const [isScrubbing, setIsScrubbing] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n // ── Change reason ref (no re-render needed) ────────────────────────────────\n const lastChangeReasonRef = useRef<ChangeReason>(\"input\");\n const _setLastChangeReason = useCallback((reason: ChangeReason) => {\n lastChangeReasonRef.current = reason;\n }, []);\n\n const _getLastChangeReason = useCallback((): ChangeReason => {\n return lastChangeReasonRef.current;\n }, []);\n\n // ── Sync controlled value → display string when value changes externally ───\n // We must distinguish a *genuine* external change (parent set a new value,\n // form reset/prefill, etc.) from the echo of our own onChange. `lastEmittedRef`\n // tracks the value we last emitted; if the incoming controlled value differs\n // from it, the change came from outside and the display must be re-synced.\n const externalValue = options.value;\n const prevExternalValueRef = useRef(externalValue);\n // Object.is (not !==) so a controlled value of NaN compares equal to itself\n // and never triggers an unconditional render-phase setState → infinite loop.\n if (!Object.is(prevExternalValueRef.current, externalValue)) {\n prevExternalValueRef.current = externalValue;\n if (!Object.is(externalValue, lastEmittedRef.current)) {\n lastEmittedRef.current = externalValue;\n // Normalise -0 so a controlled value of -0 displays as \"0\", matching the\n // typed and commit paths.\n const ev = Object.is(externalValue, -0) ? 0 : externalValue;\n const finite = ev != null && Number.isFinite(ev);\n const formatted = finite ? formatDisplay(ev as number) : \"\";\n lastFormattedRef.current = formatted;\n latestDisplayRef.current = formatted;\n setInputValueRaw(formatted);\n setRawValueState(finite ? String(ev) : null);\n }\n }\n\n // ── Reformat the display when locale / formatOptions change at runtime ──────\n // When the field is not being actively edited, a locale or format change must\n // re-render the existing value in the new format (e.g. switching en-US → de-DE).\n const formatKey = `${locale ?? \"\"}|${formatOptionsKey}|${prefix ?? \"\"}|${suffix ?? \"\"}|${effMinFrac ?? \"\"}|${effMaxFrac ?? \"\"}|${effFixedScale ?? \"\"}`;\n const prevFormatKeyRef = useRef(formatKey);\n if (prevFormatKeyRef.current !== formatKey) {\n prevFormatKeyRef.current = formatKey;\n if (numberValue != null && Number.isFinite(numberValue) && !isFocused) {\n const formatted = formatDisplay(numberValue);\n if (formatted !== inputValue) {\n setInputValueRaw(formatted);\n lastFormattedRef.current = formatted;\n latestDisplayRef.current = formatted;\n }\n }\n }\n\n // ── Internal helper: apply validation after a value change ────────────────\n const applyValidation = useCallback(\n (val: number | null) => {\n const { validationState: vs, validationError: ve } = runValidation(val);\n setValidationState(vs);\n setValidationError(ve);\n },\n [runValidation]\n );\n\n // ── setInputValue ──────────────────────────────────────────────────────────\n // `knownValue` lets the caller supply the exact numeric value when `val` is a\n // formatted string the parser cannot faithfully reverse (compact \"2.5K\",\n // scientific, unit). Without it, the value is derived by parsing `val`.\n const setInputValue = useCallback(\n (val: string, knownValue?: number | null) => {\n const parsed = parser.parse(val);\n const value = knownValue !== undefined ? knownValue : parsed.value;\n\n // Strict clamping: reject input that goes out of range (skipped when allowOutOfRange)\n if (clampBehavior === \"strict\" && !allowOutOfRange && value !== null) {\n if (minValue !== undefined && value < minValue) return;\n if (maxValue !== undefined && value > maxValue) return;\n }\n\n latestDisplayRef.current = val;\n setInputValueRaw(val);\n lastEmittedRef.current = value;\n setNumberValue(value);\n\n // rawValue is the *unformatted*, precision-preserving string — not the\n // grouped / currency-decorated display. Prefer the affordance-stripped form\n // (digits + \".\" + sign, trailing zeros intact) since it keeps the exact\n // digits the user typed — but only when it numerically denotes `value`.\n // strip() is NOT the inverse of parse() for rescaling styles (percent\n // divides typed digits by 100: \"50%\" strips to \"50\" but means 0.5) or for\n // non-invertible notation (compact \"2.5K\", scientific, unit, custom\n // formatters); there, fall back to the canonical numeric string.\n let raw: string | null = null;\n if (value !== null) {\n const stripped = parser.strip(val);\n if (/\\d/.test(stripped) && Number(stripped) === value) {\n // `value` is -0-normalized everywhere, so never surface a \"-0\" raw.\n raw = value === 0 && stripped.startsWith(\"-\") ? stripped.slice(1) : stripped;\n } else {\n raw = String(value);\n }\n }\n setRawValueState(raw);\n onRawChange?.(raw);\n applyValidation(value);\n },\n [\n parser,\n clampBehavior,\n allowOutOfRange,\n minValue,\n maxValue,\n setNumberValue,\n onRawChange,\n applyValidation,\n ]\n );\n\n // ── setNumberValue (external) ──────────────────────────────────────────────\n const setNumericValue = useCallback(\n (rawVal: number | null) => {\n // Never emit a non-finite value (NaN/Infinity) to onChange/ARIA/forms —\n // treat it as empty. A catch-all behind the config sanitization above.\n const val = rawVal !== null && !Number.isFinite(rawVal) ? null : rawVal;\n // Compute the display and update latestDisplayRef BEFORE setNumberValue, so\n // the onChange it triggers reports the matching formatted value (not the\n // previous render's).\n const formatted = val != null ? formatDisplay(val) : \"\";\n latestDisplayRef.current = formatted;\n lastEmittedRef.current = val;\n setNumberValue(val);\n setInputValueRaw(formatted);\n lastFormattedRef.current = formatted;\n if (val != null) {\n const rawStr = String(val);\n setRawValueState(rawStr);\n onRawChange?.(rawStr);\n } else {\n setRawValueState(null);\n onRawChange?.(null);\n }\n applyValidation(val);\n },\n [formatDisplay, setNumberValue, onRawChange, applyValidation]\n );\n\n // ── commit (called on blur) ────────────────────────────────────────────────\n const commit = useCallback((): number | null => {\n // Treat empty AND non-finite (NaN/Infinity from a bad controlled/default\n // value) as empty on commit, so blur/Enter never returns or emits a\n // non-finite value even though the field renders empty.\n if (numberValue == null || !Number.isFinite(numberValue)) {\n latestDisplayRef.current = \"\";\n setInputValueRaw(\"\");\n lastFormattedRef.current = \"\";\n return null;\n }\n\n let clamped = numberValue;\n // Clamp on blur, unless allowOutOfRange is true\n if (clampBehavior === \"blur\" && !allowOutOfRange) {\n clamped = clamp(numberValue, minValue, maxValue);\n }\n // Normalise negative zero so \"-0\" commits as plain \"0\"\n if (Object.is(clamped, -0)) clamped = 0;\n\n const formatted = formatDisplay(clamped);\n latestDisplayRef.current = formatted;\n setInputValueRaw(formatted);\n lastFormattedRef.current = formatted;\n\n // Round the committed value to the displayed precision so the numeric value\n // never diverges from what is shown (e.g. a percent field that rounds the\n // live-typed fraction down to its configured scale on blur). Only adopt the\n // reparsed value when it round-trips exactly back to `formatted` — this skips\n // non-invertible notations (compact \"2.5K\", scientific, unit) and any custom\n // formatter whose output the parser cannot faithfully reverse.\n let committed = clamped;\n if (!customFormatValue) {\n const reparsed = parser.parse(formatted).value;\n if (reparsed !== null && Number.isFinite(reparsed) && formatDisplay(reparsed) === formatted) {\n committed = reparsed;\n }\n }\n\n if (committed !== numberValue) {\n lastEmittedRef.current = committed;\n setNumberValue(committed);\n }\n applyValidation(committed);\n return committed;\n }, [\n numberValue,\n clampBehavior,\n allowOutOfRange,\n minValue,\n maxValue,\n parser,\n formatDisplay,\n customFormatValue,\n setNumberValue,\n applyValidation,\n ]);\n\n // Treat a non-finite value (NaN/Infinity from a bad default/controlled value)\n // as empty so it never reaches ARIA, the hidden form input, or arithmetic.\n const safeNumberValue = numberValue != null && Number.isFinite(numberValue) ? numberValue : null;\n\n // ── Step computation ───────────────────────────────────────────────────────\n const resolvedLargeStep =\n Number.isFinite(rawLargeStep) && (rawLargeStep as number) > 0\n ? (rawLargeStep as number)\n : step * 10;\n const resolvedSmallStep =\n Number.isFinite(rawSmallStep) && (rawSmallStep as number) > 0\n ? (rawSmallStep as number)\n : step * 0.1;\n\n const canIncrement =\n !options.disabled &&\n !options.readOnly &&\n (allowOutOfRange ||\n maxValue === undefined ||\n (safeNumberValue ?? Number.NEGATIVE_INFINITY) < maxValue);\n\n const canDecrement =\n !options.disabled &&\n !options.readOnly &&\n (allowOutOfRange ||\n minValue === undefined ||\n (safeNumberValue ?? Number.POSITIVE_INFINITY) > minValue);\n\n const increment = useCallback(\n (amount?: number) => {\n const s = amount ?? step;\n const base = safeNumberValue ?? 0;\n const raw = preciseAdd(base, s);\n const next = allowOutOfRange ? raw : clamp(raw, minValue, maxValue);\n setNumericValue(next);\n },\n [safeNumberValue, step, minValue, maxValue, allowOutOfRange, setNumericValue]\n );\n\n const decrement = useCallback(\n (amount?: number) => {\n const s = amount ?? step;\n const base = safeNumberValue ?? 0;\n const raw = preciseAdd(base, -s);\n const next = allowOutOfRange ? raw : clamp(raw, minValue, maxValue);\n setNumericValue(next);\n },\n [safeNumberValue, step, minValue, maxValue, allowOutOfRange, setNumericValue]\n );\n\n const incrementToMax = useCallback(() => {\n if (maxValue !== undefined) setNumericValue(maxValue);\n }, [maxValue, setNumericValue]);\n\n const decrementToMin = useCallback(() => {\n if (minValue !== undefined) setNumericValue(minValue);\n }, [minValue, setNumericValue]);\n\n return {\n inputValue,\n numberValue: safeNumberValue,\n rawValue,\n canIncrement,\n canDecrement,\n isScrubbing,\n setIsScrubbing,\n isFocused,\n setIsFocused,\n validationState,\n validationError,\n _setLastChangeReason,\n _getLastChangeReason,\n _getLatestDisplay,\n setInputValue,\n setNumberValue: setNumericValue,\n commit,\n increment,\n decrement,\n incrementToMax,\n decrementToMin,\n options: {\n ...options,\n step,\n largeStep: resolvedLargeStep,\n smallStep: resolvedSmallStep,\n // Expose the sanitized bounds so every consumer (e.g. useScrubArea's\n // aria-valuemin/max) sees cleaned values, not raw NaN/Infinity.\n minValue,\n maxValue,\n },\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { NumberFieldState, ScrubAreaOptions } from \"../core/types.js\";\n\nexport interface ScrubAreaReturn {\n /** Whether pointer lock is currently active */\n isScrubbing: boolean;\n /** Props to spread on the scrub area element */\n scrubAreaProps: {\n role: string;\n tabIndex: number;\n style: React.CSSProperties;\n \"aria-label\": string;\n \"aria-valuenow\": number | undefined;\n \"aria-valuemin\": number | undefined;\n \"aria-valuemax\": number | undefined;\n \"aria-valuetext\": string | undefined;\n \"aria-disabled\": true | undefined;\n \"data-scrubbing\": string | undefined;\n onPointerDown: (e: React.PointerEvent) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n };\n /**\n * Virtual cursor position (screen coordinates, updated by mousemove\n * during pointer lock). Use for positioning the ScrubAreaCursor.\n */\n virtualCursor: { x: number; y: number };\n}\n\n/**\n * Implements Pointer Lock API–based drag-to-scrub behavior.\n *\n * Flow:\n * 1. User presses pointer down → element requests pointer lock\n * 2. Browser hides cursor, starts delivering movementX/Y on mousemove\n * 3. Accumulated movement ÷ pixelSensitivity → increment/decrement calls\n * 4. Pointer lock exits on Escape key or programmatic exit\n */\nexport function useScrubArea(\n state: NumberFieldState,\n options: ScrubAreaOptions = {}\n): ScrubAreaReturn {\n const {\n direction = \"horizontal\",\n pixelSensitivity = 4,\n label = \"Scrub to change value\",\n } = options;\n\n const [isScrubbing, setIsScrubbingLocal] = useState(false);\n\n // Keep stable refs to avoid stale closures in event listeners\n const stateRef = useRef(state);\n stateRef.current = state;\n\n const directionRef = useRef(direction);\n directionRef.current = direction;\n\n const sensitivityRef = useRef(pixelSensitivity);\n sensitivityRef.current = pixelSensitivity;\n\n const isScrubbingRef = useRef(false);\n const accumulatorRef = useRef(0);\n const elementRef = useRef<Element | null>(null);\n const virtualCursorRef = useRef({ x: 0, y: 0 });\n const [virtualCursor, setVirtualCursor] = useState({ x: 0, y: 0 });\n\n // Stable mousemove handler (always reads latest state via refs)\n const stableMouseMove = useRef((e: MouseEvent) => {\n if (!isScrubbingRef.current) return;\n\n // Update virtual cursor\n const nx = virtualCursorRef.current.x + e.movementX;\n const ny = virtualCursorRef.current.y + e.movementY;\n virtualCursorRef.current = { x: nx, y: ny };\n setVirtualCursor({ x: nx, y: ny });\n\n // Determine delta based on direction\n const dir = directionRef.current;\n let delta = 0;\n if (dir === \"horizontal\") {\n delta = e.movementX;\n } else if (dir === \"vertical\") {\n delta = -e.movementY;\n } else {\n delta = Math.abs(e.movementX) >= Math.abs(e.movementY) ? e.movementX : -e.movementY;\n }\n\n accumulatorRef.current += delta;\n\n // Fire step when accumulated movement exceeds sensitivity. Clamp to ≥ 1px:\n // a zero or negative sensitivity would make the loops below never progress\n // (or fire millions of steps), hanging the tab.\n const sensitivity = Math.max(1, sensitivityRef.current);\n if (accumulatorRef.current >= sensitivity || accumulatorRef.current <= -sensitivity) {\n stateRef.current._setLastChangeReason(\"scrub\");\n }\n while (accumulatorRef.current >= sensitivity) {\n stateRef.current.increment();\n accumulatorRef.current -= sensitivity;\n }\n while (accumulatorRef.current <= -sensitivity) {\n stateRef.current.decrement();\n accumulatorRef.current += sensitivity;\n }\n });\n\n // Stable pointer lock change handler\n const stablePointerLockChange = useRef(() => {\n if (document.pointerLockElement === elementRef.current) {\n // Lock acquired — start scrubbing\n isScrubbingRef.current = true;\n accumulatorRef.current = 0;\n setIsScrubbingLocal(true);\n stateRef.current.setIsScrubbing(true);\n document.addEventListener(\"mousemove\", stableMouseMove.current);\n } else {\n // Lock released — stop scrubbing\n isScrubbingRef.current = false;\n accumulatorRef.current = 0;\n document.removeEventListener(\"mousemove\", stableMouseMove.current);\n setIsScrubbingLocal(false);\n stateRef.current.setIsScrubbing(false);\n }\n });\n\n // Register stable pointerlockchange listener once on mount\n useEffect(() => {\n const handler = stablePointerLockChange.current;\n document.addEventListener(\"pointerlockchange\", handler);\n return () => {\n document.removeEventListener(\"pointerlockchange\", handler);\n document.removeEventListener(\"mousemove\", stableMouseMove.current);\n // If this element still owns the pointer lock when it unmounts mid-scrub,\n // release it so the user isn't stranded with a hidden cursor / locked page.\n if (\n typeof document.exitPointerLock === \"function\" &&\n document.pointerLockElement &&\n document.pointerLockElement === elementRef.current\n ) {\n document.exitPointerLock();\n }\n // The pointerlockchange handler is already detached above, so its release\n // path won't run. Reset the shared scrubbing state here so a still-mounted\n // Root (e.g. when only the ScrubArea is conditionally unmounted) doesn't\n // keep data-scrubbing / ScrubAreaCursor stuck on.\n if (isScrubbingRef.current) {\n isScrubbingRef.current = false;\n accumulatorRef.current = 0;\n stateRef.current.setIsScrubbing(false);\n }\n };\n }, []); // Empty deps — truly stable refs, no need to re-register\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (stateRef.current.options.disabled || stateRef.current.options.readOnly) return;\n if (e.button !== 0) return;\n\n const el = e.currentTarget as HTMLElement;\n elementRef.current = el;\n virtualCursorRef.current = { x: e.clientX, y: e.clientY };\n setVirtualCursor({ x: e.clientX, y: e.clientY });\n\n // requestPointerLock() returns a promise in newer browsers and rejects\n // when the lock can't be acquired (not user-gesture-driven, already exiting,\n // etc.). Swallow it so it isn't an unhandled rejection, and reset pending\n // scrub state.\n const result = el.requestPointerLock() as unknown as Promise<void> | undefined;\n if (result && typeof result.then === \"function\") {\n result.catch(() => {\n elementRef.current = null;\n });\n }\n },\n [] // No deps — reads via refs\n );\n\n // Keyboard support: arrow keys while scrub area is focused\n const onKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (stateRef.current.options.disabled || stateRef.current.options.readOnly) return;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n stateRef.current._setLastChangeReason(\"scrub\");\n stateRef.current.increment();\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n stateRef.current._setLastChangeReason(\"scrub\");\n stateRef.current.decrement();\n }\n }, []);\n\n // Cursor CSS based on direction\n const cursorStyle =\n direction === \"horizontal\" ? \"ew-resize\" : direction === \"vertical\" ? \"ns-resize\" : \"move\";\n\n const scrubAreaProps = {\n role: \"slider\",\n tabIndex: state.options.disabled ? -1 : 0,\n style: {\n cursor: state.options.disabled ? undefined : cursorStyle,\n userSelect: \"none\" as const,\n WebkitUserSelect: \"none\" as const,\n } satisfies React.CSSProperties,\n \"aria-label\": label,\n // role=\"slider\" requires the current value (and ideally the range) to be\n // exposed, else assistive tech announces a value-less slider with no feedback\n // when the user scrubs with the arrow keys.\n \"aria-valuenow\": state.numberValue ?? undefined,\n \"aria-valuemin\": state.options.minValue,\n \"aria-valuemax\": state.options.maxValue,\n \"aria-valuetext\": state.inputValue || undefined,\n \"aria-disabled\": state.options.disabled ? (true as const) : undefined,\n \"data-scrubbing\": isScrubbing ? \"\" : undefined,\n onPointerDown,\n onKeyDown,\n };\n\n return { isScrubbing, scrubAreaProps, virtualCursor };\n}\n","\"use client\";\n\nimport React, { forwardRef, useMemo, useRef } from \"react\";\nimport type {\n NumberFieldRootProps,\n NumberFieldState,\n RenderProp,\n ScrubAreaCursorProps,\n ScrubAreaProps,\n} from \"../core/types.js\";\nimport { NumberFieldContext, useNumberFieldContext } from \"./context.js\";\nimport { useNumberField } from \"./useNumberField.js\";\nimport { useNumberFieldState } from \"./useNumberFieldState.js\";\nimport { useScrubArea } from \"./useScrubArea.js\";\n\n// ── Render prop utility ───────────────────────────────────────────────────────\n\n/**\n * Merge component props with a `render` prop.\n * Accepts either a React element or a render function.\n *\n * `forwardedRef` is threaded through explicitly because React 18 keeps `ref`\n * out of `element.props`, so a render-prop element would otherwise lose refs the\n * default element depends on — e.g. the label-registration ref carried by\n * `labelProps`. When provided, it takes precedence over the render element's own\n * `ref`; callers that need to keep a consumer ref must compose it into\n * `forwardedRef` themselves (see `<NumberField.Label>`), where it can be\n * memoized for a stable identity.\n */\nfunction renderWith(\n defaultElement: React.ReactElement,\n render: RenderProp | undefined,\n state: NumberFieldState,\n forwardedRef?: React.Ref<unknown>\n): React.ReactElement {\n if (!render) return defaultElement;\n\n const baseProps = { ...(defaultElement.props as Record<string, unknown>) };\n if (forwardedRef != null) baseProps.ref = forwardedRef;\n\n if (typeof render === \"function\") {\n return render(baseProps, state);\n }\n\n // Element form: clone with merged props.\n const merged = Object.assign({}, baseProps, render.props as Record<string, unknown>);\n if (forwardedRef != null) merged.ref = forwardedRef;\n return React.cloneElement(render, merged);\n}\n\n// ── Ref helpers ───────────────────────────────────────────────────────────────\n\n// React 19 exposes a React element's `ref` as a regular prop; React ≤18 stores\n// it on the element itself (and reading `element.ref` on React 19 logs a\n// deprecation warning), so branch on the version to read it without warnings.\n// The same version boundary marks where callback refs may return a cleanup\n// function: React 19 runs it on detach, React ≤18 ignores it (and warns).\nconst REF_IN_PROPS = Number.parseInt(React.version, 10) >= 19;\nconst SUPPORTS_REF_CLEANUP = REF_IN_PROPS;\n\nfunction getElementRef(el: React.ReactElement): React.Ref<unknown> | undefined {\n if (REF_IN_PROPS) return (el.props as { ref?: React.Ref<unknown> }).ref;\n return (el as unknown as { ref?: React.Ref<unknown> }).ref;\n}\n\n/**\n * Compose multiple refs (callback or object) into one callback ref while\n * preserving each ref's cleanup. For every ref we capture a cleanup — a function\n * ref's returned cleanup, a synthesized `ref(null)` for legacy refs, or\n * `current = null` for object refs — so consumer cleanups aren't dropped on\n * unmount or ref change.\n *\n * The two React eras differ in HOW the combined cleanup gets back to React:\n * - React 19 runs a cleanup returned from a callback ref, so we return one.\n * - React ≤18 ignores (and warns about) a returned function and instead calls\n * the ref with `null` on detach, so we stash the cleanups in a closure and run\n * them on that `null` call rather than returning a function.\n */\nfunction mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {\n const attach = (node: T | null): (() => void)[] => {\n const cleanups: (() => void)[] = [];\n for (const ref of refs) {\n if (ref == null) continue;\n if (typeof ref === \"function\") {\n const result = ref(node);\n cleanups.push(typeof result === \"function\" ? result : () => ref(null));\n } else {\n (ref as React.MutableRefObject<T | null>).current = node;\n cleanups.push(() => {\n (ref as React.MutableRefObject<T | null>).current = null;\n });\n }\n }\n return cleanups;\n };\n\n if (SUPPORTS_REF_CLEANUP) {\n return (node) => {\n const cleanups = attach(node);\n return () => {\n for (const cleanup of cleanups) cleanup();\n };\n };\n }\n\n // React ≤18: drive cleanups off the `null` detach call instead of a return.\n let cleanups: (() => void)[] = [];\n return (node) => {\n for (const cleanup of cleanups) cleanup();\n cleanups = node == null ? [] : attach(node);\n };\n}\n\n// ── Data attributes helper ────────────────────────────────────────────────────\n\nfunction stateDataAttrs(\n state: NumberFieldState,\n isInvalid: boolean\n): Record<string, string | undefined> {\n const { options } = state;\n return {\n \"data-disabled\": options.disabled ? \"\" : undefined,\n \"data-readonly\": options.readOnly ? \"\" : undefined,\n \"data-required\": options.required ? \"\" : undefined,\n \"data-scrubbing\": state.isScrubbing ? \"\" : undefined,\n \"data-focused\": state.isFocused ? \"\" : undefined,\n \"data-invalid\": isInvalid ? \"\" : undefined,\n };\n}\n\n// ── Root ──────────────────────────────────────────────────────────────────────\n\n// HTML attributes that belong on the wrapper div (not passed to state/aria hooks)\nconst DIV_ONLY_KEYS = new Set([\n \"className\",\n \"style\",\n \"id\",\n \"tabIndex\",\n \"title\",\n \"role\",\n \"aria-label\",\n \"data-testid\",\n \"onClick\",\n \"onMouseEnter\",\n \"onMouseLeave\",\n]);\n\nfunction splitProps(props: Record<string, unknown>) {\n const fieldProps: Record<string, unknown> = {};\n const divProps: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(props)) {\n if (DIV_ONLY_KEYS.has(key) || key.startsWith(\"data-\") || key.startsWith(\"aria-\")) {\n divProps[key] = val;\n } else {\n fieldProps[key] = val;\n }\n }\n return { fieldProps, divProps };\n}\n\nconst Root = forwardRef<HTMLDivElement, NumberFieldRootProps>(function NumberFieldRoot(\n { children, onValueChange, onValueCommitted, ...allProps },\n ref\n) {\n const inputRef = useRef<HTMLInputElement>(null);\n const { fieldProps, divProps } = splitProps(allProps as Record<string, unknown>);\n const props = fieldProps as Omit<\n NumberFieldRootProps,\n \"children\" | \"onValueChange\" | \"onValueCommitted\"\n >;\n\n // Keep a stable ref to onValueChange so the onChange closure never goes stale\n const onValueChangeRef = useRef(onValueChange);\n onValueChangeRef.current = onValueChange;\n\n // Keep a stable ref to the state object so onChange can read the current reason\n const stateRef = useRef<NumberFieldState | null>(null);\n\n // Wrap onChange to also fire onValueChange with the tracked reason.\n // This closure captures stateRef (stable) not state (changes each render).\n // _setLastChangeReason is called synchronously BEFORE the state mutation\n // that triggers onChange, so stateRef.current._getLastChangeReason() always\n // returns the correct reason at the time onChange fires.\n const wrappedProps = {\n ...props,\n // Forward onValueCommitted to the behavior hook, which fires it on blur/Enter.\n onValueCommitted,\n onChange: (value: number | null) => {\n props.onChange?.(value);\n if (onValueChangeRef.current && stateRef.current) {\n onValueChangeRef.current(value, {\n reason: stateRef.current._getLastChangeReason(),\n // _getLatestDisplay (not .inputValue) — at onChange time `inputValue`\n // state still holds the previous render's value; the ref is updated\n // synchronously before the emission, so it matches `value`.\n formattedValue: stateRef.current._getLatestDisplay(),\n });\n }\n },\n };\n\n const state = useNumberFieldState(wrappedProps);\n stateRef.current = state; // always keep stateRef pointing to current state\n\n const aria = useNumberField(wrappedProps, state, inputRef);\n\n // Determine if field is invalid (out-of-range or failed validate)\n const isInvalid =\n state.validationState === \"invalid\" ||\n (state.numberValue !== null &&\n ((props.minValue !== undefined && state.numberValue < props.minValue) ||\n (props.maxValue !== undefined && state.numberValue > props.maxValue)));\n\n return (\n <NumberFieldContext.Provider value={{ state, aria, inputRef, props: wrappedProps }}>\n <div\n ref={ref}\n {...(divProps as React.HTMLAttributes<HTMLDivElement>)}\n {...stateDataAttrs(state, isInvalid)}\n >\n {children}\n </div>\n </NumberFieldContext.Provider>\n );\n});\n\n// ── Label ─────────────────────────────────────────────────────────────────────\n\ninterface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Label = forwardRef<HTMLLabelElement, LabelProps>(function NumberFieldLabel(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n // labelProps carries a registration ref; merge it with the forwarded ref and,\n // for the element render-prop form, the consumer's own ref on that element, so\n // all fire (the registration is what keeps Input/Group's aria-labelledby).\n // Memoized for a stable identity so React doesn't detach/reattach (and re-run\n // ref cleanups) every render — including across the hasLabel re-render.\n const { ref: labelRef, ...labelProps } = aria.labelProps;\n const renderRef = React.isValidElement(render) ? getElementRef(render) : undefined;\n const mergedRef = useMemo(() => mergeRefs(ref, labelRef, renderRef), [ref, labelRef, renderRef]);\n const el = (\n <label ref={mergedRef} {...labelProps} {...rest}>\n {children}\n </label>\n );\n return renderWith(el, render, state, mergedRef);\n});\n\n// ── Group ─────────────────────────────────────────────────────────────────────\n\ninterface GroupProps extends React.HTMLAttributes<HTMLDivElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Group = forwardRef<HTMLDivElement, GroupProps>(function NumberFieldGroup(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n const el = (\n <div ref={ref} {...aria.groupProps} {...rest}>\n {children}\n </div>\n );\n return renderWith(el, render, state);\n});\n\n// ── Input ─────────────────────────────────────────────────────────────────────\n\ninterface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n render?: RenderProp;\n}\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(function NumberFieldInput(\n { render, ...rest },\n _ref\n) {\n const { aria, state, inputRef } = useNumberFieldContext();\n // Merge a consumer aria-describedby (passed on <Input>) with the hook's\n // auto-wired value (the mounted <Description> id) instead of letting the\n // rest-spread clobber it — otherwise putting aria-describedby on the input\n // would silently drop the description association.\n const describedBy =\n [rest[\"aria-describedby\"], aria.inputProps[\"aria-describedby\"]].filter(Boolean).join(\" \") ||\n undefined;\n const el = (\n <input\n ref={inputRef as React.RefObject<HTMLInputElement>}\n {...aria.inputProps}\n {...rest}\n aria-describedby={describedBy}\n />\n );\n return renderWith(el, render, state);\n});\n\n// ── Increment ─────────────────────────────────────────────────────────────────\n\ninterface IncrementProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Increment = forwardRef<HTMLButtonElement, IncrementProps>(function NumberFieldIncrement(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n const el = (\n <button ref={ref} {...aria.incrementButtonProps} {...rest}>\n {children ?? \"+\"}\n </button>\n );\n return renderWith(el, render, state);\n});\n\n// ── Decrement ─────────────────────────────────────────────────────────────────\n\ninterface DecrementProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Decrement = forwardRef<HTMLButtonElement, DecrementProps>(function NumberFieldDecrement(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n const el = (\n <button ref={ref} {...aria.decrementButtonProps} {...rest}>\n {children ?? \"−\"}\n </button>\n );\n return renderWith(el, render, state);\n});\n\n// ── HiddenInput ───────────────────────────────────────────────────────────────\n\nconst HiddenInput = function NumberFieldHiddenInput() {\n const { aria } = useNumberFieldContext();\n if (!aria.hiddenInputProps) return null;\n return <input {...aria.hiddenInputProps} />;\n};\n\n// ── ScrubArea ─────────────────────────────────────────────────────────────────\n\nconst ScrubArea = forwardRef<HTMLSpanElement, ScrubAreaProps>(function NumberFieldScrubArea(\n { render, children, direction = \"horizontal\", pixelSensitivity = 4, label, ...rest },\n ref\n) {\n const { state } = useNumberFieldContext();\n const { scrubAreaProps } = useScrubArea(state, { direction, pixelSensitivity, label });\n\n const el = (\n <span ref={ref} {...scrubAreaProps} {...(rest as React.HTMLAttributes<HTMLSpanElement>)}>\n {children}\n </span>\n );\n return renderWith(el, render, state);\n});\n\n// ── ScrubAreaCursor ───────────────────────────────────────────────────────────\n//\n// Renders a custom cursor element positioned at the virtual cursor location\n// during pointer lock. Use this to show a drag handle icon while scrubbing.\n// Rendered only when isScrubbing is true.\n\nconst ScrubAreaCursor = forwardRef<HTMLSpanElement, ScrubAreaCursorProps>(\n function NumberFieldScrubAreaCursor({ render, children, style, ...rest }, ref) {\n const { state } = useNumberFieldContext();\n\n if (!state.isScrubbing) return null;\n\n const el = (\n <span\n ref={ref}\n style={{\n position: \"fixed\",\n pointerEvents: \"none\",\n zIndex: 9999,\n ...style,\n }}\n {...(rest as React.HTMLAttributes<HTMLSpanElement>)}\n >\n {children}\n </span>\n );\n return renderWith(el, render, state);\n }\n);\n\n// ── Description ───────────────────────────────────────────────────────────────\n\ninterface DescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {\n children?: React.ReactNode;\n}\n\nconst Description = forwardRef<HTMLParagraphElement, DescriptionProps>(\n function NumberFieldDescription({ children, ...rest }, ref) {\n const { aria } = useNumberFieldContext();\n // descriptionProps carries a registration ref (like labelProps) so the input's\n // aria-describedby only points here while a Description is mounted. Merge it\n // with the forwarded ref so both fire.\n const { ref: descRef, ...descriptionProps } = aria.descriptionProps;\n const mergedRef = useMemo(() => mergeRefs(ref, descRef), [ref, descRef]);\n return (\n <p ref={mergedRef} {...descriptionProps} {...rest}>\n {children}\n </p>\n );\n }\n);\n\n// ── ErrorMessage ──────────────────────────────────────────────────────────────\n\ninterface ErrorMessageProps extends React.HTMLAttributes<HTMLParagraphElement> {\n children?: React.ReactNode;\n}\n\nconst ErrorMessage = forwardRef<HTMLParagraphElement, ErrorMessageProps>(\n function NumberFieldErrorMessage({ children, ...rest }, ref) {\n const { aria, state } = useNumberFieldContext();\n // If no children provided, fall back to the validation error string (if any)\n const content = children ?? state.validationError ?? null;\n if (!content) return null;\n return (\n <p ref={ref} {...aria.errorMessageProps} {...rest}>\n {content}\n </p>\n );\n }\n);\n\n// ── Formatted ─────────────────────────────────────────────────────────────────\n//\n// Read-only display of the current formatted value. Useful for showing the\n// formatted number inline without an editable input (e.g., in a data table).\n\ninterface FormattedProps extends React.HTMLAttributes<HTMLSpanElement> {\n render?: RenderProp;\n}\n\nconst Formatted = forwardRef<HTMLSpanElement, FormattedProps>(function NumberFieldFormatted(\n { render, style, ...rest },\n ref\n) {\n const { state, aria } = useNumberFieldContext();\n // The input only sets `style` for RTL locales, so its presence flags RTL.\n const isRTL = aria.inputProps.style != null;\n // Isolate the number from surrounding bidi text (and mirror the input's RTL\n // alignment + data-rtl hook) so an inline formatted value renders correctly\n // next to RTL copy instead of inheriting the wrong direction.\n const mergedStyle: React.CSSProperties = isRTL\n ? { direction: \"ltr\", textAlign: \"right\", unicodeBidi: \"plaintext\", ...style }\n : { unicodeBidi: \"isolate\", ...style };\n const el = (\n <span\n ref={ref}\n aria-hidden=\"true\"\n data-rtl={isRTL ? \"\" : undefined}\n style={mergedStyle}\n {...rest}\n >\n {state.inputValue}\n </span>\n );\n return renderWith(el, render, state);\n});\n\n// ── Namespace export ──────────────────────────────────────────────────────────\n\nexport const NumberField = {\n Root,\n Label,\n Group,\n Input,\n Increment,\n Decrement,\n HiddenInput,\n ScrubArea,\n ScrubAreaCursor,\n Description,\n ErrorMessage,\n Formatted,\n};\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { createFormatter } from \"../core/formatter.js\";\nimport type { UseNumberFieldStateOptions } from \"../core/types.js\";\n\ntype FormatOptions = Pick<\n UseNumberFieldStateOptions,\n | \"locale\"\n | \"formatOptions\"\n | \"prefix\"\n | \"suffix\"\n | \"minimumFractionDigits\"\n | \"maximumFractionDigits\"\n | \"fixedDecimalScale\"\n>;\n\n/**\n * Lightweight display-only formatting hook. Returns the formatted string for\n * a numeric value using the same Intl.NumberFormat engine as the full input.\n *\n * Use this when you need to display a formatted number in a read-only context\n * (table cells, summaries, labels) without the overhead of a full input state machine.\n *\n * @example\n * const price = useNumberFieldFormat(1234567.89, {\n * locale: 'en-US',\n * formatOptions: { style: 'currency', currency: 'USD' },\n * })\n * // price === \"$1,234,567.89\"\n *\n * @example\n * const pct = useNumberFieldFormat(0.4267, {\n * formatOptions: { style: 'percent', maximumFractionDigits: 1 },\n * })\n * // pct === \"42.7%\"\n */\nexport function useNumberFieldFormat(value: number | null, options: FormatOptions = {}): string {\n const {\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n } = options;\n\n const formatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n locale,\n JSON.stringify(formatOptions),\n prefix,\n suffix,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n ]\n );\n\n return useMemo(() => {\n if (value === null || value === undefined) return \"\";\n return formatter.format(value);\n }, [value, formatter]);\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunkZKLZ7UKZ_cjs=require('./chunk-ZKLZ7UKZ.cjs');function y(e,i){return e>="0"&&e<="9"||e===i.decimalSeparator||e===i.minusSign||e==="-"||e==="."&&i.decimalSeparator!=="."&&i.groupingSeparator!=="."}function O(e,i,r){let o=0;for(let l=0;l<i&&l<e.length;l++)y(e[l],r)&&o++;return o}function h(e,i){let r=e.length,o=new Array(r+1).fill(true);for(let l=0;l<r;l++)e[l]===i.groupingSeparator&&(o[l+1]=false);return o[0]=true,o[r]=true,o}function M(e,i,r,o,l){let s=chunkZKLZ7UKZ_cjs.b(e),u=O(s,i,o),g=e.slice(0,i),f=g.includes("-")||g.includes(o.minusSign),m=r.includes("-")||r.includes(o.minusSign);f&&!m&&(u=Math.max(0,u-1)),l==="deleteContentBackward"&&i>0&&e[i-1]===o.groupingSeparator&&(u=Math.max(0,u-1));let c=h(r,o),p=chunkZKLZ7UKZ_cjs.b(r),n=0,a=0;for(let t=0;t<p.length;t++){if(n===u){a=t;break}y(p[t],o)&&n++,a=t+1;}return u>0&&n<u&&(a=r.length),a=P(a,c),a}function P(e,i){if(i[e])return e;for(let r=e+1;r<i.length;r++)if(i[r])return r;for(let r=e-1;r>=0;r--)if(i[r])return r;return 0}var D=false;function L(e){if(typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production"){if(D)return;D=true,console.warn("[raqam] Invalid formatOptions/locale \u2014 using a safe fallback.",e);}}var V=256,b=new Map;function v(e,i){let r=`${e??""}::${JSON.stringify(i??{})}`,o=b.get(r);if(o)return b.delete(r),b.set(r,o),o;let l;try{l=new Intl.NumberFormat(e,i);}catch(s){L(s);try{l=new Intl.NumberFormat(e);}catch{l=new Intl.NumberFormat;}}if(b.set(r,l),b.size>V){let s=b.keys().next().value;s!==void 0&&b.delete(s);}return l}function j(e,i){let r=v(e,i),o=v(e,{minimumFractionDigits:1,maximumFractionDigits:1,numberingSystem:i?.numberingSystem}),l=o.formatToParts(-12345.6),s=".",u=",",g="-",f="0";for(let n of l)n.type==="decimal"&&(s=n.value),n.type==="group"&&(u=n.value),n.type==="minusSign"&&(g=n.value);for(let n of o.formatToParts(0))if(n.type==="integer"){f=n.value;break}let m=/^(ar|he|fa|ur|syc|nqo|ug|yi)/i,c=r.resolvedOptions().locale,p=m.test(c);return {decimalSeparator:s,groupingSeparator:u,minusSign:g,zero:f,isRTL:p}}function A(e){let i=e.allowDecimal??true;return {effMinFrac:i?e.minimumFractionDigits:0,effMaxFrac:i?e.maximumFractionDigits:0,effFixedScale:i?e.fixedDecimalScale:false}}function S(e){let i={...e.formatOptions};e.minimumFractionDigits!==void 0&&(i.minimumFractionDigits=e.minimumFractionDigits),e.maximumFractionDigits!==void 0&&(i.maximumFractionDigits=e.maximumFractionDigits),e.fixedDecimalScale&&e.maximumFractionDigits!==void 0&&(i.minimumFractionDigits=e.maximumFractionDigits,i.maximumFractionDigits=e.maximumFractionDigits);let r=v(e.locale,i),o=null;function l(){return o||(o=j(e.locale,i)),o}function s(f){let m=r.formatToParts(f);if(!e.prefix&&!e.suffix)return m;let c=[];return e.prefix&&c.push({type:"literal",value:e.prefix}),c.push(...m),e.suffix&&c.push({type:"literal",value:e.suffix}),c}function u(f){if(!Number.isFinite(f))return "";let m=r.format(f);return (e.prefix??"")+m+(e.suffix??"")}function g(f){let m=s(f);return {formatted:m.map(p=>p.value).join(""),parts:m}}return {format:u,formatToParts:s,getLocaleInfo:l,formatResult:g}}var E=256;function R(e,i){return i?!!(/^-0+$/.test(e)||/\.$/.test(e)||/\.\d*0$/.test(e)||/^-?\.\d+$/.test(e)):false}function _(e={}){let i=e.allowNegative??true,r=e.allowDecimal??true,o=e.formatOptions?.style==="percent",l=S({locale:e.locale,formatOptions:e.formatOptions,prefix:e.prefix,suffix:e.suffix}),s="";if(e.formatOptions?.style==="currency")try{s=l.formatToParts(1).filter(n=>n.type==="currency").map(n=>n.value).join("");}catch{s="";}let u="",g=e.formatOptions?.notation;if(g==="scientific"||g==="engineering")try{let n=chunkZKLZ7UKZ_cjs.b(l.formatToParts(1234).filter(a=>a.type==="exponentSeparator").map(a=>a.value).join(""));n&&n!=="e"&&n!=="E"&&(u=n);}catch{u="";}function f(){return l.getLocaleInfo()}function m(n){let a=f(),t=chunkZKLZ7UKZ_cjs.b(n);t=t.replace(/[--]/g,""),u&&(t=t.split(u).join("e")),s&&(t=t.split(s).join(""));let d=t.match(/^\((.+)\)$/);d&&(t=`-${d[1]}`),e.prefix&&t.startsWith(e.prefix)&&(t=t.slice(e.prefix.length)),e.suffix&&t.endsWith(e.suffix)&&(t=t.slice(0,-e.suffix.length)),a.groupingSeparator&&(t=t.split(a.groupingSeparator).join("")),a.decimalSeparator!=="."&&(t=t.split(a.decimalSeparator).join(".")),a.minusSign!=="-"&&(t=t.split(a.minusSign).join("-")),t.includes("\u2212")&&(t=t.split("\u2212").join("-"));let I=t.trim(),F=I.match(/^([+-]?(?:\d+(?:\.\d*)?|\.\d+))[eE]([+-]?\d+)(.*)$/);if(F&&!/\d/.test(F[3])&&!/^[eE+-]/.test(F[3]))return `${F[1]}e${F[2]}`;if(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)[eE]/.test(I))return I;if(t=t.replace(/[^\d.-]/g,"").trim(),t.includes("-")){let N=t.startsWith("-");t=t.replace(/-/g,""),N&&(t=`-${t}`);}return t}function c(n){if(!n||n.trim()==="")return {value:null,isValid:false,isIntermediate:false};if(n.length>E)return {value:null,isValid:false,isIntermediate:false};let a=m(n);if(a==="")return {value:null,isValid:false,isIntermediate:false};if(a==="-")return {value:null,isValid:false,isIntermediate:i};if(a==="."||a==="-.")return {value:null,isValid:false,isIntermediate:r&&(a==="."||i)};if(!i&&a.startsWith("-"))return {value:null,isValid:false,isIntermediate:false};if(!r&&a.includes("."))return {value:null,isValid:false,isIntermediate:false};if(/[eE]/.test(a)){if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)[eE][+-]?\d+$/.test(a))return {value:null,isValid:false,isIntermediate:false};let d=Number(a);return Number.isFinite(d)?!r&&!Number.isInteger(d)?{value:null,isValid:false,isIntermediate:false}:(Object.is(d,-0)&&(d=0),o&&d!==0&&(d=Number((d/100).toPrecision(15))),{value:d,isValid:true,isIntermediate:false}):{value:null,isValid:false,isIntermediate:false}}if(!/^-?\d*(?:\.\d*)?$/.test(a))return {value:null,isValid:false,isIntermediate:false};let t=Number.parseFloat(a);return Number.isFinite(t)?(Object.is(t,-0)&&(t=0),o&&t!==0&&(t=Number((t/100).toPrecision(15))),{value:t,isValid:true,isIntermediate:R(a,r)}):{value:null,isValid:false,isIntermediate:false}}function p(n){return c(n).isIntermediate}return {parse:c,isIntermediate:p,getLocaleInfo:f,strip:m}}exports.a=h;exports.b=M;exports.c=A;exports.d=S;exports.e=_;//# sourceMappingURL=chunk-PM3EDICU.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-PM3EDICU.cjs.map
|