meticulous-ui 3.2.5 → 3.2.7

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 (54) hide show
  1. package/README.md +17 -73
  2. package/package.json +1 -1
  3. package/utils/announceToScreenReader.js +9 -0
  4. package/utils/buildURL.js +9 -0
  5. package/utils/cancelablePromise.js +17 -0
  6. package/utils/captureException.js +12 -0
  7. package/utils/clearStorage.js +6 -0
  8. package/utils/debounce.js +9 -0
  9. package/utils/decodeJWT.js +11 -0
  10. package/utils/detectOutsideClick.js +10 -0
  11. package/utils/fallback.js +4 -0
  12. package/utils/focusElement.js +7 -0
  13. package/utils/generateAriaId.js +5 -0
  14. package/utils/getCurrentPath.js +4 -0
  15. package/utils/getLocalStorage.js +11 -0
  16. package/utils/getQueryParams.js +9 -0
  17. package/utils/getSessionStorage.js +11 -0
  18. package/utils/getToken.js +4 -0
  19. package/utils/getVariant.js +10 -0
  20. package/utils/handleKeyboardNavigation.js +17 -0
  21. package/utils/hasPermission.js +13 -0
  22. package/utils/index.js +202 -91
  23. package/utils/isActiveRoute.js +4 -0
  24. package/utils/isAuthenticated.js +14 -0
  25. package/utils/isFeatureEnabled.js +10 -0
  26. package/utils/lazyLoadComponent.js +5 -0
  27. package/utils/lockBodyScroll.js +6 -0
  28. package/utils/logError.js +7 -0
  29. package/utils/measureElement.js +7 -0
  30. package/utils/memoize.js +12 -0
  31. package/utils/parallel.js +4 -0
  32. package/utils/rafThrottle.js +11 -0
  33. package/utils/redirectTo.js +6 -0
  34. package/utils/removeLocalStorage.js +6 -0
  35. package/utils/removeQueryParam.js +7 -0
  36. package/utils/removeToken.js +4 -0
  37. package/utils/requestIdleTask.js +6 -0
  38. package/utils/retry.js +13 -0
  39. package/utils/safeAsync.js +10 -0
  40. package/utils/safeJSONParse.js +10 -0
  41. package/utils/safeJSONStringify.js +10 -0
  42. package/utils/scrollToElement.js +7 -0
  43. package/utils/scrollToTop.js +6 -0
  44. package/utils/sequential.js +9 -0
  45. package/utils/setLocalStorage.js +9 -0
  46. package/utils/setQueryParam.js +7 -0
  47. package/utils/setSessionStorage.js +9 -0
  48. package/utils/setToken.js +4 -0
  49. package/utils/sleep.js +4 -0
  50. package/utils/throttle.js +10 -0
  51. package/utils/toggleFullscreen.js +7 -0
  52. package/utils/trapFocus.js +16 -0
  53. package/utils/unlockBodyScroll.js +6 -0
  54. package/utils/withTimeout.js +9 -0
package/README.md CHANGED
@@ -142,79 +142,23 @@ import blue from 'meticulous-ui/colors/blue';
142
142
 
143
143
  ## 📦 Utils
144
144
 
