meticulous-ui 3.2.3 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -83,30 +83,30 @@ import blue from 'meticulous-ui/colors/blue';
83
83
 
84
84
  ## 📦 Icon Components
85
85
 
86
- | Group | Icons |
87
- | --- | --- |
88
- | Arrows & Chevrons | `ArrowDown`, `ArrowLeft`, `ArrowRight`, `ArrowUp`, `ChevronDown`, `ChevronLeft`, `ChevronRight`, `ChevronUp` |
89
- | Actions | `Add`, `AddCircle`, `AddCircleFilled`, `Minus`, `MinusCircle`, `MinusCircleFilled`, `Close`, `CloseCircleFilled`, `CloseCircleOutline`, `Check`, `CheckDouble`, `Link`, `Search`, `Loading` |
90
- | Bells & Dots | `BellFilled`, `BellOutline`, `BellOffFilled`, `BellOffOutline`, `DotsHorizontalFilled`, `DotsHorizontalOutline`, `DotsVerticalFilled`, `DotsVerticalOutline` |
91
- | Bookmarks & Reactions | `BookmarkFilled`, `BookmarkOutline`, `HeartFilled`, `HeartOutline`, `StarFilled`, `StarOutline`, `ThumbsUpFilled`, `ThumbsUpOutline`, `ThumbsDownFilled`, `ThumbsDownOutline` |
92
- | Calendar & Clock | `CalendarDays`, `CalendarLinesPen`, `ClockCircleOutline`, `ClockSquareOutline` |
93
- | Commerce | `BagFilled`, `BagOutline`, `CartFilled`, `CartOutline`, `CartCheckFilled`, `CartCheckOutline`, `CartCrossFilled`, `CartCrossOutline`, `CartMinusFilled`, `CartMinusOutline`, `CartPlusFilled`, `CartPlusOutline`, `PaymentCardFilled`, `PaymentCardOutline`, `WalletFilled`, `WalletOutline`, `MoneyBagOutline`, `MoneyBriefcaseFilled`, `MoneyBriefcaseOutline`, `RupeeOutlined`, `RupeeSign` |
94
- | Communication | `CommentFilled`, `CommentOutline`, `CommentBubbleFilled`, `CommentBubbleOutline`, `CommentLineFilled`, `CommentLineOutline`, `EmailFilled`, `EmailOutline`, `PhoneFilled`, `PhoneOutline`, `PhoneCallingFilled`, `PhoneCallingOutline`, `ContactDetailsFilled`, `ContactDetailsOutline` |
95
- | Delivery & Boxes | `BoxFilled`, `BoxOutline`, `BoxCoveredFilled`, `BoxCoveredOutline`, `DeliveryTruckFastFilled`, `DeliveryTruckFastOutline`, `DeliveryTruckLeftFilled`, `DeliveryTruckLeftOutline`, `DeliveryTruckRightFilled`, `DeliveryTruckRightOutline` |
96
- | Doors & Exit | `DoorClosedFilled`, `DoorClosedOutline`, `DoorOpenFilled`, `DoorOpenOutline`, `ExitArrowInOutline`, `ExitArrowOutOutline` |
97
- | Edit & Files | `EditBoxThick`, `EditBoxThin`, `SaveFilled`, `SaveOutline`, `Download`, `DownloadBoxFilled`, `DownloadBoxOutline`, `Upload`, `UploadBoxFilled`, `UploadBoxOutline` |
98
- | Eye & Fullscreen | `EyeClosed`, `EyeFilled`, `EyeOutline`, `FullScreenFilled`, `FullScreenOutline`, `FullScreenArrowThick`, `FullScreenArrowThin` |
99
- | Filter, Sort & Menu | `Filter`, `FilterList`, `FilterThickFilled`, `FilterThickOutline`, `SortBottomToTop`, `SortTopToBottom`, `SortHorizontal`, `SortVertical`, `HamburgerMenu`, `HamburgerSpaced`, `SettingFilled`, `SettingOutline` |
100
- | Home & Location | `HomeFilled`, `HomeOutline`, `LocationFilled`, `LocationOutline`, `LocationArrowFilled`, `LocationArrowOutline`, `Pin`, `PinFilled`, `PinOutline`, `PinAddFilled`, `PinAddOutline`, `PinCircleFilled`, `PinCircleOutline`, `PinSubFilled`, `PinSubOutline` |
101
- | Info & Help | `Info`, `InfoCircleFilled`, `InfoCircleOutline`, `InfoSquareFilled`, `InfoSquareOutline`, `Help`, `HelpCircleFilled`, `HelpCircleOutline`, `DetailsOutline` |
102
- | Keys & Locks | `KeyFilled`, `KeyOutline`, `KeyInSquareFilled`, `KeyInSquareOutline`, `KeySideSquareFilled`, `KeySideSquareOutline`, `KeySquareFilled`, `KeySquareOutline`, `LockKeyhole`, `LockKeyholeOutline`, `LockKeyholeUnlocked`, `LockKeyholeUnlockedOutline` |
103
- | Media & Volume | `MediaPlayFilled`, `MediaPlayOutline`, `MediaPlayCircleFilled`, `MediaPlayCircleOutline`, `MediaPauseFilled`, `MediaPauseOutline`, `MediaPauseCircleFilled`, `MediaPauseCircleOuline`, `MediaStopFilled`, `MediaStopOutline`, `MediaStopCircleFilled`, `MediaStopCircleOutline`, `VolumeFilled`, `VolumeOutline`, `VolumeMuteFilled`, `VolumeMuteOutline`, `VolumeOffFilled`, `VolumeOffOutline` |
104
- | Profile | `ProfileMaleFilled`, `ProfileMaleOutline`, `ProfileFemaleOutline`, `ProfileGroupFilled` |
105
- | Security & Shield | `ShieldFilled`, `ShieldOutline`, `ShieldCheckFilled`, `ShieldCheckOutline`, `ShieldCrossFilled`, `ShieldCrossOutline`, `ShieldWarningFilled`, `ShieldWarningOutline`, `NoEntry`, `NoEntryFilled`, `NoEntryOutline` |
106
- | Share | `ShareFilled`, `ShareOutline`, `ShareAllFilled`, `ShareAllOutline`, `ShareBoxOutline`, `ShareThickFilled` |
107
- | Social Media | `DiscordConversation`, `DiscordFilled`, `DiscordOutline`, `FacebookFilled`, `FacebookOutline`, `FacebookMessengerOutline`, `FacebookRoundFilled`, `InstagramOuline`, `InstagramRoundFilled`, `LinkedinFilled`, `LinkedinOutline`, `LinkedinRoundFilled`, `PinterestFilled`, `PinterestOutline`, `RedditFilled`, `RedditOutline`, `RedditRoundFilled`, `RedditRoundOutline`, `SnapchatFilled`, `SnapchatOutline`, `TelegramFilled`, `TelegramOutline`, `TelegramRoundFilled`, `TiktokBox`, `TiktokThickFilled`, `TiktokThinFilled`, `WhatsappFilled`, `WhatsappOutline`, `Youtube`, `YoutubeFilled`, `YoutubeRoundFilled` |
108
- | Trash | `TrashFilled`, `TrashOutline`, `TrashBigFilled`, `TrashBigOutline`, `TrashLinesFilled`, `TrashLinesOutline` |
109
- | Warnings & Errors | `Warning`, `WarningSmall`, `WarningCircleFilled`, `WarningCircleOutline`, `WarningTriangleFilled`, `WarningTriangleOutline` |
86
+ | Group | Icons |
87
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
88
+ | Arrows & Chevrons | `ArrowDown`, `ArrowLeft`, `ArrowRight`, `ArrowUp`, `ChevronDown`, `ChevronLeft`, `ChevronRight`, `ChevronUp` |
89
+ | Actions | `Add`, `AddCircle`, `AddCircleFilled`, `Minus`, `MinusCircle`, `MinusCircleFilled`, `Close`, `CloseCircleFilled`, `CloseCircleOutline`, `Check`, `CheckDouble`, `Link`, `Search`, `Loading` |
90
+ | Bells & Dots | `BellFilled`, `BellOutline`, `BellOffFilled`, `BellOffOutline`, `DotsHorizontalFilled`, `DotsHorizontalOutline`, `DotsVerticalFilled`, `DotsVerticalOutline` |
91
+ | Bookmarks & Reactions | `BookmarkFilled`, `BookmarkOutline`, `HeartFilled`, `HeartOutline`, `StarFilled`, `StarOutline`, `ThumbsUpFilled`, `ThumbsUpOutline`, `ThumbsDownFilled`, `ThumbsDownOutline` |
92
+ | Calendar & Clock | `CalendarDays`, `CalendarLinesPen`, `ClockCircleOutline`, `ClockSquareOutline` |
93
+ | Commerce | `BagFilled`, `BagOutline`, `CartFilled`, `CartOutline`, `CartCheckFilled`, `CartCheckOutline`, `CartCrossFilled`, `CartCrossOutline`, `CartMinusFilled`, `CartMinusOutline`, `CartPlusFilled`, `CartPlusOutline`, `PaymentCardFilled`, `PaymentCardOutline`, `WalletFilled`, `WalletOutline`, `MoneyBagOutline`, `MoneyBriefcaseFilled`, `MoneyBriefcaseOutline`, `RupeeOutlined`, `RupeeSign` |
94
+ | Communication | `CommentFilled`, `CommentOutline`, `CommentBubbleFilled`, `CommentBubbleOutline`, `CommentLineFilled`, `CommentLineOutline`, `EmailFilled`, `EmailOutline`, `PhoneFilled`, `PhoneOutline`, `PhoneCallingFilled`, `PhoneCallingOutline`, `ContactDetailsFilled`, `ContactDetailsOutline` |
95
+ | Delivery & Boxes | `BoxFilled`, `BoxOutline`, `BoxCoveredFilled`, `BoxCoveredOutline`, `DeliveryTruckFastFilled`, `DeliveryTruckFastOutline`, `DeliveryTruckLeftFilled`, `DeliveryTruckLeftOutline`, `DeliveryTruckRightFilled`, `DeliveryTruckRightOutline` |
96
+ | Doors & Exit | `DoorClosedFilled`, `DoorClosedOutline`, `DoorOpenFilled`, `DoorOpenOutline`, `ExitArrowInOutline`, `ExitArrowOutOutline` |
97
+ | Edit & Files | `EditBoxThick`, `EditBoxThin`, `SaveFilled`, `SaveOutline`, `Download`, `DownloadBoxFilled`, `DownloadBoxOutline`, `Upload`, `UploadBoxFilled`, `UploadBoxOutline` |
98
+ | Eye & Fullscreen | `EyeClosed`, `EyeFilled`, `EyeOutline`, `FullScreenFilled`, `FullScreenOutline`, `FullScreenArrowThick`, `FullScreenArrowThin` |
99
+ | Filter, Sort & Menu | `Filter`, `FilterList`, `FilterThickFilled`, `FilterThickOutline`, `SortBottomToTop`, `SortTopToBottom`, `SortHorizontal`, `SortVertical`, `HamburgerMenu`, `HamburgerSpaced`, `SettingFilled`, `SettingOutline` |
100
+ | Home & Location | `HomeFilled`, `HomeOutline`, `LocationFilled`, `LocationOutline`, `LocationArrowFilled`, `LocationArrowOutline`, `Pin`, `PinFilled`, `PinOutline`, `PinAddFilled`, `PinAddOutline`, `PinCircleFilled`, `PinCircleOutline`, `PinSubFilled`, `PinSubOutline` |
101
+ | Info & Help | `Info`, `InfoCircleFilled`, `InfoCircleOutline`, `InfoSquareFilled`, `InfoSquareOutline`, `Help`, `HelpCircleFilled`, `HelpCircleOutline`, `DetailsOutline` |
102
+ | Keys & Locks | `KeyFilled`, `KeyOutline`, `KeyInSquareFilled`, `KeyInSquareOutline`, `KeySideSquareFilled`, `KeySideSquareOutline`, `KeySquareFilled`, `KeySquareOutline`, `LockKeyhole`, `LockKeyholeOutline`, `LockKeyholeUnlocked`, `LockKeyholeUnlockedOutline` |
103
+ | Media & Volume | `MediaPlayFilled`, `MediaPlayOutline`, `MediaPlayCircleFilled`, `MediaPlayCircleOutline`, `MediaPauseFilled`, `MediaPauseOutline`, `MediaPauseCircleFilled`, `MediaPauseCircleOuline`, `MediaStopFilled`, `MediaStopOutline`, `MediaStopCircleFilled`, `MediaStopCircleOutline`, `VolumeFilled`, `VolumeOutline`, `VolumeMuteFilled`, `VolumeMuteOutline`, `VolumeOffFilled`, `VolumeOffOutline` |
104
+ | Profile | `ProfileMaleFilled`, `ProfileMaleOutline`, `ProfileFemaleOutline`, `ProfileGroupFilled` |
105
+ | Security & Shield | `ShieldFilled`, `ShieldOutline`, `ShieldCheckFilled`, `ShieldCheckOutline`, `ShieldCrossFilled`, `ShieldCrossOutline`, `ShieldWarningFilled`, `ShieldWarningOutline`, `NoEntry`, `NoEntryFilled`, `NoEntryOutline` |
106
+ | Share | `ShareFilled`, `ShareOutline`, `ShareAllFilled`, `ShareAllOutline`, `ShareBoxOutline`, `ShareThickFilled` |
107
+ | Social Media | `DiscordConversation`, `DiscordFilled`, `DiscordOutline`, `FacebookFilled`, `FacebookOutline`, `FacebookMessengerOutline`, `FacebookRoundFilled`, `InstagramOuline`, `InstagramRoundFilled`, `LinkedinFilled`, `LinkedinOutline`, `LinkedinRoundFilled`, `PinterestFilled`, `PinterestOutline`, `RedditFilled`, `RedditOutline`, `RedditRoundFilled`, `RedditRoundOutline`, `SnapchatFilled`, `SnapchatOutline`, `TelegramFilled`, `TelegramOutline`, `TelegramRoundFilled`, `TiktokBox`, `TiktokThickFilled`, `TiktokThinFilled`, `WhatsappFilled`, `WhatsappOutline`, `Youtube`, `YoutubeFilled`, `YoutubeRoundFilled` |
108
+ | Trash | `TrashFilled`, `TrashOutline`, `TrashBigFilled`, `TrashBigOutline`, `TrashLinesFilled`, `TrashLinesOutline` |
109
+ | Warnings & Errors | `Warning`, `WarningSmall`, `WarningCircleFilled`, `WarningCircleOutline`, `WarningTriangleFilled`, `WarningTriangleOutline` |
110
110
 
