@primereact/hooks 11.0.0-alpha.8 → 11.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +45 -0
- package/README.md +34 -0
- package/index.d.ts +9 -0
- package/index.mjs +1 -1
- package/index.mjs.map +1 -1
- package/package.json +8 -12
- package/use-controlled-state/index.mjs +1 -1
- package/use-controlled-state/index.mjs.map +1 -1
- package/use-filter/_matchers.d.ts +23 -0
- package/use-filter/index.d.ts +94 -0
- package/use-filter/index.mjs +2 -0
- package/use-filter/index.mjs.map +1 -0
- package/use-hot-key/index.d.ts +25 -0
- package/use-hot-key/index.mjs +2 -0
- package/use-hot-key/index.mjs.map +1 -0
- package/use-is-mobile/index.d.ts +18 -0
- package/use-is-mobile/index.mjs +2 -0
- package/use-is-mobile/index.mjs.map +1 -0
- package/use-local-storage/index.d.ts +56 -0
- package/use-local-storage/index.mjs +2 -0
- package/use-local-storage/index.mjs.map +1 -0
- package/use-mask/index.d.ts +96 -67
- package/use-mask/index.mjs +1 -1
- package/use-mask/index.mjs.map +1 -1
- package/use-mounted/index.d.ts +36 -0
- package/use-mounted/index.mjs +2 -0
- package/use-mounted/index.mjs.map +1 -0
- package/use-number-formatter/index.d.ts +194 -0
- package/use-number-formatter/index.mjs +2 -0
- package/use-number-formatter/index.mjs.map +1 -0
- package/use-number-formatter/index.test.d.ts +0 -0
- package/use-presence/index.d.ts +1 -2
- package/use-presence/index.mjs +1 -1
- package/use-presence/index.mjs.map +1 -1
- package/use-props/index.d.ts +16 -11
- package/use-props/index.mjs +1 -1
- package/use-props/index.mjs.map +1 -1
- package/use-queue-task/index.d.ts +1 -0
- package/use-queue-task/index.mjs +2 -0
- package/use-queue-task/index.mjs.map +1 -0
- package/use-queue-task/index.test.d.ts +0 -0
- package/use-sortable-list/index.d.ts +43 -0
- package/use-sortable-list/index.mjs +2 -0
- package/use-sortable-list/index.mjs.map +1 -0
- package/use-tree-filter/index.d.ts +52 -0
- package/use-tree-filter/index.mjs +2 -0
- package/use-tree-filter/index.mjs.map +1 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The options for the `useNumberFormatter` hook.
|
|
3
|
+
*/
|
|
4
|
+
export interface UseNumberFormatterOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The numeric value to be formatted.
|
|
7
|
+
*/
|
|
8
|
+
value?: number | string | null | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Locale to be used in formatting.
|
|
11
|
+
*/
|
|
12
|
+
locale?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The locale matching algorithm to use. Possible values are 'lookup' and 'best fit'.
|
|
15
|
+
* @default 'best fit'
|
|
16
|
+
*/
|
|
17
|
+
localeMatcher?: 'lookup' | 'best fit';
|
|
18
|
+
/**
|
|
19
|
+
* Defines the behavior of the component.
|
|
20
|
+
* @default 'decimal'
|
|
21
|
+
*/
|
|
22
|
+
mode?: 'decimal' | 'currency';
|
|
23
|
+
/**
|
|
24
|
+
* The currency to use in currency formatting (ISO 4217 currency codes).
|
|
25
|
+
*/
|
|
26
|
+
currency?: string;
|
|
27
|
+
/**
|
|
28
|
+
* How to display the currency in currency formatting.
|
|
29
|
+
*/
|
|
30
|
+
currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name';
|
|
31
|
+
/**
|
|
32
|
+
* Whether to use grouping separators, such as thousands separators.
|
|
33
|
+
* @default true
|
|
34
|
+
*/
|
|
35
|
+
useGrouping?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The minimum number of fraction digits to use.
|
|
38
|
+
*/
|
|
39
|
+
minFractionDigits?: number;
|
|
40
|
+
/**
|
|
41
|
+
* The maximum number of fraction digits to use.
|
|
42
|
+
*/
|
|
43
|
+
maxFractionDigits?: number;
|
|
44
|
+
/**
|
|
45
|
+
* How decimals should be rounded.
|
|
46
|
+
*/
|
|
47
|
+
roundingMode?: 'ceil' | 'floor' | 'expand' | 'trunc' | 'halfCeil' | 'halfFloor' | 'halfExpand' | 'halfTrunc' | 'halfEven';
|
|
48
|
+
/**
|
|
49
|
+
* Text to display before the value.
|
|
50
|
+
*/
|
|
51
|
+
prefix?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Text to display after the value.
|
|
54
|
+
*/
|
|
55
|
+
suffix?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Minimum boundary value (used to determine if minus sign is allowed).
|
|
58
|
+
*/
|
|
59
|
+
min?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Whether to format the value.
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
format?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The exposes for the `useNumberFormatter` hook.
|
|
68
|
+
*/
|
|
69
|
+
export interface UseNumberFormatterExposes {
|
|
70
|
+
/**
|
|
71
|
+
* The formatted value based on the provided value and options.
|
|
72
|
+
*/
|
|
73
|
+
formattedValue: string;
|
|
74
|
+
/**
|
|
75
|
+
* Formats a numeric value to a localized string.
|
|
76
|
+
* @param value - The value to format
|
|
77
|
+
* @returns The formatted string
|
|
78
|
+
*/
|
|
79
|
+
formatValue: (value: number | string | null | undefined) => string;
|
|
80
|
+
/**
|
|
81
|
+
* Parses a formatted string back to a numeric value.
|
|
82
|
+
* @param text - The text to parse
|
|
83
|
+
* @returns The parsed number, '-' for minus sign only, or null if invalid
|
|
84
|
+
*/
|
|
85
|
+
parseValue: (text: string) => number | string | null;
|
|
86
|
+
/**
|
|
87
|
+
* Adds two numbers with floating-point precision handling.
|
|
88
|
+
* @param base - The base number
|
|
89
|
+
* @param increment - The increment to add
|
|
90
|
+
* @returns The sum with proper precision
|
|
91
|
+
*/
|
|
92
|
+
addWithPrecision: (base: number, increment: number) => number;
|
|
93
|
+
/**
|
|
94
|
+
* Checks if the mode is decimal.
|
|
95
|
+
* @returns True if mode is 'decimal'
|
|
96
|
+
*/
|
|
97
|
+
isDecimalMode: () => boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Checks if a character is a numeral character (digit, decimal, group separator, or minus sign).
|
|
100
|
+
* @param char - The character to check
|
|
101
|
+
* @returns True if the character is a numeral character
|
|
102
|
+
*/
|
|
103
|
+
isNumeralChar: (char: string) => boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Checks if a character is a minus sign.
|
|
106
|
+
* @param char - The character to check
|
|
107
|
+
* @returns True if the character is a minus sign
|
|
108
|
+
*/
|
|
109
|
+
isMinusSign: (char: string) => boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Checks if a character is a decimal sign.
|
|
112
|
+
* @param char - The character to check
|
|
113
|
+
* @returns True if the character is a decimal sign
|
|
114
|
+
*/
|
|
115
|
+
isDecimalSign: (char: string) => boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Checks if minus sign is allowed based on min value.
|
|
118
|
+
* @returns True if minus sign is allowed
|
|
119
|
+
*/
|
|
120
|
+
allowMinusSign: () => boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Gets the decimal character indexes in a value string.
|
|
123
|
+
* @param val - The value string to analyze
|
|
124
|
+
* @returns Object with decimalCharIndex and decimalCharIndexWithoutPrefix
|
|
125
|
+
*/
|
|
126
|
+
getDecimalCharIndexes: (val: string) => {
|
|
127
|
+
decimalCharIndex: number;
|
|
128
|
+
decimalCharIndexWithoutPrefix: number;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Gets various character indexes (decimal, minus, suffix, currency) in a value string.
|
|
132
|
+
* @param val - The value string to analyze
|
|
133
|
+
* @returns Object with character indexes
|
|
134
|
+
*/
|
|
135
|
+
getCharIndexes: (val: string) => {
|
|
136
|
+
decimalCharIndex: number;
|
|
137
|
+
minusCharIndex: number;
|
|
138
|
+
suffixCharIndex: number;
|
|
139
|
+
currencyCharIndex: number;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Gets the length of decimal part in a formatted value.
|
|
143
|
+
* @param value - The formatted value string
|
|
144
|
+
* @returns The decimal length
|
|
145
|
+
*/
|
|
146
|
+
getDecimalLength: (value: string) => number;
|
|
147
|
+
/**
|
|
148
|
+
* Concatenates two value strings, handling decimal positions.
|
|
149
|
+
* @param val1 - The first value
|
|
150
|
+
* @param val2 - The second value
|
|
151
|
+
* @returns The concatenated result
|
|
152
|
+
*/
|
|
153
|
+
concatValues: (val1: string, val2: string) => string;
|
|
154
|
+
/**
|
|
155
|
+
* The group character used for thousands separator.
|
|
156
|
+
*/
|
|
157
|
+
groupChar: string | null;
|
|
158
|
+
/**
|
|
159
|
+
* The prefix character/string.
|
|
160
|
+
*/
|
|
161
|
+
prefixChar: string | null;
|
|
162
|
+
/**
|
|
163
|
+
* The suffix character/string.
|
|
164
|
+
*/
|
|
165
|
+
suffixChar: string | null;
|
|
166
|
+
/**
|
|
167
|
+
* The resolved Intl.NumberFormat options.
|
|
168
|
+
*/
|
|
169
|
+
resolvedOptions: () => Intl.ResolvedNumberFormatOptions | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* Reinitializes the parser (call when options change).
|
|
172
|
+
*/
|
|
173
|
+
constructParser: () => void;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* useNumberFormatter hook is used to format and parse numbers using Intl.NumberFormat.
|
|
177
|
+
*
|
|
178
|
+
* @param {UseNumberFormatterOptions} options - The options for the number formatter.
|
|
179
|
+
* @returns {UseNumberFormatterExposes} - The exposed methods for the number formatter.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```tsx
|
|
183
|
+
* const formatter = useNumberFormatter({
|
|
184
|
+
* value: 1234.56,
|
|
185
|
+
* locale: 'en-US',
|
|
186
|
+
* mode: 'currency',
|
|
187
|
+
* currency: 'USD'
|
|
188
|
+
* });
|
|
189
|
+
*
|
|
190
|
+
* const formatted = formatter.formatValue(1234.56); // "$1,234.56"
|
|
191
|
+
* const parsed = formatter.parseValue("$1,234.56"); // 1234.56
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export declare function useNumberFormatter(options?: UseNumberFormatterOptions): UseNumberFormatterExposes;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var ar=Object.defineProperty,lr=Object.defineProperties;var or=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var mr=Object.prototype.hasOwnProperty,fr=Object.prototype.propertyIsEnumerable;var T=(o,a,t)=>a in o?ar(o,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[a]=t,k=(o,a)=>{for(var t in a||(a={}))mr.call(a,t)&&T(o,t,a[t]);if(L)for(var t of L(a))fr.call(a,t)&&T(o,t,a[t]);return o},A=(o,a)=>lr(o,or(a));import*as i from"react";function pr(o={}){let{value:a,locale:t,localeMatcher:G,mode:x="decimal",currency:g,currencyDisplay:h,useGrouping:_=!0,minFractionDigits:C,maxFractionDigits:E,roundingMode:F,prefix:b,suffix:R,min:S,format:q=!0}=o,O=i.useRef(null),V=i.useRef(null),w=i.useRef(null),I=i.useRef(null),l=i.useRef(null),p=i.useRef(null),s=i.useRef(null),d=i.useRef(null),c=i.useRef(null),m=i.useRef(null),y=i.useRef(null),D=i.useRef(null),P=()=>({localeMatcher:G,style:x,currency:g,currencyDisplay:h,useGrouping:_,minimumFractionDigits:C!=null?C:void 0,maximumFractionDigits:E!=null?E:void 0,roundingMode:F}),N=r=>r.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),z=()=>{var e,n;let r=new Intl.NumberFormat(t,A(k({},P()),{useGrouping:!1}));return new RegExp(`[${r.format(1.1).replace((e=d.current)!=null?e:"","").trim().replace((n=l.current)!=null?n:"","")}]`,"g")},B=()=>{var e;let r=new Intl.NumberFormat(t,{useGrouping:!0});return V.current=r.format(1e6).trim().replace((e=l.current)!=null?e:"","").charAt(0),new RegExp(`[${V.current}]`,"g")},H=()=>{var e;let r=new Intl.NumberFormat(t,{useGrouping:!1});return new RegExp(`[${r.format(-1).trim().replace((e=l.current)!=null?e:"","")}]`,"g")},J=()=>{var r,e;if(g){let n=new Intl.NumberFormat(t,{style:"currency",currency:g,currencyDisplay:h,minimumFractionDigits:0,maximumFractionDigits:0,roundingMode:F});return new RegExp(`[${n.format(1).replace(/\s/g,"").replace((r=l.current)!=null?r:"","").replace((e=p.current)!=null?e:"","")}]`,"g")}return new RegExp("[]","g")},K=()=>{if(b)y.current=new RegExp(N(b),"g");else{let e=new Intl.NumberFormat(t,{style:x,currency:g,currencyDisplay:h}).format(1).split("1")[0];y.current=new RegExp(N(e),"g")}return y.current},Q=()=>{if(R)m.current=new RegExp(N(R),"g");else{let e=new Intl.NumberFormat(t,{style:x,currency:g,currencyDisplay:h,minimumFractionDigits:0,maximumFractionDigits:0,roundingMode:F}).format(1).split("1")[1];m.current=new RegExp(N(e),"g")}return m.current},U=()=>{O.current=new Intl.NumberFormat(t,P());let r=[...new Intl.NumberFormat(t,{useGrouping:!1}).format(9876543210)].reverse(),e=new Map(r.map((n,u)=>[n,u]));if(l.current=new RegExp(`[${r.join("")}]`,"g"),p.current=B(),s.current=H(),d.current=J(),c.current=z(),m.current=Q(),y.current=K(),D.current=n=>e.get(n),b)w.current=b;else{let n=new Intl.NumberFormat(t,{style:x,currency:g,currencyDisplay:h});w.current=n.format(1).split("1")[0]}if(R)I.current=R;else{let n=new Intl.NumberFormat(t,{style:x,currency:g,currencyDisplay:h,minimumFractionDigits:0,maximumFractionDigits:0,roundingMode:F});I.current=n.format(1).split("1")[1]}},W=r=>{if(r!=null){if(typeof r=="string"&&r==="-")return r;if(q){let e=new Intl.NumberFormat(t,P()),n=typeof r=="string"?Number(r):r,u=e.format(n);return b&&(u=b+u),R&&(u=u+R),u}return r.toString()}return""},X=r=>{var n;let e=r.replace(m.current||"","").replace(y.current||"","").trim().replace(/\s/g,"").replace(d.current||"","");if(c.current&&s.current&&l.current){let u=new RegExp(`[${[...new Intl.NumberFormat(t,{useGrouping:!1}).format(9876543210)].reverse().join("")}${new Intl.NumberFormat(t).format(1.1).replace(/[0-9]/g,"")}${new Intl.NumberFormat(t).format(-1).replace(/[0-9]/g,"")}]`,"g");e=((n=e.match(u))==null?void 0:n.join(""))||""}if(p.current&&(e=e.replace(p.current,"")),s.current&&(e=e.replace(s.current,"-")),c.current&&(e=e.replace(c.current,".")),l.current&&D.current&&(e=e.replace(l.current,u=>{let f=D.current?D.current(u):void 0;return f!==void 0?f.toString():""})),e){if(e==="-")return e;let u=+e;return isNaN(u)?null:u}return null},Y=(r,e)=>{let n=r.toString(),u=e.toString(),f=n.includes(".")?n.split(".")[1].length:0,$=u.includes(".")?u.split(".")[1].length:0,M=Math.max(f,$),j=Math.pow(10,M);return Math.round((r+e)*j)/j},Z=()=>x==="decimal",v=()=>{l.current&&(l.current.lastIndex=0),c.current&&(c.current.lastIndex=0),p.current&&(p.current.lastIndex=0),s.current&&(s.current.lastIndex=0)},rr=r=>r.length===1&&(l.current&&l.current.test(r)||c.current&&c.current.test(r)||p.current&&p.current.test(r)||s.current&&s.current.test(r))?(v(),!0):!1,er=r=>s.current&&s.current.test(r)||r==="-"?(s.current&&(s.current.lastIndex=0),!0):!1,nr=r=>t!=null&&t.includes("fr")&&[".",","].includes(r)||c.current&&c.current.test(r)?(c.current&&(c.current.lastIndex=0),!0):!1,tr=()=>S==null||S<0,ur=r=>{let e=c.current?r.search(c.current):-1;c.current&&(c.current.lastIndex=0);let n=r.replace(y.current||"","").trim().replace(/\s/g,"").replace(d.current||"",""),u=c.current?n.search(c.current):-1;return c.current&&(c.current.lastIndex=0),{decimalCharIndex:e,decimalCharIndexWithoutPrefix:u}},cr=r=>{let e=M=>{M&&(M.lastIndex=0)},n=c.current?r.search(c.current):-1;e(c.current);let u=s.current?r.search(s.current):-1;e(s.current);let f=m.current?r.search(m.current):-1;e(m.current);let $=d.current?r.search(d.current):-1;return e(d.current),{decimalCharIndex:n,minusCharIndex:u,suffixCharIndex:f,currencyCharIndex:$}},sr=r=>{var e,n,u;if(r){let f=r.split((e=c.current)!=null?e:"");if(f.length===2)return f[1].replace((n=m.current)!=null?n:"","").trim().replace(/\s/g,"").replace((u=d.current)!=null?u:"","").length}return 0},ir=(r,e)=>{if(r&&e){let n=c.current,u=n?e.search(n):-1;if(n&&(n.lastIndex=0),I.current)return u!==-1?r.replace(I.current,"").split(n!=null?n:"")[0]+e.replace(I.current,"").slice(u)+I.current:r;if(w.current)return u!==-1?r.split(n!=null?n:"")[0]+e.slice(u):r}return r};return i.useEffect(()=>{U()},[t,G,x,g,h,_,C,E,F,b,R]),{formattedValue:W(a),formatValue:W,parseValue:X,addWithPrecision:Y,isDecimalMode:Z,isNumeralChar:rr,isMinusSign:er,isDecimalSign:nr,allowMinusSign:tr,getDecimalCharIndexes:ur,getCharIndexes:cr,getDecimalLength:sr,concatValues:ir,groupChar:V.current,prefixChar:w.current,suffixChar:I.current,resolvedOptions:()=>{var r;return(r=O.current)==null?void 0:r.resolvedOptions()},constructParser:U}}export{pr as useNumberFormatter};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/use-number-formatter/index.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * The options for the `useNumberFormatter` hook.\n */\nexport interface UseNumberFormatterOptions {\n /**\n * The numeric value to be formatted.\n */\n value?: number | string | null | undefined;\n /**\n * Locale to be used in formatting.\n */\n locale?: string;\n /**\n * The locale matching algorithm to use. Possible values are 'lookup' and 'best fit'.\n * @default 'best fit'\n */\n localeMatcher?: 'lookup' | 'best fit';\n /**\n * Defines the behavior of the component.\n * @default 'decimal'\n */\n mode?: 'decimal' | 'currency';\n /**\n * The currency to use in currency formatting (ISO 4217 currency codes).\n */\n currency?: string;\n /**\n * How to display the currency in currency formatting.\n */\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name';\n /**\n * Whether to use grouping separators, such as thousands separators.\n * @default true\n */\n useGrouping?: boolean;\n /**\n * The minimum number of fraction digits to use.\n */\n minFractionDigits?: number;\n /**\n * The maximum number of fraction digits to use.\n */\n maxFractionDigits?: number;\n /**\n * How decimals should be rounded.\n */\n roundingMode?: 'ceil' | 'floor' | 'expand' | 'trunc' | 'halfCeil' | 'halfFloor' | 'halfExpand' | 'halfTrunc' | 'halfEven';\n /**\n * Text to display before the value.\n */\n prefix?: string;\n /**\n * Text to display after the value.\n */\n suffix?: string;\n /**\n * Minimum boundary value (used to determine if minus sign is allowed).\n */\n min?: number;\n /**\n * Whether to format the value.\n * @default true\n */\n format?: boolean;\n}\n\n/**\n * The exposes for the `useNumberFormatter` hook.\n */\nexport interface UseNumberFormatterExposes {\n /**\n * The formatted value based on the provided value and options.\n */\n formattedValue: string;\n /**\n * Formats a numeric value to a localized string.\n * @param value - The value to format\n * @returns The formatted string\n */\n formatValue: (value: number | string | null | undefined) => string;\n /**\n * Parses a formatted string back to a numeric value.\n * @param text - The text to parse\n * @returns The parsed number, '-' for minus sign only, or null if invalid\n */\n parseValue: (text: string) => number | string | null;\n /**\n * Adds two numbers with floating-point precision handling.\n * @param base - The base number\n * @param increment - The increment to add\n * @returns The sum with proper precision\n */\n addWithPrecision: (base: number, increment: number) => number;\n /**\n * Checks if the mode is decimal.\n * @returns True if mode is 'decimal'\n */\n isDecimalMode: () => boolean;\n /**\n * Checks if a character is a numeral character (digit, decimal, group separator, or minus sign).\n * @param char - The character to check\n * @returns True if the character is a numeral character\n */\n isNumeralChar: (char: string) => boolean;\n /**\n * Checks if a character is a minus sign.\n * @param char - The character to check\n * @returns True if the character is a minus sign\n */\n isMinusSign: (char: string) => boolean;\n /**\n * Checks if a character is a decimal sign.\n * @param char - The character to check\n * @returns True if the character is a decimal sign\n */\n isDecimalSign: (char: string) => boolean;\n /**\n * Checks if minus sign is allowed based on min value.\n * @returns True if minus sign is allowed\n */\n allowMinusSign: () => boolean;\n /**\n * Gets the decimal character indexes in a value string.\n * @param val - The value string to analyze\n * @returns Object with decimalCharIndex and decimalCharIndexWithoutPrefix\n */\n getDecimalCharIndexes: (val: string) => { decimalCharIndex: number; decimalCharIndexWithoutPrefix: number };\n /**\n * Gets various character indexes (decimal, minus, suffix, currency) in a value string.\n * @param val - The value string to analyze\n * @returns Object with character indexes\n */\n getCharIndexes: (val: string) => { decimalCharIndex: number; minusCharIndex: number; suffixCharIndex: number; currencyCharIndex: number };\n /**\n * Gets the length of decimal part in a formatted value.\n * @param value - The formatted value string\n * @returns The decimal length\n */\n getDecimalLength: (value: string) => number;\n /**\n * Concatenates two value strings, handling decimal positions.\n * @param val1 - The first value\n * @param val2 - The second value\n * @returns The concatenated result\n */\n concatValues: (val1: string, val2: string) => string;\n /**\n * The group character used for thousands separator.\n */\n groupChar: string | null;\n /**\n * The prefix character/string.\n */\n prefixChar: string | null;\n /**\n * The suffix character/string.\n */\n suffixChar: string | null;\n /**\n * The resolved Intl.NumberFormat options.\n */\n resolvedOptions: () => Intl.ResolvedNumberFormatOptions | undefined;\n /**\n * Reinitializes the parser (call when options change).\n */\n constructParser: () => void;\n}\n\n/**\n * useNumberFormatter hook is used to format and parse numbers using Intl.NumberFormat.\n *\n * @param {UseNumberFormatterOptions} options - The options for the number formatter.\n * @returns {UseNumberFormatterExposes} - The exposed methods for the number formatter.\n *\n * @example\n * ```tsx\n * const formatter = useNumberFormatter({\n * value: 1234.56,\n * locale: 'en-US',\n * mode: 'currency',\n * currency: 'USD'\n * });\n *\n * const formatted = formatter.formatValue(1234.56); // \"$1,234.56\"\n * const parsed = formatter.parseValue(\"$1,234.56\"); // 1234.56\n * ```\n */\nexport function useNumberFormatter(options: UseNumberFormatterOptions = {}): UseNumberFormatterExposes {\n const { value, locale, localeMatcher, mode = 'decimal', currency, currencyDisplay, useGrouping = true, minFractionDigits, maxFractionDigits, roundingMode, prefix, suffix, min, format = true } = options;\n\n // Internal refs for regex patterns\n const numberFormat = React.useRef<Intl.NumberFormat | null>(null);\n const groupCharRef = React.useRef<string | null>(null);\n const prefixCharRef = React.useRef<string | null>(null);\n const suffixCharRef = React.useRef<string | null>(null);\n const _numeral = React.useRef<RegExp | null>(null);\n const _group = React.useRef<RegExp | null>(null);\n const _minusSign = React.useRef<RegExp | null>(null);\n const _currency = React.useRef<RegExp | null>(null);\n const _decimal = React.useRef<RegExp | null>(null);\n const _suffix = React.useRef<RegExp | null>(null);\n const _prefix = React.useRef<RegExp | null>(null);\n const _index = React.useRef<((d: string) => number | undefined) | null>(null);\n\n const getOptions = () => {\n return {\n localeMatcher: localeMatcher,\n style: mode,\n currency: currency,\n currencyDisplay: currencyDisplay,\n useGrouping: useGrouping,\n minimumFractionDigits: minFractionDigits ?? undefined,\n maximumFractionDigits: maxFractionDigits ?? undefined,\n roundingMode: roundingMode\n };\n };\n\n const escapeRegExp = (text: string) => {\n return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\n };\n\n const getDecimalExpression = () => {\n const formatter = new Intl.NumberFormat(locale, { ...getOptions(), useGrouping: false });\n\n return new RegExp(\n `[${formatter\n .format(1.1)\n .replace(_currency.current ?? '', '')\n .trim()\n .replace(_numeral.current ?? '', '')}]`,\n 'g'\n );\n };\n\n const getGroupingExpression = () => {\n const formatter = new Intl.NumberFormat(locale, { useGrouping: true });\n\n groupCharRef.current = formatter\n .format(1000000)\n .trim()\n .replace(_numeral.current ?? '', '')\n .charAt(0);\n\n return new RegExp(`[${groupCharRef.current}]`, 'g');\n };\n\n const getMinusSignExpression = () => {\n const formatter = new Intl.NumberFormat(locale, { useGrouping: false });\n\n return new RegExp(\n `[${formatter\n .format(-1)\n .trim()\n .replace(_numeral.current ?? '', '')}]`,\n 'g'\n );\n };\n\n const getCurrencyExpression = () => {\n if (currency) {\n const formatter = new Intl.NumberFormat(locale, { style: 'currency', currency: currency, currencyDisplay: currencyDisplay, minimumFractionDigits: 0, maximumFractionDigits: 0, roundingMode: roundingMode });\n\n return new RegExp(\n `[${formatter\n .format(1)\n .replace(/\\s/g, '')\n .replace(_numeral.current ?? '', '')\n .replace(_group.current ?? '', '')}]`,\n 'g'\n );\n }\n\n return new RegExp(`[]`, 'g');\n };\n\n const getPrefixExpression = () => {\n if (prefix) {\n _prefix.current = new RegExp(escapeRegExp(prefix), 'g');\n } else {\n const formatter = new Intl.NumberFormat(locale, { style: mode, currency: currency, currencyDisplay: currencyDisplay });\n\n const prefixStr = formatter.format(1).split('1')[0];\n\n _prefix.current = new RegExp(escapeRegExp(prefixStr), 'g');\n }\n\n return _prefix.current;\n };\n\n const getSuffixExpression = () => {\n if (suffix) {\n _suffix.current = new RegExp(escapeRegExp(suffix), 'g');\n } else {\n const formatter = new Intl.NumberFormat(locale, { style: mode, currency: currency, currencyDisplay: currencyDisplay, minimumFractionDigits: 0, maximumFractionDigits: 0, roundingMode: roundingMode });\n\n const suffixStr = formatter.format(1).split('1')[1];\n\n _suffix.current = new RegExp(escapeRegExp(suffixStr), 'g');\n }\n\n return _suffix.current;\n };\n\n const constructParser = () => {\n numberFormat.current = new Intl.NumberFormat(locale, getOptions());\n const numerals = [...new Intl.NumberFormat(locale, { useGrouping: false }).format(9876543210)].reverse();\n const index = new Map(numerals.map((d, i) => [d, i]));\n\n _numeral.current = new RegExp(`[${numerals.join('')}]`, 'g');\n _group.current = getGroupingExpression();\n _minusSign.current = getMinusSignExpression();\n _currency.current = getCurrencyExpression();\n _decimal.current = getDecimalExpression();\n _suffix.current = getSuffixExpression();\n _prefix.current = getPrefixExpression();\n _index.current = (d) => index.get(d);\n\n // Set prefix and suffix chars\n if (prefix) {\n prefixCharRef.current = prefix;\n } else {\n const formatter = new Intl.NumberFormat(locale, { style: mode, currency: currency, currencyDisplay: currencyDisplay });\n\n prefixCharRef.current = formatter.format(1).split('1')[0];\n }\n\n if (suffix) {\n suffixCharRef.current = suffix;\n } else {\n const formatter = new Intl.NumberFormat(locale, { style: mode, currency: currency, currencyDisplay: currencyDisplay, minimumFractionDigits: 0, maximumFractionDigits: 0, roundingMode: roundingMode });\n\n suffixCharRef.current = formatter.format(1).split('1')[1];\n }\n };\n\n const formatValue = (value: number | string | null | undefined) => {\n if (value != null) {\n if (typeof value === 'string' && value === '-') {\n // Minus sign\n return value;\n }\n\n if (format) {\n const formatter = new Intl.NumberFormat(locale, getOptions());\n const numericValue = typeof value === 'string' ? Number(value) : value;\n let formattedValue = formatter.format(numericValue);\n\n if (prefix) {\n formattedValue = prefix + formattedValue;\n }\n\n if (suffix) {\n formattedValue = formattedValue + suffix;\n }\n\n return formattedValue;\n }\n\n return value.toString();\n }\n\n return '';\n };\n\n const parseValue = (text: string) => {\n let cleanText = text\n .replace(_suffix.current || '', '')\n .replace(_prefix.current || '', '')\n .trim()\n .replace(/\\s/g, '')\n .replace(_currency.current || '', '');\n\n if (_decimal.current && _minusSign.current && _numeral.current) {\n const validChars = new RegExp(\n `[${[...new Intl.NumberFormat(locale, { useGrouping: false }).format(9876543210)].reverse().join('')}${new Intl.NumberFormat(locale).format(1.1).replace(/[0-9]/g, '')}${new Intl.NumberFormat(locale)\n .format(-1)\n .replace(/[0-9]/g, '')}]`,\n 'g'\n );\n\n cleanText = cleanText.match(validChars)?.join('') || '';\n }\n\n if (_group.current) {\n cleanText = cleanText.replace(_group.current, '');\n }\n\n if (_minusSign.current) {\n cleanText = cleanText.replace(_minusSign.current, '-');\n }\n\n if (_decimal.current) {\n cleanText = cleanText.replace(_decimal.current, '.');\n }\n\n if (_numeral.current && _index.current) {\n cleanText = cleanText.replace(_numeral.current, (d) => {\n const res = _index.current ? _index.current(d) : undefined;\n\n return res !== undefined ? res.toString() : '';\n });\n }\n\n if (cleanText) {\n if (cleanText === '-') return cleanText;\n\n const parsedValue = +cleanText;\n\n return isNaN(parsedValue) ? null : parsedValue;\n }\n\n return null;\n };\n\n const addWithPrecision = (base: number, increment: number) => {\n const baseStr = base.toString();\n const stepStr = increment.toString();\n\n const baseDecimalPlaces = baseStr.includes('.') ? baseStr.split('.')[1].length : 0;\n const stepDecimalPlaces = stepStr.includes('.') ? stepStr.split('.')[1].length : 0;\n\n const maxDecimalPlaces = Math.max(baseDecimalPlaces, stepDecimalPlaces);\n const precision = Math.pow(10, maxDecimalPlaces);\n\n return Math.round((base + increment) * precision) / precision;\n };\n\n const isDecimalMode = () => {\n return mode === 'decimal';\n };\n\n const resetRegex = () => {\n if (_numeral.current) _numeral.current.lastIndex = 0;\n\n if (_decimal.current) _decimal.current.lastIndex = 0;\n\n if (_group.current) _group.current.lastIndex = 0;\n\n if (_minusSign.current) _minusSign.current.lastIndex = 0;\n };\n\n const isNumeralChar = (char: string) => {\n if (char.length === 1 && ((_numeral.current && _numeral.current.test(char)) || (_decimal.current && _decimal.current.test(char)) || (_group.current && _group.current.test(char)) || (_minusSign.current && _minusSign.current.test(char)))) {\n resetRegex();\n\n return true;\n }\n\n return false;\n };\n\n const isMinusSignFn = (char: string) => {\n if ((_minusSign.current && _minusSign.current.test(char)) || char === '-') {\n if (_minusSign.current) {\n _minusSign.current.lastIndex = 0;\n }\n\n return true;\n }\n\n return false;\n };\n\n const isDecimalSignFn = (char: string) => {\n if ((locale?.includes('fr') && ['.', ','].includes(char)) || (_decimal.current && _decimal.current.test(char))) {\n if (_decimal.current) {\n _decimal.current.lastIndex = 0;\n }\n\n return true;\n }\n\n return false;\n };\n\n const allowMinusSign = () => {\n return min === undefined || min === null || min < 0;\n };\n\n const getDecimalCharIndexes = (val: string) => {\n const decimalCharIndex = _decimal.current ? val.search(_decimal.current) : -1;\n\n if (_decimal.current) {\n _decimal.current.lastIndex = 0;\n }\n\n const filteredVal = val\n .replace(_prefix.current || '', '')\n .trim()\n .replace(/\\s/g, '')\n .replace(_currency.current || '', '');\n const decimalCharIndexWithoutPrefix = _decimal.current ? filteredVal.search(_decimal.current) : -1;\n\n if (_decimal.current) {\n _decimal.current.lastIndex = 0;\n }\n\n return { decimalCharIndex, decimalCharIndexWithoutPrefix };\n };\n\n const getCharIndexes = (val: string) => {\n const resetRegexLastIndex = (regex: RegExp | null) => {\n if (regex) {\n regex.lastIndex = 0;\n }\n };\n\n const decimalCharIndex = _decimal.current ? val.search(_decimal.current) : -1;\n\n resetRegexLastIndex(_decimal.current);\n\n const minusCharIndex = _minusSign.current ? val.search(_minusSign.current) : -1;\n\n resetRegexLastIndex(_minusSign.current);\n\n const suffixCharIndex = _suffix.current ? val.search(_suffix.current) : -1;\n\n resetRegexLastIndex(_suffix.current);\n\n const currencyCharIndex = _currency.current ? val.search(_currency.current) : -1;\n\n resetRegexLastIndex(_currency.current);\n\n return { decimalCharIndex, minusCharIndex, suffixCharIndex, currencyCharIndex };\n };\n\n const getDecimalLength = (value: string) => {\n if (value) {\n const valueSplit = value.split(_decimal.current ?? '');\n\n if (valueSplit.length === 2) {\n return valueSplit[1]\n .replace(_suffix.current ?? '', '')\n .trim()\n .replace(/\\s/g, '')\n .replace(_currency.current ?? '', '').length;\n }\n }\n\n return 0;\n };\n\n const concatValues = (val1: string, val2: string) => {\n if (val1 && val2) {\n const decimalRegex = _decimal.current;\n const decimalCharIndex = decimalRegex ? val2.search(decimalRegex) : -1;\n\n if (decimalRegex) {\n decimalRegex.lastIndex = 0;\n }\n\n if (suffixCharRef.current) {\n return decimalCharIndex !== -1 ? val1.replace(suffixCharRef.current, '').split(decimalRegex ?? '')[0] + val2.replace(suffixCharRef.current, '').slice(decimalCharIndex) + suffixCharRef.current : val1;\n } else if (prefixCharRef.current) {\n return decimalCharIndex !== -1 ? val1.split(decimalRegex ?? '')[0] + val2.slice(decimalCharIndex) : val1;\n }\n }\n\n return val1;\n };\n\n React.useEffect(() => {\n constructParser();\n }, [locale, localeMatcher, mode, currency, currencyDisplay, useGrouping, minFractionDigits, maxFractionDigits, roundingMode, prefix, suffix]);\n\n return {\n formattedValue: formatValue(value),\n formatValue,\n parseValue,\n addWithPrecision,\n isDecimalMode,\n isNumeralChar,\n isMinusSign: isMinusSignFn,\n isDecimalSign: isDecimalSignFn,\n allowMinusSign,\n getDecimalCharIndexes,\n getCharIndexes,\n getDecimalLength,\n concatValues,\n groupChar: groupCharRef.current,\n prefixChar: prefixCharRef.current,\n suffixChar: suffixCharRef.current,\n resolvedOptions: () => numberFormat.current?.resolvedOptions(),\n constructParser\n };\n}\n"],"mappings":"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","names":["React","useNumberFormatter","options","value","locale","localeMatcher","mode","currency","currencyDisplay","useGrouping","minFractionDigits","maxFractionDigits","roundingMode","prefix","suffix","min","format","numberFormat","groupCharRef","prefixCharRef","suffixCharRef","_numeral","_group","_minusSign","_currency","_decimal","_suffix","_prefix","_index","getOptions","escapeRegExp","text","getDecimalExpression","_a","_b","formatter","__spreadProps","__spreadValues","getGroupingExpression","getMinusSignExpression","getCurrencyExpression","getPrefixExpression","prefixStr","getSuffixExpression","suffixStr","constructParser","numerals","index","d","i","formatValue","numericValue","formattedValue","parseValue","cleanText","validChars","res","parsedValue","addWithPrecision","base","increment","baseStr","stepStr","baseDecimalPlaces","stepDecimalPlaces","maxDecimalPlaces","precision","isDecimalMode","resetRegex","isNumeralChar","char","isMinusSignFn","isDecimalSignFn","allowMinusSign","getDecimalCharIndexes","val","decimalCharIndex","filteredVal","decimalCharIndexWithoutPrefix","getCharIndexes","resetRegexLastIndex","regex","minusCharIndex","suffixCharIndex","currencyCharIndex","getDecimalLength","_c","valueSplit","concatValues","val1","val2","decimalRegex"]}
|
|
File without changes
|
package/use-presence/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
/**
|
|
3
2
|
* usePresence hook is used to manage the presence of a component.
|
|
4
3
|
*
|
|
@@ -17,5 +16,5 @@ export declare function usePresence(open: boolean, fallbackMs?: number): {
|
|
|
17
16
|
present: boolean;
|
|
18
17
|
exiting: boolean;
|
|
19
18
|
mounted: boolean;
|
|
20
|
-
ref:
|
|
19
|
+
ref: (node: HTMLElement | null) => void;
|
|
21
20
|
};
|
package/use-presence/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as n from"react";function E(c,f=500){let[m,i]=n.useState(c),[d,a]=n.useState(!1),[R,l]=n.useState(!1),o=n.useRef(null),t=n.useRef(null),r=n.useRef(null),v=n.useCallback(e=>{o.current=e},[]);return n.useEffect(()=>{if(t.current&&(t.current(),t.current=null),r.current&&(r.current(),r.current=null),c){i(!0),a(!1);let e=[];e.push(requestAnimationFrame(()=>{e.push(requestAnimationFrame(()=>{e.push(requestAnimationFrame(()=>l(!0)))}))})),r.current=()=>{e.forEach(u=>cancelAnimationFrame(u)),e.length=0}}else if(o.current){a(!0),l(!1);let e=o.current,u=!1,s=()=>{u||(u=!0,i(!1),a(!1),e.removeEventListener("transitionend",s),e.removeEventListener("animationend",s),t.current=null)};e.addEventListener("transitionend",s,{passive:!0}),e.addEventListener("animationend",s,{passive:!0}),t.current=()=>{u||(e.removeEventListener("transitionend",s),e.removeEventListener("animationend",s))}}else l(!1),i(!1),a(!1)},[c,f]),n.useEffect(()=>()=>{t.current&&t.current(),r.current&&r.current()},[]),{present:m,exiting:d,mounted:R,ref:v}}export{E as usePresence};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/use-presence/index.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * usePresence hook is used to manage the presence of a component.\n *\n * @param open - The open state.\n * @returns An object containing the present, exiting, mounted, and ref states.\n *\n * @example\n * ```tsx\n * const { present, exiting, mounted, ref } = usePresence(true);\n *\n * return present && (\n * <div className=\"card flex justify-center\"></div>\n * );\n */\n\nexport function usePresence(open: boolean, fallbackMs: number = 500) {\n const [present, setPresent] = React.useState(open);\n const [exiting, setExiting] = React.useState(false);\n const [mounted, setMounted] = React.useState(false);\n const
|
|
1
|
+
{"version":3,"sources":["../../src/use-presence/index.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * usePresence hook is used to manage the presence of a component.\n *\n * @param open - The open state.\n * @returns An object containing the present, exiting, mounted, and ref states.\n *\n * @example\n * ```tsx\n * const { present, exiting, mounted, ref } = usePresence(true);\n *\n * return present && (\n * <div className=\"card flex justify-center\"></div>\n * );\n */\n\nexport function usePresence(open: boolean, fallbackMs: number = 500) {\n const [present, setPresent] = React.useState(open);\n const [exiting, setExiting] = React.useState(false);\n const [mounted, setMounted] = React.useState(false);\n const nodeRef = React.useRef<HTMLElement | null>(null);\n const cleanupRef = React.useRef<(() => void) | null>(null);\n const rafCleanupRef = React.useRef<(() => void) | null>(null);\n\n const ref = React.useCallback((node: HTMLElement | null) => {\n nodeRef.current = node;\n }, []);\n\n React.useEffect(() => {\n if (cleanupRef.current) {\n cleanupRef.current();\n cleanupRef.current = null;\n }\n\n if (rafCleanupRef.current) {\n rafCleanupRef.current();\n rafCleanupRef.current = null;\n }\n\n if (open) {\n setPresent(true);\n setExiting(false);\n\n const rafs: number[] = [];\n\n rafs.push(\n requestAnimationFrame(() => {\n rafs.push(\n requestAnimationFrame(() => {\n rafs.push(requestAnimationFrame(() => setMounted(true)));\n })\n );\n })\n );\n\n rafCleanupRef.current = () => {\n rafs.forEach((raf) => cancelAnimationFrame(raf));\n rafs.length = 0;\n };\n } else if (nodeRef.current) {\n setExiting(true);\n setMounted(false);\n const node = nodeRef.current;\n let isHandled = false;\n\n const handleEnd = () => {\n if (isHandled) return;\n\n isHandled = true;\n\n setPresent(false);\n setExiting(false);\n\n node.removeEventListener('transitionend', handleEnd);\n node.removeEventListener('animationend', handleEnd);\n\n cleanupRef.current = null;\n };\n\n node.addEventListener('transitionend', handleEnd, { passive: true });\n node.addEventListener('animationend', handleEnd, { passive: true });\n\n // const fallbackTimeout = setTimeout(() => {\n // if (!isHandled) {\n // handleEnd();\n // }\n // }, fallbackMs);\n\n cleanupRef.current = () => {\n // clearTimeout(fallbackTimeout);\n\n if (!isHandled) {\n node.removeEventListener('transitionend', handleEnd);\n node.removeEventListener('animationend', handleEnd);\n }\n };\n } else {\n setMounted(false);\n setPresent(false);\n setExiting(false);\n }\n }, [open, fallbackMs]);\n\n React.useEffect(() => {\n return () => {\n if (cleanupRef.current) {\n cleanupRef.current();\n }\n\n if (rafCleanupRef.current) {\n rafCleanupRef.current();\n }\n };\n }, []);\n\n return { present, exiting, mounted, ref };\n}\n"],"mappings":"AAAA,UAAYA,MAAW,QAiBhB,SAASC,EAAYC,EAAeC,EAAqB,IAAK,CACjE,GAAM,CAACC,EAASC,CAAU,EAAU,WAASH,CAAI,EAC3C,CAACI,EAASC,CAAU,EAAU,WAAS,EAAK,EAC5C,CAACC,EAASC,CAAU,EAAU,WAAS,EAAK,EAC5CC,EAAgB,SAA2B,IAAI,EAC/CC,EAAmB,SAA4B,IAAI,EACnDC,EAAsB,SAA4B,IAAI,EAEtDC,EAAY,cAAaC,GAA6B,CACxDJ,EAAQ,QAAUI,CACtB,EAAG,CAAC,CAAC,EAEL,OAAM,YAAU,IAAM,CAWlB,GAVIH,EAAW,UACXA,EAAW,QAAQ,EACnBA,EAAW,QAAU,MAGrBC,EAAc,UACdA,EAAc,QAAQ,EACtBA,EAAc,QAAU,MAGxBV,EAAM,CACNG,EAAW,EAAI,EACfE,EAAW,EAAK,EAEhB,IAAMQ,EAAiB,CAAC,EAExBA,EAAK,KACD,sBAAsB,IAAM,CACxBA,EAAK,KACD,sBAAsB,IAAM,CACxBA,EAAK,KAAK,sBAAsB,IAAMN,EAAW,EAAI,CAAC,CAAC,CAC3D,CAAC,CACL,CACJ,CAAC,CACL,EAEAG,EAAc,QAAU,IAAM,CAC1BG,EAAK,QAASC,GAAQ,qBAAqBA,CAAG,CAAC,EAC/CD,EAAK,OAAS,CAClB,CACJ,SAAWL,EAAQ,QAAS,CACxBH,EAAW,EAAI,EACfE,EAAW,EAAK,EAChB,IAAMK,EAAOJ,EAAQ,QACjBO,EAAY,GAEVC,EAAY,IAAM,CAChBD,IAEJA,EAAY,GAEZZ,EAAW,EAAK,EAChBE,EAAW,EAAK,EAEhBO,EAAK,oBAAoB,gBAAiBI,CAAS,EACnDJ,EAAK,oBAAoB,eAAgBI,CAAS,EAElDP,EAAW,QAAU,KACzB,EAEAG,EAAK,iBAAiB,gBAAiBI,EAAW,CAAE,QAAS,EAAK,CAAC,EACnEJ,EAAK,iBAAiB,eAAgBI,EAAW,CAAE,QAAS,EAAK,CAAC,EAQlEP,EAAW,QAAU,IAAM,CAGlBM,IACDH,EAAK,oBAAoB,gBAAiBI,CAAS,EACnDJ,EAAK,oBAAoB,eAAgBI,CAAS,EAE1D,CACJ,MACIT,EAAW,EAAK,EAChBJ,EAAW,EAAK,EAChBE,EAAW,EAAK,CAExB,EAAG,CAACL,EAAMC,CAAU,CAAC,EAEf,YAAU,IACL,IAAM,CACLQ,EAAW,SACXA,EAAW,QAAQ,EAGnBC,EAAc,SACdA,EAAc,QAAQ,CAE9B,EACD,CAAC,CAAC,EAEE,CAAE,QAAAR,EAAS,QAAAE,EAAS,QAAAE,EAAS,IAAAK,CAAI,CAC5C","names":["React","usePresence","open","fallbackMs","present","setPresent","exiting","setExiting","mounted","setMounted","nodeRef","cleanupRef","rafCleanupRef","ref","node","rafs","raf","isHandled","handleEnd"]}
|
package/use-props/index.d.ts
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Used to merge and differentiate incoming props with the default props.
|
|
3
|
-
* - Keys that exist in both `props1` and `props2` are placed in `props`, with values from `
|
|
4
|
-
* - Keys that exist in `
|
|
3
|
+
* - Keys that exist in both `props1` and `props2` are placed in `props`, with values from `props2`.
|
|
4
|
+
* - Keys that exist in `props2` but not in `props1` are placed in `attrs`.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Uses structural comparison to preserve referential stability — if the computed
|
|
7
|
+
* props and attrs are shallowly equal to the previous result, the same reference is returned.
|
|
8
|
+
* This prevents unnecessary downstream useMemo invalidation even when the parent
|
|
9
|
+
* passes a new props object reference with identical values (e.g., from JSX spread).
|
|
8
10
|
*
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
11
|
+
* @template P1 The type of the default set of props.
|
|
12
|
+
* @template P2 The type of the incoming set of props.
|
|
13
|
+
*
|
|
14
|
+
* @param props1 The default set of props (e.g., default props).
|
|
15
|
+
* @param props2 The incoming set of props (e.g., user-defined or dynamic props).
|
|
11
16
|
* @returns An object containing:
|
|
12
|
-
* - `props`: A new object containing keys that exist in both `props1` and `props2`, using values from `
|
|
13
|
-
* - `attrs`: A new object containing keys that exist only in `
|
|
17
|
+
* - `props`: A new object containing keys that exist in both `props1` and `props2`, using values from `props2`.
|
|
18
|
+
* - `attrs`: A new object containing keys that exist only in `props2`, excluding any keys from `props1`.
|
|
14
19
|
*
|
|
15
20
|
* @example
|
|
16
21
|
* ```ts
|
|
17
|
-
* const { props, attrs } = useProps({
|
|
22
|
+
* const { props, attrs } = useProps({ className: 'baz' }, { id: 'foo', className: 'bar' });
|
|
18
23
|
*
|
|
19
24
|
* console.log(props); // { className: 'bar' }
|
|
20
25
|
* console.log(attrs); // { id: 'foo' }
|
|
21
26
|
* ```
|
|
22
27
|
*/
|
|
23
28
|
export declare function useProps<P1, P2>(props1?: P1, props2?: P2): {
|
|
24
|
-
props: Pick<P1 & P2, keyof
|
|
25
|
-
attrs: Omit<
|
|
29
|
+
props: Pick<P1 & P2, keyof P1>;
|
|
30
|
+
attrs: Omit<P2, keyof P1>;
|
|
26
31
|
};
|
package/use-props/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var k=Object.defineProperty;var l=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable;var R=(r,n,t)=>n in r?k(r,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[n]=t,P=(r,n)=>{for(var t in n||(n={}))g.call(n,t)&&R(r,t,n[t]);if(l)for(var t of l(n))w.call(n,t)&&R(r,t,n[t]);return r};import*as u from"react";function f(r,n){if(r===n)return!0;let t=Object.keys(r),o=Object.keys(n);if(t.length!==o.length)return!1;for(let e=0;e<t.length;e++){let s=t[e];if(r[s]!==n[s])return!1}return!0}function d(r={},n={}){let t=u.useRef(null);return u.useMemo(()=>{let o=P({},r),e={};Object.entries(n).forEach(([c,i])=>{c in r?o[c]=i:e[c]=i});let s=t.current;if(s&&f(s.props,o)&&f(s.attrs,e))return s;let a={props:o,attrs:e};return t.current=a,a},[r,n])}export{d as useProps};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/use-props/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/use-props/index.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * Used to merge and differentiate incoming props with the default props.\n * - Keys that exist in both `props1` and `props2` are placed in `props`, with values from `
|
|
1
|
+
{"version":3,"sources":["../../src/use-props/index.ts"],"sourcesContent":["import * as React from 'react';\n\n/**\n * Performs a shallow comparison of two objects to determine if their values are equal.\n * Returns true if both objects have the same keys with the same values (by reference).\n */\nfunction shallowEqual(objA: Record<string, unknown>, objB: Record<string, unknown>): boolean {\n if (objA === objB) return true;\n\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n\n if (keysA.length !== keysB.length) return false;\n\n for (let i = 0; i < keysA.length; i++) {\n const key = keysA[i];\n\n if (objA[key] !== objB[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Used to merge and differentiate incoming props with the default props.\n * - Keys that exist in both `props1` and `props2` are placed in `props`, with values from `props2`.\n * - Keys that exist in `props2` but not in `props1` are placed in `attrs`.\n *\n * Uses structural comparison to preserve referential stability — if the computed\n * props and attrs are shallowly equal to the previous result, the same reference is returned.\n * This prevents unnecessary downstream useMemo invalidation even when the parent\n * passes a new props object reference with identical values (e.g., from JSX spread).\n *\n * @template P1 The type of the default set of props.\n * @template P2 The type of the incoming set of props.\n *\n * @param props1 The default set of props (e.g., default props).\n * @param props2 The incoming set of props (e.g., user-defined or dynamic props).\n * @returns An object containing:\n * - `props`: A new object containing keys that exist in both `props1` and `props2`, using values from `props2`.\n * - `attrs`: A new object containing keys that exist only in `props2`, excluding any keys from `props1`.\n *\n * @example\n * ```ts\n * const { props, attrs } = useProps({ className: 'baz' }, { id: 'foo', className: 'bar' });\n *\n * console.log(props); // { className: 'bar' }\n * console.log(attrs); // { id: 'foo' }\n * ```\n */\nexport function useProps<P1, P2>(props1: P1 = {} as P1, props2: P2 = {} as P2) {\n type Props = Pick<P1 & P2, keyof P1>;\n type Attrs = Omit<P2, keyof P1>;\n type Result = { props: Props; attrs: Attrs };\n\n const prevRef = React.useRef<Result | null>(null);\n\n return React.useMemo(() => {\n const newProps = { ...props1 } as Props;\n const newAttrs = {} as Attrs;\n\n Object.entries(props2 as Record<string, unknown>).forEach(([key, value]) => {\n if (key in (props1 as Record<string, unknown>)) {\n (newProps as Record<string, unknown>)[key] = value;\n } else {\n (newAttrs as Record<string, unknown>)[key] = value;\n }\n });\n\n const prev = prevRef.current;\n\n if (prev && shallowEqual(prev.props as Record<string, unknown>, newProps as Record<string, unknown>) && shallowEqual(prev.attrs as Record<string, unknown>, newAttrs as Record<string, unknown>)) {\n return prev;\n }\n\n const result: Result = { props: newProps, attrs: newAttrs };\n\n prevRef.current = result;\n\n return result;\n }, [props1, props2]);\n}\n"],"mappings":"yVAAA,UAAYA,MAAW,QAMvB,SAASC,EAAaC,EAA+BC,EAAwC,CACzF,GAAID,IAASC,EAAM,MAAO,GAE1B,IAAMC,EAAQ,OAAO,KAAKF,CAAI,EACxBG,EAAQ,OAAO,KAAKF,CAAI,EAE9B,GAAIC,EAAM,SAAWC,EAAM,OAAQ,MAAO,GAE1C,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACnC,IAAMC,EAAMH,EAAME,CAAC,EAEnB,GAAIJ,EAAKK,CAAG,IAAMJ,EAAKI,CAAG,EAAG,MAAO,EACxC,CAEA,MAAO,EACX,CA6BO,SAASC,EAAiBC,EAAa,CAAC,EAASC,EAAa,CAAC,EAAS,CAK3E,IAAMC,EAAgB,SAAsB,IAAI,EAEhD,OAAa,UAAQ,IAAM,CACvB,IAAMC,EAAWC,EAAA,GAAKJ,GAChBK,EAAW,CAAC,EAElB,OAAO,QAAQJ,CAAiC,EAAE,QAAQ,CAAC,CAACH,EAAKQ,CAAK,IAAM,CACpER,KAAQE,EACPG,EAAqCL,CAAG,EAAIQ,EAE5CD,EAAqCP,CAAG,EAAIQ,CAErD,CAAC,EAED,IAAMC,EAAOL,EAAQ,QAErB,GAAIK,GAAQf,EAAae,EAAK,MAAkCJ,CAAmC,GAAKX,EAAae,EAAK,MAAkCF,CAAmC,EAC3L,OAAOE,EAGX,IAAMC,EAAiB,CAAE,MAAOL,EAAU,MAAOE,CAAS,EAE1D,OAAAH,EAAQ,QAAUM,EAEXA,CACX,EAAG,CAACR,EAAQC,CAAM,CAAC,CACvB","names":["React","shallowEqual","objA","objB","keysA","keysB","i","key","useProps","props1","props2","prevRef","newProps","__spreadValues","newAttrs","value","prev","result"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useQueueTask: () => (id: string | number, task: () => void) => void;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as e from"react";var a=()=>{let t=e.useRef(new Map),r=e.useRef(!1),u=e.useCallback(()=>{r.current=!1;let s=t.current;t.current=new Map,s.forEach(c=>c())},[]);return e.useCallback((s,c)=>{t.current.set(s,c),r.current||(r.current=!0,queueMicrotask(u))},[u])};export{a as useQueueTask};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/use-queue-task/index.ts"],"sourcesContent":["import * as React from 'react';\n\nexport const useQueueTask = () => {\n const tasksRef = React.useRef(new Map<string | number, () => void>());\n const scheduledRef = React.useRef(false);\n\n const flush = React.useCallback(() => {\n scheduledRef.current = false;\n const tasks = tasksRef.current;\n\n tasksRef.current = new Map();\n tasks.forEach((task) => task());\n }, []);\n\n return React.useCallback(\n (id: string | number, task: () => void) => {\n tasksRef.current.set(id, task);\n\n if (!scheduledRef.current) {\n scheduledRef.current = true;\n queueMicrotask(flush);\n }\n },\n [flush]\n );\n};\n"],"mappings":"AAAA,UAAYA,MAAW,QAEhB,IAAMC,EAAe,IAAM,CAC9B,IAAMC,EAAiB,SAAO,IAAI,GAAkC,EAC9DC,EAAqB,SAAO,EAAK,EAEjCC,EAAc,cAAY,IAAM,CAClCD,EAAa,QAAU,GACvB,IAAME,EAAQH,EAAS,QAEvBA,EAAS,QAAU,IAAI,IACvBG,EAAM,QAASC,GAASA,EAAK,CAAC,CAClC,EAAG,CAAC,CAAC,EAEL,OAAa,cACT,CAACC,EAAqBD,IAAqB,CACvCJ,EAAS,QAAQ,IAAIK,EAAID,CAAI,EAExBH,EAAa,UACdA,EAAa,QAAU,GACvB,eAAeC,CAAK,EAE5B,EACA,CAACA,CAAK,CACV,CACJ","names":["React","useQueueTask","tasksRef","scheduledRef","flush","tasks","task","id"]}
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface SortableListState<TListId extends string = string, TItem = unknown> {
|
|
3
|
+
draggedItems: TItem[];
|
|
4
|
+
draggedIndex: number | null;
|
|
5
|
+
sourceListId: TListId | null;
|
|
6
|
+
dragOverListId: TListId | null;
|
|
7
|
+
dragOverIndex: number | null;
|
|
8
|
+
isDragging: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface UseSortableListOptions<TListId extends string = string, TItem = unknown> {
|
|
11
|
+
/** Called when items are reordered within the same list */
|
|
12
|
+
onReorder: (listId: TListId, fromIndex: number, toIndex: number) => void;
|
|
13
|
+
/** Called when items are dropped onto a different list */
|
|
14
|
+
onTransfer?: (sourceListId: TListId, targetListId: TListId, items: TItem[], targetIndex?: number) => void;
|
|
15
|
+
/** Whether a transfer from source to target is allowed. Defaults to true. */
|
|
16
|
+
canTransfer?: (sourceListId: TListId, targetListId: TListId) => boolean;
|
|
17
|
+
/** Resolve the set of items to drag. Useful for multi-selection. Defaults to [item]. */
|
|
18
|
+
getSelectedItems?: (listId: TListId, item: TItem) => TItem[];
|
|
19
|
+
}
|
|
20
|
+
export interface UseSortableListReturn<TListId extends string = string, TItem = unknown> {
|
|
21
|
+
dragState: SortableListState<TListId, TItem>;
|
|
22
|
+
/**
|
|
23
|
+
* Drag handlers for the list container.
|
|
24
|
+
* Must be spread onto the list wrapper element — handles both same-list reorder
|
|
25
|
+
* (via dragOverIndexRef) and cross-list transfer in onDrop, so individual items
|
|
26
|
+
* do not need onDrop handlers and CSS transitions on items are safe to use.
|
|
27
|
+
*/
|
|
28
|
+
getListHandlers: (listId: TListId) => {
|
|
29
|
+
onDragOver: (e: React.DragEvent) => void;
|
|
30
|
+
onDrop: (e: React.DragEvent) => void;
|
|
31
|
+
};
|
|
32
|
+
/** Drag handlers for individual items (onDragStart, onDragOver, onDragEnd) */
|
|
33
|
+
getItemHandlers: (listId: TListId, index: number, item: TItem) => {
|
|
34
|
+
draggable: true;
|
|
35
|
+
'data-index': number;
|
|
36
|
+
onDragStart: (e: React.DragEvent) => void;
|
|
37
|
+
onDragOver: (e: React.DragEvent) => void;
|
|
38
|
+
onDragEnd: () => void;
|
|
39
|
+
};
|
|
40
|
+
/** Reset all drag state */
|
|
41
|
+
reset: () => void;
|
|
42
|
+
}
|
|
43
|
+
export declare function useSortableList<TListId extends string = string, TItem = unknown>({ onReorder, onTransfer, canTransfer, getSelectedItems }: UseSortableListOptions<TListId, TItem>): UseSortableListReturn<TListId, TItem>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var k=Object.defineProperty,w=Object.defineProperties;var A=Object.getOwnPropertyDescriptors;var D=Object.getOwnPropertySymbols;var C=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var S=(d,t,a)=>t in d?k(d,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):d[t]=a,v=(d,t)=>{for(var a in t||(t={}))C.call(t,a)&&S(d,a,t[a]);if(D)for(var a of D(t))H.call(t,a)&&S(d,a,t[a]);return d},b=(d,t)=>w(d,A(t));import*as o from"react";var O={draggedItems:[],draggedIndex:null,sourceListId:null,dragOverListId:null,dragOverIndex:null,isDragging:!1};function h({onReorder:d,onTransfer:t,canTransfer:a,getSelectedItems:f}){let c=o.useRef([]),u=o.useRef(null),I=o.useRef(null),L=o.useRef(null),[x,T]=o.useState(O),g=o.useCallback(()=>{c.current=[],u.current=null,I.current=null,L.current=null,T(O)},[]),l=o.useCallback((e,r)=>t?a?a(e,r):!0:!1,[t,a]),E=o.useCallback(e=>({onDragOver:r=>{r.preventDefault();let i=u.current;i===e?r.dataTransfer.dropEffect="move":i&&(r.dataTransfer.dropEffect=l(i,e)?"move":"none"),T(n=>n.dragOverListId!==e?b(v({},n),{dragOverListId:e,dragOverIndex:null}):n)},onDrop:r=>{r.preventDefault();let i=u.current,n=I.current,s=L.current;i===e?n!==null&&s!==null&&n!==s&&d(e,n,s):i&&c.current.length>0&&l(i,e)&&t(i,e,c.current,s!=null?s:void 0),g()}}),[d,t,l,g]),p=o.useCallback((e,r,i)=>({draggable:!0,"data-index":r,onDragStart:n=>{let s=f?f(e,i):[i];n.dataTransfer.effectAllowed="move",n.dataTransfer.setData("text/plain",""),c.current=s,u.current=e,I.current=r,L.current=r,requestAnimationFrame(()=>{T({draggedItems:s,draggedIndex:r,sourceListId:e,dragOverListId:null,dragOverIndex:null,isDragging:!0})})},onDragOver:n=>{n.preventDefault(),n.stopPropagation();let s=u.current,R=s===e;R?n.dataTransfer.dropEffect="move":s&&(n.dataTransfer.dropEffect=l(s,e)?"move":"none"),!(R&&r===I.current)&&(L.current=r,T(m=>m.dragOverListId!==e||m.dragOverIndex!==r?b(v({},m),{dragOverListId:e,dragOverIndex:r}):m))},onDragEnd:g}),[l,f,g]);return{dragState:x,getListHandlers:E,getItemHandlers:p,reset:g}}export{h as useSortableList};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/use-sortable-list/index.ts"],"sourcesContent":["'use client';\nimport * as React from 'react';\n\nexport interface SortableListState<TListId extends string = string, TItem = unknown> {\n draggedItems: TItem[];\n draggedIndex: number | null;\n sourceListId: TListId | null;\n dragOverListId: TListId | null;\n dragOverIndex: number | null;\n isDragging: boolean;\n}\n\nexport interface UseSortableListOptions<TListId extends string = string, TItem = unknown> {\n /** Called when items are reordered within the same list */\n onReorder: (listId: TListId, fromIndex: number, toIndex: number) => void;\n /** Called when items are dropped onto a different list */\n onTransfer?: (sourceListId: TListId, targetListId: TListId, items: TItem[], targetIndex?: number) => void;\n /** Whether a transfer from source to target is allowed. Defaults to true. */\n canTransfer?: (sourceListId: TListId, targetListId: TListId) => boolean;\n /** Resolve the set of items to drag. Useful for multi-selection. Defaults to [item]. */\n getSelectedItems?: (listId: TListId, item: TItem) => TItem[];\n}\n\nexport interface UseSortableListReturn<TListId extends string = string, TItem = unknown> {\n dragState: SortableListState<TListId, TItem>;\n /**\n * Drag handlers for the list container.\n * Must be spread onto the list wrapper element — handles both same-list reorder\n * (via dragOverIndexRef) and cross-list transfer in onDrop, so individual items\n * do not need onDrop handlers and CSS transitions on items are safe to use.\n */\n getListHandlers: (listId: TListId) => {\n onDragOver: (e: React.DragEvent) => void;\n onDrop: (e: React.DragEvent) => void;\n };\n /** Drag handlers for individual items (onDragStart, onDragOver, onDragEnd) */\n getItemHandlers: (\n listId: TListId,\n index: number,\n item: TItem\n ) => {\n draggable: true;\n 'data-index': number;\n onDragStart: (e: React.DragEvent) => void;\n onDragOver: (e: React.DragEvent) => void;\n onDragEnd: () => void;\n };\n /** Reset all drag state */\n reset: () => void;\n}\n\nconst INITIAL_STATE = {\n draggedItems: [],\n draggedIndex: null,\n sourceListId: null,\n dragOverListId: null,\n dragOverIndex: null,\n isDragging: false\n};\n\nexport function useSortableList<TListId extends string = string, TItem = unknown>({ onReorder, onTransfer, canTransfer, getSelectedItems }: UseSortableListOptions<TListId, TItem>): UseSortableListReturn<TListId, TItem> {\n const draggedItemsRef = React.useRef<TItem[]>([]);\n const dragSourceRef = React.useRef<TListId | null>(null);\n const draggedIndexRef = React.useRef<number | null>(null);\n // Tracks the last hovered item index so list-level onDrop always uses the correct target,\n // regardless of where the cursor is when released (even over a transitioning item).\n const dragOverIndexRef = React.useRef<number | null>(null);\n\n const [dragState, setDragState] = React.useState<SortableListState<TListId, TItem>>(INITIAL_STATE as SortableListState<TListId, TItem>);\n\n const reset = React.useCallback(() => {\n draggedItemsRef.current = [];\n dragSourceRef.current = null;\n draggedIndexRef.current = null;\n dragOverIndexRef.current = null;\n setDragState(INITIAL_STATE as SortableListState<TListId, TItem>);\n }, []);\n\n const isTransferAllowed = React.useCallback(\n (sourceListId: TListId, targetListId: TListId) => {\n if (!onTransfer) return false;\n\n return canTransfer ? canTransfer(sourceListId, targetListId) : true;\n },\n [onTransfer, canTransfer]\n );\n\n const getListHandlers = React.useCallback(\n (listId: TListId) => ({\n onDragOver: (e: React.DragEvent) => {\n e.preventDefault();\n const sourceListId = dragSourceRef.current;\n\n if (sourceListId === listId) {\n e.dataTransfer.dropEffect = 'move';\n } else if (sourceListId) {\n e.dataTransfer.dropEffect = isTransferAllowed(sourceListId, listId) ? 'move' : 'none';\n }\n\n setDragState((prev) => (prev.dragOverListId !== listId ? { ...prev, dragOverListId: listId, dragOverIndex: null } : prev));\n },\n onDrop: (e: React.DragEvent) => {\n e.preventDefault();\n const sourceListId = dragSourceRef.current;\n const fromIndex = draggedIndexRef.current;\n const toIndex = dragOverIndexRef.current;\n\n if (sourceListId === listId) {\n // Same-list reorder using the last committed hover index.\n // Because drop is handled here (not on individual items), CSS transitions\n // on items cannot affect which element receives the drop event.\n if (fromIndex !== null && toIndex !== null && fromIndex !== toIndex) {\n onReorder(listId, fromIndex, toIndex);\n }\n } else if (sourceListId && draggedItemsRef.current.length > 0 && isTransferAllowed(sourceListId, listId)) {\n onTransfer!(sourceListId, listId, draggedItemsRef.current, toIndex ?? undefined);\n }\n\n reset();\n }\n }),\n [onReorder, onTransfer, isTransferAllowed, reset]\n );\n\n const getItemHandlers = React.useCallback(\n (listId: TListId, index: number, item: TItem) => ({\n draggable: true as const,\n 'data-index': index,\n onDragStart: (e: React.DragEvent) => {\n const itemsToDrag = getSelectedItems ? getSelectedItems(listId, item) : [item];\n\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', '');\n\n // Set refs immediately so dragOver/drop handlers work from the first event.\n draggedItemsRef.current = itemsToDrag;\n dragSourceRef.current = listId;\n draggedIndexRef.current = index;\n dragOverIndexRef.current = index;\n\n // Defer the state update by one frame so the browser captures the drag\n // ghost image from the element while it is still visible (opacity: 1).\n // React's synchronous batch flush would otherwise hide the element\n // (opacity: 0 in consumer code) before the ghost snapshot is taken.\n requestAnimationFrame(() => {\n setDragState({\n draggedItems: itemsToDrag,\n draggedIndex: index,\n sourceListId: listId,\n dragOverListId: null,\n dragOverIndex: null,\n isDragging: true\n });\n });\n },\n onDragOver: (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n const sourceListId = dragSourceRef.current;\n const isSameList = sourceListId === listId;\n\n if (isSameList) {\n e.dataTransfer.dropEffect = 'move';\n } else if (sourceListId) {\n e.dataTransfer.dropEffect = isTransferAllowed(sourceListId, listId) ? 'move' : 'none';\n }\n\n // The dragged item stays at its original slot (invisible placeholder).\n // Skip dragOverIndex updates for it to prevent the feedback loop where\n // hovering the invisible item resets all visual shifts.\n if (isSameList && index === draggedIndexRef.current) {\n return;\n }\n\n dragOverIndexRef.current = index;\n setDragState((prev) => (prev.dragOverListId !== listId || prev.dragOverIndex !== index ? { ...prev, dragOverListId: listId, dragOverIndex: index } : prev));\n },\n onDragEnd: reset\n }),\n [isTransferAllowed, getSelectedItems, reset]\n );\n\n return { dragState, getListHandlers, getItemHandlers, reset };\n}\n"],"mappings":"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","names":["React","INITIAL_STATE","useSortableList","onReorder","onTransfer","canTransfer","getSelectedItems","draggedItemsRef","dragSourceRef","draggedIndexRef","dragOverIndexRef","dragState","setDragState","reset","isTransferAllowed","sourceListId","targetListId","getListHandlers","listId","e","prev","__spreadProps","__spreadValues","fromIndex","toIndex","getItemHandlers","index","item","itemsToDrag","isSameList"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { registerMatcher, unregisterMatcher, type BuiltInMatchMode, type FilterMatcher, type FilterRule } from '@primereact/hooks/use-filter';
|
|
2
|
+
export { registerMatcher, unregisterMatcher };
|
|
3
|
+
export type TreeFilterMode = 'lenient' | 'strict';
|
|
4
|
+
export interface TreeNodeLike {
|
|
5
|
+
key?: string | number;
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
children?: TreeNodeLike[];
|
|
8
|
+
}
|
|
9
|
+
export interface UseTreeFilterOptions<TNode extends TreeNodeLike, TMode extends string = BuiltInMatchMode> {
|
|
10
|
+
nodes: TNode[];
|
|
11
|
+
rules?: FilterRule<TMode>[];
|
|
12
|
+
defaultRules?: FilterRule<TMode>[];
|
|
13
|
+
/**
|
|
14
|
+
* Shorthand for the single-field case. When set, the hook synthesizes a single
|
|
15
|
+
* `{ field, value, matchMode }` rule. Ignored when `rules` / `defaultRules` is provided.
|
|
16
|
+
*/
|
|
17
|
+
field?: string | string[];
|
|
18
|
+
/** Controlled value for the shorthand `field`. Omit to let the hook own the state. */
|
|
19
|
+
value?: unknown;
|
|
20
|
+
/** Initial value when the hook owns the state. */
|
|
21
|
+
defaultValue?: unknown;
|
|
22
|
+
/** Fires when the shorthand `value` changes. */
|
|
23
|
+
onValueChange?: (value: unknown) => void;
|
|
24
|
+
/** Match mode for the shorthand `field`. Defaults to `'contains'`. */
|
|
25
|
+
matchMode?: TMode;
|
|
26
|
+
matchers?: Partial<Record<TMode, FilterMatcher>> & Record<string, FilterMatcher>;
|
|
27
|
+
filterMode?: TreeFilterMode;
|
|
28
|
+
filterLocale?: string;
|
|
29
|
+
filterDelay?: number;
|
|
30
|
+
/** When true, `filteredNodes` is returned as-is; the consumer fetches filtered data itself. */
|
|
31
|
+
lazy?: boolean;
|
|
32
|
+
/** Fires after rules settle (honours `filterDelay`). The consumer is expected to fetch filtered tree data. */
|
|
33
|
+
onLazyLoad?: (event: LazyTreeFilterEvent<TMode>) => void;
|
|
34
|
+
onRulesChange?: (rules: FilterRule<TMode>[]) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface LazyTreeFilterEvent<TMode extends string = string> {
|
|
37
|
+
rules: FilterRule<TMode>[];
|
|
38
|
+
filterMode: TreeFilterMode;
|
|
39
|
+
filterLocale?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface UseTreeFilterReturn<TNode extends TreeNodeLike, TMode extends string = string> {
|
|
42
|
+
rules: FilterRule<TMode>[];
|
|
43
|
+
filteredNodes: TNode[];
|
|
44
|
+
isFiltered: boolean;
|
|
45
|
+
setRules: (rules: FilterRule<TMode>[]) => void;
|
|
46
|
+
value: unknown;
|
|
47
|
+
setValue: (value: unknown) => void;
|
|
48
|
+
clearAll: () => void;
|
|
49
|
+
match: (node: TNode) => boolean;
|
|
50
|
+
matchers: Readonly<Record<string, FilterMatcher>>;
|
|
51
|
+
}
|
|
52
|
+
export declare function useTreeFilter<TNode extends TreeNodeLike, TMode extends string = BuiltInMatchMode>(options: UseTreeFilterOptions<TNode, TMode>): UseTreeFilterReturn<TNode, TMode>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var K=Object.defineProperty,P=Object.defineProperties;var q=Object.getOwnPropertyDescriptors;var S=Object.getOwnPropertySymbols;var Q=Object.prototype.hasOwnProperty,W=Object.prototype.propertyIsEnumerable;var E=(e,t,r)=>t in e?K(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,u=(e,t)=>{for(var r in t||(t={}))Q.call(t,r)&&E(e,r,t[r]);if(S)for(var r of S(t))W.call(t,r)&&E(e,r,t[r]);return e},T=(e,t)=>P(e,q(t));import{useControlledState as X}from"@primereact/hooks/use-controlled-state";import{BUILT_IN_MATCHERS as Y,getGlobalMatchers as Z,matchRule as $,registerMatcher as oe,ruleHasValue as ee,unregisterMatcher as se}from"@primereact/hooks/use-filter";import{resolveFieldData as U}from"@primeuix/utils/object";import*as n from"react";function te(e,t){let r=e.data!==null&&typeof e.data=="object";if(r&&t in e.data)return e.data[t];if(r){let s=U(e.data,t);if(s!==void 0)return s}return t in e?e[t]:U(e,t)}function re(e){return!e.children||e.children.length===0}function j(e,t,r,s){let d=Array.isArray(t.field)?t.field:[t.field],i={};for(let a of d)i[a]=te(e,a);return $(i,T(u({},t),{field:d}),r,s)}function B(e,t,r,s,d){let i=[];for(let a of e){let N=t.every(R=>j(a,R,r,s)),c=null;if(a.children&&a.children.length>0){let R=B(a.children,t,r,s,d);R.length>0&&(c=R)}d?re(a)?N&&i.push(a):c&&i.push(T(u({},a),{children:c})):N?i.push(a):c&&i.push(T(u({},a),{children:c}))}return i}function ie(e){var C,V,z,A,D;let t=e.field!==void 0&&e.rules===void 0&&e.defaultRules===void 0,r=(C=e.matchMode)!=null?C:"contains",[s,d]=X({value:e.value,defaultValue:e.defaultValue,onChange:e.onValueChange}),i=n.useCallback(l=>d(l),[d]),a=e.rules!==void 0,[N,c]=n.useState((V=e.defaultRules)!=null?V:[]),R=n.useMemo(()=>t?[{field:e.field,value:s,matchMode:r}]:[],[t,e.field,s,r]),f=t?R:a?(z=e.rules)!=null?z:[]:N,m=n.useRef(e.onRulesChange);m.current=e.onRulesChange;let y=n.useCallback(l=>{var o,w,I;t?d((w=(o=l[0])==null?void 0:o.value)!=null?w:null):a||c(l),(I=m.current)==null||I.call(m,l)},[t,a,d]),M=e.filterLocale,v=(A=e.filterDelay)!=null?A:0,g=(D=e.filterMode)!=null?D:"lenient",F=n.useMemo(()=>{var l;return u(u(u({},Y),Z()),(l=e.matchers)!=null?l:{})},[e.matchers]),[O,H]=n.useState(f);n.useEffect(()=>{if(v<=0)return;let l=setTimeout(()=>H(f),v);return()=>clearTimeout(l)},[f,v]);let k=v>0?O:f,h=n.useMemo(()=>k.filter(ee),[k]),_=n.useCallback(l=>h.every(o=>j(l,o,F,M)),[h,F,M]),L=!!e.lazy,p=n.useMemo(()=>L||h.length===0?e.nodes:B(e.nodes,h,F,M,g==="strict"),[L,e.nodes,h,F,M,g]),b=n.useRef(e.onLazyLoad);b.current=e.onLazyLoad;let x=n.useRef(null);n.useEffect(()=>{var o;if(!L)return;let l=JSON.stringify(k)+"|"+g;x.current!==l&&(x.current=l,(o=b.current)==null||o.call(b,{rules:k,filterMode:g,filterLocale:M}))},[L,k,g,M]);let G=n.useCallback(l=>y(l),[y]),J=n.useCallback(()=>{let l=f.map(o=>Array.isArray(o.constraints)?T(u({},o),{constraints:o.constraints.map(w=>T(u({},w),{value:null}))}):T(u({},o),{value:null}));y(l)},[f,y]);return{rules:f,filteredNodes:p,isFiltered:h.length>0,setRules:G,value:s,setValue:i,clearAll:J,match:_,matchers:F}}export{oe as registerMatcher,se as unregisterMatcher,ie as useTreeFilter};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|