145
- ### General
146
-
147
- | Function | Signature | Description |
148
- | ------------- | -------------------------- | ----------------------------------------- |
149
- | `compose` | `(...funcs) (val) any` | Right-to-left function composition |
150
- | `randomInt` | `(min, max) number` | Random integer in `[min, floor(max + 1))` |
151
- | `randomValue` | `(min, max) number` | Random float in `[min, max + 1)` |
152
-
153
- ### Data Utilities
154
-
155
- | Function | Signature | Description |
156
- | ----------------- | -------------------------------- | ------------------------------------------------------------------------ |
157
- | `deepClone` | `(obj) any` | Recursively clones objects, arrays, and Dates with no shared references |
158
- | `mergeDeep` | `(target, source) object` | Deep-merges source into target; source wins on conflicts |
159
- | `pick` | `(obj, keys) object` | Returns a new object with only the specified keys |
160
- | `omit` | `(obj, keys) object` | Returns a new object without the specified keys |
161
- | `isEmpty` | `(value) → boolean` | `true` for `null`, `undefined`, `""`, `[]`, `{}` |
162
- | `isEqual` | `(a, b) → boolean` | Deep structural equality — handles objects, arrays, and Dates |
163
- | `hasEqualProps` | `(oldProps, newProps) → boolean` | Deep equality ignoring function-valued keys; ideal for `React.memo` |
164
- | `isNonEmptyArray` | `(arr) → boolean` | `true` only when the value is an array with at least one element |
165
- | `flattenObject` | `(obj, prefix?) → object` | Collapses nested object to dot-notation keys |
166
- | `groupBy` | `(array, key) → object` | Groups array items into an object of arrays keyed by a field or function |
167
- | `keyBy` | `(array, key) → object` | Converts an array into a lookup object keyed by a field or function |
168
- | `uniqueBy` | `(array, key) → array` | Removes duplicates by a field or function; first occurrence wins |
169
- | `sortBy` | `(array, key) → array` | Ascending sort by a field or function; non-mutating |
170
- | `chunk` | `(array, size) → array[]` | Splits array into consecutive chunks of the given size |
171
-
172
- ### String Utilities
173
-
174
- | Function | Signature | Description |
175
- | ------------------- | ----------------------- | ------------------------------------------------------------------- |
176
- | `capFirstLetter` | `(str) → string` | Takes a string and returns with first letter capitalised |
177
- | `capitalize` | `(str) → string` | Uppercases first character, lowercases the rest |
178
- | `titleCase` | `(str) → string` | Capitalizes the first letter of every word |
179
- | `camelCase` | `(str) → string` | Converts to `camelCase` from spaces, hyphens, or underscores |
180
- | `snakeCase` | `(str) → string` | Converts to `snake_case` from camelCase, spaces, or hyphens |
181
- | `kebabCase` | `(str) → string` | Converts to `kebab-case` from camelCase, spaces, or underscores |
182
- | `truncate` | `(str, limit) → string` | Trims to `limit` characters and appends `…` |
183
- | `slugify` | `(str) → string` | URL-safe slug — strips diacritics, removes special chars |
184
- | `removeExtraSpaces` | `(str) → string` | Trims and collapses internal whitespace runs to a single space |
185
- | `maskEmail` | `(str) → string` | Shows only the first character of the local part, e.g. `j***@x.com` |
186
- | `maskPhone` | `(str) → string` | Masks all digits except the last four; preserves formatting chars |
187
- | `generateInitials` | `(name) → string` | Extracts uppercased first letter of each word, e.g. `"JD"` |
188
-
189
- ### Device Utilities
190
-
191
- | Function | Signature | Description |
192
- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------ |
193
- | `isMobile` | `() → boolean` | `true` when the UA matches any known mobile platform |
194
- | `isIOS` | `() → boolean` | `true` on iPhone, iPad, and iPod; handles iPadOS 13+ UA quirk |
195
- | `isAndroid` | `() → boolean` | `true` when the UA string contains `Android` |
196
- | `isSafari` | `() → boolean` | `true` for genuine Safari; excludes Chrome/Android which also include "Safari" |
197
- | `isDarkMode` | `() → boolean` | `true` when the OS/browser prefers dark color scheme |
198
- | `isOnline` | `() → boolean` | `true` when the browser reports network connectivity |
199
- | `copyToClipboard` | `(text: string) → Promise<void>` | Copies text using Clipboard API with `execCommand` fallback |
200
- | `downloadFile` | `(url: string, filename?: string) → void` | Triggers a file download; filename inferred from URL if omitted |
201
- | `openInNewTab` | `(url: string) → void` | Opens URL in a new tab with `noopener,noreferrer` |
202
- | `getScreenSize` | `() → { width, height, deviceWidth, deviceHeight, pixelRatio }` | Returns viewport size, physical screen size, and device pixel ratio |
203
-
204
- ### Validation Utilities
205
-
206
- | Function | Signature | Description |
207
- | ------------------ | ---------------------- | ------------------------------------------------------------------------- |
208
- | `isEmail` | `(value) → boolean` | Valid email — must have local part, `@`, and domain with dot |
209
- | `isPhone` | `(value) → boolean` | Plausible phone — optional `+`, 7–15 digits, allows spaces/hyphens/parens |
210
- | `isURL` | `(value) → boolean` | Valid `http` or `https` URL via native `URL` constructor |
211
- | `isPasswordStrong` | `(value) → boolean` | 8+ chars with uppercase, lowercase, digit, and special character |
212
- | `isPAN` | `(value) → boolean` | Indian PAN — `AAAAA0000A` (5 letters, 4 digits, 1 letter) |
213
- | `isAadhaar` | `(value) → boolean` | Indian Aadhaar — 12 digits, first digit non-zero; strips spaces |
214
- | `isGST` | `(value) → boolean` | Indian GSTIN — 2-digit state code + PAN + entity digit + `Z` + check char |
215
- | `isRequired` | `(value) → boolean` | `false` for `null`, `undefined`, blank strings, and empty arrays |
216
- | `minLength` | `(value, n) → boolean` | `true` when `value.length >= n` |
217
- | `maxLength` | `(value, n) → boolean` | `true` when `value.length <= n` |
145
+ | Category | Functions |
146
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
147
+ | **String** | `capFirstLetter`, `capitalize`, `titleCase`, `camelCase`, `snakeCase`, `kebabCase`, `slugify`, `truncate`, `removeExtraSpaces`, `maskEmail`, `maskPhone`, `generateInitials`, |
148
+ | **Number** | `clamp`, `formatCurrency`, `formatNumber`, `formatCompactNumber`, `percentage`, `randomInt`, `randomBetween`, `randomValue`, `roundTo`, |
149
+ | **Date-Time** | `formatDate`, `formatTime`, `addDays`, `differenceInDays`, `isToday`, `isPast`, `timeAgo`, `getGreetingByTime`, `countdown`, |
150
+ | **Data** | `deepClone`, `mergeDeep`, `pick`, `omit`, `isEmpty`, `isEqual`, `hasEqualProps`, `isNonEmptyArray`, `flattenObject`, `groupBy`, `keyBy`, `uniqueBy`, `sortBy`, `chunk`, `compose`, |
151
+ | **Validation** | `isEmail`, `isPhone`, `isURL`, `isPasswordStrong`, `isPAN`, `isAadhaar`, `isGST`, `isRequired`, `minLength`, `maxLength`, |
152
+ | **Device** | `isMobile`, `isIOS`, `isAndroid`, `isSafari`, `isDarkMode`, `isOnline`, `copyToClipboard`, `downloadFile`, `openInNewTab`, `getScreenSize`, |
153
+ | **Storage** | `setLocalStorage`, `getLocalStorage`, `removeLocalStorage`, `setSessionStorage`, `getSessionStorage`, `clearStorage`, |
154
+ | **Routing** | `getQueryParams`, `setQueryParam`, `removeQueryParam`, `buildURL`, `redirectTo`, `getCurrentPath`, `isActiveRoute`, |
155
+ | **UI** | `scrollToTop`, `scrollToElement`, `lockBodyScroll`, `unlockBodyScroll`, `toggleFullscreen`, `focusElement`, `detectOutsideClick`, `measureElement`, |
156
+ | **Performance** | `debounce`, `throttle`, `memoize`, `lazyLoadComponent`, `requestIdleTask`, `rafThrottle`, |
157
+ | **Async** | `retry`, `sleep`, `withTimeout`, `parallel`, `sequential`, `safeAsync`, `cancelablePromise` |
158
+ | **Accessibility** | `announceToScreenReader`, `trapFocus`, `generateAriaId`, `handleKeyboardNavigation` |
159
+ | **Error Handling** | `logError`, `captureException`, `safeJSONParse`, `safeJSONStringify`, `fallback` |
160
+ | **Auth** | `isAuthenticated`, `getToken`, `setToken`, `removeToken`, `decodeJWT`, `hasPermission` |
161
+ | **Feature Flags** | `isFeatureEnabled`, `getVariant` |
218
162
 