111
111
  ## 📦 Tokens
112
112
 
@@ -186,20 +186,35 @@ import blue from 'meticulous-ui/colors/blue';
186
186
  | `maskPhone` | `(str) → string` | Masks all digits except the last four; preserves formatting chars |
187
187
  | `generateInitials` | `(name) → string` | Extracts uppercased first letter of each word, e.g. `"JD"` |
188
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
+
189
204
  ### Validation Utilities
190
205
 
191
- | Function | Signature | Description |
192
- | ------------------ | ---------------------- | ---------------------------------------------------------------------------- |
193
- | `isEmail` | `(value) → boolean` | Valid email — must have local part, `@`, and domain with dot |
194
- | `isPhone` | `(value) → boolean` | Plausible phone — optional `+`, 7–15 digits, allows spaces/hyphens/parens |
195
- | `isURL` | `(value) → boolean` | Valid `http` or `https` URL via native `URL` constructor |
196
- | `isPasswordStrong` | `(value) → boolean` | 8+ chars with uppercase, lowercase, digit, and special character |
197
- | `isPAN` | `(value) → boolean` | Indian PAN — `AAAAA0000A` (5 letters, 4 digits, 1 letter) |
198
- | `isAadhaar` | `(value) → boolean` | Indian Aadhaar — 12 digits, first digit non-zero; strips spaces |
199
- | `isGST` | `(value) → boolean` | Indian GSTIN — 2-digit state code + PAN + entity digit + `Z` + check char |
200
- | `isRequired` | `(value) → boolean` | `false` for `null`, `undefined`, blank strings, and empty arrays |
201
- | `minLength` | `(value, n) → boolean` | `true` when `value.length >= n` |
202
- | `maxLength` | `(value, n) → boolean` | `true` when `value.length <= n` |
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` |
203
218
 
204
219
  ## 🌱 Features
205
220
 
@@ -3,7 +3,7 @@ import { useState as a, useRef as de, useEffect as O } from "react";
3
3
  import ce from "../Glass/Glass.js";
4
4
  import ue from "./components/TimerRing/TimerRing.js";
5
5
  import h from "../../colors/white.js";
6
- import { Wrapper as me, Dimmer as he, DotsWrapper as pe, AllDots as ge, Dots as be, Time as U, TimeTxt as _, HourHand as fe, MinuteHand as Se, SecondHand as Te, AlarmRing as $e, BulletRing as Ae, Bullet as ye, VisuallyHidden as Re, LeftActions as De, ActionBtn as p, MediaStopFilledWrapper as Pe, MediaPauseFilledWrapper as we, MediaPlayFilledWrapper as He, RightActions as Ie, AddWrapper as Me } from "./styles.js";
6
+ import { Wrapper as me, AlarmRing as he, BulletRing as pe, Bullet as ge, VisuallyHidden as be, Dimmer as fe, DotsWrapper as Se, AllDots as Te, Dots as $e, Time as U, TimeTxt as _, HourHand as Ae, MinuteHand as ye, SecondHand as Re, LeftActions as De, ActionBtn as p, MediaStopFilledWrapper as Pe, MediaPauseFilledWrapper as we, MediaPlayFilledWrapper as He, RightActions as Ie, AddWrapper as Me } from "./styles.js";
7
7
  import { getSize as ke } from "./helpers.js";
8
8
  const c = () => {
9
9
  }, Ce = (g) => () => {
@@ -63,14 +63,43 @@ const c = () => {
63
63
  const w = S.toLocaleString("en-Us", { hour12: !0, timeZone: o }).split(", ")[1], C = w.split(" ")[0], W = w.split(" ")[1], z = w.split(":").slice(0, 2).join(":"), l = !(Number.isInteger(s) && s > 0), L = `${b ? C : z} ${W}`;
64
64
  return /* @__PURE__ */ n(me, { $color: g, role: "region", "aria-label": "Clock", $size: t, ...Q, children: [
65
65
  /* @__PURE__ */ e(ce, { borderRadius: `${ke(16.67)({ $size: t })}rem`, "aria-hidden": "true" }),
66
+ (!l || R) && /* @__PURE__ */ n(v, { children: [
67
+ /* @__PURE__ */ e(
68
+ he,
69
+ {
70
+ $dismissing: R,
71
+ onAnimationEnd: te,
72
+ "aria-hidden": "true",
73
+ children: /* @__PURE__ */ e(ue, { progress: s >= 60 ? 1 : s % 60 / 60 })
74
+ }
75
+ ),
76
+ /* @__PURE__ */ e(
77
+ pe,
78
+ {
79
+ $size: t,
80
+ style: { "--bullet-rotate": `${Y}deg` },
81
+ $dismissing: R,
82
+ "aria-hidden": "true",
83
+ children: /* @__PURE__ */ e(ge, { $size: t })
84
+ }
85
+ ),
86
+ /* @__PURE__ */ e(
87
+ be,
88
+ {
89
+ role: "timer",
90
+ "aria-live": "polite",
91
+ "aria-label": `${s} seconds remaining`
92
+ }
93
+ )
94
+ ] }),
66
95
  I && /* @__PURE__ */ n(v, { children: [
67
- /* @__PURE__ */ e(he, { "aria-hidden": "true", $size: t, children: /* @__PURE__ */ e(pe, { children: /* @__PURE__ */ e(ge, { "aria-hidden": "true", children: [...Array(60)].map((N, d) => /* @__PURE__ */ e(be, { $i: d, $size: t }, d)) }) }) }),
96
+ /* @__PURE__ */ e(fe, { "aria-hidden": "true", $size: t, children: /* @__PURE__ */ e(Se, { children: /* @__PURE__ */ e(Te, { "aria-hidden": "true", children: [...Array(60)].map((N, d) => /* @__PURE__ */ e($e, { $i: d, $size: t }, d)) }) }) }),
68
97
  f ? /* @__PURE__ */ n(U, { as: "time", dateTime: S.toISOString(), "aria-label": L, children: [
69
98
  /* @__PURE__ */ e(_, { $size: t, "aria-hidden": "true", children: b ? C : z }),
70
99
  /* @__PURE__ */ e(_, { $size: t, "aria-hidden": "true", children: W })
71
100
  ] }) : /* @__PURE__ */ n(U, { as: "time", dateTime: S.toISOString(), "aria-label": L, children: [
72
101
  /* @__PURE__ */ e(
73
- fe,
102
+ Ae,
74
103
  {
75
104
  $size: t,
76
105
  style: { "--hand-rotate": `${A.hour}deg` },
@@ -78,7 +107,7 @@ const c = () => {
78
107
  }
79
108
  ),
80
109
  /* @__PURE__ */ e(
81
- Se,
110
+ ye,
82
111
  {
83
112
  $size: t,
84
113
  style: { "--hand-rotate": `${A.minute}deg` },
@@ -86,7 +115,7 @@ const c = () => {
86
115
  }
87
116
  ),
88
117
  /* @__PURE__ */ e(
89
- Te,
118
+ Re,
90
119
  {
91
120
  $size: t,
92
121
  style: { "--hand-rotate": `${A.second}deg` },
@@ -95,35 +124,6 @@ const c = () => {
95
124
  )
96
125
  ] })
97
126
  ] }),
98
- (!l || R) && /* @__PURE__ */ n(v, { children: [
99
- /* @__PURE__ */ e(
100
- $e,
101
- {
102
- $dismissing: R,
103
- onAnimationEnd: te,
104
- "aria-hidden": "true",
105
- children: /* @__PURE__ */ e(ue, { progress: s >= 60 ? 1 : s % 60 / 60 })
106
- }
107
- ),
108
- /* @__PURE__ */ e(
109
- Ae,
110
- {
111
- $size: t,
112
- style: { "--bullet-rotate": `${45 + Y}deg` },
113
- $dismissing: R,
114
- "aria-hidden": "true",
115
- children: /* @__PURE__ */ e(ye, { $size: t })
116
- }
117
- ),
118
- /* @__PURE__ */ e(
119
- Re,
120
- {
121
- role: "timer",
122
- "aria-live": "polite",
123
- "aria-label": `${s} seconds remaining`
124
- }
125
- )
126
- ] }),
127
127
  r > 0 && /* @__PURE__ */ n(
128
128
  De,
129
129
  {
@@ -15,7 +15,7 @@ const r = 33, e = 2 * Math.PI * r, u = ({ progress: o }) => {
15
15
  cy: 48,
16
16
  r,
17
17
  stroke: "rgba(255,255,255,.2)",
18
- strokeWidth: 2,
18
+ strokeWidth: 1,
19
19
  fill: "none"
20
20
  }
21
21
  ),
@@ -27,7 +27,7 @@ const r = 33, e = 2 * Math.PI * r, u = ({ progress: o }) => {
27
27
  cy: 48,
28
28
  r,
29
29
  stroke: a,
30
- strokeWidth: 1,
30
+ strokeWidth: 1.33,
31
31
  fill: "none",
32
32
  strokeLinecap: "round",
33
33
  strokeDasharray: e,
@@ -8,7 +8,7 @@ import u from "../../colors/black.js";
8
8
  import b from "../../colors/red.js";
9
9
  import { COLOR_MAPPING as $ } from "./constants.js";
10
10
  import { getSize as t } from "./helpers.js";
11
- const s = 1, g = 16.67, a = 1.67, f = 3.404, v = ({ $color: e }) => $[e], n = r`
11
+ const s = 1, f = 16.67, a = 1.67, g = 3.404, v = ({ $color: e }) => $[e], n = r`
12
12
  position: absolute;
13
13
  bottom: 50%;
14
14
  transform-origin: bottom;
@@ -19,7 +19,7 @@ const s = 1, g = 16.67, a = 1.67, f = 3.404, v = ({ $color: e }) => $[e], n = r`
19
19
  position: relative;
