meticulous-ui 3.2.2 → 3.2.4

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,250 +83,30 @@ import blue from 'meticulous-ui/colors/blue';
83
83
 
84
84
  ## 📦 Icon Components
85
85
 
86
- | Icons | Description |
87
- | ---------------------------- | ---------------------------------- |
88
- | `AddCircleFilled` | Add circle filled icon |
89
- | `AddCircle` | Add circle icon |
90
- | `Add` | Add icon |
91
- | `ArrowDown` | Arrow down icon |
92
- | `ArrowLeft` | Arrow left icon |
93
- | `ArrowRight` | Arrow right icon |
94
- | `ArrowUp` | Arrow up icon |
95
- | `BagFilled` | Bag filled icon |
96
- | `BagOutline` | Bag outline icon |
97
- | `BellFilled` | Bell filled icon |
98
- | `BellOffFilled` | Bell off filled icon |
99
- | `BellOffOutline` | Bell off outline icon |
100
- | `BellOutline` | Bell outline icon |
101
- | `BookmarkFilled` | Bookmark filled icon |
102
- | `BookmarkOutline` | Bookmark outline icon |
103
- | `BoxCoveredFilled` | Box covered filled icon |
104
- | `BoxCoveredOutline` | Box covered outline icon |
105
- | `BoxFilled` | Box filled icon |
106
- | `BoxOutline` | Box outline icon |
107
- | `CalendarDays` | Calendar days icon |
108
- | `CalendarLinesPen` | Calendar lines pen icon |
109
- | `CartCheckFilled` | Cart check filled icon |
110
- | `CartCheckOutline` | Cart check outline icon |
111
- | `CartCrossFilled` | Cart cross filled icon |
112
- | `CartCrossOutline` | Cart cross outline icon |
113
- | `CartFilled` | Cart filled icon |
114
- | `CartMinusFilled` | Cart minus filled icon |
115
- | `CartMinusOutline` | Cart minus outline icon |
116
- | `CartOutline` | Cart outline icon |
117
- | `CartPlusFilled` | Cart plus filled icon |
118
- | `CartPlusOutline` | Cart plus outline icon |
119
- | `CheckDouble` | Check double icon |
120
- | `Check` | Check icon |
121
- | `ChevronDown` | Chevron down icon |
122
- | `ChevronLeft` | Chevron left icon |
123
- | `ChevronRight` | Chevron right icon |
124
- | `ChevronUp` | Chevron up icon |
125
- | `ClockCircleOutline` | Clock circle outline icon |
126
- | `ClockSquareOutline` | Clock square outline icon |
127
- | `CloseCircleFilled` | Close circle filled icon |
128
- | `CloseCircleOutline` | Close circle outline icon |
129
- | `Close` | Close icon |
130
- | `CommentBubbleFilled` | Comment bubble filled icon |
131
- | `CommentBubbleOutline` | Comment bubble outline icon |
132
- | `CommentFilled` | Comment filled icon |
133
- | `CommentLineFilled` | Comment line filled icon |
134
- | `CommentLineOutline` | Comment line outline icon |
135
- | `CommentOutline` | Comment outline icon |
136
- | `ContactDetailsFilled` | Contact details filled icon |
137
- | `ContactDetailsOutline` | Contact details outline icon |
138
- | `DeliveryTruckFastFilled` | Delivery truck fast filled icon |
139
- | `DeliveryTruckFastOutline` | Delivery truck fast outline icon |
140
- | `DeliveryTruckLeftFilled` | Delivery truck left filled icon |
141
- | `DeliveryTruckLeftOutline` | Delivery truck left outline icon |
142
- | `DeliveryTruckRightFilled` | Delivery truck right filled icon |
143
- | `DeliveryTruckRightOutline` | Delivery truck right outline icon |
144
- | `DetailsOutline` | Details outline icon |
145
- | `DiscordConversation` | Discord conversation icon |
146
- | `DiscordFilled` | Discord filled icon |
147
- | `DiscordOutline` | Discord outline icon |
148
- | `DoorClosedFilled` | Door closed filled icon |
149
- | `DoorClosedOutline` | Door closed outline icon |
150
- | `DoorOpenFilled` | Door open filled icon |
151
- | `DoorOpenOutline` | Door open outline icon |
152
- | `DotsHorizontalFilled` | Dots horizontal filled icon |
153
- | `DotsHorizontalOutline` | Dots horizontal outline icon |
154
- | `DotsVerticalFilled` | Dots vertical filled icon |
155
- | `DotsVerticalOutline` | Dots vertical outline icon |
156
- | `DownloadBoxFilled` | Download box filled icon |
157
- | `DownloadBoxOutline` | Download box outline icon |
158
- | `Download` | Download icon |
159
- | `EditBoxThick` | Edit box thick icon |
160
- | `EditBoxThin` | Edit box thin icon |
161
- | `EmailFilled` | Email filled icon |
162
- | `EmailOutline` | Email outline icon |
163
- | `ExitArrowInOutline` | Exit arrow in outline icon |
164
- | `ExitArrowOutOutline` | Exit arrow out outline icon |
165
- | `EyeClosed` | Eye closed icon |
166
- | `EyeFilled` | Eye filled icon |
167
- | `EyeOutline` | Eye outline icon |
168
- | `FacebookFilled` | Facebook filled icon |
169
- | `FacebookMessengerOutline` | Facebook messenger outline icon |
170
- | `FacebookOutline` | Facebook outline icon |
171
- | `FacebookRoundFilled` | Facebook round filled icon |
172
- | `FilterList` | Filter list icon |
173
- | `FilterThickFilled` | Filter thick filled icon |
174
- | `FilterThickOutline` | Filter thick outline icon |
175
- | `Filter` | Filter icon |
176
- | `FullScreenArrowThick` | Full screen arrow thick icon |
177
- | `FullScreenArrowThin` | Full screen arrow thin icon |
178
- | `FullScreenFilled` | Full screen filled icon |
179
- | `FullScreenOutline` | Full screen outline icon |
180
- | `HamburgerMenu` | Hamburger menu icon |
181
- | `HamburgerSpaced` | Hamburger spaced icon |
182
- | `HeartFilled` | Heart filled icon |
183
- | `HeartOutline` | Heart outline icon |
184
- | `HelpCircleFilled` | Help circle filled icon |
185
- | `HelpCircleOutline` | Help circle outline icon |
186
- | `Help` | Help icon |
187
- | `HomeFilled` | Home filled icon |
188
- | `HomeOutline` | Home outline icon |
189
- | `InfoCircleFilled` | Info circle filled icon |
190
- | `InfoCircleOutline` | Info circle outline icon |
191
- | `InfoSquareFilled` | Info square filled icon |
192
- | `InfoSquareOutline` | Info square outline icon |
193
- | `Info` | Info icon |
194
- | `InstagramOuline` | Instagram ouline icon |
195
- | `InstagramRoundFilled` | Instagram round filled icon |
196
- | `KeyFilled` | Key filled icon |
197
- | `KeyInSquareFilled` | Key in square filled icon |
198
- | `KeyInSquareOutline` | Key in square outline icon |
199
- | `KeyOutline` | Key outline icon |
200
- | `KeySideSquareFilled` | Key side square filled icon |
201
- | `KeySideSquareOutline` | Key side square outline icon |
202
- | `KeySquareFilled` | Key square filled icon |
203
- | `KeySquareOutline` | Key square outline icon |
204
- | `Link` | Link icon |
205
- | `LinkedinFilled` | Linkedin filled icon |
206
- | `LinkedinOutline` | Linkedin outline icon |
207
- | `LinkedinRoundFilled` | Linkedin round filled icon |
208
- | `Loading` | Loading icon |
209
- | `LocationArrowFilled` | Location arrow filled icon |
210
- | `LocationArrowOutline` | Location arrow outline icon |
211
- | `LocationFilled` | Location filled icon |
212
- | `LocationOutline` | Location outline icon |
213
- | `LockKeyholeOutline` | Lock keyhole outline icon |
214
- | `LockKeyholeUnlockedOutline` | Lock keyhole unlocked outline icon |
215
- | `LockKeyholeUnlocked` | Lock keyhole unlocked icon |
216
- | `LockKeyhole` | Lock keyhole icon |
217
- | `MediaPauseCircleFilled` | Media pause circle filled icon |
218
- | `MediaPauseCircleOuline` | Media pause circle ouline icon |
219
- | `MediaPauseFilled` | Media pause filled icon |
220
- | `MediaPauseOutline` | Media pause outline icon |
221
- | `MediaPlayCircleFilled` | Media play circle filled icon |
222
- | `MediaPlayCircleOutline` | Media play circle outline icon |
223
- | `MediaPlayFilled` | Media play filled icon |
224
- | `MediaPlayOutline` | Media play outline icon |
225
- | `MediaStopCircleFilled` | Media stop circle filled icon |
226
- | `MediaStopCircleOutline` | Media stop circle outline icon |
227
- | `MediaStopFilled` | Media stop filled icon |
228
- | `MediaStopOutline` | Media stop outline icon |
229
- | `MinusCircleFilled` | Minus circle filled icon |
230
- | `MinusCircle` | Minus circle icon |
231
- | `Minus` | Minus icon |
232
- | `MoneyBagOutline` | Money bag outline icon |
233
- | `MoneyBriefcaseFilled` | Money briefcase filled icon |
234
- | `MoneyBriefcaseOutline` | Money briefcase outline icon |
235
- | `NoEntryFilled` | No entry filled icon |
236
- | `NoEntryOutline` | No entry outline icon |
237
- | `NoEntry` | No entry icon |
238
- | `PaymentCardFilled` | Payment card filled icon |
239
- | `PaymentCardOutline` | Payment card outline icon |
240
- | `PhoneCallingFilled` | Phone calling filled icon |
241
- | `PhoneCallingOutline` | Phone calling outline icon |
242
- | `PhoneFilled` | Phone filled icon |
243
- | `PhoneOutline` | Phone outline icon |
244
- | `PinAddFilled` | Pin add filled icon |
245
- | `PinAddOutline` | Pin add outline icon |
246
- | `PinCircleFilled` | Pin circle filled icon |
247
- | `PinCircleOutline` | Pin circle outline icon |
248
- | `PinFilled` | Pin filled icon |
249
- | `PinOutline` | Pin outline icon |
250
- | `PinSubFilled` | Pin sub filled icon |
251
- | `PinSubOutline` | Pin sub outline icon |
252
- | `Pin` | Pin icon |
253
- | `PinterestFilled` | Pinterest filled icon |
254
- | `PinterestOutline` | Pinterest outline icon |
255
- | `ProfileFemaleOutline` | Profile female outline icon |
256
- | `ProfileGroupFilled` | Profile group filled icon |
257
- | `ProfileMaleFilled` | Profile male filled icon |
258
- | `ProfileMaleOutline` | Profile male outline icon |
259
- | `RedditFilled` | Reddit filled icon |
260
- | `RedditOutline` | Reddit outline icon |
261
- | `RedditRoundFilled` | Reddit round filled icon |
262
- | `RedditRoundOutline` | Reddit round outline icon |
263
- | `RupeeOutlined` | Rupee outline icon |
264
- | `RupeeSign` | Rupee sign icon |
265
- | `SaveFilled` | Save filled icon |
266
- | `SaveOutline` | Save outline icon |
267
- | `Search` | Search icon |
268
- | `SettingFilled` | Setting filled icon |
269
- | `SettingOutline` | Setting outline icon |
270
- | `ShareAllFilled` | Share all filled icon |
271
- | `ShareAllOutline` | Share all outline icon |
272
- | `ShareBoxOutline` | Share box outline icon |
273
- | `ShareFilled` | Share filled icon |
274
- | `ShareOutline` | Share outline icon |
275
- | `ShareThickFilled` | Share thick filled icon |
276
- | `ShieldCheckFilled` | Shield check filled icon |
277
- | `ShieldCheckOutline` | Shield check outline icon |
278
- | `ShieldCrossFilled` | Shield cross filled icon |
279
- | `ShieldCrossOutline` | Shield cross outline icon |
280
- | `ShieldFilled` | Shield filled icon |
281
- | `ShieldOutline` | Shield outline icon |
282
- | `ShieldWarningFilled` | Shield warning filled icon |
283
- | `ShieldWarningOutline` | Shield warning outline icon |
284
- | `SnapchatFilled` | Snapchat filled icon |
285
- | `SnapchatOutline` | Snapchat outline icon |
286
- | `SortBottomToTop` | Sort bottom to top icon |
287
- | `SortHorizontal` | Sort horizontal icon |
288
- | `SortTopToBottom` | Sort top to bottom icon |
289
- | `SortVertical` | Sort vertical icon |
290
- | `StarFilled` | Star filled icon |
291
- | `StarOutline` | Star outline icon |
292
- | `TelegramFilled` | Telegram filled icon |
293
- | `TelegramOutline` | Telegram outline icon |
294
- | `TelegramRoundFilled` | Telegram round filled icon |
295
- | `ThumbsDownFilled` | Thumbs down filled icon |
296
- | `ThumbsDownOutline` | Thumbs down outline icon |
297
- | `ThumbsUpFilled` | Thumbs up filled icon |
298
- | `ThumbsUpOutline` | Thumbs up outline icon |
299
- | `TiktokBox` | Tiktok box icon |
300
- | `TiktokThickFilled` | Tiktok thick filled icon |
301
- | `TiktokThinFilled` | Tiktok thin filled icon |
302
- | `TrashBigFilled` | Trash big filled icon |
303
- | `TrashBigOutline` | Trash big outline icon |
304
- | `TrashFilled` | Trash filled icon |
305
- | `TrashLinesFilled` | Trash lines filled icon |
306
- | `TrashLinesOutline` | Trash lines outline icon |
307
- | `TrashOutline` | Trash outline icon |
308
- | `UploadBoxFilled` | Upload box filled icon |
309
- | `UploadBoxOutline` | Upload box outline icon |
310
- | `Upload` | Upload icon |
311
- | `VolumeFilled` | Volume filled icon |
312
- | `VolumeMuteFilled` | Volume mute filled icon |
313
- | `VolumeMuteOutline` | Volume mute outline icon |
314
- | `VolumeOffFilled` | Volume off filled icon |
315
- | `VolumeOffOutline` | Volume off outline icon |
316
- | `VolumeOutline` | Volume outline icon |
317
- | `WalletFilled` | Wallet filled icon |
318
- | `WalletOutline` | Wallet outline icon |
319
- | `WarningCircleFilled` | Warning circle filled icon |
320
- | `WarningCircleOutline` | Warning circle outline icon |
321
- | `WarningSmall` | Warning small icon |
322
- | `WarningTriangleFilled` | Warning triangle filled icon |
323
- | `WarningTriangleOutline` | Warning triangle outline icon |
324
- | `Warning` | Warning icon |
325
- | `WhatsappFilled` | Whatsapp filled icon |
326
- | `WhatsappOutline` | Whatsapp outline icon |
327
- | `YoutubeFilled` | Youtube filled icon |
328
- | `YoutubeRoundFilled` | Youtube round filled icon |
329
- | `Youtube` | Youtube icon |
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` |
330
110
 
331
111
  ## 📦 Tokens
332
112
 
@@ -406,6 +186,36 @@ import blue from 'meticulous-ui/colors/blue';
406
186
  | `maskPhone` | `(str) → string` | Masks all digits except the last four; preserves formatting chars |
407
187
  | `generateInitials` | `(name) → string` | Extracts uppercased first letter of each word, e.g. `"JD"` |
408
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` |
218
+
409
219
  ## 🌱 Features
