@danieljoffe/shared-ui 0.0.1 → 0.1.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.
Files changed (54) hide show
  1. package/dist/index.js +110 -5358
  2. package/dist/lib/Alert.js +72 -0
  3. package/dist/lib/AspectRatio.js +31 -0
  4. package/dist/lib/Avatar.js +47 -0
  5. package/dist/lib/Badge.js +43 -0
  6. package/dist/lib/Breadcrumb.js +28 -0
  7. package/dist/lib/Button.js +82 -0
  8. package/dist/lib/CTACard.js +31 -0
  9. package/dist/lib/Card.js +91 -0
  10. package/dist/lib/Checkbox.js +75 -0
  11. package/dist/lib/Container.js +35 -0
  12. package/dist/lib/Divider.js +48 -0
  13. package/dist/lib/Dropdown.js +158 -0
  14. package/dist/lib/FormFieldError.js +8 -0
  15. package/dist/lib/Grid.js +67 -0
  16. package/dist/lib/GridBg.js +31 -0
  17. package/dist/lib/Heading.js +40 -0
  18. package/dist/lib/Input.js +55 -0
  19. package/dist/lib/Kbd.js +19 -0
  20. package/dist/lib/Loading.js +44 -0
  21. package/dist/lib/Modal.js +119 -0
  22. package/dist/lib/PageContainer.js +35 -0
  23. package/dist/lib/PageLayout.js +25 -0
  24. package/dist/lib/Pagination.js +111 -0
  25. package/dist/lib/ProgressBar.js +68 -0
  26. package/dist/lib/Section.js +58 -0
  27. package/dist/lib/SectionLabel.js +19 -0
  28. package/dist/lib/Select.js +67 -0
  29. package/dist/lib/Sidebar.js +97 -0
  30. package/dist/lib/Skeleton.js +63 -0
  31. package/dist/lib/Spacer.js +17 -0
  32. package/dist/lib/Spinner.js +39 -0
  33. package/dist/lib/Stack.js +59 -0
  34. package/dist/lib/StatsCard.js +79 -0
  35. package/dist/lib/StructuredData.js +15 -0
  36. package/dist/lib/Switch.js +69 -0
  37. package/dist/lib/Table.js +91 -0
  38. package/dist/lib/Tabs.js +101 -0
  39. package/dist/lib/Text.js +48 -0
  40. package/dist/lib/Textarea.js +50 -0
  41. package/dist/lib/ThemeProvider.js +54 -0
  42. package/dist/lib/ThemeToggle.js +29 -0
  43. package/dist/lib/Toast.js +95 -0
  44. package/dist/lib/Tooltip.js +70 -0
  45. package/dist/lib/index.js +112 -0
  46. package/dist/lib/styles/formStyles.js +24 -0
  47. package/dist/lib/styles/semanticVariants.js +27 -0
  48. package/dist/lib/types.js +1 -0
  49. package/dist/lib/utils/ErrorBoundary.js +17 -0
  50. package/dist/lib/utils/ModalErrorBoundary.js +17 -0
  51. package/dist/lib/utils/cn.js +8 -0
  52. package/dist/lib/utils/index.js +10 -0
  53. package/dist/lib/utils/validateProps.js +7 -0
  54. package/package.json +7 -4