20
20
  height: ${t(s)}rem;
21
21
  width: ${t(s)}rem;
22
- border-radius: ${t(g)}rem;
22
+ border-radius: ${t(f)}rem;
23
23
  background-color: ${v};
24
24
  `, W = o.div`
25
25
  position: absolute;
@@ -47,7 +47,7 @@ const s = 1, g = 16.67, a = 1.67, f = 3.404, v = ({ $color: e }) => $[e], n = r`
47
47
  width: ${t(120)}rem;
48
48
  height: ${t(120)}rem;
49
49
  background: rgba(255, 255, 255, 0.4);
50
- transform-origin: ${t(f)}rem;
50
+ transform-origin: ${t(g)}rem;
51
51
  border-radius: 2px;
52
52
  rotate: ${({ $i: e }) => `${e * 6}deg`};
53
53
 
@@ -88,13 +88,13 @@ const s = 1, g = 16.67, a = 1.67, f = 3.404, v = ({ $color: e }) => $[e], n = r`
88
88
  background: ${b.m800};
89
89
  `, d = l`
90
90
  from { opacity: 1; transform: scale(1); }
91
- to { opacity: 0; transform: scale(0.85); }
91
+ to { opacity: 0; transform: scale(0.9); }
92
92
  `, E = o.div`