219
163
  ## 🌱 Features
220
164
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meticulous-ui",
3
- "version": "3.2.5",
3
+ "version": "3.2.7",
4
4
  "license": "ISC",
5
5
  "description": "A comprehensive React UI component library with a wide range of customizable components, icons, colors, and utilities for building modern web applications.",
6
6
  "main": "./index.js",
@@ -0,0 +1,9 @@
1
+ const i = (t, o = "polite") => {
2
+ const e = document.createElement("div");
3
+ e.setAttribute("aria-live", o), e.setAttribute("aria-atomic", "true"), e.style.cssText = "position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0", document.body.appendChild(e), requestAnimationFrame(() => {
4
+ e.textContent = t, setTimeout(() => document.body.removeChild(e), 1e3);
5
+ });
6
+ };
7
+ export {
8
+ i as default
9
+ };
@@ -0,0 +1,9 @@
1
+ const a = (r, e = {}) => {
2
+ const t = new URL(r, window.location.origin);
3
+ return Object.entries(e).forEach(([n, o]) => {
4
+ t.searchParams.set(n, o);
5
+ }), t.toString();
6
+ };
7
+ export {
8
+ a as default
9
+ };
@@ -0,0 +1,17 @@
1
+ const t = (c) => {
2
+ let e = !1;
3
+ return {
4
+ promise: new Promise((n, a) => {
5
+ c.then(
6
+ (r) => e ? a({ canceled: !0 }) : n(r),
7
+ (r) => a(e ? { canceled: !0 } : r)
8
+ );
9
+ }),
10
+ cancel: () => {
11
+ e = !0;
12
+ }
13
+ };
14
+ };
15
+ export {
16
+ t as default
17
+ };
@@ -0,0 +1,12 @@
1
+ const o = (e, n = {}) => {
2
+ const t = {
3
+ message: e instanceof Error ? e.message : String(e),
4
+ stack: e instanceof Error ? e.stack : void 0,
5
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6
+ ...n
7
+ };
8
+ return typeof window < "u" && typeof window.__captureException == "function" ? window.__captureException(t) : console.error("[captureException]", t), t;
9
+ };
10
+ export {
11
+ o as default
12
+ };
@@ -0,0 +1,6 @@
1
+ const a = () => {
2
+ localStorage.clear(), sessionStorage.clear();
3
+ };
4
+ export {
5
+ a as default
6
+ };
@@ -0,0 +1,9 @@
1
+ const u = (t, o) => {
2
+ let e;
3
+ return (...r) => {
4
+ clearTimeout(e), e = setTimeout(() => t(...r), o);
5
+ };
6
+ };
7
+ export {
8
+ u as default
9
+ };
@@ -0,0 +1,11 @@
1
+ const e = (t) => {
2
+ try {
3
+ const [, a] = t.split(".");
4
+ return JSON.parse(atob(a));
5
+ } catch {
6
+ return null;
7
+ }
8
+ };
9
+ export {
10
+ e as default
11
+ };
@@ -0,0 +1,10 @@
1
+ const s = (t, d) => {
2
+ const e = (n) => {
3
+ const o = (t == null ? void 0 : t.current) ?? t;
4
+ o && !o.contains(n.target) && d(n);
5
+ };
6
+ return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
7
+ };
8
+ export {
9
+ s as default
10
+ };
@@ -0,0 +1,4 @@
1
+ const f = (n, d) => n != null && n !== "" ? n : d;
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,7 @@
1
+ const o = (t) => {
2
+ const c = (t == null ? void 0 : t.current) ?? t;
3
+ c == null || c.focus();
4
+ };
5
+ export {
6
+ o as default
7
+ };
@@ -0,0 +1,5 @@
1
+ let a = 0;
2
+ const t = (e = "aria") => `${e}-${++a}`;
3
+ export {
4
+ t as default
5
+ };
@@ -0,0 +1,4 @@
1
+ const t = () => window.location.pathname;
2
+ export {
3
+ t as default
4
+ };
@@ -0,0 +1,11 @@
1
+ const l = (e) => {
2
+ try {
3
+ const t = localStorage.getItem(e);
4
+ return t !== null ? JSON.parse(t) : null;
5
+ } catch {
6
+ return null;
7
+ }
8
+ };
9
+ export {
10
+ l as default
11
+ };
@@ -0,0 +1,9 @@
1
+ const o = () => {
2
+ const a = {};
3
+ return new URLSearchParams(window.location.search).forEach((r, e) => {
4
+ a[e] = r;
5
+ }), a;
6
+ };
7
+ export {
8
+ o as default
9
+ };
@@ -0,0 +1,11 @@
1
+ const n = (e) => {
2
+ try {
3
+ const t = sessionStorage.getItem(e);
4
+ return t !== null ? JSON.parse(t) : null;
5
+ } catch {
6
+ return null;
7
+ }
8
+ };
9
+ export {
10
+ n as default
11
+ };
@@ -0,0 +1,4 @@
1
+ const e = (t = "auth_token") => localStorage.getItem(t);
2
+ export {
3
+ e as default
4
+ };
@@ -0,0 +1,10 @@
1
+ const n = (t, a = "ab_variants") => {
2
+ try {
3
+ return JSON.parse(localStorage.getItem(a) ?? "{}")[t] ?? null;
4
+ } catch {
5
+ return null;
6
+ }
7
+ };
8
+ export {
9
+ n as default
10
+ };
@@ -0,0 +1,17 @@
1
+ const y = (a, t, h = {}) => {
2
+ const { onSelect: o, loop: l = !0, orientation: p = "vertical" } = h, n = p === "horizontal" ? "ArrowLeft" : "ArrowUp", v = p === "horizontal" ? "ArrowRight" : "ArrowDown";
3
+ return (r) => {
4
+ if (r.key === v) {
5
+ r.preventDefault();
6
+ const f = t + 1 >= a.length ? l ? 0 : t : t + 1;
7
+ o == null || o(f, a[f]);
8
+ } else if (r.key === n) {
9
+ r.preventDefault();
10
+ const f = t - 1 < 0 ? l ? a.length - 1 : t : t - 1;
11
+ o == null || o(f, a[f]);
12
+ } else r.key === "Home" ? (r.preventDefault(), o == null || o(0, a[0])) : r.key === "End" && (r.preventDefault(), o == null || o(a.length - 1, a[a.length - 1]));
13
+ };
14
+ };
15
+ export {
16
+ y as default
17
+ };
@@ -0,0 +1,13 @@
1
+ import n from "./decodeJWT.js";
2
+ import a from "./getToken.js";
3
+ const l = (o, s = "auth_token") => {
4
+ const t = a(s);
5
+ if (!t) return !1;
6
+ const r = n(t);
7
+ if (!r) return !1;
8
+ const e = r.roles ?? r.role ?? [];
9
+ return Array.isArray(e) ? e.includes(o) : e === o;
10
+ };
11
+ export {
12
+ l as default
13
+ };
package/utils/index.js CHANGED
@@ -1,52 +1,52 @@
1
1
  import o from "./capFirstLetter.js";