410
220
 
411
221
  ⚛️ Built with React + Styled Components
@@ -1,8 +1,8 @@
1
1
  import t, { keyframes as r } from "styled-components";
2
- import s from "../../colors/white.js";
2
+ import o from "../../colors/white.js";
3
3
  import n from "../Icons/Close/Close.js";
4
- import i from "../../colors/grey.js";
5
- const a = r`
4
+ import a from "../../colors/grey.js";
5
+ const s = r`
6
6
  from { transform: scale(0); }
7
7
  to { transform: scale(1); }
8
8
  `, d = r`
@@ -17,7 +17,7 @@ const a = r`
17
17
  opacity: 1;
18
18
  transform: translateX(0); /* Move to its final position */
19
19
  }
20
- `, c = r`
20
+ `, h = r`
21
21
  from {
22
22
  opacity: 1;
23
23
  transform: translateX(0);
@@ -26,7 +26,7 @@ const a = r`
26
26
  opacity: 0;
27
27
  transform: translateX(100%); /* Move off-screen to the right */
28
28
  }
29
- `, u = t.div`
29
+ `, w = t.div`
30
30
  position: fixed;
31
31
  top: 1.6rem;
32
32
  right: 1.6rem;
@@ -35,7 +35,7 @@ const a = r`
35
35
  display: flex;
36
36
  flex-direction: column;
37
37
  gap: 1.6rem;
38
- `, w = t.div`
38
+ `, g = t.div`
39
39
  display: flex;
40
40
  align-items: center;
41
41
  justify-content: space-between;
@@ -54,7 +54,7 @@ const a = r`
54
54
 