93
93
  position: absolute;
94
94
  inset: 0;
95
95
  pointer-events: none;
96
96
  ${({ $dismissing: e }) => e && r`
97
- animation: ${d} 0.4s ease-out forwards;
97
+ animation: ${d} 0.6s ease-out forwards;
98
98
  `}
99
99
  `, z = o.div`
100
100
  position: absolute;
@@ -155,21 +155,24 @@ const s = 1, g = 16.67, a = 1.67, f = 3.404, v = ({ $color: e }) => $[e], n = r`
155
155
  clip-path: inset(50%);
156
156
  white-space: nowrap;
157
157
  `, Q = o.div`
158
+ position: absolute;
158
159
  width: ${t(35)}rem;
159
160
  height: ${t(35)}rem;
160
161
  border-radius: 50%;
161
162
  background-color: ${i};
163
+ left: calc(-${t(70)}rem);
164
+ top: calc(-${t(100 / 33)}rem - ${t(70)}rem);
162
165
  `, U = o.div`
163
166
  position: absolute;
164
- left: 26%;
165
- top: 24%;
167
+ left: 50%;
168
+ top: 48%;
169
+ width: 0;
170
+ height: 0;
166
171
  rotate: var(--bullet-rotate);
167
- height: ${t(2.05)}rem;
168
- width: ${t(2.05)}rem;
169
- transform-origin: center;
172
+ transform-origin: 0 0;
170
173
  transition: rotate 0.3s ease;
171
174
  ${({ $dismissing: e }) => e && r`