@@ -0,0 +1,158 @@
1
+ "use client";
2
+ import { jsxs as D, jsx as f } from "react/jsx-runtime";
3
+ import { useState as I, useRef as p, useId as R, useMemo as j, useCallback as v, useEffect as A } from "react";
4
+ import { cn as m } from "./utils/cn.js";
5
+ function U({
6
+ trigger: E,
7
+ items: l,
8
+ align: N = "left",
9
+ className: C
10
+ }) {
11
+ const [o, a] = I(!1), [c, i] = I(-1), b = p(null), u = p(null), g = p([]), h = R(), x = `dropdown-menu-${h}`, w = `dropdown-trigger-${h}`, t = j(
12
+ () => l.reduce((e, r, n) => (!r.divider && !r.disabled && e.push(n), e), []),
13
+ [l]
14
+ ), s = v((e) => {
15
+ i(e), g.current[e]?.focus();
16
+ }, []), k = v(() => {
17
+ a(!0);
18
+ }, []), d = v(() => {
19
+ a(!1), i(-1), u.current?.focus();
20
+ }, []), y = p(!1);
21
+ A(() => {
22
+ const e = t[0];
23
+ o && !y.current && e != null && requestAnimationFrame(() => {
24
+ s(e);
25
+ }), y.current = o;
26
+ }, [o, t, s]), A(() => {
27
+ const e = (r) => {
28
+ b.current && !b.current.contains(r.target) && (a(!1), i(-1));
29
+ };
30
+ return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
31
+ }, []);
32
+ const K = (e) => {
33
+ e.key === "ArrowDown" || e.key === "ArrowUp" ? (e.preventDefault(), o || k()) : e.key === "Escape" && o && (e.preventDefault(), d());
34
+ }, M = (e) => {
35
+ const r = t.indexOf(c);
36
+ switch (e.key) {
37
+ case "ArrowDown": {
38
+ e.preventDefault();
39
+ const n = r < t.length - 1 ? t[r + 1] : t[0];
40
+ n != null && s(n);
41
+ break;
42
+ }
43
+ case "ArrowUp": {
44
+ e.preventDefault();
45
+ const n = r > 0 ? t[r - 1] : t[t.length - 1];
46
+ n != null && s(n);
47
+ break;
48
+ }
49
+ case "Home": {
50
+ e.preventDefault();
51
+ const n = t[0];
52
+ n != null && s(n);
53
+ break;
54
+ }
55
+ case "End": {
56
+ e.preventDefault();
57
+ const n = t[t.length - 1];
58
+ n != null && s(n);
59
+ break;
60
+ }
61
+ case "Escape": {
62
+ e.preventDefault(), d();
63
+ break;
64
+ }
65
+ case "Enter":
66
+ case " ": {
67
+ if (e.preventDefault(), c >= 0) {
68
+ const n = l[c];
69
+ n && !n.divider && !n.disabled && (n.onClick?.(), a(!1), i(-1), u.current?.focus());
70
+ }
71
+ break;
72
+ }
73
+ case "Tab": {
74
+ d();
75
+ break;
76
+ }
77
+ }
78
+ };
79
+ return /* @__PURE__ */ D("div", { ref: b, className: m("relative inline-flex", C), children: [
80
+ /* @__PURE__ */ f(
81
+ "button",
82
+ {
83
+ ref: u,
84
+ id: w,
85
+ type: "button",
86
+ "aria-haspopup": "menu",
87
+ "aria-expanded": o,
88
+ "aria-controls": o ? x : void 0,
89
+ onClick: () => o ? d() : k(),
90
+ onKeyDown: K,
91
+ className: "inline-flex items-center",
92
+ children: E
93
+ }
94
+ ),
95
+ o && /* @__PURE__ */ f(
96
+ "div",
97
+ {
98
+ id: x,
99
+ role: "menu",
100
+ "aria-labelledby": w,
101
+ tabIndex: -1,
102
+ onKeyDown: M,
103
+ className: m(
104
+ "absolute z-50 mt-1 top-full min-w-[180px]",
105
+ "bg-surface-elevated border border-border rounded-lg shadow-lg",
106
+ "py-1 animate-slide-down motion-reduce:animate-none",
107
+ N === "right" ? "right-0" : "left-0"
108
+ ),
109
+ children: l.map(
110
+ (e, r) => e.divider ? /* @__PURE__ */ f(
111
+ "div",
112
+ {
113
+ role: "separator",
114
+ className: "my-1 border-t border-border"
115
+ },
116
+ r
117
+ ) : /* @__PURE__ */ D(
118
+ "button",
119
+ {
120
+ ref: (n) => {
121
+ g.current[r] = n;
122
+ },
123
+ role: "menuitem",
124
+ tabIndex: r === c ? 0 : -1,
125
+ "aria-disabled": e.disabled || void 0,
126
+ onClick: () => {
127
+ e.disabled || (e.onClick?.(), a(!1), i(-1), u.current?.focus());
128
+ },
129
+ className: m(
130
+ "w-full flex items-center gap-2 px-3 py-1.5 text-sm text-left",
131
+ "transition-colors duration-100 cursor-pointer",
132
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-2",
133
+ "focus-visible:ring-offset-surface",
134
+ e.disabled && "opacity-50 cursor-not-allowed",
135
+ e.danger ? "text-error hover:bg-error-light" : "text-text-primary hover:bg-surface-tertiary"
136
+ ),
137
+ children: [
138
+ e.icon && /* @__PURE__ */ f(
139
+ "span",
140
+ {
141
+ className: "inline-flex h-4 w-4 shrink-0 items-center justify-center",
142
+ "aria-hidden": "true",
143
+ children: e.icon
144
+ }
145
+ ),
146
+ e.label
147
+ ]
148
+ },
149
+ r
150
+ )
151
+ )
152
+ }
153
+ )
154
+ ] });
155
+ }
156
+ export {
157
+ U as Dropdown
158
+ };
@@ -0,0 +1,8 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { Text as i } from "./Text.js";
3
+ function m({ message: r, id: o }) {
4
+ return r ? /* @__PURE__ */ t(i, { variant: "error", id: o, className: "mt-1.5", children: r }) : null;
5
+ }
6
+ export {
7
+ m as FormFieldError
8
+ };
@@ -0,0 +1,67 @@
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ import { cn as m } from "./utils/cn.js";
3
+ import "react";
4
+ const r = {
5
+ 0: "",
6
+ 1: "grid-cols-1",
7
+ 2: "grid-cols-1 sm:grid-cols-2",
8
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
9
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
10
+ 6: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-6",
11
+ 12: "grid-cols-4 sm:grid-cols-6 lg:grid-cols-12"
12
+ }, i = {
13
+ none: "gap-0",
14
+ sm: "gap-2 sm:gap-3",
15
+ md: "gap-4 sm:gap-6",
16
+ lg: "gap-6 sm:gap-8",
17
+ xl: "gap-8 sm:gap-12"
18
+ };
19
+ function u({
20
+ as: s,
21
+ children: o,
22
+ cols: l = 12,
23
+ gap: c = "md",
24
+ className: n,
25
+ ref: g,
26
+ ...p
27
+ }) {
28
+ return /* @__PURE__ */ a(
29
+ s || "div",
30
+ {
31
+ ref: g,
32
+ className: m("grid", r[l], i[c], n),
33
+ ...p,
34
+ children: o
35
+ }
36
+ );
37
+ }
38
+ const d = {
39
+ 1: "col-span-1",
40
+ 2: "col-span-1 sm:col-span-2",
41
+ 3: "col-span-1 sm:col-span-2 lg:col-span-3",
42
+ 4: "col-span-1 sm:col-span-2 lg:col-span-4",
43
+ 6: "col-span-2 sm:col-span-3 lg:col-span-6",
44
+ 12: "col-span-full"
45
+ };
46
+ function x({
47
+ as: s,
48
+ children: o,
49
+ colSpan: l = 1,
50
+ className: c,
51
+ ref: n,
52
+ ...g
53
+ }) {
54
+ return /* @__PURE__ */ a(
55
+ s || "div",
56
+ {
57
+ ref: n,
58
+ className: m("flex", d[l], c),
59
+ ...g,
60
+ children: o
61
+ }
62
+ );
63
+ }
64
+ export {
65
+ u as Grid,
66
+ x as GridItem
67
+ };
@@ -0,0 +1,31 @@
1
+ import { jsxs as n, jsx as r } from "react/jsx-runtime";
2
+ import { cn as o } from "./utils/cn.js";
3
+ import "react";
4
+ function s({ ref: e, className: a }) {
5
+ return /* @__PURE__ */ n(
6
+ "div",
7
+ {
8
+ ref: e,
9
+ className: o(
10
+ "absolute inset-0 overflow-hidden pointer-events-none",
11
+ a
12
+ ),
13
+ children: [
14
+ /* @__PURE__ */ r(
15
+ "div",
16
+ {
17
+ className: "absolute inset-0 opacity-[0.03]",
18
+ style: {
19
+ backgroundImage: "linear-gradient(var(--color-border) 1px, transparent 1px), linear-gradient(90deg, var(--color-border) 1px, transparent 1px)",
20
+ backgroundSize: "64px 64px"
21
+ }
22
+ }
23
+ ),
24
+ /* @__PURE__ */ r("div", { className: "absolute top-0 left-1/2 -translate-x-1/2 w-[800px] h-[600px] bg-brand-500/5 rounded-full blur-3xl" })
25
+ ]
26
+ }
27
+ );
28
+ }
29
+ export {
30
+ s as GridBg
31
+ };
@@ -0,0 +1,40 @@
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { cn as n } from "./utils/cn.js";
3
+ import "react";
4
+ const a = {
5
+ hero: "text-4xl sm:text-5xl font-bold text-text-primary tracking-tight leading-[1.1]",
6
+ detail: "text-3xl sm:text-4xl lg:text-5xl font-bold text-text-primary tracking-tight",
7
+ subtitle: "text-2xl font-bold text-text-primary tracking-tight",
8
+ section: "text-2xl sm:text-3xl font-bold text-text-primary tracking-tight",
9
+ cardTitle: "text-sm font-semibold text-text-primary",
10
+ component: "text-lg font-semibold text-text-primary",
11
+ mdxH1: "text-2xl font-bold text-text-primary tracking-tight mb-6",
12
+ mdxH2: "text-lg font-semibold text-text-primary mt-12 mb-4 scroll-mt-20",
13
+ mdxH3: "text-sm font-semibold text-text-primary mt-8 mb-3 scroll-mt-20",
14
+ mdxH4: "text-xs font-medium text-text-secondary mt-6 mb-2 uppercase tracking-wider"
15
+ }, d = {
16
+ hero: "h1",
17
+ detail: "h1",
18
+ subtitle: "h2",
19
+ section: "h2",
20
+ cardTitle: "h3",
21
+ component: "h3",
22
+ mdxH1: "h1",
23
+ mdxH2: "h2",
24
+ mdxH3: "h3",
25
+ mdxH4: "h4"
26
+ };
27
+ function h({
28
+ as: e,
29
+ variant: t,
30
+ className: x,
31
+ children: m,
32
+ ref: r,
33
+ ...i
34
+ }) {
35
+ const o = e ?? d[t];
36
+ return /* @__PURE__ */ l(o, { ref: r, className: n(a[t], x), ...i, children: m });
37
+ }
38
+ export {
39
+ h as Heading
40
+ };
@@ -0,0 +1,55 @@
1
+ import { jsxs as m, jsx as i } from "react/jsx-runtime";
2
+ import { useId as D } from "react";
3
+ import { FORM_LABEL as R, REQUIRED_MARK as h, DISABLED as x, FIELD_PLACEHOLDER as S, BASE_FIELD as y, FIELD_ERROR as F, FIELD_SUCCESS as N } from "./styles/formStyles.js";
4
+ import { Text as c } from "./Text.js";
5
+ import { cn as _ } from "./utils/cn.js";
6
+ const A = {
7
+ sm: "px-3 py-1.5 text-sm",
8
+ md: "px-4 py-2.5",
9
+ lg: "px-5 py-3 text-lg"
10
+ };
11
+ function j({
12
+ label: n,
13
+ error: t,
14
+ helperText: e,
15
+ success: l,
16
+ size: o = "md",
17
+ className: p,
18
+ id: E,
19
+ required: a,
20
+ ref: I,
21
+ ...u
22
+ }) {
23
+ const f = D(), s = E ?? f, r = t ? `${s}-error` : void 0, d = e && !t ? `${s}-helper` : void 0, L = r || d, v = () => t ? F : l ? N : "";
24
+ return /* @__PURE__ */ m("div", { className: "w-full", children: [
25
+ n && /* @__PURE__ */ m("label", { htmlFor: s, className: R, children: [
26
+ n,
27
+ a && /* @__PURE__ */ i("span", { className: h, children: "*" })
28
+ ] }),
29
+ /* @__PURE__ */ i(
30
+ "input",
31
+ {
32
+ ref: I,
33
+ id: s,
34
+ "aria-invalid": t ? "true" : void 0,
35
+ "aria-required": a || void 0,
36
+ "aria-describedby": L,
37
+ required: a,
38
+ className: _(
39
+ y,
40
+ A[o],
41
+ S,
42
+ x,
43
+ v(),
44
+ p
45
+ ),
46
+ ...u
47
+ }
48
+ ),
49
+ t && /* @__PURE__ */ i(c, { variant: "error", id: r, className: "mt-1.5", role: "alert", children: t }),
50
+ e && !t && /* @__PURE__ */ i(c, { variant: "helper", id: d, className: "mt-1.5", children: e })
51
+ ] });
52
+ }
53
+ export {
54
+ j as Input
55
+ };
@@ -0,0 +1,19 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { cn as n } from "./utils/cn.js";
3
+ import "react";
4
+ function x({ children: e, ref: r, className: t }) {
5
+ return /* @__PURE__ */ o(
6
+ "kbd",
7
+ {
8
+ ref: r,
9
+ className: n(
10
+ "hidden sm:inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 text-[10px] font-mono font-medium text-text-tertiary bg-surface-tertiary border border-border rounded-xs",
11
+ t
12
+ ),
13
+ children: e
14
+ }
15
+ );
16
+ }
17
+ export {
18
+ x as Kbd
19
+ };
@@ -0,0 +1,44 @@
1
+ import { jsx as e, jsxs as n } from "react/jsx-runtime";
2
+ import { Text as s } from "./Text.js";
3
+ import { cn as l } from "./utils/cn.js";
4
+ import "react";
5
+ function c({
6
+ "aria-label": i = "Loading content",
7
+ className: a,
8
+ ref: t,
9
+ ...o
10
+ }) {
11
+ return /* @__PURE__ */ e(
12
+ "div",
13
+ {
14
+ ref: t,
15
+ className: l(
16
+ "flex items-center justify-center min-h-52 w-full",
17
+ a
18
+ ),
19
+ role: "status",
20
+ "aria-live": "polite",
21
+ "aria-label": i,
22
+ ...o,
23
+ children: /* @__PURE__ */ n("div", { className: "flex flex-col items-center gap-4", children: [
24
+ /* @__PURE__ */ n("div", { className: "flex gap-1", children: [
25
+ /* @__PURE__ */ e("div", { className: "size-2 bg-brand-500 rounded-full animate-[bounceSubtle_0.6s_ease-in-out_infinite] motion-reduce:animate-none" }),
26
+ /* @__PURE__ */ e("div", { className: "size-2 bg-brand-500/60 rounded-full animate-[bounceSubtle_0.6s_ease-in-out_infinite_0.1s] motion-reduce:animate-none" }),
27
+ /* @__PURE__ */ e("div", { className: "size-2 bg-brand-500 rounded-full animate-[bounceSubtle_0.6s_ease-in-out_infinite_0.2s] motion-reduce:animate-none" }),
28
+ /* @__PURE__ */ e("div", { className: "size-2 bg-brand-500/60 rounded-full animate-[bounceSubtle_0.6s_ease-in-out_infinite_0.3s] motion-reduce:animate-none" })
29
+ ] }),
30
+ /* @__PURE__ */ e(
31
+ s,
32
+ {
33
+ variant: "caption",
34
+ className: "animate-[pulseSlow_2s_ease-in-out_infinite] motion-reduce:animate-none",
35
+ children: "Loading..."
36
+ }
37
+ )
38
+ ] })
39
+ }
40
+ );
41
+ }
42
+ export {
43
+ c as Loading
44
+ };
@@ -0,0 +1,119 @@
1
+ "use client";
2
+ import { jsxs as c, jsx as t } from "react/jsx-runtime";
3
+ import { X as x } from "lucide-react";
4
+ import { useRef as g, useEffect as u, useCallback as D, useId as I } from "react";
5
+ import { Button as E } from "./Button.js";
6
+ import { Heading as R } from "./Heading.js";
7
+ import { DISMISS_BUTTON as k } from "./styles/formStyles.js";
8
+ import { cn as N } from "./utils/cn.js";
9
+ const S = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])', A = {
10
+ sm: "max-w-md",
11
+ md: "max-w-lg",
12
+ lg: "max-w-2xl",
13
+ xl: "max-w-4xl"
14
+ }, B = {
15
+ default: "bg-surface-elevated border border-border-secondary"
16
+ };
17
+ function X({
18
+ isOpen: r,
19
+ onClose: f,
20
+ title: n,
21
+ children: C,
22
+ size: L = "md",
23
+ footer: m,
24
+ variant: z = "default",
25
+ className: T,
26
+ closeOnBackdropClick: j = !0,
27
+ ref: l
28
+ }) {
29
+ const i = g(null), d = g(null);
30
+ u(() => {
31
+ if (!(typeof document > "u"))
32
+ return r ? (i.current = document.activeElement, document.body.style.overflow = "hidden") : document.body.style.overflow = "", () => {
33
+ document.body.style.overflow = "";
34
+ };
35
+ }, [r]);
36
+ const o = D(() => {
37
+ f(), i.current instanceof HTMLElement && i.current.focus();
38
+ }, [f]);
39
+ u(() => {
40
+ if (typeof window > "u") return;
41
+ const e = (v) => {
42
+ v.key === "Escape" && r && o();
43
+ };
44
+ return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
45
+ }, [r, o]), u(() => {
46
+ if (!r || !d.current) return;
47
+ const e = d.current, y = e.querySelectorAll(S)[0];
48
+ y && y.focus();
49
+ const h = (a) => {
50
+ if (a.key !== "Tab") return;
51
+ const s = e.querySelectorAll(S);
52
+ if (s.length === 0) return;
53
+ const p = s[0], w = s[s.length - 1];
54
+ a.shiftKey && document.activeElement === p ? (a.preventDefault(), w.focus()) : !a.shiftKey && document.activeElement === w && (a.preventDefault(), p.focus());
55
+ };
56
+ return document.addEventListener("keydown", h), () => document.removeEventListener("keydown", h);
57
+ }, [r]);
58
+ const b = I();
59
+ return r ? /* @__PURE__ */ c("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
60
+ /* @__PURE__ */ t(
61
+ "div",
62
+ {
63
+ className: "absolute inset-0 bg-surface/80 backdrop-blur-sm",
64
+ onClick: j ? o : void 0,
65
+ "aria-hidden": "true"
66
+ }
67
+ ),
68
+ /* @__PURE__ */ c(
69
+ "div",
70
+ {
71
+ ref: (e) => {
72
+ d.current = e, typeof l == "function" ? l(e) : l && (l.current = e);
73
+ },
74
+ role: "dialog",
75
+ "aria-modal": "true",
76
+ "aria-labelledby": n ? b : void 0,
77
+ "aria-label": n ? void 0 : "Dialog",
78
+ className: N(
79
+ "relative w-full rounded-lg shadow-2xl",
80
+ A[L],
81
+ B[z],
82
+ T
83
+ ),
84
+ children: [
85
+ n && /* @__PURE__ */ c("div", { className: "flex items-center justify-between p-4 sm:p-6 border-b border-border", children: [
86
+ /* @__PURE__ */ t(R, { variant: "component", id: b, children: n }),
87
+ /* @__PURE__ */ t(
88
+ E,
89
+ {
90
+ variant: "bare",
91
+ size: "sm",
92
+ onClick: o,
93
+ "aria-label": "Close dialog",
94
+ className: k,
95
+ children: /* @__PURE__ */ t(x, { className: "size-5", "aria-hidden": "true" })
96
+ }
97
+ )
98
+ ] }),
99
+ !n && /* @__PURE__ */ t(
100
+ E,
101
+ {
102
+ variant: "bare",
103
+ size: "sm",
104
+ onClick: o,
105
+ "aria-label": "Close dialog",
106
+ className: N("absolute top-4 right-4", k),
107
+ children: /* @__PURE__ */ t(x, { className: "size-5", "aria-hidden": "true" })
108
+ }
109
+ ),
110
+ /* @__PURE__ */ t("div", { className: "p-4 sm:p-6", children: C }),
111
+ m && /* @__PURE__ */ t("div", { className: "flex items-center justify-end gap-3 p-4 sm:p-6 border-t border-border", children: m })
112
+ ]
113
+ }
114
+ )
115
+ ] }) : null;
116
+ }
117
+ export {
118
+ X as Modal
119
+ };
@@ -0,0 +1,35 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { Container as c } from "./Container.js";
3
+ import { cn as t } from "./utils/cn.js";
4
+ import "react";
5
+ function x({
6
+ children: r,
7
+ as: a = "div",
8
+ size: n = "sm",
9
+ wrapperClassName: i,
10
+ className: o,
11
+ ref: m,
12
+ ...s
13
+ }) {
14
+ return /* @__PURE__ */ e(
15
+ a,
16
+ {
17
+ ref: m,
18
+ className: t("flex justify-center", i),
19
+ "data-testid": "page-container-outer",
20
+ ...s,
21
+ children: /* @__PURE__ */ e(
22
+ c,
23
+ {
24
+ size: n,
25
+ className: t("flex flex-col py-8 md:py-14", o),
26
+ "data-testid": "page-container-inner",
27
+ children: r
28
+ }
29
+ )
30
+ }
31
+ );
32
+ }
33
+ export {
34
+ x as PageContainer
35
+ };
@@ -0,0 +1,25 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { PageContainer as e } from "./PageContainer.js";
3
+ import { cn as i } from "./utils/cn.js";
4
+ import "react";
5
+ function f({
6
+ children: o,
7
+ wide: a = !1,
8
+ className: m,
9
+ ...r
10
+ }) {
11
+ return /* @__PURE__ */ t(
12
+ e,
13
+ {
14
+ as: "main",
15
+ id: "main-content",
16
+ size: a ? "lg" : "sm",
17
+ className: i("py-16 lg:py-24 space-y-24", m),
18
+ ...r,
19
+ children: o
20
+ }
21
+ );
22
+ }
23
+ export {
24
+ f as PageLayout
25
+ };