2
2
  import r from "./capitalize.js";
3
3
  import m from "./camelCase.js";
4
- import i from "./chunk.js";
5
- import t from "./clamp.js";
6
- import p from "./compose.js";
7
- import f from "./deepClone.js";
8
- import e from "./flattenObject.js";
4
+ import t from "./chunk.js";
5
+ import i from "./clamp.js";
6
+ import e from "./compose.js";
7
+ import p from "./deepClone.js";
8
+ import f from "./flattenObject.js";
9
9
  import a from "./formatCompactNumber.js";
10
10
  import s from "./formatCurrency.js";
11
11
  import n from "./formatDate.js";
12
- import d from "./formatNumber.js";
13
- import l from "./formatTime.js";
14
- import c from "./generateInitials.js";
12
+ import l from "./formatNumber.js";
13
+ import c from "./formatTime.js";
14
+ import d from "./generateInitials.js";
15
15
  import u from "./getGreetingByTime.js";
16
- import y from "./groupBy.js";
17
- import g from "./hasEqualProps.js";
18
- import b from "./addDays.js";
19
- import k from "./countdown.js";
20
- import C from "./differenceInDays.js";
21
- import h from "./isEmpty.js";
22
- import E from "./isEqual.js";
23
- import S from "./isNonEmptyArray.js";
24
- import T from "./isPast.js";
25
- import B from "./isToday.js";
26
- import P from "./kebabCase.js";
27
- import w from "./keyBy.js";
28
- import A from "./maskEmail.js";
29
- import D from "./maskPhone.js";
16
+ import g from "./groupBy.js";
17
+ import y from "./hasEqualProps.js";
18
+ import S from "./addDays.js";
19
+ import T from "./countdown.js";
20
+ import k from "./differenceInDays.js";
21
+ import b from "./isEmpty.js";
22
+ import h from "./isEqual.js";
23
+ import E from "./isNonEmptyArray.js";
24
+ import P from "./isPast.js";
25
+ import C from "./isToday.js";
26
+ import A from "./kebabCase.js";
27
+ import L from "./keyBy.js";
28
+ import B from "./maskEmail.js";
29
+ import N from "./maskPhone.js";
30
30
  import I from "./mergeDeep.js";