172
- animation: ${d} 0.4s ease-out forwards;
175
+ animation: ${d} 0.6s ease-out forwards;
173
176
  `}
174
177
  `;
175
178
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meticulous-ui",
3
- "version": "3.2.3",
3
+ "version": "3.2.5",
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,12 @@
1
+ const a = async (t) => {
2
+ var o;
3
+ if ((o = navigator.clipboard) != null && o.writeText) {
4
+ await navigator.clipboard.writeText(t);
5
+ return;
6
+ }
7
+ const e = document.createElement("textarea");
8
+ e.value = t, e.style.cssText = "position:fixed;opacity:0", document.body.appendChild(e), e.select(), document.execCommand("copy"), document.body.removeChild(e);
9
+ };
10
+ export {
11
+ a as default
12
+ };
@@ -0,0 +1,7 @@
1
+ const n = (d, e) => {
2
+ const o = document.createElement("a");
3
+ o.href = d, o.download = e || d.split("/").pop() || "download", document.body.appendChild(o), o.click(), document.body.removeChild(o);
4
+ };
5
+ export {
6
+ n as default
7
+ };
@@ -0,0 +1,10 @@
1
+ const e = () => ({
2
+ width: window.innerWidth,
3
+ height: window.innerHeight,
4
+ deviceWidth: screen.width,
5
+ deviceHeight: screen.height,
6
+ pixelRatio: window.devicePixelRatio || 1
7
+ });
8
+ export {
9
+ e as default
10
+ };
package/utils/index.js CHANGED
@@ -1,50 +1,50 @@
1
- import r from "./capFirstLetter.js";
2
- import o from "./capitalize.js";
1
+ import o from "./capFirstLetter.js";
2
+ import r from "./capitalize.js";
3
3
  import m from "./camelCase.js";