55
55
  &.fade-out {
56
56
  opacity: 0;
57
- animation: ${c} 0.5s ease-in forwards; /* slide right */
57
+ animation: ${h} 0.5s ease-in forwards; /* slide right */
58
58
  }
59
59
 
60
60
  @media screen and (max-width: 768px) {
@@ -63,12 +63,26 @@ const a = r`
63
63
  border-radius: 0.96rem;
64
64
  padding: 0.48rem 1.28rem;
65
65
  }
66
- `, x = t.div`
66
+
67
+ @media screen and (max-width: 480px) {
68
+ height: 5.2rem;
69
+ width: 30rem;
70
+ border-radius: 0.88rem;
71
+ padding: 0.44rem 1.12rem;
72
+ }
73
+
74
+ @media screen and (max-width: 380px) {
75
+ height: 4.8rem;
76
+ width: 27rem;
77
+ border-radius: 0.8rem;
78
+ padding: 0.4rem 1rem;
79
+ }
80
+ `, u = t.div`
67
81
  position: absolute;
68
82
  top: 50%;
69
83
  left: 50%;
70
84
  transform: translate(-50%, -50%);
71
- background-color: ${s};
85
+ background-color: ${o};
72
86
  width: 2.88rem;
73
87
  height: 2.88rem;
74
88
  border-radius: 50%;
@@ -77,18 +91,38 @@ const a = r`
77
91
  width: 2.16rem;
78
92
  height: 2.16rem;
79
93
  }
