@dimasbaguspm/versaur 0.0.20 → 0.0.22

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
@@ -1,7 +1,21 @@
1
+
1
2
  # Versaur UI
2
3
 
3
- A modern React UI library built with TypeScript and Tailwind CSS, featuring tree-shakable
4
- components
4
+ <p align="left">
5
+ <a href="https://www.npmjs.com/package/@dimasbaguspm/versaur" target="_blank" rel="noopener noreferrer">
6
+ <img src="https://img.shields.io/npm/v/%40dimasbaguspm%2Fversaur?style=flat-square&color=%23e07a5f" alt="NPM Version" />
7
+ </a>
8
+ <a href="https://www.npmjs.com/package/@dimasbaguspm/versaur" target="_blank" rel="noopener noreferrer">
9
+ <img src="https://img.shields.io/npm/dy/%40dimasbaguspm%2Fversaur?style=flat-square&color=%2381b29a" alt="NPM Downloads" />
10
+ </a>
11
+ <a href="https://www.npmjs.com/package/@dimasbaguspm/versaur" target="_blank" rel="noopener noreferrer">
12
+ <img src="https://img.shields.io/npm/last-update/%40dimasbaguspm%2Fversaur?style=flat-square&color=%2384a5c0" alt="NPM Last Update" />
13
+ </a>
14
+ </p>
15
+
16
+ A modern React UI library built with TypeScript and Tailwind CSS, featuring tree-shakable components
17
+
18
+ Website: [versaur.dimasbaguspm.com](https://versaur.dimasbaguspm.com)
5
19
 
6
20
 
7
21
  ## Features
@@ -19,7 +33,9 @@ components
19
33
  ## Installation
20
34
 
21
35
  ```bash
22
- yarn install @dimasbaguspm/versaur
36
+ npm install @dimasbaguspm/versaur
37
+ yarn add @dimasbaguspm/versaur
38
+ bun add @dimasbaguspm/versaur
23
39
  ```
24
40
 
25
41
  ## Usage
@@ -27,13 +43,13 @@ yarn install @dimasbaguspm/versaur
27
43
  ### Import all components
28
44
 
29
45
  ```tsx
30
- import { Button, Input, Card } from '@dimasbaguspm/versaur'
46
+ import { Button, Input, Drawer } from '@dimasbaguspm/versaur'
31
47
  ```
32
48
 
33
49
  ### Tree-shakable imports
34
50
 
35
51
  ```tsx
36
- // Import only what you need
52
+ // import only what you need
37
53
  import { Button } from '@dimasbaguspm/versaur/primitive'
38
54
  ```
39
55
 
@@ -47,7 +63,7 @@ Versaur provides an ESLint rule to enforce sub-path imports for optimal tree-sha
47
63
  1. In your FlatConfig file (e.g., `eslint.config.js`), import and spread the rule:
48
64
 
49
65
  ```js
50
- // eslint.config.js
66
+ // eslint.config.{js|ts}
51
67
  import { versaurEnforceSubpathImport } from '@dimasbaguspm/versaur/enforce-subpath-import'
52
68
 
53
69
  export default [
@@ -0,0 +1,573 @@
1
+ import { c, j as n, a as d } from "./index-DOdDlCoL.js";
2
+ import y, { useState as b, useEffect as h, createContext as S, useContext as R, forwardRef as w, useRef as C, useCallback as T, useMemo as H } from "react";
3
+ import z from "react-dom";
4
+ function D() {
5
+ if (typeof window > "u") return !1;
6
+ const e = window.navigator.userAgent, o = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
7
+ e
8
+ ), t = /iPad|Android(?=.*Mobile)|Tablet/i.test(e), r = "ontouchstart" in window || navigator.maxTouchPoints > 0, a = window.innerWidth <= 1024;
9
+ return o || t || r && a;
10
+ }
11
+ function k() {
12
+ return typeof window < "u" && "navigator" in window && "virtualKeyboard" in navigator;
13
+ }
14
+ function F() {
15
+ const [e, o] = b(!1), [t, r] = b(0), [a, s] = b(0), [i, m] = b(!1), [p, x] = b(!1);
16
+ return h(() => {
17
+ if (!D()) {
18
+ m(!1);
19
+ return;
20
+ }
21
+ m(!0), x(k());
22
+ }, []), h(() => {
23
+ if (!i || !k())
24
+ return;
25
+ const u = navigator.virtualKeyboard, l = () => {
26
+ const { boundingRect: f } = u, v = f?.height || 0, g = f?.width || 0;
27
+ o(v > 0), r(v), s(g);
28
+ };
29
+ return l(), u.addEventListener("geometrychange", l), () => {
30
+ u.removeEventListener(
31
+ "geometrychange",
32
+ l
33
+ );
34
+ };
35
+ }, [i]), h(() => {
36
+ if (!i || k())
37
+ return;
38
+ const u = window.innerHeight;
39
+ let l;
40
+ const f = () => {
41
+ clearTimeout(l), l = setTimeout(() => {
42
+ const v = window.visualViewport?.height ?? window.innerHeight, g = u - v, V = g > 150;
43
+ o(V), r(V ? g : 0), s(V ? window.innerWidth : 0);
44
+ }, 100);
45
+ };
46
+ return "visualViewport" in window && window.visualViewport ? (window.visualViewport.addEventListener("resize", f), () => {
47
+ clearTimeout(l), window.visualViewport?.removeEventListener(
48
+ "resize",
49
+ f
50
+ );
51
+ }) : (window.addEventListener("resize", f), () => {
52
+ clearTimeout(l), window.removeEventListener("resize", f);
53
+ });
54
+ }, [i]), h(() => {
55
+ i || (o(!1), r(0), s(0));
56
+ }, [i]), {
57
+ isOpen: e,
58
+ height: t,
59
+ width: a,
60
+ isSupported: i,
61
+ usingNativeAPI: p
62
+ };
63
+ }
64
+ const E = S(null);
65
+ function I() {
66
+ const e = R(E);
67
+ if (!e)
68
+ throw new Error(
69
+ "Modal components must be used within a ModalRoot component"
70
+ );
71
+ return e;
72
+ }
73
+ const P = c(
74
+ "fixed inset-0 z-60 transition-opacity duration-300 bg-foreground/30 backdrop-blur-md flex items-center justify-center transition-opacity duration-200 ease-in-out",
75
+ {
76
+ variants: {
77
+ placement: {
78
+ top: "items-start",
79
+ center: "items-center"
80
+ }
81
+ },
82
+ defaultVariants: {
83
+ placement: "center"
84
+ }
85
+ }
86
+ ), L = c(
87
+ [
88
+ "absolute z-61 bg-white rounded-lg shadow-xl",
89
+ "flex flex-col",
90
+ "outline-none",
91
+ "transition-all duration-200 ease-in-out"
92
+ ],
93
+ {
94
+ variants: {
95
+ size: {
96
+ sm: "w-[20rem] max-w-[90%]",
97
+ // 20rem, 320px
98
+ md: "w-[28rem] max-w-[90%]",
99
+ // 28rem, 448px
100
+ lg: "w-[36rem] max-w-[90%]",
101
+ // 36rem, 576px
102
+ "fit-content": "w-fit max-w-[90%]"
103
+ // Fit content, no max width
104
+ },
105
+ placement: {
106
+ top: "top-8 left-1/2 -translate-x-1/2",
107
+ center: "top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
108
+ },
109
+ isOpen: {
110
+ true: "opacity-100 scale-100",
111
+ false: "opacity-0 scale-95 pointer-events-none"
112
+ }
113
+ },
114
+ defaultVariants: {
115
+ size: "md",
116
+ placement: "center",
117
+ isOpen: !1
118
+ }
119
+ }
120
+ ), A = w(
121
+ ({ className: e, ...o }, t) => /* @__PURE__ */ n.jsx(
122
+ "div",
123
+ {
124
+ ref: t,
125
+ className: d("px-6 pt-6 pb-2 text-lg font-semibold", e),
126
+ ...o
127
+ }
128
+ )
129
+ ), K = w(
130
+ ({ className: e, ...o }, t) => /* @__PURE__ */ n.jsx(
131
+ "div",
132
+ {
133
+ ref: t,
134
+ className: d("px-6 py-4 flex justify-end gap-2", e),
135
+ ...o
136
+ }
137
+ )
138
+ ), W = w(
139
+ ({ className: e, ...o }, t) => /* @__PURE__ */ n.jsx("div", { ref: t, className: d("px-6 py-2", e), ...o })
140
+ ), O = w(
141
+ (e, o) => {
142
+ const { isOpen: t, placement: r, onClose: a } = I();
143
+ return /* @__PURE__ */ n.jsx(
144
+ "div",
145
+ {
146
+ ref: o,
147
+ role: "presentation",
148
+ tabIndex: -1,
149
+ "aria-modal": "true",
150
+ onClick: a,
151
+ className: d(
152
+ P({ placement: r }),
153
+ t ? "opacity-100" : "opacity-0 pointer-events-none"
154
+ ),
155
+ ...e
156
+ }
157
+ );
158
+ }
159
+ );
160
+ function B(e, o, t) {
161
+ const r = C(null);
162
+ return h(() => {
163
+ r.current && r.current.focus();
164
+ }, []), h(() => {
165
+ const a = (s) => {
166
+ s.key === "Escape" && e && r.current && r.current.contains(document.activeElement) && !t && o();
167
+ };
168
+ return e && (document.addEventListener("keydown", a), document.body.style.overflow = "hidden"), () => {
169
+ document.removeEventListener("keydown", a), document.body.style.overflow = "unset";
170
+ };
171
+ }, [e, o, t, r]), r;
172
+ }
173
+ const N = ({
174
+ container: e,
175
+ children: o
176
+ }) => {
177
+ if (typeof window > "u" || typeof document > "u")
178
+ return /* @__PURE__ */ n.jsx(n.Fragment, { children: o });
179
+ const t = e ?? document.body;
180
+ return t ? z.createPortal(o, t) : /* @__PURE__ */ n.jsx(n.Fragment, { children: o });
181
+ }, _ = ({
182
+ isOpen: e,
183
+ onClose: o,
184
+ size: t = "md",
185
+ placement: r = "center",
186
+ children: a,
187
+ container: s,
188
+ ...i
189
+ }) => {
190
+ const m = {
191
+ isOpen: e,
192
+ onClose: o,
193
+ size: t,
194
+ placement: r
195
+ }, p = B(e, o);
196
+ return /* @__PURE__ */ n.jsx(N, { container: s, children: /* @__PURE__ */ n.jsx(E.Provider, { value: m, children: /* @__PURE__ */ n.jsxs(
197
+ "div",
198
+ {
199
+ className: d(
200
+ "fixed z-50 inset-0 pointer-events-none",
201
+ e && "pointer-events-auto"
202
+ ),
203
+ children: [
204
+ /* @__PURE__ */ n.jsx(O, {}),
205
+ /* @__PURE__ */ n.jsx(
206
+ "div",
207
+ {
208
+ ref: p,
209
+ className: d(L({ size: t, placement: r, isOpen: e })),
210
+ role: "dialog",
211
+ tabIndex: -1,
212
+ "aria-hidden": !e,
213
+ ...i,
214
+ children: a
215
+ }
216
+ )
217
+ ]
218
+ }
219
+ ) }) });
220
+ }, he = Object.assign(_, {
221
+ Header: A,
222
+ Body: W,
223
+ Footer: K
224
+ }), M = S(null);
225
+ function j() {
226
+ const e = R(M);
227
+ if (!e)
228
+ throw new Error(
229
+ "Drawer components must be used within a DrawerRoot component"
230
+ );
231
+ return e;
232
+ }
233
+ const $ = c(
234
+ "fixed inset-0 z-50 transition-opacity duration-300 bg-foreground/30 backdrop-blur-md",
235
+ {
236
+ variants: {
237
+ state: {
238
+ open: "opacity-100",
239
+ closed: "opacity-0 pointer-events-none"
240
+ }
241
+ },
242
+ defaultVariants: {
243
+ state: "closed"
244
+ }
245
+ }
246
+ ), G = c("fixed z-50 shadow-xl flex flex-col", {
247
+ variants: {
248
+ position: {
249
+ left: "left-0 top-0 bottom-0 border-r",
250
+ right: "right-0 top-0 bottom-0 border-l"
251
+ },
252
+ size: {
253
+ sm: "w-80",
254
+ md: "w-96",
255
+ lg: "w-[28rem]",
256
+ xl: "w-[32rem]",
257
+ "3/4": "w-[75vw]",
258
+ full: "w-full"
259
+ },
260
+ variant: {
261
+ default: "bg-white border-border",
262
+ glass: "bg-white/10 backdrop-blur-lg border-white/20"
263
+ },
264
+ transitionType: {
265
+ slide: "transition-transform duration-300 ease-in-out",
266
+ fade: "transition-opacity duration-300 ease-in-out"
267
+ }
268
+ },
269
+ defaultVariants: {
270
+ position: "right",
271
+ size: "md",
272
+ variant: "default",
273
+ transitionType: "slide"
274
+ }
275
+ }), U = c("flex-shrink-0 px-6", {
276
+ variants: {
277
+ variant: {
278
+ default: "bg-white",
279
+ glass: "bg-transparent "
280
+ },
281
+ tab: {
282
+ true: "pt-4 pb-2",
283
+ false: "border-b border-border py-4 "
284
+ }
285
+ },
286
+ defaultVariants: {
287
+ variant: "default",
288
+ tab: !1
289
+ }
290
+ }), q = c("flex-1 overflow-y-auto px-6 py-4", {
291
+ variants: {
292
+ variant: {
293
+ default: "bg-white",
294
+ glass: "bg-transparent"
295
+ }
296
+ },
297
+ defaultVariants: {
298
+ variant: "default"
299
+ }
300
+ }), J = c("flex-shrink-0 px-6 py-4 border-t", {
301
+ variants: {
302
+ variant: {
303
+ default: "bg-white border-border",
304
+ glass: "bg-transparent border-white/10"
305
+ },
306
+ responsiveFlex: {
307
+ true: "flex flex-row gap-3 sm:justify-end [&>*]:sm:flex-grow-0 [&>*]:flex-grow",
308
+ false: "flex gap-2"
309
+ }
310
+ },
311
+ defaultVariants: {
312
+ variant: "default",
313
+ responsiveFlex: !0
314
+ }
315
+ }), Q = y.forwardRef(({ className: e, ...o }, t) => {
316
+ const { isOpen: r, onClose: a } = j(), s = () => {
317
+ a();
318
+ };
319
+ return /* @__PURE__ */ n.jsx(
320
+ "div",
321
+ {
322
+ ref: t,
323
+ onClick: s,
324
+ className: d(
325
+ $({
326
+ state: r ? "open" : "closed"
327
+ }),
328
+ e
329
+ ),
330
+ ...o
331
+ }
332
+ );
333
+ }), X = y.forwardRef(
334
+ ({ children: e, className: o, hasTab: t, ...r }, a) => {
335
+ const { variant: s } = j();
336
+ return /* @__PURE__ */ n.jsx(
337
+ "div",
338
+ {
339
+ ref: a,
340
+ className: d(
341
+ U({ variant: s, tab: !!t }),
342
+ o
343
+ ),
344
+ ...r,
345
+ children: e
346
+ }
347
+ );
348
+ }
349
+ ), Y = w(
350
+ ({ children: e, className: o, ...t }, r) => /* @__PURE__ */ n.jsx("div", { ref: r, className: d("[&>div]:px-6", o), ...t, children: e })
351
+ ), Z = y.forwardRef(
352
+ ({ children: e, className: o, ...t }, r) => {
353
+ const { variant: a } = j();
354
+ return /* @__PURE__ */ n.jsx(
355
+ "div",
356
+ {
357
+ ref: r,
358
+ className: d(q({ variant: a }), o),
359
+ ...t,
360
+ children: e
361
+ }
362
+ );
363
+ }
364
+ ), ee = y.forwardRef(
365
+ ({ children: e, className: o, responsiveFlex: t = !0, ...r }, a) => {
366
+ const { variant: s } = j();
367
+ return /* @__PURE__ */ n.jsx(
368
+ "div",
369
+ {
370
+ ref: a,
371
+ className: d(
372
+ J({ variant: s, responsiveFlex: t }),
373
+ o
374
+ ),
375
+ ...r,
376
+ children: e
377
+ }
378
+ );
379
+ }
380
+ ), te = ({
381
+ container: e,
382
+ children: o,
383
+ isOpen: t,
384
+ onClose: r,
385
+ position: a = "right",
386
+ size: s = "md",
387
+ variant: i = "default",
388
+ transitionType: m = "slide",
389
+ className: p,
390
+ ...x
391
+ }) => {
392
+ const u = T(() => {
393
+ r(!1);
394
+ }, [r]), l = {
395
+ isOpen: t,
396
+ onClose: u,
397
+ position: a,
398
+ size: s,
399
+ variant: i,
400
+ transitionType: m
401
+ }, f = B(t, u);
402
+ return /* @__PURE__ */ n.jsx(N, { container: e, children: /* @__PURE__ */ n.jsx(M.Provider, { value: l, children: /* @__PURE__ */ n.jsxs(
403
+ "div",
404
+ {
405
+ className: d(
406
+ "fixed z-50 inset-0 pointer-events-none",
407
+ t && "pointer-events-auto"
408
+ ),
409
+ children: [
410
+ /* @__PURE__ */ n.jsx(Q, {}),
411
+ /* @__PURE__ */ n.jsx(
412
+ "div",
413
+ {
414
+ ref: f,
415
+ tabIndex: -1,
416
+ role: t ? "dialog" : void 0,
417
+ "aria-modal": t ? "true" : void 0,
418
+ className: d(
419
+ G({
420
+ position: a,
421
+ size: s,
422
+ variant: i,
423
+ transitionType: m
424
+ }),
425
+ m === "slide" ? [
426
+ !t && a === "left" && "-translate-x-full",
427
+ !t && a === "right" && "translate-x-full"
428
+ ] : [
429
+ "left-0 right-0 top-0 bottom-0",
430
+ t ? "opacity-100" : "opacity-0 pointer-events-none"
431
+ ],
432
+ p
433
+ ),
434
+ ...x,
435
+ children: t && o
436
+ }
437
+ )
438
+ ]
439
+ }
440
+ ) }) });
441
+ }, be = Object.assign(te, {
442
+ Header: X,
443
+ Tab: Y,
444
+ Body: Z,
445
+ Footer: ee
446
+ }), oe = c(
447
+ [
448
+ "fixed left-0 bottom-0 z-40 w-full max-h-[90dvh] bg-background rounded-t-xl shadow-lg border-t border-border rounded-lg",
449
+ "transition-transform duration-300 ease-in-out will-change-transform",
450
+ "overflow-hidden"
451
+ // Ensure content doesn't overflow when keyboard adjusts height
452
+ ],
453
+ {
454
+ variants: {
455
+ open: {
456
+ true: "translate-y-0",
457
+ false: "translate-y-full"
458
+ }
459
+ },
460
+ defaultVariants: {
461
+ open: !1
462
+ }
463
+ }
464
+ ), re = c(
465
+ ["fixed inset-0 z-40 duration-300"],
466
+ {
467
+ variants: {
468
+ open: {
469
+ true: "backdrop-blur-md bg-foreground/30",
470
+ false: "pointer-events-none"
471
+ }
472
+ },
473
+ defaultVariants: {
474
+ open: !1
475
+ }
476
+ }
477
+ ), ne = c("px-4 pt-4 pb-2 flex-shrink-0"), ae = c([
478
+ "px-4 py-2 flex-1 overflow-y-auto",
479
+ "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-border"
480
+ ]), se = c("px-4 pt-2 pb-4 flex-shrink-0"), ie = w(function({ className: o, ...t }, r) {
481
+ return /* @__PURE__ */ n.jsx(
482
+ "h2",
483
+ {
484
+ ref: r,
485
+ className: ["text-lg font-semibold text-foreground", o].filter(Boolean).join(" "),
486
+ ...t
487
+ }
488
+ );
489
+ }), de = w(({ className: e, ...o }, t) => /* @__PURE__ */ n.jsx(
490
+ "div",
491
+ {
492
+ ref: t,
493
+ className: ne({ className: e }),
494
+ ...o
495
+ }
496
+ )), le = w(
497
+ ({ className: e, ...o }, t) => /* @__PURE__ */ n.jsx(
498
+ "div",
499
+ {
500
+ ref: t,
501
+ className: ae({ className: e }),
502
+ ...o
503
+ }
504
+ )
505
+ ), ce = w(({ className: e, ...o }, t) => /* @__PURE__ */ n.jsx(
506
+ "div",
507
+ {
508
+ ref: t,
509
+ className: se({ className: e }),
510
+ ...o
511
+ }
512
+ )), ue = (...e) => (o) => {
513
+ e.forEach((t) => {
514
+ typeof t == "function" ? t(o) : t && "current" in t && (t.current = o);
515
+ });
516
+ }, fe = w(
517
+ ({ isOpen: e, children: o, className: t, onClose: r, container: a, ...s }, i) => {
518
+ const m = B(e, r), {
519
+ isOpen: p,
520
+ height: x,
521
+ isSupported: u
522
+ } = F(), l = H(() => !e || !u || !p ? {} : {
523
+ // Adjust bottom position to sit above the virtual keyboard
524
+ bottom: `${x}px`,
525
+ // Reduce max height to account for keyboard
526
+ maxHeight: `calc(90dvh - ${x}px)`,
527
+ // Ensure smooth transition
528
+ transition: "bottom 0.2s ease-in-out, max-height 0.2s ease-in-out"
529
+ }, [e, u, p, x]), f = () => {
530
+ r?.();
531
+ };
532
+ return /* @__PURE__ */ n.jsxs(N, { container: a, children: [
533
+ /* @__PURE__ */ n.jsx(
534
+ "div",
535
+ {
536
+ className: re({ open: e }),
537
+ "aria-hidden": "true",
538
+ onClick: f
539
+ }
540
+ ),
541
+ /* @__PURE__ */ n.jsx(
542
+ "div",
543
+ {
544
+ ref: ue(i, m),
545
+ className: d(
546
+ oe({
547
+ open: e
548
+ }),
549
+ "flex flex-col",
550
+ // Add flex layout for proper header/body/footer arrangement
551
+ t
552
+ ),
553
+ style: l,
554
+ role: "dialog",
555
+ "aria-modal": "true",
556
+ tabIndex: -1,
557
+ ...s,
558
+ children: o
559
+ }
560
+ )
561
+ ] });
562
+ }
563
+ ), ve = Object.assign(fe, {
564
+ Header: de,
565
+ Title: ie,
566
+ Body: le,
567
+ Footer: ce
568
+ });
569
+ export {
570
+ ve as B,
571
+ be as D,
572
+ he as M
573
+ };
@@ -1,10 +1,10 @@
1
1
  import { c as j, j as e, a as p } from "./index-DOdDlCoL.js";
2
2
  import x, { createContext as S, useContext as V, useRef as $, forwardRef as I, useState as O, useId as D, useEffect as X, useMemo as P } from "react";
3
3
  import { Check as F, Calendar as Y, SearchIcon as Z, Clock as ee, Banknote as re, MailIcon as te } from "lucide-react";
4
- import { I as z } from "./image-rectangle-DH7v2xvp.js";
4
+ import { I as z } from "./image-rectangle-C6cgL8R9.js";
5
5
  import "./snackbar-DH8jCh2V.js";
6
6
  import "./text-CRsIInRA.js";
7
- import { M, D as E, B as R } from "./bottom-sheet-DbtyWwsy.js";
7
+ import { M, D as E, B as R } from "./bottom-sheet-CCDa5VGo.js";
8
8
  const oe = j("space-y-2", {
9
9
  variants: {
10
10
  direction: {
@@ -1,4 +1,4 @@
1
- import { B as a, C as n, b as p, a as u, D as s, k as I, E as i, M as l, P as S, R as c, d as r, c as g, S as h, e as o, j as m, i as M, h as b, f as k, T as x, g as C } from "../bottom-sheet-input-C7cYfBaK.js";
1
+ import { B as a, C as n, b as p, a as u, D as s, k as I, E as i, M as l, P as S, R as c, d as r, c as g, S as h, e as o, j as m, i as M, h as b, f as k, T as x, g as C } from "../bottom-sheet-input-nVi11sIJ.js";
2
2
  export {
3
3
  a as BottomSheetInput,
4
4
  n as CheckboxInput,