4
- import t from "./chunk.js";
5
- import i from "./clamp.js";
4
+ import i from "./chunk.js";
5
+ import t from "./clamp.js";
6
6
  import p from "./compose.js";
7
7
  import f from "./deepClone.js";
8
8
  import e 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 c from "./formatNumber.js";
13
- import u from "./formatTime.js";
14
- import d from "./generateInitials.js";
15
- import l from "./getGreetingByTime.js";
12
+ import d from "./formatNumber.js";
13
+ import l from "./formatTime.js";
14
+ import c from "./generateInitials.js";
15
+ import u from "./getGreetingByTime.js";
16
16
  import y from "./groupBy.js";
17
17
  import g from "./hasEqualProps.js";
18
- import h from "./addDays.js";
18
+ import b from "./addDays.js";
19
19
  import k from "./countdown.js";
20
20
  import C from "./differenceInDays.js";
21
- import E from "./isEmpty.js";
22
- import B from "./isEqual.js";
23
- import P from "./isNonEmptyArray.js";
24
- import b from "./isPast.js";
25
- import T from "./isToday.js";
26
- import q from "./kebabCase.js";
27
- import x from "./keyBy.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
28
  import A from "./maskEmail.js";
29
29
  import D from "./maskPhone.js";
30
- import L from "./mergeDeep.js";
30
+ import I from "./mergeDeep.js";
31
31
  import N from "./omit.js";
