@himanshu-sorathiya/react-kit 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +90 -28
  2. package/dist/index.js +325 -165
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -34,34 +34,86 @@ export type DateOperator = "equals" | "before" | "after" | "between";
34
34
  export type SelectOperator = "equals" | "notEquals";
35
35
  export type MultiselectOperator = "in" | "notIn" | "intersects";
36
36
  export type CustomOperator = "custom";
37
- export type FilterOperator = TextOperator | NumberOperator | BooleanOperator | DateOperator | SelectOperator | MultiselectOperator | CustomOperator;
38
- export interface FilterOptions {
37
+ export interface FilterOptions<T = unknown> {
39
38
  caseSensitive?: boolean;
40
- compare?: (itemValue: any, filterValue: any, item: any) => boolean;
39
+ compare?: (itemValue: unknown, filterValue: unknown, item: T) => boolean;
41
40
  }
42
- export interface FilterConfig extends FilterOptions {
41
+ export type BaseFilterConfig<T> = FilterOptions<T> & {
43
42
  id: string;
44
43
  field: string;
45
- type: FilterType;
46
- operator: FilterOperator;
47
- value: any;
48
- }
49
- export type FilterState = FilterConfig[];
44
+ isActive?: boolean;
45
+ };
46
+ export type FilterConfig<T = unknown> = BaseFilterConfig<T> & ({
47
+ type: "text";
48
+ operator: TextOperator;
49
+ value: string;
50
+ } | {
51
+ type: "number";
52
+ operator: "between";
53
+ value: {
54
+ min: number;
55
+ max: number;
56
+ };
57
+ } | {
58
+ type: "number";
59
+ operator: Exclude<NumberOperator, "between">;
60
+ value: number;
61
+ } | {
62
+ type: "boolean";
63
+ operator: BooleanOperator;
64
+ value: boolean;
65
+ } | {
66
+ type: "date";
67
+ operator: "between";
68
+ value: {
69
+ min: string | number | Date;
70
+ max: string | number | Date;
71
+ };
72
+ } | {
73
+ type: "date";
74
+ operator: Exclude<DateOperator, "between">;
75
+ value: string | number | Date;
76
+ } | {
77
+ type: "select";
78
+ operator: SelectOperator;
79
+ value: string | number;
80
+ } | {
81
+ type: "multiselect";
82
+ operator: MultiselectOperator;
83
+ value: (string | number)[];
84
+ } | {
85
+ type: "custom";
86
+ operator: CustomOperator;
87
+ value: unknown;
88
+ });
89
+ export type FilterState<T> = FilterConfig<T>[];
50
90
  export interface UseFilterReturn<T> {
51
91
  filteredItems: T[];
52
- filters: FilterState;
53
- addFilter: (filter: FilterConfig) => void;
92
+ filters: FilterState<T>;
93
+ upsertFilter: (filter: FilterConfig<T>) => void;
54
94
  removeFilter: (id: string | string[]) => void;
55
95
  clearFilters: () => void;
56
96
  resetFilters: () => void;
57
- setFilters: (filters: FilterConfig[]) => void;
58
- toggleFilter: (filter: FilterConfig) => void;
59
- updateFilterConfig: (id: string, partialConfig: Partial<Omit<FilterConfig, "id">>) => void;
60
- getFilterValue: (id: string) => any;
61
- updateFilterValue: (id: string, value: any) => void;
97
+ replaceFilters: (filters: FilterConfig<T>[]) => void;
98
+ toggleFilter: (filter: FilterConfig<T>) => void;
99
+ updateFilterConfig: (id: string, partialConfig: Partial<Omit<FilterConfig<T>, "id">>) => void;
100
+ getFilterValue: (id: string) => unknown;
101
+ updateFilterValue: (id: string, value: unknown) => void;
62
102
  isFilterActive: (id: string) => boolean;
63
103
  }
64
- export declare function useFilter<T>(data: T[], initialFilters?: FilterState): UseFilterReturn<T>;
104
+ export declare function useFilter<T>(data: T[], initialFilters?: FilterState<T>): UseFilterReturn<T>;
105
+ export interface FuzzySearchOptions {
106
+ threshold?: number;
107
+ caseSensitive?: boolean;
108
+ matchStrategy?: "any" | "all";
109
+ exactPhraseBonus?: boolean;
110
+ }
111
+ export type UseFuzzySearchFields = [
112
+ string,
113
+ number
114
+ ][];
115
+ export type UseFuzzySearchReturn<T> = T[];
116
+ export declare function useFuzzySearch<T>(data: T[], query: string, fields: UseFuzzySearchFields, options?: FuzzySearchOptions): UseFuzzySearchReturn<T>;
65
117
  declare const validKeyEventTypes: readonly [
66
118
  "keydown",
67
119
  "keyup",
@@ -116,32 +168,42 @@ export interface UsePaginationReturn<T> {
116
168
  }
117
169
  export declare function usePagination<T>(data: T[], initialPageSize: number, initialPageIndex?: number): UsePaginationReturn<T>;
118
170
  export type SortType = "numeric" | "alphabetical" | "alphanumeric" | "boolean" | "date" | "basic" | "custom";
119
- export interface SortOptions {
171
+ export interface BaseSortOptions {
120
172
  desc?: boolean;
121
- caseSensitive?: boolean;
122
173
  disableSortRemoval?: boolean;
123
174
  invertSorting?: boolean;
124
- sortUndefined?: "first" | "last" | false | -1 | 1;
125
- compare?: (a: any, b: any) => number;
175
+ sortUndefined?: "first" | "last" | -1 | 1;
126
176
  }
127
- export interface SortConfig extends SortOptions {
177
+ export interface BaseSortConfig extends BaseSortOptions {
128
178
  id: string;
129
- type: SortType;
130
179
  field?: string;
131
180
  }
132
- export type SortState = Array<SortConfig>;
181
+ export type SortConfig = BaseSortConfig & ({
182
+ type: "numeric" | "boolean" | "date" | "basic";
183
+ } | {
184
+ type: "alphabetical" | "alphanumeric";
185
+ caseSensitive?: boolean;
186
+ } | {
187
+ type: "custom";
188
+ compare: (a: unknown, b: unknown) => number;
189
+ });
190
+ export type SortState = SortConfig[];
191
+ export type SortOptionsForType<T extends SortType> = Omit<Extract<SortConfig, {
192
+ type: T;
193
+ }>, "id" | "type" | "field">;
133
194
  export interface UseSortReturn<T> {
134
195
  sortedItems: T[];
135
196
  sorts: SortState;
136
- addSort: (sort: SortConfig) => void;
197
+ upsertSorts: (sort: SortConfig) => void;
137
198
  removeSort: (id: string | string[]) => void;
138
199
  clearSorts: () => void;
139
200
  resetSorts: () => void;
140
- setSorts: (sorts: SortState) => void;
141
- getSortDirection: (id: string) => "asc" | "desc" | undefined;
142
- toggleSort: (id: string, type: SortType, options?: SortOptions & {
201
+ replaceSorts: (sorts: SortState) => void;
202
+ toggleSort: <TType extends SortType>(id: string, type: TType, options?: SortOptionsForType<TType> & {
143
203
  multi?: boolean;
204
+ field?: string;
144
205
  }) => void;
206
+ getSortDirection: (id: string) => "asc" | "desc" | undefined;
145
207
  getNextSortingOrder: (id: string) => "asc" | "desc" | "none";
146
208
  getSortIndex: (id: string) => number | undefined;
147
209
  }
package/dist/index.js CHANGED
@@ -73,11 +73,11 @@ function p(e, t, n = {}) {
73
73
  //#region src/utils/filterUtils.ts
74
74
  var m = {
75
75
  text: {
76
- contains: (e, t, n) => n?.caseSensitive ? String(e).includes(String(t)) : String(e).toLowerCase().includes(String(t).toLowerCase()),
77
- equals: (e, t, n) => n?.caseSensitive ? String(e) === String(t) : String(e).toLowerCase() === String(t).toLowerCase(),
78
- startsWith: (e, t, n) => n?.caseSensitive ? String(e).startsWith(String(t)) : String(e).toLowerCase().startsWith(String(t).toLowerCase()),
79
- endsWith: (e, t, n) => n?.caseSensitive ? String(e).endsWith(String(t)) : String(e).toLowerCase().endsWith(String(t).toLowerCase()),
80
- notContains: (e, t, n) => n?.caseSensitive ? !String(e).includes(String(t)) : !String(e).toLowerCase().includes(String(t).toLowerCase())
76
+ contains: (e, t, n) => e == null ? !1 : n?.caseSensitive ? String(e).includes(String(t)) : String(e).toLowerCase().includes(String(t).toLowerCase()),
77
+ equals: (e, t, n) => e == null ? !1 : n?.caseSensitive ? String(e) === String(t) : String(e).toLowerCase() === String(t).toLowerCase(),
78
+ startsWith: (e, t, n) => e == null ? !1 : n?.caseSensitive ? String(e).startsWith(String(t)) : String(e).toLowerCase().startsWith(String(t).toLowerCase()),
79
+ endsWith: (e, t, n) => e == null ? !1 : n?.caseSensitive ? String(e).endsWith(String(t)) : String(e).toLowerCase().endsWith(String(t).toLowerCase()),
80
+ notContains: (e, t, n) => e == null ? !0 : n?.caseSensitive ? !String(e).includes(String(t)) : !String(e).toLowerCase().includes(String(t).toLowerCase())
81
81
  },
82
82
  number: {
83
83
  equals: (e, t) => Number(e) === Number(t),
@@ -85,29 +85,35 @@ var m = {
85
85
  lessThan: (e, t) => Number(e) < Number(t),
86
86
  greaterThanOrEqual: (e, t) => Number(e) >= Number(t),
87
87
  lessThanOrEqual: (e, t) => Number(e) <= Number(t),
88
- between: (e, t) => Number(e) >= Number(t.min) && Number(e) <= Number(t.max)
88
+ between: (e, t) => {
89
+ if (typeof t != "object" || !t) return !1;
90
+ let { min: n, max: r } = t;
91
+ return n == null || r == null ? !1 : Number(e) >= Number(n) && Number(e) <= Number(r);
92
+ }
89
93
  },
90
94
  boolean: { equals: (e, t) => !!e == !!t },
91
95
  date: {
92
96
  equals: (e, t) => {
93
97
  if (!e || !t) return !1;
94
- let n = new Date(e).getTime(), r = new Date(t).getTime();
95
- return Number.isNaN(n) || Number.isNaN(r) ? !1 : n === r;
98
+ let n = new Date(e), r = new Date(t);
99
+ return Number.isNaN(n.getTime()) || Number.isNaN(r.getTime()) ? !1 : n.getFullYear() === r.getFullYear() && n.getMonth() === r.getMonth() && n.getDate() === r.getDate();
96
100
  },
97
101
  before: (e, t) => {
98
102
  if (!e || !t) return !1;
99
- let n = new Date(e).getTime(), r = new Date(t).getTime();
103
+ let n = new Date(e).setHours(0, 0, 0, 0), r = new Date(t).setHours(0, 0, 0, 0);
100
104
  return Number.isNaN(n) || Number.isNaN(r) ? !1 : n < r;
101
105
  },
102
106
  after: (e, t) => {
103
107
  if (!e || !t) return !1;
104
- let n = new Date(e).getTime(), r = new Date(t).getTime();
108
+ let n = new Date(e).setHours(0, 0, 0, 0), r = new Date(t).setHours(0, 0, 0, 0);
105
109
  return Number.isNaN(n) || Number.isNaN(r) ? !1 : n > r;
106
110
  },
107
111
  between: (e, t) => {
108
- if (!e || !t?.min || !t?.max) return !1;
109
- let n = new Date(e).getTime(), r = new Date(t.min).getTime(), i = new Date(t.max).getTime();
110
- return Number.isNaN(n) || Number.isNaN(r) || Number.isNaN(i) ? !1 : n >= r && n <= i;
112
+ if (!e || typeof t != "object" || !t) return !1;
113
+ let { min: n, max: r } = t;
114
+ if (n == null || r == null) return !1;
115
+ let i = new Date(e).setHours(0, 0, 0, 0), a = new Date(n).setHours(0, 0, 0, 0), o = new Date(r).setHours(0, 0, 0, 0);
116
+ return Number.isNaN(i) || Number.isNaN(a) || Number.isNaN(o) ? !1 : i >= a && i <= o;
111
117
  }
112
118
  },
113
119
  select: {
@@ -124,20 +130,26 @@ var m = {
124
130
  //#region src/utils/utils.ts
125
131
  function h(e, t, n) {
126
132
  if (typeof e != "object" || !e) return e;
127
- let r = (t || n) ?? "";
128
- return r.includes(".") ? r.split(".").reduce((e, t) => e?.[t], e) : e?.[r];
133
+ let r = t ?? n ?? "";
134
+ return Array.isArray(r) ? r.reduce((e, t) => e?.[t], e) : r.includes(".") ? r.split(".").reduce((e, t) => e?.[t], e) : e?.[r];
129
135
  }
130
136
  //#endregion
131
137
  //#region src/hooks/useFilter.ts
132
138
  function g(e, n = []) {
133
- let [r, a] = o(n), s = i(() => e.filter((e) => r.every((t) => {
134
- let { id: n, field: r, type: i, operator: a, value: o, compare: s } = t, c = h(e, r, n);
135
- if (i === "custom" || a === "custom") return s ? s(c, o, e) : !0;
136
- let l = m[i];
137
- if (!l) return !0;
138
- let u = l[a];
139
- return u ? u(c, o, t) : !0;
140
- })), [e, r]), c = t((e) => {
139
+ let [r, a] = o(n), s = i(() => {
140
+ let t = r.filter((e) => e.isActive !== !1).map((e) => ({
141
+ ...e,
142
+ pathArray: (e.field || e.id).split(".")
143
+ }));
144
+ return e.filter((e) => t.every((t) => {
145
+ let { id: n, type: r, operator: i, value: a, compare: o, pathArray: s } = t, c = h(e, s, n);
146
+ if (r === "custom") return o ? o(c, a, e) : !0;
147
+ let l = m[r];
148
+ if (!l) return !0;
149
+ let u = l[i];
150
+ return u ? u(c, a, t) : !0;
151
+ }));
152
+ }, [e, r]), c = t((e) => {
141
153
  a((t) => t.some((t) => t.id === e.id) ? t.map((t) => t.id === e.id ? e : t) : [...t, e]);
142
154
  }, []), l = t((e) => {
143
155
  a((t) => Array.isArray(e) ? t.filter((t) => !e.includes(t.id)) : t.filter((t) => t.id !== e));
@@ -147,21 +159,22 @@ function g(e, n = []) {
147
159
  a(n);
148
160
  }, [n]), f = t((e) => {
149
161
  a(e);
150
- }, []), p = t((e) => r.find((t) => t.id === e)?.value, [r]), g = t((e, t) => {
151
- a((n) => n.map((n) => n.id === e ? {
152
- ...n,
153
- value: t
154
- } : n));
155
- }, []), _ = t((e) => r.some((t) => t.id === e), [r]);
162
+ }, []);
156
163
  return {
157
164
  filteredItems: s,
158
165
  filters: r,
159
- addFilter: c,
166
+ upsertFilter: c,
160
167
  removeFilter: l,
161
168
  clearFilters: u,
162
169
  resetFilters: d,
163
170
  toggleFilter: t((e) => {
164
- a((t) => t.some((t) => t.id === e.id) ? t.filter((t) => t.id !== e.id) : [...t, e]);
171
+ a((t) => t.some((t) => t.id === e.id) ? t.map((t) => t.id === e.id ? {
172
+ ...t,
173
+ isActive: t.isActive === !1
174
+ } : t) : [...t, {
175
+ ...e,
176
+ isActive: !0
177
+ }]);
165
178
  }, []),
166
179
  updateFilterConfig: t((e, t) => {
167
180
  a((n) => n.map((n) => n.id === e ? {
@@ -169,45 +182,184 @@ function g(e, n = []) {
169
182
  ...t
170
183
  } : n));
171
184
  }, []),
172
- setFilters: f,
173
- getFilterValue: p,
174
- updateFilterValue: g,
175
- isFilterActive: _
185
+ replaceFilters: f,
186
+ getFilterValue: t((e) => r.find((t) => t.id === e)?.value, [r]),
187
+ updateFilterValue: t((e, t) => {
188
+ a((n) => n.map((n) => n.id === e ? {
189
+ ...n,
190
+ value: t
191
+ } : n));
192
+ }, []),
193
+ isFilterActive: t((e) => {
194
+ let t = r.find((t) => t.id === e);
195
+ return t ? t.isActive !== !1 : !1;
196
+ }, [r])
176
197
  };
177
198
  }
178
199
  //#endregion
200
+ //#region src/utils/fuzzySearchUtils.ts
201
+ function _(e, t, n = !1) {
202
+ let r = e.trim(), i = t.trim(), a = r.length > 1 && r === r.toUpperCase() && /^[A-Z]+$/.test(r);
203
+ if (n || (r = r.toLowerCase(), i = i.toLowerCase()), r === i) return 1;
204
+ if (r === "" || i === "") return 0;
205
+ if (a) {
206
+ let e = i.split(/[^a-z0-9]+/i).filter((e) => e.length > 0);
207
+ if (e.length >= r.length) {
208
+ let t = 0, n = 0;
209
+ for (let i = 0; i < r.length; i++) {
210
+ let a = r[i];
211
+ for (; n < e.length;) {
212
+ if ((e[n] ?? "")[0] === a) {
213
+ t++, n++;
214
+ break;
215
+ }
216
+ n++;
217
+ }
218
+ }
219
+ if (t === r.length) return .85;
220
+ }
221
+ }
222
+ let o = !1;
223
+ for (let e = 0; e < r.length; e++) if (i.includes(r[e] ?? "")) {
224
+ o = !0;
225
+ break;
226
+ }
227
+ if (!o) return 0;
228
+ let s = i.indexOf(r);
229
+ if (s !== -1) {
230
+ let e = s === 0, t = s / i.length * (e ? .01 : .1), n = (i.length - r.length) / i.length * (e ? .01 : .05);
231
+ return Math.max(.7, .95 - t - n);
232
+ }
233
+ let c = 0, l = -1, u = 0, d = 0, f = 0;
234
+ for (let e = 0; e < r.length; e++) {
235
+ let t = r[e];
236
+ if (!t) continue;
237
+ let n = i.indexOf(t, f);
238
+ if (n !== -1) c++, l !== -1 && (n > l ? u += n - l : (d++, u += 1)), l = n, f = n + 1, f >= i.length && (f = 0);
239
+ else {
240
+ let e = i.indexOf(t);
241
+ e !== -1 && (c++, d++, l = e, f = e + 1);
242
+ }
243
+ }
244
+ if (c < r.length / 2) return 0;
245
+ let p = c / r.length, m = .6 ** d, h = c > 1 ? u / (c - 1) : 1, g = Math.max(.4, 1 - h / i.length), _ = p * m * g;
246
+ return Math.max(0, _ * .45);
247
+ }
248
+ //#endregion
249
+ //#region src/hooks/useFuzzySearch.ts
250
+ function v(e, t, n, r = {}) {
251
+ let a = r.threshold ?? .01, o = r.caseSensitive ?? !1, s = r.matchStrategy ?? "any", c = r.exactPhraseBonus ?? !0, l = i(() => n.length === 0 || e.length === 0 ? [] : e.map((e, t) => {
252
+ let r = [], i = [];
253
+ for (let [t, a] of n) {
254
+ let n = h(e, t);
255
+ if (Array.isArray(n)) {
256
+ for (let e of n) if (e != null && e !== "" && typeof e != "object") {
257
+ let t = String(e);
258
+ i.push(t);
259
+ let n = t.split(/[^a-z0-9]+/i).filter((e) => e.length > 0);
260
+ for (let e of n) r.push({
261
+ text: e,
262
+ weight: a
263
+ });
264
+ }
265
+ } else if (n != null && n !== "" && typeof n != "object") {
266
+ let e = String(n);
267
+ i.push(e);
268
+ let t = e.split(/[^a-z0-9]+/i).filter((e) => e.length > 0);
269
+ for (let e of t) r.push({
270
+ text: e,
271
+ weight: a
272
+ });
273
+ }
274
+ }
275
+ return {
276
+ item: e,
277
+ index: t,
278
+ tokens: r,
279
+ combinedFlatText: i.join(" ")
280
+ };
281
+ }), [e, n]);
282
+ return i(() => {
283
+ let n = t.trim();
284
+ if (!n || l.length === 0) return e;
285
+ let r = n.split(/\s+/).filter((e) => e.length > 0);
286
+ if (r.length === 0) return e;
287
+ let i = [], u = .3;
288
+ for (let e of l) {
289
+ let t = 0, n = 0, l = !1;
290
+ for (let i of r) {
291
+ let r = 0, a = o ? i : i.toLowerCase();
292
+ for (let t of e.tokens) {
293
+ let e = (o ? t.text : t.text.toLowerCase()).split(/\s+/).filter((e) => e.length > 0);
294
+ for (let n of e) {
295
+ if (!n.includes(a)) {
296
+ if (n.length < i.length / 2) continue;
297
+ let e = Math.abs(i.length - n.length), t = Math.max(i.length, n.length);
298
+ if (t > 0 && (t - e) / t < u) continue;
299
+ }
300
+ let e = _(i, n, o) * t.weight;
301
+ e > r && (r = e);
302
+ }
303
+ }
304
+ r >= u && n++, t += r;
305
+ }
306
+ if (s === "all" && n < r.length && (l = !0), !l) {
307
+ let n = t / r.length;
308
+ if (c && r.length > 1) {
309
+ let t = r.map((e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("\\s+");
310
+ new RegExp(t, o ? "g" : "gi").test(e.combinedFlatText) && (n += .15);
311
+ }
312
+ n >= a && i.push({
313
+ item: e.item,
314
+ score: n,
315
+ index: e.index
316
+ });
317
+ }
318
+ }
319
+ return i.toSorted((e, t) => t.score === e.score ? e.index - t.index : t.score - e.score).map((e) => e.item);
320
+ }, [
321
+ l,
322
+ e,
323
+ t,
324
+ a,
325
+ o,
326
+ s,
327
+ c
328
+ ]);
329
+ }
330
+ //#endregion
179
331
  //#region src/constants/keyConstants.ts
180
- var _ = [
332
+ var y = [
181
333
  "keydown",
182
334
  "keyup",
183
335
  "keypress"
184
336
  ];
185
337
  //#endregion
186
338
  //#region src/hooks/useKey.ts
187
- function v(e, t, { enabled: n = !0, preventDefault: i = !0, stopPropagation: o = !0, eventType: s = "keydown", requireReset: c = !1, ignoreInputs: l = !0, ctrlKey: u = !1, shiftKey: d = !1, altKey: f = !1, metaKey: p = !1, target: m = window } = {}) {
188
- let h = a(t), g = a(n), v = a(!1), y = m && "current" in m && m.current || window;
339
+ function b(e, t, { enabled: n = !0, preventDefault: i = !0, stopPropagation: o = !0, eventType: s = "keydown", requireReset: c = !1, ignoreInputs: l = !0, ctrlKey: u = !1, shiftKey: d = !1, altKey: f = !1, metaKey: p = !1, target: m = window } = {}) {
340
+ let h = a(t), g = a(n), _ = a(!1), v = m && "current" in m && m.current || window;
189
341
  r(() => {
190
342
  h.current = t;
191
343
  }, [t]), r(() => {
192
344
  g.current = n;
193
345
  }, [n]), r(() => {
194
- if (!y) return;
195
- let t = _.includes(s) ? s : "keydown";
346
+ if (!v) return;
347
+ let t = y.includes(s) ? s : "keydown";
196
348
  function n(t) {
197
349
  if (!(t instanceof KeyboardEvent)) return;
198
350
  let n = t.key.toLowerCase();
199
- (n === e.toLowerCase() || u && n === "control" || d && n === "shift" || f && n === "alt" || p && n === "meta") && (v.current = !1);
351
+ (n === e.toLowerCase() || u && n === "control" || d && n === "shift" || f && n === "alt" || p && n === "meta") && (_.current = !1);
200
352
  }
201
353
  function r(t) {
202
354
  if (!(t instanceof KeyboardEvent) || !g.current) return;
203
355
  let n = t.target;
204
356
  if (!(l && n instanceof HTMLElement && (n instanceof HTMLInputElement || n instanceof HTMLTextAreaElement || n instanceof HTMLSelectElement || n.isContentEditable)) && t.ctrlKey === u && t.shiftKey === d && t.altKey === f && t.metaKey === p && e.toLowerCase() === t.key.toLowerCase()) {
205
- if (c && v.current) return;
206
- v.current = !0, h.current(t), i && t.preventDefault(), o && t.stopPropagation();
357
+ if (c && _.current) return;
358
+ _.current = !0, h.current(t), i && t.preventDefault(), o && t.stopPropagation();
207
359
  }
208
360
  }
209
- return y.addEventListener(t, r), y.addEventListener("keyup", n), () => {
210
- y.removeEventListener(t, r), y.removeEventListener("keyup", n);
361
+ return v.addEventListener(t, r), v.addEventListener("keyup", n), () => {
362
+ v.removeEventListener(t, r), v.removeEventListener("keyup", n);
211
363
  };
212
364
  }, [
213
365
  e,
@@ -220,78 +372,80 @@ function v(e, t, { enabled: n = !0, preventDefault: i = !0, stopPropagation: o =
220
372
  d,
221
373
  f,
222
374
  p,
223
- y
375
+ v
224
376
  ]);
225
377
  }
226
378
  //#endregion
227
379
  //#region src/hooks/usePagination.ts
228
- function y(e, n, r = 0) {
380
+ function x(e, n, r = 0) {
229
381
  let [a, s] = o(n), [c, l] = o(r), u = Math.max(1, Math.ceil(e.length / Math.max(1, a))), d = Math.min(Math.max(0, c), u - 1);
230
- return c !== d && l(d), {
231
- currentItems: i(() => typeof a != "number" || a < 1 ? [] : e.slice(c * a, (c + 1) * a), [
232
- c,
233
- a,
234
- e
235
- ]),
382
+ c !== d && l(d);
383
+ let f = i(() => typeof a != "number" || a < 1 ? [] : e.slice(c * a, (c + 1) * a), [
384
+ c,
385
+ a,
386
+ e
387
+ ]), p = c > 0, m = c < u - 1, h = t(() => {
388
+ l((e) => e < u - 1 ? e + 1 : e);
389
+ }, [u]), g = t(() => {
390
+ l((e) => e > 0 ? e - 1 : e);
391
+ }, []), _ = t(() => {
392
+ l(0);
393
+ }, []), v = t(() => {
394
+ l(u - 1);
395
+ }, [u]), y = t((e) => {
396
+ typeof e == "number" && e >= 0 && e <= u - 1 && l(e);
397
+ }, [u]), b = t((t) => {
398
+ if (typeof t == "number" && t > 0) {
399
+ s(t);
400
+ let n = Math.max(1, Math.ceil(e.length / Math.max(1, t)));
401
+ l((e) => Math.min(Math.max(0, e), n - 1));
402
+ }
403
+ }, [e.length]), x = t(() => {
404
+ l(Math.min(Math.max(0, r), u - 1));
405
+ }, [r, u]);
406
+ return {
407
+ currentItems: f,
236
408
  pageSize: a,
237
409
  pageIndex: c,
238
410
  totalPages: u,
239
- canPrevious: c > 0,
240
- canNext: c < u - 1,
241
- nextPage: t(() => {
242
- l((e) => e < u - 1 ? e + 1 : e);
243
- }, [u]),
244
- previousPage: t(() => {
245
- l((e) => e > 0 ? e - 1 : e);
246
- }, []),
247
- firstPage: t(() => {
248
- l(0);
249
- }, []),
250
- lastPage: t(() => {
251
- l(u - 1);
252
- }, [u]),
253
- setPageIndex: t((e) => {
254
- typeof e == "number" && e >= 0 && e <= u - 1 && l(e);
255
- }, [u]),
256
- setPageSize: t((t) => {
257
- if (typeof t == "number" && t > 0) {
258
- s(t);
259
- let n = Math.max(1, Math.ceil(e.length / Math.max(1, t)));
260
- l((e) => Math.min(Math.max(0, e), n - 1));
261
- }
262
- }, [e.length]),
263
- resetPageIndex: t(() => {
264
- l(Math.min(Math.max(0, r), u - 1));
265
- }, [r, u]),
411
+ canPrevious: p,
412
+ canNext: m,
413
+ nextPage: h,
414
+ previousPage: g,
415
+ firstPage: _,
416
+ lastPage: v,
417
+ setPageSize: b,
418
+ setPageIndex: y,
266
419
  resetPageSize: t(() => {
267
420
  s(Math.max(1, n));
268
421
  let t = Math.max(1, Math.ceil(e.length / Math.max(1, n)));
269
422
  l((e) => Math.min(Math.max(0, e), t - 1));
270
- }, [n, e.length])
423
+ }, [n, e.length]),
424
+ resetPageIndex: x
271
425
  };
272
426
  }
273
427
  //#endregion
274
428
  //#region src/utils/sortUtils.ts
275
- function b(e, t, n = {}) {
276
- let { sortUndefined: r, desc: i = !1 } = n, a = D(e, t, r, i);
429
+ function S(e, t, n = {}) {
430
+ let { sortUndefined: r, desc: i = !1 } = n, a = k(e, t, r, i);
277
431
  if (a !== null) return a;
278
432
  let o = !!e;
279
433
  return o === !!t ? 0 : o ? 1 : -1;
280
434
  }
281
- function x(e, t, n = {}) {
282
- let { sortUndefined: r, desc: i = !1 } = n, a = D(e, t, r, i);
435
+ function C(e, t, n = {}) {
436
+ let { sortUndefined: r, desc: i = !1 } = n, a = k(e, t, r, i);
283
437
  if (a !== null) return a;
284
- let o = e === "" || e === null ? NaN : Number(e), s = t === "" || t === null ? NaN : Number(t), c = Number.isNaN(o), l = Number.isNaN(s);
285
- return c || l ? D(c ? void 0 : o, l ? void 0 : s, r, i) ?? 0 : o - s;
438
+ let o = Number(e), s = Number(t), c = Number.isNaN(o), l = Number.isNaN(s);
439
+ return c || l ? k(c ? void 0 : o, l ? void 0 : s, r, i) ?? 0 : o - s;
286
440
  }
287
- function S(e, t, n = {}) {
288
- let { desc: r = !1, sortUndefined: i, caseSensitive: a = !1 } = n, o = D(e, t, i, r);
441
+ function w(e, t, n = {}) {
442
+ let { desc: r = !1, sortUndefined: i, caseSensitive: a = !1 } = n, o = k(e, t, i, r);
289
443
  if (o !== null) return o;
290
444
  let s = String(e), c = String(t);
291
445
  return s.localeCompare(c, void 0, { sensitivity: a ? "variant" : "base" });
292
446
  }
293
- function C(e, t, n = {}) {
294
- let { desc: r = !1, sortUndefined: i, caseSensitive: a = !1 } = n, o = D(e, t, i, r);
447
+ function T(e, t, n = {}) {
448
+ let { desc: r = !1, sortUndefined: i, caseSensitive: a = !1 } = n, o = k(e, t, i, r);
295
449
  if (o !== null) return o;
296
450
  let s = String(e), c = String(t);
297
451
  return s.localeCompare(c, void 0, {
@@ -299,116 +453,122 @@ function C(e, t, n = {}) {
299
453
  sensitivity: a ? "variant" : "base"
300
454
  });
301
455
  }
302
- function w(e, t, n = {}) {
303
- let { desc: r = !1, sortUndefined: i } = n, a = D(e, t, i, r);
456
+ function E(e, t, n = {}) {
457
+ let { desc: r = !1, sortUndefined: i } = n, a = k(e, t, i, r);
304
458
  if (a !== null) return a;
305
- let o = new Date(e).getTime(), s = new Date(t).getTime();
306
- return (Number.isNaN(o) ? 0 : o) - (Number.isNaN(s) ? 0 : s);
459
+ let o = new Date(e).getTime(), s = new Date(t).getTime(), c = Number.isNaN(o), l = Number.isNaN(s);
460
+ return (c || l) && (a = k(c ? void 0 : o, l ? void 0 : s, i, r), a !== null) ? a : o - s;
307
461
  }
308
- function T(e, t, n = {}) {
309
- let { desc: r = !1, sortUndefined: i } = n, a = D(e, t, i, r);
462
+ function D(e, t, n = {}) {
463
+ let { desc: r = !1, sortUndefined: i } = n, a = k(e, t, i, r);
310
464
  return a === null ? e < t ? -1 : +(e > t) : a;
311
465
  }
312
- function E(e, t, n = {}) {
313
- let { desc: r = !1, sortUndefined: i, compare: a } = n, o = D(e, t, i, r);
466
+ function O(e, t, n = {}) {
467
+ let { desc: r = !1, sortUndefined: i, compare: a } = n, o = k(e, t, i, r);
314
468
  return o === null ? typeof a == "function" ? a(e, t) : e < t ? -1 : +(e > t) : o;
315
469
  }
316
- function D(e, t, n = !1, r) {
317
- let i = e ?? void 0, a = t ?? void 0;
318
- if (i !== void 0 && a !== void 0) return null;
319
- if (i === void 0 && a === void 0 || n === !1) return 0;
320
- if (n === "first") return i === void 0 ? -1 : 1;
321
- if (n === "last") return i === void 0 ? 1 : -1;
470
+ function k(e, t, n = "last", r) {
471
+ let i = e == null || e === "", a = t == null || t === "";
472
+ if (i && a) return 0;
473
+ if (!i && !a) return null;
474
+ if (n === "first") return i ? -1 : 1;
475
+ if (n === "last") return i ? 1 : -1;
322
476
  if (n === -1) {
323
477
  let e = r ? 1 : -1;
324
- return i === void 0 ? e : -e;
478
+ return i ? e : -e;
325
479
  }
326
480
  if (n === 1) {
327
481
  let e = r ? 1 : -1;
328
- return i === void 0 ? -e : e;
482
+ return i ? -e : e;
329
483
  }
330
484
  return null;
331
485
  }
332
486
  //#endregion
333
487
  //#region src/hooks/useSort.ts
334
- function O(e, n = []) {
335
- let [r, a] = o(n);
336
- return {
337
- sortedItems: i(() => e.toSorted((e, t) => {
338
- for (let n of r) {
339
- let { type: r, field: i, id: a, desc: o = !1, invertSorting: s = !1 } = n, c = h(e, i, a), l = h(t, i, a), u;
340
- switch (r) {
488
+ function A(e, n = []) {
489
+ let [r, a] = o(n), s = i(() => {
490
+ let t = r.map((e) => ({
491
+ ...e,
492
+ pathArray: (e.field || e.id).split(".")
493
+ }));
494
+ return [...e].sort((e, n) => {
495
+ for (let r of t) {
496
+ let { type: t, id: i, desc: a = !1, invertSorting: o = !1, pathArray: s } = r, c = h(e, s, i), l = h(n, s, i), u;
497
+ switch (t) {
341
498
  case "numeric":
342
- u = x(c, l, n);
499
+ u = C(c, l, r);
343
500
  break;
344
501
  case "alphabetical":
345
- u = S(c, l, n);
502
+ u = w(c, l, r);
346
503
  break;
347
504
  case "alphanumeric":
348
- u = C(c, l, n);
505
+ u = T(c, l, r);
349
506
  break;
350
507
  case "boolean":
351
- u = b(c, l, n);
508
+ u = S(c, l, r);
352
509
  break;
353
510
  case "date":
354
- u = w(c, l, n);
511
+ u = E(c, l, r);
355
512
  break;
356
513
  case "basic":
357
- u = T(c, l, n);
514
+ u = D(c, l, r);
358
515
  break;
359
516
  case "custom":
360
- u = E(c, l, n);
517
+ u = O(c, l, r);
361
518
  break;
362
- default: u = T(c, l, n);
519
+ default: u = D(c, l, r);
363
520
  }
364
- if (u !== 0) return u * (o === s ? 1 : -1);
521
+ if (u !== 0) return u * (a === o ? 1 : -1);
365
522
  }
366
523
  return 0;
367
- }), [r, e]),
524
+ });
525
+ }, [r, e]), c = t((e) => a((t) => t.some((t) => t.id === e.id) ? t.map((t) => t.id === e.id ? e : t) : [...t, e]), []), l = t((e) => {
526
+ a((t) => Array.isArray(e) ? t.filter((t) => !e.includes(t.id)) : t.filter((t) => t.id !== e));
527
+ }, []), u = t(() => a([]), []), d = t(() => a(n), [n]), f = t((e) => a(e), []), p = t((e, t, n) => {
528
+ let { multi: r = !1, ...i } = n || {};
529
+ a((n) => {
530
+ let a = n.find((t) => t.id === e);
531
+ if (!a) {
532
+ let a = {
533
+ id: e,
534
+ type: t,
535
+ ...i,
536
+ desc: !1
537
+ };
538
+ return r ? [...n, a] : [a];
539
+ }
540
+ if (!a.desc) {
541
+ let t = {
542
+ ...a,
543
+ ...i,
544
+ desc: !0
545
+ };
546
+ return r ? n.map((n) => n.id === e ? t : n) : [t];
547
+ }
548
+ if (a.disableSortRemoval || i.disableSortRemoval) {
549
+ let t = {
550
+ ...a,
551
+ ...i,
552
+ desc: !1
553
+ };
554
+ return r ? n.map((n) => n.id === e ? t : n) : [t];
555
+ }
556
+ return r ? n.filter((t) => t.id !== e) : [];
557
+ });
558
+ }, []);
559
+ return {
560
+ sortedItems: s,
368
561
  sorts: r,
369
- addSort: t((e) => a((t) => t.some((t) => t.id === e.id) ? t.map((t) => t.id === e.id ? e : t) : [...t, e]), []),
370
- removeSort: t((e) => {
371
- a((t) => Array.isArray(e) ? t.filter((t) => !e.includes(t.id)) : t.filter((t) => t.id !== e));
372
- }, []),
373
- clearSorts: t(() => a([]), []),
374
- resetSorts: t(() => a(n), [n]),
375
- setSorts: t((e) => a(e), []),
562
+ upsertSorts: c,
563
+ removeSort: l,
564
+ clearSorts: u,
565
+ resetSorts: d,
566
+ replaceSorts: f,
376
567
  getSortDirection: t((e) => {
377
568
  let t = r.find((t) => t.id === e);
378
569
  return t ? t.desc ? "desc" : "asc" : void 0;
379
570
  }, [r]),
380
- toggleSort: t((e, t, n) => {
381
- let { multi: r = !1, ...i } = n || {};
382
- a((n) => {
383
- let a = n.find((t) => t.id === e);
384
- if (!a) {
385
- let a = {
386
- id: e,
387
- type: t,
388
- ...i,
389
- desc: !1
390
- };
391
- return r ? [...n, a] : [a];
392
- }
393
- if (!a.desc) {
394
- let t = {
395
- ...a,
396
- ...i,
397
- desc: !0
398
- };
399
- return r ? n.map((n) => n.id === e ? t : n) : [t];
400
- }
401
- if (a.disableSortRemoval || i.disableSortRemoval) {
402
- let t = {
403
- ...a,
404
- ...i,
405
- desc: !1
406
- };
407
- return r ? n.map((n) => n.id === e ? t : n) : [t];
408
- }
409
- return r ? n.filter((t) => t.id !== e) : [];
410
- });
411
- }, []),
571
+ toggleSort: p,
412
572
  getNextSortingOrder: t((e) => {
413
573
  let t = r.find((t) => t.id === e);
414
574
  return t ? t.desc ? t.disableSortRemoval ? "asc" : "none" : "desc" : "asc";
@@ -421,7 +581,7 @@ function O(e, n = []) {
421
581
  }
422
582
  //#endregion
423
583
  //#region src/hooks/useThrottle.ts
424
- function k(e, n, i = {}) {
584
+ function j(e, n, i = {}) {
425
585
  let [s, c] = o(!1), l = i.leading ?? !0, u = i.trailing ?? !0, d = a(e), f = a(null), p = a(-1), m = a(null);
426
586
  r(() => {
427
587
  d.current = e;
@@ -455,4 +615,4 @@ function k(e, n, i = {}) {
455
615
  };
456
616
  }
457
617
  //#endregion
458
- export { d as ModalLayout, f as useDebounce, p as useDebouncedValue, g as useFilter, v as useKey, u as useModal, y as usePagination, O as useSort, k as useThrottle };
618
+ export { d as ModalLayout, f as useDebounce, p as useDebouncedValue, g as useFilter, v as useFuzzySearch, b as useKey, u as useModal, x as usePagination, A as useSort, j as useThrottle };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@himanshu-sorathiya/react-kit",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "An opinionated collection of react hooks, and reusable UI components.",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",