94
+
95
+ @media screen and (max-width: 480px) {
96
+ width: 1.92rem;
97
+ height: 1.92rem;
98
+ }
99
+
100
+ @media screen and (max-width: 380px) {
101
+ width: 1.76rem;
102
+ height: 1.76rem;
103
+ }
80
104
  `, b = t.div`
81
105
  position: relative;
82
106
  width: 6.4rem;
83
107
  height: 6.4rem;
84
108
  border-radius: 50%;
85
109
  background-color: ${({ $side: e }) => e};
86
- animation: ${a} 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.5s both;
110
+ animation: ${s} 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.5s both;
87
111
 
88
112
  @media screen and (max-width: 768px) {
89
113
  width: 4.8rem;
90
114
  height: 4.8rem;
91
115
  }
116
+
117
+ @media screen and (max-width: 480px) {
118
+ width: 4.3rem;
119
+ height: 4.3rem;
120
+ }
121
+
122
+ @media screen and (max-width: 380px) {
123
+ width: 3.9rem;
124
+ height: 3.9rem;
125
+ }
92
126
  `, $ = t.div`
93
127
  position: absolute;
94
128
  top: ${({ $isWarning: e }) => e ? "49%" : "50%"};
@@ -124,8 +158,18 @@ const a = r`
124
158
  width: 3.6rem;
125
159
  height: 3.6rem;
126
160
  }
127
- `, o = 75.4, l = r`
128
- from { stroke-dashoffset: ${o}; }
161
+
162
+ @media screen and (max-width: 480px) {
163
+ width: 3.2rem;
164
+ height: 3.2rem;
165
+ }
166
+
167
+ @media screen and (max-width: 380px) {
168
+ width: 2.9rem;
169
+ height: 2.9rem;
170
+ }
171
+ `, i = 75.4, c = r`
172
+ from { stroke-dashoffset: ${i}; }
129
173
  to { stroke-dashoffset: 0; }
130
174
  `, v = t.div`
131
175
  position: relative;
@@ -146,7 +190,7 @@ const a = r`
146
190
  stroke: ${({ $color: e }) => e};
