@ramme-io/ui 4.1.1 → 4.2.0

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.
@@ -1,27 +1,28 @@
1
- import { jsx as r, jsxs as b } from "react/jsx-runtime";
2
- import { useState as p, useRef as L, useCallback as s, useEffect as y } from "react";
3
- import { createPortal as z } from "react-dom";
4
- import { Icon as F } from "../ui/Icon.js";
5
- import { cn as g } from "../../utils/cn.js";
6
- import { useBodyScrollLock as A } from "../../lib/hooks/useBodyScrollLock.js";
7
- const P = {
1
+ import { jsx as r, jsxs as p } from "react/jsx-runtime";
2
+ import { useState as y, useRef as L, useCallback as c, useEffect as g, useId as z } from "react";
3
+ import { createPortal as D } from "react-dom";
4
+ import { useDialogFocus as A } from "../../lib/hooks/useDialogFocus.js";
5
+ import { Icon as P } from "../ui/Icon.js";
6
+ import { cn as v } from "../../utils/cn.js";
7
+ import { useBodyScrollLock as q } from "../../lib/hooks/useBodyScrollLock.js";
8
+ const B = {
8
9
  sm: "320px",
9
10
  md: "480px",
10
11
  lg: "640px",
11
12
  xl: "80vw",
12
13
  full: "100vw"
13
- }, W = ({
14
+ }, J = ({
14
15
  isOpen: o,
15
- onClose: n,
16
- children: v,
17
- footer: d,
16
+ onClose: a,
17
+ children: k,
18
+ footer: f,
18
19
  position: l = "right",
19
- size: f = "md",
20
- title: m,
21
- className: k,
22
- overlayDismiss: u = !0
20
+ size: u = "md",
21
+ title: n,
22
+ className: S,
23
+ overlayDismiss: m = !0
23
24
  }) => {
24
- const [i, x] = p(!1), [h, w] = p(!1), c = L(null), S = (e) => P[e] || e, C = s(() => {
25
+ const [s, x] = y(!1), [h, w] = y(!1), i = L(null), C = (e) => B[e] || e, E = c(() => {
25
26
  switch (l) {
26
27
  case "left":
27
28
  return { from: "-translate-x-full", to: "translate-x-0", positionClass: "left-0 top-0 h-full" };
@@ -34,11 +35,11 @@ const P = {
34
35
  default:
35
36
  return { from: "translate-x-full", to: "translate-x-0", positionClass: "right-0 top-0 h-full" };
36
37
  }
37
- }, [l]), E = s(() => {
38
- const e = {}, t = S(f);
38
+ }, [l]), I = c(() => {
39
+ const e = {}, t = C(u);
39
40
  return l === "left" || l === "right" ? (e.width = t, e.maxWidth = "100dvw") : (e.height = t, e.maxHeight = "100dvh"), e;
40
- }, [l, f]), { from: N, to: T, positionClass: R } = C(), j = E();
41
- A(o), y(() => {
41
+ }, [l, u]), { from: N, to: T, positionClass: R } = E(), j = I();
42
+ q(o), g(() => {
42
43
  let e, t;
43
44
  return o ? (x(!0), e = requestAnimationFrame(() => {
44
45
  t = window.setTimeout(() => w(!0), 10);
@@ -46,48 +47,55 @@ const P = {
46
47
  cancelAnimationFrame(e), clearTimeout(t);
47
48
  };
48
49
  }, [o]);
49
- const I = s((e) => {
50
- u && c.current && !c.current.contains(e.target) && n();
51
- }, [n, u]), a = s((e) => {
52
- e.key === "Escape" && o && n();
53
- }, [o, n]);
54
- return y(() => (i ? document.addEventListener("keydown", a) : document.removeEventListener("keydown", a), () => document.removeEventListener("keydown", a)), [i, a]), i ? z(
50
+ const F = c((e) => {
51
+ m && i.current && !i.current.contains(e.target) && a();
52
+ }, [a, m]), b = z();
53
+ A(s, i);
54
+ const d = c((e) => {
55
+ e.key === "Escape" && o && a();
56
+ }, [o, a]);
57
+ return g(() => (s ? document.addEventListener("keydown", d) : document.removeEventListener("keydown", d), () => document.removeEventListener("keydown", d)), [s, d]), s ? D(
55
58
  /* @__PURE__ */ r(
56
59
  "div",
57
60
  {
58
- className: g(
61
+ className: v(
59
62
  "fixed inset-0 z-drawer flex transition-opacity duration-500 ease-in-out",
60
63
  h ? "opacity-100" : "opacity-0",
61
64
  "bg-black/50"
62
65
  ),
63
- onClick: I,
64
- children: /* @__PURE__ */ b(
66
+ onClick: F,
67
+ children: /* @__PURE__ */ p(
65
68
  "div",
66
69
  {
67
- ref: c,
70
+ ref: i,
71
+ role: "dialog",
72
+ "aria-modal": "true",
73
+ tabIndex: -1,
74
+ "aria-labelledby": n ? b : void 0,
75
+ "aria-label": n ? void 0 : "Drawer",
68
76
  style: j,
69
- className: g(
77
+ className: v(
70
78
  "fixed bg-card border-border text-foreground shadow-xl flex flex-col",
71
79
  "transform transition-transform duration-500 ease-out",
72
80
  R,
73
81
  h ? T : N,
74
- k
82
+ S
75
83
  ),
76
84
  children: [
77
- /* @__PURE__ */ b("div", { className: "flex justify-between items-center p-4 border-b border-border flex-shrink-0", children: [
78
- m && /* @__PURE__ */ r("h3", { className: "text-xl font-semibold", children: m }),
85
+ /* @__PURE__ */ p("div", { className: "flex justify-between items-center p-4 border-b border-border flex-shrink-0", children: [
86
+ n && /* @__PURE__ */ r("h3", { id: b, className: "text-xl font-semibold", children: n }),
79
87
  /* @__PURE__ */ r(
80
88
  "button",
81
89
  {
82
- onClick: n,
90
+ onClick: a,
83
91
  className: "-mr-2 inline-flex min-h-11 min-w-11 items-center justify-center text-muted-foreground hover:text-foreground transition-colors",
84
92
  "aria-label": "Close drawer",
85
- children: /* @__PURE__ */ r(F, { name: "x", size: 24 })
93
+ children: /* @__PURE__ */ r(P, { name: "x", size: 24 })
86
94
  }
87
95
  )
88
96
  ] }),
89
- /* @__PURE__ */ r("div", { className: "flex-grow p-4 overflow-y-auto overscroll-contain", children: v }),
90
- d && /* @__PURE__ */ r("div", { className: "p-4 border-t border-border flex-shrink-0 bg-card", children: d })
97
+ /* @__PURE__ */ r("div", { className: "flex-grow p-4 overflow-y-auto overscroll-contain", children: k }),
98
+ f && /* @__PURE__ */ r("div", { className: "p-4 border-t border-border flex-shrink-0 bg-card", children: f })
91
99
  ]
92
100
  }
93
101
  )
@@ -97,5 +105,5 @@ const P = {
97
105
  ) : null;
98
106
  };
99
107
  export {
100
- W as Drawer
108
+ J as Drawer
101
109
  };
@@ -1,42 +1,47 @@
1
- import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
- import { useRef as m, useCallback as f, useEffect as u } from "react";
3
- import { createPortal as b } from "react-dom";
4
- import { Icon as x } from "../ui/Icon.js";
5
- import { cn as v } from "../../utils/cn.js";
6
- const N = ({ isOpen: r, onClose: o, children: n, title: d, footer: a, className: i }) => {
7
- const s = m(null), l = f((c) => {
8
- c.key === "Escape" && r && o();
9
- }, [r, o]);
10
- return u(() => (document.addEventListener("keydown", l, !1), () => {
11
- document.removeEventListener("keydown", l, !1);
12
- }), [l]), r ? b(
13
- /* @__PURE__ */ e("div", { className: "fixed inset-0 z-drawer flex items-center justify-center p-4 bg-black/50", children: /* @__PURE__ */ t(
1
+ import { jsx as e, jsxs as i } from "react/jsx-runtime";
2
+ import { useRef as f, useId as u, useCallback as b, useEffect as x } from "react";
3
+ import { createPortal as v } from "react-dom";
4
+ import { useDialogFocus as h } from "../../lib/hooks/useDialogFocus.js";
5
+ import { Icon as p } from "../ui/Icon.js";
6
+ import { cn as g } from "../../utils/cn.js";
7
+ const I = ({ isOpen: r, onClose: d, children: n, title: o, footer: l, className: c }) => {
8
+ const t = f(null);
9
+ h(r, t);
10
+ const s = u(), a = b((m) => {
11
+ m.key === "Escape" && r && d();
12
+ }, [r, d]);
13
+ return x(() => (document.addEventListener("keydown", a, !1), () => {
14
+ document.removeEventListener("keydown", a, !1);
15
+ }), [a]), r ? v(
16
+ /* @__PURE__ */ e("div", { className: "fixed inset-0 z-drawer flex items-center justify-center p-4 bg-black/50", children: /* @__PURE__ */ i(
14
17
  "div",
15
18
  {
16
- ref: s,
17
- className: v(
19
+ ref: t,
20
+ className: g(
18
21
  "relative w-full max-w-lg mx-auto rounded-lg shadow-xl overflow-hidden",
19
22
  "bg-card border border-border text-foreground",
20
- i
23
+ c
21
24
  ),
22
25
  role: "dialog",
23
26
  "aria-modal": "true",
24
- "aria-labelledby": d ? "modal-title" : void 0,
27
+ tabIndex: -1,
28
+ "aria-labelledby": o ? s : void 0,
29
+ "aria-label": o ? void 0 : "Dialog",
25
30
  children: [
26
- /* @__PURE__ */ t("div", { className: "flex justify-between items-center p-4 border-b border-border", children: [
27
- d && /* @__PURE__ */ e("h3", { id: "modal-title", className: "text-xl font-semibold", children: d }),
31
+ /* @__PURE__ */ i("div", { className: "flex justify-between items-center p-4 border-b border-border", children: [
32
+ o && /* @__PURE__ */ e("h3", { id: s, className: "text-xl font-semibold", children: o }),
28
33
  /* @__PURE__ */ e(
29
34
  "button",
30
35
  {
31
- onClick: o,
36
+ onClick: d,
32
37
  className: "text-muted-foreground hover:text-foreground transition-colors",
33
38
  "aria-label": "Close modal",
34
- children: /* @__PURE__ */ e(x, { name: "x", size: 20 })
39
+ children: /* @__PURE__ */ e(p, { name: "x", size: 20 })
35
40
  }
36
41
  )
37
42
  ] }),
38
43
  /* @__PURE__ */ e("div", { className: "p-4", children: n }),
39
- a && /* @__PURE__ */ e("div", { className: "p-4 border-t border-border flex justify-end space-x-2", children: a })
44
+ l && /* @__PURE__ */ e("div", { className: "p-4 border-t border-border flex justify-end space-x-2", children: l })
40
45
  ]
41
46
  }
42
47
  ) }),
@@ -44,5 +49,5 @@ const N = ({ isOpen: r, onClose: o, children: n, title: d, footer: a, className:
44
49
  ) : null;
45
50
  };
46
51
  export {
47
- N as Modal
52
+ I as Modal
48
53
  };
@@ -1,24 +1,25 @@
1
1
  import { jsxs as u, jsx as e } from "react/jsx-runtime";
2
- import { useState as m, useRef as E, useEffect as w, useCallback as S } from "react";
2
+ import { useState as m, useRef as E, useEffect as x, useCallback as S } from "react";
3
3
  import { createPortal as j } from "react-dom";
4
- import { Icon as A } from "../ui/Icon.js";
5
- import { cn as x } from "../../utils/cn.js";
6
- import { useBodyScrollLock as R } from "../../lib/hooks/useBodyScrollLock.js";
7
- import { useSheetGesture as B } from "../../lib/hooks/useSheetGesture.js";
8
- const G = ({
9
- isOpen: o,
4
+ import { useDialogFocus as A } from "../../lib/hooks/useDialogFocus.js";
5
+ import { Icon as F } from "../ui/Icon.js";
6
+ import { cn as y } from "../../utils/cn.js";
7
+ import { useBodyScrollLock as I } from "../../lib/hooks/useBodyScrollLock.js";
8
+ import { useSheetGesture as R } from "../../lib/hooks/useSheetGesture.js";
9
+ const Y = ({
10
+ isOpen: n,
10
11
  onClose: r,
11
- children: y,
12
- detents: v = [0.6, 1],
12
+ children: v,
13
+ detents: k = [0.6, 1],
13
14
  initialDetent: f = 0,
14
- title: s,
15
+ title: d,
15
16
  footer: h,
16
- overlayDismiss: k = !0,
17
- className: N
17
+ overlayDismiss: N = !0,
18
+ className: D
18
19
  }) => {
19
- const [d, b] = m(!1), [g, p] = m(!1), D = E(null), [l] = m(
20
+ const [s, b] = m(!1), [g, p] = m(!1), w = E(null), [l] = m(
20
21
  () => typeof window < "u" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
21
- ), i = [...v].sort((n, a) => n - a), t = B({
22
+ ), i = [...k].sort((o, a) => o - a), t = R({
22
23
  detents: i,
23
24
  // Under reduced motion there is no drag, so a partial height would be a
24
25
  // height the reader can never change. Open fully instead.
@@ -26,30 +27,30 @@ const G = ({
26
27
  onDismiss: r,
27
28
  reducedMotion: l
28
29
  });
29
- R(o), w(() => {
30
- let n, a;
31
- return o ? (b(!0), t.setHeight(i[l ? i.length - 1 : f] ?? i[0]), n = requestAnimationFrame(() => {
30
+ I(n), x(() => {
31
+ let o, a;
32
+ return n ? (b(!0), t.setHeight(i[l ? i.length - 1 : f] ?? i[0]), o = requestAnimationFrame(() => {
32
33
  a = window.setTimeout(() => p(!0), 10);
33
34
  })) : (p(!1), a = window.setTimeout(() => b(!1), 320)), () => {
34
- cancelAnimationFrame(n), clearTimeout(a);
35
+ cancelAnimationFrame(o), clearTimeout(a);
35
36
  };
36
- }, [o]);
37
+ }, [n]), A(s, w);
37
38
  const c = S(
38
- (n) => {
39
- n.key === "Escape" && o && r();
39
+ (o) => {
40
+ o.key === "Escape" && n && r();
40
41
  },
41
- [o, r]
42
+ [n, r]
42
43
  );
43
- if (w(() => {
44
- if (d)
44
+ if (x(() => {
45
+ if (s)
45
46
  return document.addEventListener("keydown", c), () => document.removeEventListener("keydown", c);
46
- }, [d, c]), !d) return null;
47
+ }, [s, c]), !s) return null;
47
48
  const P = g ? 1 - t.height : 1;
48
49
  return j(
49
50
  /* @__PURE__ */ u(
50
51
  "div",
51
52
  {
52
- className: x(
53
+ className: y(
53
54
  "fixed inset-0 z-drawer",
54
55
  "transition-opacity duration-300 ease-out",
55
56
  g ? "opacity-100" : "opacity-0"
@@ -59,24 +60,25 @@ const G = ({
59
60
  "div",
60
61
  {
61
62
  className: "absolute inset-0 bg-black/50",
62
- onClick: k ? r : void 0,
63
+ onClick: N ? r : void 0,
63
64
  "aria-hidden": "true"
64
65
  }
65
66
  ),
66
67
  /* @__PURE__ */ u(
67
68
  "div",
68
69
  {
69
- ref: D,
70
+ ref: w,
70
71
  role: "dialog",
71
72
  "aria-modal": "true",
72
- "aria-label": s ?? "Sheet",
73
+ tabIndex: -1,
74
+ "aria-label": d ?? "Sheet",
73
75
  style: {
74
76
  transform: `translateY(${P * 100}%)`,
75
77
  // Laid out at full height and slid down; only transform animates.
76
78
  height: "100dvh",
77
79
  paddingBottom: "env(safe-area-inset-bottom)"
78
80
  },
79
- className: x(
81
+ className: y(
80
82
  "absolute inset-x-0 bottom-0 flex flex-col",
81
83
  "bg-card text-foreground border-t border-border shadow-xl",
82
84
  // The corners round while the sheet is partial and square off once it
@@ -86,7 +88,7 @@ const G = ({
86
88
  // finger, not chase it.
87
89
  t.dragging ? "transition-none" : "transition-transform duration-300 ease-out",
88
90
  "motion-reduce:transition-none",
89
- N
91
+ D
90
92
  ),
91
93
  children: [
92
94
  /* @__PURE__ */ e(
@@ -106,7 +108,7 @@ const G = ({
106
108
  style: { touchAction: "none" },
107
109
  className: "flex shrink-0 items-center justify-between gap-3 px-4 pb-3",
108
110
  children: [
109
- s ? /* @__PURE__ */ e("h2", { className: "text-lg font-semibold leading-tight", children: s }) : /* @__PURE__ */ e("span", {}),
111
+ d ? /* @__PURE__ */ e("h2", { className: "text-lg font-semibold leading-tight", children: d }) : /* @__PURE__ */ e("span", {}),
110
112
  /* @__PURE__ */ e(
111
113
  "button",
112
114
  {
@@ -114,7 +116,7 @@ const G = ({
114
116
  onClick: r,
115
117
  "aria-label": "Close",
116
118
  className: "-mr-2 inline-flex min-h-11 min-w-11 items-center justify-center rounded-full text-muted-foreground transition-colors hover:text-foreground",
117
- children: /* @__PURE__ */ e(A, { name: "x", size: 22 })
119
+ children: /* @__PURE__ */ e(F, { name: "x", size: 22 })
118
120
  }
119
121
  )
120
122
  ]
@@ -125,7 +127,7 @@ const G = ({
125
127
  {
126
128
  onPointerDown: t.onBodyPointerDown,
127
129
  className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 pb-4",
128
- children: y
130
+ children: v
129
131
  }
130
132
  ),
131
133
  h && /* @__PURE__ */ e("div", { className: "shrink-0 border-t border-border bg-card px-4 py-3", children: h })
@@ -139,6 +141,6 @@ const G = ({
139
141
  );
140
142
  };
141
143
  export {
142
- G as Sheet,
143
- G as default
144
+ Y as Sheet,
145
+ Y as default
144
146
  };