31
- import N from "./omit.js";
32
- import q from "./percentage.js";
33
- import x from "./pick.js";
34
- import L from "./randomBetween.js";
35
- import O from "./randomInt.js";
36
- import z from "./randomValue.js";
31
+ import q from "./omit.js";
32
+ import v from "./percentage.js";
33
+ import w from "./pick.js";
34
+ import O from "./randomBetween.js";
35
+ import x from "./randomInt.js";
36
+ import D from "./randomValue.js";
37
37
  import F from "./removeExtraSpaces.js";
38
- import G from "./roundTo.js";
39
- import M from "./slugify.js";
40
- import R from "./snakeCase.js";
41
- import j from "./sortBy.js";
42
- import v from "./timeAgo.js";
43
- import U from "./titleCase.js";
44
- import V from "./truncate.js";
45
- import H from "./uniqueBy.js";
46
- import J from "./isEmail.js";
38
+ import R from "./roundTo.js";
39
+ import z from "./slugify.js";
40
+ import J from "./snakeCase.js";
41
+ import Q from "./sortBy.js";
42
+ import G from "./timeAgo.js";
43
+ import M from "./titleCase.js";
44
+ import U from "./truncate.js";
45
+ import V from "./uniqueBy.js";
46
+ import j from "./isEmail.js";
47
47
  import K from "./isPhone.js";
48
- import Q from "./isURL.js";
49
- import W from "./isPasswordStrong.js";
48
+ import W from "./isURL.js";
49
+ import H from "./isPasswordStrong.js";
50
50
  import X from "./isPAN.js";
51
51
  import Y from "./isAadhaar.js";
52
52
  import Z from "./isGST.js";
@@ -55,69 +55,120 @@ import $ from "./minLength.js";
55
55
  import oo from "./maxLength.js";
56
56
  import ro from "./isMobile.js";
57
57
  import mo from "./isIOS.js";
58
- import io from "./isAndroid.js";
59
- import to from "./isSafari.js";
60
- import po from "./isDarkMode.js";
61
- import fo from "./isOnline.js";
62
- import eo from "./copyToClipboard.js";
58
+ import to from "./isAndroid.js";
59
+ import io from "./isSafari.js";
60
+ import eo from "./isDarkMode.js";
61
+ import po from "./isOnline.js";
62
+ import fo from "./copyToClipboard.js";
63
63
  import ao from "./downloadFile.js";
64
64
  import so from "./openInNewTab.js";
65
65
  import no from "./getScreenSize.js";