32
- import w from "./percentage.js";
33
- import I from "./pick.js";
34
- import S from "./randomBetween.js";
35
- import G from "./randomInt.js";
36
- import R from "./randomValue.js";
37
- import j from "./removeExtraSpaces.js";
38
- import v from "./roundTo.js";
39
- import z from "./slugify.js";
40
- import F from "./snakeCase.js";
41
- import O from "./sortBy.js";
42
- import U from "./timeAgo.js";
43
- import V from "./titleCase.js";
44
- import H from "./truncate.js";
45
- import J from "./uniqueBy.js";
46
- import K from "./isEmail.js";
47
- import M from "./isPhone.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";
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";
47
+ import K from "./isPhone.js";
48
48
  import Q from "./isURL.js";
49
49
  import W from "./isPasswordStrong.js";
50
50
  import X from "./isPAN.js";
@@ -52,60 +52,70 @@ import Y from "./isAadhaar.js";
52
52
  import Z from "./isGST.js";
53
53
  import _ from "./isRequired.js";
54
54
  import $ from "./minLength.js";
55
- import rr from "./maxLength.js";
56
- const mo = {
55
+ import oo from "./maxLength.js";
56
+ import ro from "./isMobile.js";
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";
63
+ import ao from "./downloadFile.js";
64
+ import so from "./openInNewTab.js";
65
+ import no from "./getScreenSize.js";
66
+ const Tr = {
57
67
  // string
58
- capFirstLetter: r,
59
- capitalize: o,
68
+ capFirstLetter: o,
69
+ capitalize: r,
60
70
  camelCase: m,
61
- generateInitials: d,
62
- kebabCase: q,
71
+ generateInitials: c,
72
+ kebabCase: P,
63
73
  maskEmail: A,
64
74
  maskPhone: D,
65
- removeExtraSpaces: j,
66
- slugify: z,
67
- snakeCase: F,
68
- titleCase: V,
69
- truncate: H,
75
+ removeExtraSpaces: F,
76
+ slugify: M,
77
+ snakeCase: R,
78
+ titleCase: U,
79
+ truncate: V,
70
80
  // number
71
- clamp: i,
81
+ clamp: t,
72
82
  formatCompactNumber: a,
73
83
  formatCurrency: s,
74
- formatNumber: c,
75
- percentage: w,
76
- randomBetween: S,
77
- randomInt: G,
78
- randomValue: R,
79
- roundTo: v,
84
+ formatNumber: d,
85
+ percentage: q,
86
+ randomBetween: L,
87
+ randomInt: O,
88
+ randomValue: z,
89
+ roundTo: G,
80
90
  // date-time
81
- addDays: h,
91
+ addDays: b,
82
92
  countdown: k,
83
93
  differenceInDays: C,
84
94
  formatDate: n,
85
- formatTime: u,
86
- getGreetingByTime: l,
87
- isPast: b,
88
- isToday: T,
89
- timeAgo: U,
95
+ formatTime: l,
96
+ getGreetingByTime: u,
97
+ isPast: T,
98
+ isToday: B,
99
+ timeAgo: v,
90
100
  // object / array
91
- chunk: t,
101
+ chunk: i,
92
102
  compose: p,
93
103
  deepClone: f,
94
104
  flattenObject: e,
95
105
  groupBy: y,
96
106
  hasEqualProps: g,
97
- isEmpty: E,
98
- isEqual: B,
99
- isNonEmptyArray: P,
100
- keyBy: x,
101
- mergeDeep: L,
107
+ isEmpty: h,
108
+ isEqual: E,
109
+ isNonEmptyArray: S,
110
+ keyBy: w,
111
+ mergeDeep: I,
102
112
  omit: N,
103
- pick: I,
104
- sortBy: O,
105
- uniqueBy: J,
113
+ pick: x,
114
+ sortBy: j,
115
+ uniqueBy: H,
106
116
  // validation
107
- isEmail: K,
108
- isPhone: M,
117
+ isEmail: J,
118
+ isPhone: K,
109
119
  isURL: Q,
110
120
  isPasswordStrong: W,
111
121
  isPAN: X,
@@ -113,8 +123,19 @@ const mo = {
113
123
  isGST: Z,
114
124
  isRequired: _,
115
125
  minLength: $,
116
- maxLength: rr
126
+ maxLength: oo,
127
+ // device
128
+ isMobile: ro,
129
+ isIOS: mo,
130
+ isAndroid: io,
131
+ isSafari: to,
132
+ isDarkMode: po,
133
+ isOnline: fo,
134
+ copyToClipboard: eo,
135
+ downloadFile: ao,
136
+ openInNewTab: so,
137
+ getScreenSize: no
117
138
  };
118
139
  export {
119
- mo as default
140
+ Tr as default
120
141
  };
@@ -0,0 +1,4 @@
1
+ const t = () => /Android/i.test(navigator.userAgent);
2
+ export {
3
+ t as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const e = () => window.matchMedia("(prefers-color-scheme: dark)").matches;
2
+ export {
3
+ e as default
4
+ };
package/utils/isIOS.js ADDED
@@ -0,0 +1,4 @@
1
+ const t = () => /iPhone|iPad|iPod/i.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
2
+ export {
3
+ t as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const e = () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
2
+ export {
3
+ e as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const n = () => navigator.onLine;
2
+ export {
3
+ n as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const a = () => /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
2
+ export {
3
+ a as default
4
+ };
@@ -0,0 +1,6 @@
1
+ const n = (e) => {
2
+ window.open(e, "_blank", "noopener,noreferrer");
3
+ };
4
+ export {
5
+ n as default
6
+ };