147
191
  stroke-width: 2;
148
192
  stroke-linecap: round;
149
- stroke-dasharray: ${o};
193
+ stroke-dasharray: ${i};
150
194
  }
151
195
 
152
196
  circle:first-child {
@@ -155,17 +199,25 @@ const a = r`
155
199
  }
156
200
 
157
201
  circle:last-child {
158
- stroke-dashoffset: ${o};
159
- animation: ${l} ${({ $duration: e }) => e - 0.5}s linear forwards;
202
+ stroke-dashoffset: ${i};
203
+ animation: ${c} ${({ $duration: e }) => e - 0.5}s linear forwards;
160
204
  animation-play-state: ${({ $paused: e }) => e ? "paused" : "running"};
161
205
  }
162
206
  `, C = t(n)`
163
207
  cursor: pointer;
164
- `, R = t.div`
208
+ `, z = t.div`
165
209
  font-weight: 600;
166
210
  font-size: 1.92rem;
167
- color: ${i.m800};
168
- `, z = t.div`
211
+ color: ${a.m800};
212
+
213
+ @media screen and (max-width: 480px) {
214
+ font-size: 1.72rem;
215
+ }
216
+
217
+ @media screen and (max-width: 380px) {
218
+ font-size: 1.56rem;
219
+ }
220
+ `, R = t.div`
169
221
  display: flex;
170
222
  flex-direction: column;
171
223
  gap: 0.32rem;
@@ -174,22 +226,39 @@ const a = r`
174
226
  @media screen and (max-width: 768px) {
175
227
  width: 24rem;
176
228
  }
229
+
230
+ @media screen and (max-width: 480px) {
231
+ width: 21rem;
232
+ }
233
+
234
+ @media screen and (max-width: 380px) {
235
+ max-width: 18rem;
236
+ width: auto;
237
+ }
177
238
  `, I = t.div`
178
239
  font-weight: 400;
179
240
  font-size: 1.6rem;
180
- color: ${i.m700};
241
+ color: ${a.m700};
242
+
243
+ @media screen and (max-width: 480px) {
244
+ font-size: 1.44rem;
245
+ }
246
+
247
+ @media screen and (max-width: 380px) {
248
+ font-size: 1.32rem;
249
+ }
181
250
  `;
182
251
  export {
183
252
  v as CloseButtonContainer,
184
253
  C as CloseWrapper,
185
254
  $ as Icon,
186
- x as LogoContainer,
187
- z as Message,
255
+ u as LogoContainer,
256
+ R as Message,
188
257
  b as Outer,
189
258
  y as OuterChild,
190
259
  k as ProgressRing,
191
260
  I as Subtitle,
192
- R as Title,
193
- w as ToastWrapper,
194
- u as ToastsContainer
261
+ z as Title,
262
+ g as ToastWrapper,
263
+ w as ToastsContainer
195
264
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "meticulous-ui",
3
- "version": "3.2.2",
4
- "license": "MIT",
3
+ "version": "3.2.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",
7
7
  "module": "./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
+ };
@@ -1,6 +1,8 @@
1
1
  const a = (e, t = "en-US") => {
2
2
  const n = e instanceof Date ? e : new Date(e);
3
- return isNaN(n) ? "" : new Intl.DateTimeFormat(t, { year: "numeric", month: "long", day: "numeric" }).format(n);
3
+ return isNaN(n) ? "" : new Intl.DateTimeFormat(t, { year: "numeric", month: "long", day: "numeric" }).format(
4
+ n
5
+ );
4
6
  };
5
7
  export {
6
8
  a as default
@@ -1,6 +1,10 @@
1
1
  const r = (t, n = "en-US") => {
2
2
  const e = t instanceof Date ? t : new Date(t);
3
- return isNaN(e) ? "" : new Intl.DateTimeFormat(n, { hour: "numeric", minute: "2-digit", hour12: !0 }).format(e);
3
+ return isNaN(e) ? "" : new Intl.DateTimeFormat(n, {
4
+ hour: "numeric",
5
+ minute: "2-digit",
6
+ hour12: !0
7
+ }).format(e);
4
8
  };
5
9
  export {
6
10
  r as default
@@ -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,99 +1,141 @@
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
- import n from "./formatCurrency.js";
11
- import s from "./formatDate.js";
12
- import c from "./formatNumber.js";
13
- import u from "./formatTime.js";
14
- import y from "./generateInitials.js";
15
- import l from "./getGreetingByTime.js";
16
- import d from "./groupBy.js";
10
+ import s from "./formatCurrency.js";
11
+ import n from "./formatDate.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
+ import y from "./groupBy.js";
17
17
  import g from "./hasEqualProps.js";
18
- import k from "./addDays.js";
19
- import C from "./countdown.js";
20
- import B from "./differenceInDays.js";
21
- import E from "./isEmpty.js";
22
- import b from "./isEqual.js";
23
- import D from "./isNonEmptyArray.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
24
  import T from "./isPast.js";
25
- import h from "./isToday.js";
26
- import q from "./kebabCase.js";
27
- import x from "./keyBy.js";
28
- import I from "./maskEmail.js";
29
- import N from "./maskPhone.js";
30
- import P from "./mergeDeep.js";
31
- import w from "./omit.js";
32
- import A from "./percentage.js";
33
- import j from "./pick.js";
34
- import v from "./randomBetween.js";
35
- import z from "./randomInt.js";
36
- import F from "./randomValue.js";
37
- import G from "./removeExtraSpaces.js";
38
- import L from "./roundTo.js";
39
- import O from "./slugify.js";
40
- import S from "./snakeCase.js";
41
- import V from "./sortBy.js";
42
- import H from "./timeAgo.js";
43
- import J from "./titleCase.js";
44
- import K from "./truncate.js";
45
- import M from "./uniqueBy.js";
46
- const Gr = {
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";
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";
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
+ import Q from "./isURL.js";
49
+ import W from "./isPasswordStrong.js";
50
+ import X from "./isPAN.js";
51
+ import Y from "./isAadhaar.js";
52
+ import Z from "./isGST.js";
53
+ import _ from "./isRequired.js";
54
+ import $ from "./minLength.js";
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 = {
47
67
  // string
48
- capFirstLetter: r,
49
- capitalize: o,
68
+ capFirstLetter: o,
69
+ capitalize: r,
50
70
  camelCase: m,
51
- generateInitials: y,
52
- kebabCase: q,
53
- maskEmail: I,
54
- maskPhone: N,
55
- removeExtraSpaces: G,
56
- slugify: O,
57
- snakeCase: S,
58
- titleCase: J,
59
- truncate: K,
71
+ generateInitials: c,
72
+ kebabCase: P,
73
+ maskEmail: A,
74
+ maskPhone: D,
75
+ removeExtraSpaces: F,
76
+ slugify: M,
77
+ snakeCase: R,
78
+ titleCase: U,
79
+ truncate: V,
60
80
  // number
61
- clamp: i,
81
+ clamp: t,
62
82
  formatCompactNumber: a,
63
- formatCurrency: n,
64
- formatNumber: c,
65
- percentage: A,
66
- randomBetween: v,
67
- randomInt: z,
68
- randomValue: F,
69
- roundTo: L,
83
+ formatCurrency: s,
84
+ formatNumber: d,
85
+ percentage: q,
86
+ randomBetween: L,
87
+ randomInt: O,
88
+ randomValue: z,
89
+ roundTo: G,
70
90
  // date-time
71
- addDays: k,
72
- countdown: C,
73
- differenceInDays: B,
74
- formatDate: s,
75
- formatTime: u,
76
- getGreetingByTime: l,
91
+ addDays: b,
92
+ countdown: k,
93
+ differenceInDays: C,
94
+ formatDate: n,
95
+ formatTime: l,
96
+ getGreetingByTime: u,
77
97
  isPast: T,
78
- isToday: h,
79
- timeAgo: H,
98
+ isToday: B,
99
+ timeAgo: v,
80
100
  // object / array
81
- chunk: t,
101
+ chunk: i,
82
102
  compose: p,
83
103
  deepClone: f,
84
104
  flattenObject: e,
85
- groupBy: d,
105
+ groupBy: y,
86
106
  hasEqualProps: g,
87
- isEmpty: E,
88
- isEqual: b,
89
- isNonEmptyArray: D,
90
- keyBy: x,
91
- mergeDeep: P,
92
- omit: w,
93
- pick: j,
94
- sortBy: V,
95
- uniqueBy: M
107
+ isEmpty: h,
108
+ isEqual: E,
109
+ isNonEmptyArray: S,
110
+ keyBy: w,
111
+ mergeDeep: I,
112
+ omit: N,
113
+ pick: x,
114
+ sortBy: j,
115
+ uniqueBy: H,
116
+ // validation
117
+ isEmail: J,
118
+ isPhone: K,
119
+ isURL: Q,
120
+ isPasswordStrong: W,
121
+ isPAN: X,
122
+ isAadhaar: Y,
123
+ isGST: Z,
124
+ isRequired: _,
125
+ minLength: $,
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
96
138
  };
97
139
  export {
98
- Gr as default
140
+ Tr as default
99
141
  };
@@ -0,0 +1,8 @@
1
+ const e = (t) => {
2
+ if (typeof t != "string") return !1;
3
+ const s = t.replace(/\s/g, "");
4
+ return /^[1-9]\d{11}$/.test(s);
5
+ };
6
+ export {
7
+ e as default
8
+ };
@@ -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
+ };
@@ -0,0 +1,4 @@
1
+ const s = (t) => typeof t != "string" ? !1 : /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.trim());
2
+ export {
3
+ s as default
4
+ };
package/utils/isGST.js ADDED
@@ -0,0 +1,4 @@
1
+ const r = (t) => typeof t != "string" ? !1 : /^\d{2}[A-Z]{5}\d{4}[A-Z]{1}\d{1}Z[A-Z\d]{1}$/i.test(t.trim());
2
+ export {
3
+ r 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
+ };
package/utils/isPAN.js ADDED
@@ -0,0 +1,4 @@
1
+ const r = (t) => typeof t != "string" ? !1 : /^[A-Z]{5}[0-9]{4}[A-Z]$/i.test(t.trim());
2
+ export {
3
+ r as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const r = (t) => typeof t != "string" ? !1 : /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d]).{8,}$/.test(t);
2
+ export {
3
+ r as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const e = (t) => typeof t != "string" ? !1 : /^[+]?[\d\s\-().]{7,15}$/.test(t.trim());
2
+ export {
3
+ e as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const t = (r) => r == null ? !1 : typeof r == "string" ? r.trim().length > 0 : Array.isArray(r) ? r.length > 0 : !0;
2
+ export {
3
+ t as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const a = () => /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
2
+ export {
3
+ a as default
4
+ };
package/utils/isURL.js ADDED
@@ -0,0 +1,12 @@
1
+ const o = (t) => {
2
+ if (typeof t != "string") return !1;
3
+ try {
4
+ const r = new URL(t.trim());
5
+ return r.protocol === "http:" || r.protocol === "https:";
6
+ } catch {
7
+ return !1;
8
+ }
9
+ };
10
+ export {
11
+ o as default
12
+ };
@@ -0,0 +1,4 @@
1
+ const n = (t, e) => typeof t != "string" ? !1 : t.length <= e;
2
+ export {
3
+ n as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const n = (t, e) => typeof t != "string" ? !1 : t.length >= e;
2
+ export {
3
+ n 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
+ };