66
- const Tr = {
66
+ import lo from "./getQueryParams.js";
67
+ import co from "./setQueryParam.js";
68
+ import uo from "./removeQueryParam.js";
69
+ import go from "./buildURL.js";
70
+ import yo from "./redirectTo.js";
71
+ import So from "./getCurrentPath.js";
72
+ import To from "./isActiveRoute.js";
73
+ import ko from "./setLocalStorage.js";
74
+ import bo from "./getLocalStorage.js";
75
+ import ho from "./removeLocalStorage.js";
76
+ import Eo from "./setSessionStorage.js";
77
+ import Po from "./getSessionStorage.js";
78
+ import Co from "./clearStorage.js";
79
+ import Ao from "./debounce.js";
80
+ import Lo from "./throttle.js";
81
+ import Bo from "./memoize.js";
82
+ import No from "./lazyLoadComponent.js";
83
+ import Io from "./requestIdleTask.js";
84
+ import qo from "./rafThrottle.js";
85
+ import vo from "./scrollToTop.js";
86
+ import wo from "./scrollToElement.js";
87
+ import Oo from "./lockBodyScroll.js";
88
+ import xo from "./unlockBodyScroll.js";
89
+ import Do from "./toggleFullscreen.js";
90
+ import Fo from "./focusElement.js";
91
+ import Ro from "./detectOutsideClick.js";
92
+ import zo from "./measureElement.js";
93
+ import Jo from "./announceToScreenReader.js";
94
+ import Qo from "./trapFocus.js";
95
+ import Go from "./generateAriaId.js";
96
+ import Mo from "./handleKeyboardNavigation.js";
97
+ import Uo from "./logError.js";
98
+ import Vo from "./captureException.js";
99
+ import jo from "./safeJSONParse.js";
100
+ import Ko from "./safeJSONStringify.js";
101
+ import Wo from "./fallback.js";
102
+ import Ho from "./isAuthenticated.js";
103
+ import Xo from "./getToken.js";
104
+ import Yo from "./setToken.js";
105
+ import Zo from "./removeToken.js";
106
+ import _o from "./decodeJWT.js";
107
+ import $o from "./hasPermission.js";
108
+ import or from "./isFeatureEnabled.js";
109
+ import rr from "./getVariant.js";
110
+ import mr from "./retry.js";
111
+ import tr from "./sleep.js";
112
+ import ir from "./withTimeout.js";
113
+ import er from "./parallel.js";
114
+ import pr from "./sequential.js";
115
+ import fr from "./safeAsync.js";
116
+ import ar from "./cancelablePromise.js";
117
+ const St = {
67
118
  // string
68
119
  capFirstLetter: o,
69
120
  capitalize: r,
70
121
  camelCase: m,
71
- generateInitials: c,
72
- kebabCase: P,
73
- maskEmail: A,
74
- maskPhone: D,
122
+ generateInitials: d,
123
+ kebabCase: A,
124
+ maskEmail: B,
125
+ maskPhone: N,
75
126
  removeExtraSpaces: F,
76
- slugify: M,
77
- snakeCase: R,
78
- titleCase: U,
79
- truncate: V,
127
+ slugify: z,
128
+ snakeCase: J,
129
+ titleCase: M,
130
+ truncate: U,
80
131
  // number
81
- clamp: t,
132
+ clamp: i,
82
133
  formatCompactNumber: a,
83
134
  formatCurrency: s,
84
- formatNumber: d,
85
- percentage: q,
86
- randomBetween: L,
87
- randomInt: O,
88
- randomValue: z,
89
- roundTo: G,
135
+ formatNumber: l,
136
+ percentage: v,
137
+ randomBetween: O,
138
+ randomInt: x,
139
+ randomValue: D,
140
+ roundTo: R,
90
141
  // date-time
91
- addDays: b,
92
- countdown: k,
93
- differenceInDays: C,
142
+ addDays: S,
143
+ countdown: T,
144
+ differenceInDays: k,
94
145
  formatDate: n,
95
- formatTime: l,
146
+ formatTime: c,
96
147
  getGreetingByTime: u,
97
- isPast: T,
98
- isToday: B,
99
- timeAgo: v,
148
+ isPast: P,
149
+ isToday: C,
150
+ timeAgo: G,
100
151
  // object / array
101
- chunk: i,
102
- compose: p,
103
- deepClone: f,
104
- flattenObject: e,
105
- groupBy: y,
106
- hasEqualProps: g,
107
- isEmpty: h,
108
- isEqual: E,
109
- isNonEmptyArray: S,
110
- keyBy: w,
152
+ chunk: t,
153
+ compose: e,
154
+ deepClone: p,
155
+ flattenObject: f,
156
+ groupBy: g,
157
+ hasEqualProps: y,
158
+ isEmpty: b,
159
+ isEqual: h,
160
+ isNonEmptyArray: E,
161
+ keyBy: L,
111
162
  mergeDeep: I,
112
- omit: N,
113
- pick: x,
114
- sortBy: j,
115
- uniqueBy: H,
163
+ omit: q,
164
+ pick: w,
165
+ sortBy: Q,
166
+ uniqueBy: V,
116
167
  // validation
117
- isEmail: J,
168
+ isEmail: j,
118
169
  isPhone: K,
119
- isURL: Q,
120
- isPasswordStrong: W,
170
+ isURL: W,
171
+ isPasswordStrong: H,
121
172
  isPAN: X,
122
173
  isAadhaar: Y,
123
174
  isGST: Z,
@@ -127,15 +178,75 @@ const Tr = {
127
178
  // device
128
179
  isMobile: ro,
129
180
  isIOS: mo,
130
- isAndroid: io,
131
- isSafari: to,
132
- isDarkMode: po,
133
- isOnline: fo,
134
- copyToClipboard: eo,
181
+ isAndroid: to,
182
+ isSafari: io,
183
+ isDarkMode: eo,
184
+ isOnline: po,
185
+ copyToClipboard: fo,
135
186
  downloadFile: ao,
136
187
  openInNewTab: so,
137
- getScreenSize: no
188
+ getScreenSize: no,
189
+ // routing
190
+ getQueryParams: lo,
191
+ setQueryParam: co,
192
+ removeQueryParam: uo,
193
+ buildURL: go,
194
+ redirectTo: yo,
195
+ getCurrentPath: So,
196
+ isActiveRoute: To,
197
+ // storage
198
+ setLocalStorage: ko,
199
+ getLocalStorage: bo,
200
+ removeLocalStorage: ho,
201
+ setSessionStorage: Eo,
202
+ getSessionStorage: Po,
203
+ clearStorage: Co,
204
+ // performance
205
+ debounce: Ao,
206
+ throttle: Lo,
207
+ memoize: Bo,
208
+ lazyLoadComponent: No,
209
+ requestIdleTask: Io,
210
+ rafThrottle: qo,
211
+ // ui / dom
212
+ scrollToTop: vo,
213
+ scrollToElement: wo,
214
+ lockBodyScroll: Oo,
215
+ unlockBodyScroll: xo,
216
+ toggleFullscreen: Do,
217
+ focusElement: Fo,
218
+ detectOutsideClick: Ro,
219
+ measureElement: zo,
220
+ // accessibility
221
+ announceToScreenReader: Jo,
222
+ trapFocus: Qo,
223
+ generateAriaId: Go,
224
+ handleKeyboardNavigation: Mo,
225
+ // error handling
226
+ logError: Uo,
227
+ captureException: Vo,
228
+ safeJSONParse: jo,
229
+ safeJSONStringify: Ko,
230
+ fallback: Wo,
231
+ // auth
232
+ isAuthenticated: Ho,
233
+ getToken: Xo,
234
+ setToken: Yo,
235
+ removeToken: Zo,
236
+ decodeJWT: _o,
237
+ hasPermission: $o,
238
+ // feature flags
239
+ isFeatureEnabled: or,
240
+ getVariant: rr,
241
+ // async / api
242
+ retry: mr,
243
+ sleep: tr,
244
+ withTimeout: ir,
245
+ parallel: er,
246
+ sequential: pr,
247
+ safeAsync: fr,
248
+ cancelablePromise: ar
138
249
  };
139
250
  export {
140
- Tr as default
251
+ St as default
141
252
  };
@@ -0,0 +1,4 @@
1
+ const o = (t) => window.location.pathname === t;
2
+ export {
3
+ o as default
4
+ };
@@ -0,0 +1,14 @@
1
+ import o from "./getToken.js";
2
+ const s = (r = "auth_token") => {
3
+ const t = o(r);
4
+ if (!t) return !1;
5
+ try {
6
+ const [, n] = t.split("."), { exp: e } = JSON.parse(atob(n));
7
+ return !(e && Date.now() / 1e3 > e);
8
+ } catch {
9
+ return !!t;
10
+ }
11
+ };
12
+ export {
13
+ s as default
14
+ };
@@ -0,0 +1,10 @@
1
+ const r = (e, t = "feature_flags") => {
2
+ try {
3
+ return JSON.parse(localStorage.getItem(t) ?? "{}")[e] === !0;
4
+ } catch {
5
+ return !1;
6
+ }
7
+ };
8
+ export {
9
+ r as default
10
+ };
@@ -0,0 +1,5 @@
1
+ import { lazy as a } from "react";
2
+ const e = (o) => a(o);
3
+ export {
4
+ e as default
5
+ };
@@ -0,0 +1,6 @@
1
+ const o = () => {
2
+ document.body.style.overflow = "hidden";
3
+ };
4
+ export {
5
+ o as default
6
+ };
@@ -0,0 +1,7 @@
1
+ const c = (s, n = {}) => {
2
+ const o = s instanceof Error ? s.message : String(s), t = s instanceof Error ? s.stack : void 0;
3
+ console.error("[logError]", o, { ...n, stack: t });
4
+ };
5
+ export {
6
+ c as default
7
+ };
@@ -0,0 +1,7 @@
1
+ const e = (t) => {
2
+ const n = (t == null ? void 0 : t.current) ?? t;
3
+ return n ? n.getBoundingClientRect() : null;
4
+ };
5
+ export {
6
+ e as default
7
+ };
@@ -0,0 +1,12 @@
1
+ const c = (s) => {
2
+ const e = /* @__PURE__ */ new Map();
3
+ return (...n) => {
4
+ const t = JSON.stringify(n);
5
+ if (e.has(t)) return e.get(t);
6
+ const r = s(...n);
7
+ return e.set(t, r), r;
8
+ };
9
+ };
10
+ export {
11
+ c as default
12
+ };
@@ -0,0 +1,4 @@
1
+ const a = (l) => Promise.all(l);
2
+ export {
3
+ a as default
4
+ };
@@ -0,0 +1,11 @@
1
+ const l = (t) => {
2
+ let r = null;
3
+ return (...e) => {
4
+ r === null && (r = requestAnimationFrame(() => {
5
+ t(...e), r = null;
6
+ }));
7
+ };
8
+ };
9
+ export {
10
+ l as default
11
+ };
@@ -0,0 +1,6 @@
1
+ const e = (o) => {
2
+ window.location.href = o;
3
+ };
4
+ export {
5
+ e as default
6
+ };
@@ -0,0 +1,6 @@
1
+ const o = (e) => {
2
+ localStorage.removeItem(e);
3
+ };
4
+ export {
5
+ o as default
6
+ };
@@ -0,0 +1,7 @@
1
+ const o = (a) => {
2
+ const e = new URL(window.location.href);
3
+ e.searchParams.delete(a), window.history.pushState({}, "", e);
4
+ };
5
+ export {
6
+ o as default
7
+ };
@@ -0,0 +1,4 @@
1
+ const o = (e = "auth_token") => localStorage.removeItem(e);
2
+ export {
3
+ o as default
4
+ };
@@ -0,0 +1,6 @@
1
+ const l = (e) => {
2
+ typeof requestIdleCallback < "u" ? requestIdleCallback(e) : setTimeout(e, 1);
3
+ };
4
+ export {
5
+ l as default
6
+ };
package/utils/retry.js ADDED
@@ -0,0 +1,13 @@
1
+ const c = async (a, e = 3) => {
2
+ let r;
3
+ for (let t = 0; t < e; t++)
4
+ try {
5
+ return await a();
6
+ } catch (o) {
7
+ r = o;
8
+ }
9
+ throw r;
10
+ };
11
+ export {
12
+ c as default
13
+ };
@@ -0,0 +1,10 @@
1
+ const n = (r) => async (...e) => {
2
+ try {
3
+ return [null, await r(...e)];
4
+ } catch (t) {
5
+ return [t, null];
6
+ }
7
+ };
8
+ export {
9
+ n as default
10
+ };
@@ -0,0 +1,10 @@
1
+ const t = (r, e = null) => {
2
+ try {
3
+ return JSON.parse(r);
4
+ } catch {
5
+ return e;
6
+ }
7
+ };
8
+ export {
9
+ t as default
10
+ };
@@ -0,0 +1,10 @@
1
+ const e = (t, r = "", n) => {
2
+ try {
3
+ return JSON.stringify(t, null, n);
4
+ } catch {
5
+ return r;
6
+ }
7
+ };
8
+ export {
9
+ e as default
10
+ };
@@ -0,0 +1,7 @@
1
+ const l = (o, e = "smooth") => {
2
+ const t = document.getElementById(o);
3
+ t && t.scrollIntoView({ behavior: e, block: "start" });
4
+ };
5
+ export {
6
+ l as default
7
+ };
@@ -0,0 +1,6 @@
1
+ const l = (o = "smooth") => {
2
+ window.scrollTo({ top: 0, behavior: o });
3
+ };
4
+ export {
5
+ l as default
6
+ };
@@ -0,0 +1,9 @@
1
+ const e = async (t) => {
2
+ const s = [];
3
+ for (const a of t)
4
+ s.push(await a());
5
+ return s;
6
+ };
7
+ export {
8
+ e as default
9
+ };
@@ -0,0 +1,9 @@
1
+ const e = (t, a) => {
2
+ try {
3
+ localStorage.setItem(t, JSON.stringify(a));
4
+ } catch {
5
+ }
6
+ };
7
+ export {
8
+ e as default
9
+ };
@@ -0,0 +1,7 @@
1
+ const s = (a, e) => {
2
+ const t = new URL(window.location.href);
3
+ t.searchParams.set(a, e), window.history.pushState({}, "", t);
4
+ };
5
+ export {
6
+ s as default
7
+ };
@@ -0,0 +1,9 @@
1
+ const e = (t, s) => {
2
+ try {
3
+ sessionStorage.setItem(t, JSON.stringify(s));
4
+ } catch {
5
+ }
6
+ };
7
+ export {
8
+ e as default
9
+ };
@@ -0,0 +1,4 @@
1
+ const o = (t, e = "auth_token") => localStorage.setItem(e, t);
2
+ export {
3
+ o as default
4
+ };
package/utils/sleep.js ADDED
@@ -0,0 +1,4 @@
1
+ const t = (e) => new Promise((s) => setTimeout(s, e));
2
+ export {
3
+ t as default
4
+ };
@@ -0,0 +1,10 @@
1
+ const n = (l, o) => {
2
+ let t = 0;
3
+ return (...a) => {
4
+ const e = Date.now();
5
+ e - t >= o && (t = e, l(...a));
6
+ };
7
+ };
8
+ export {
9
+ n as default
10
+ };
@@ -0,0 +1,7 @@
1
+ const l = (e = document.documentElement) => {
2
+ var u, c;
3
+ document.fullscreenElement ? (c = document.exitFullscreen) == null || c.call(document) : (u = e.requestFullscreen) == null || u.call(e);
4
+ };
5
+ export {
6
+ l as default
7
+ };
@@ -0,0 +1,16 @@
1
+ const c = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])', d = (t) => {
2
+ const e = (t == null ? void 0 : t.current) ?? t;
3
+ if (!e) return () => {
4
+ };
5
+ const i = () => [...e.querySelectorAll(c)], s = (n) => {
6
+ if (n.key !== "Tab") return;
7
+ const o = i();
8
+ if (!o.length) return;
9
+ const r = o[0], a = o[o.length - 1];
10
+ n.shiftKey ? document.activeElement === r && (n.preventDefault(), a.focus()) : document.activeElement === a && (n.preventDefault(), r.focus());
11
+ };
12
+ return e.addEventListener("keydown", s), () => e.removeEventListener("keydown", s);
13
+ };
14
+ export {
15
+ d as default
16
+ };
@@ -0,0 +1,6 @@
1
+ const o = () => {
2
+ document.body.style.overflow = "";
3
+ };
4
+ export {
5
+ o as default
6
+ };
@@ -0,0 +1,9 @@
1
+ const m = (t, e) => {
2
+ const o = new Promise(
3
+ (i, r) => setTimeout(() => r(new Error(`Timed out after ${e}ms`)), e)
4
+ );
5
+ return Promise.race([t, o]);
6
+ };
7
+ export {
8
+ m as default
9
+ };