@skiddph/prui 0.5.0 → 0.6.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,19 +1,19 @@
1
- import { jsx as e, jsxs as p, Fragment as je } from "react/jsx-runtime";
1
+ import { jsx as e, jsxs as p, Fragment as Oe } from "react/jsx-runtime";
2
2
  import * as s from "react";
3
- import { Routes as Me, Route as ae, Navigate as $e, MemoryRouter as Oe, BrowserRouter as Ae, useLocation as oe, useNavigate as ze, Outlet as De, Link as Fe, NavLink as Le } from "react-router-dom";
4
- import { ChevronsRight as Ie, ChevronsLeft as Be, X as _e, Menu as qe, Search as Ke, Palette as Ue, ChevronDown as Ve, Pencil as Je, Trash2 as Ye, Plus as He, Clock as We } from "lucide-react";
5
- import { cn as w } from "../core/cn.js";
6
- import { Dropdown as Xe } from "../core/dropdown.js";
3
+ import { Routes as Ae, Route as ae, Navigate as De, MemoryRouter as ze, BrowserRouter as Fe, useLocation as ce, useNavigate as Le, Outlet as Ie, Link as Be, NavLink as _e } from "react-router-dom";
4
+ import { ChevronsRight as re, ChevronsLeft as ne, X as qe, Menu as Ke, Search as Ue, Palette as Ve, ChevronDown as He, Pencil as Je, Trash2 as Ye, Plus as We, Clock as Xe } from "lucide-react";
5
+ import { cn as S } from "../core/cn.js";
6
+ import { Dropdown as Ge } from "../core/dropdown.js";
7
7
  import { Button as D } from "../core/button.js";
8
- import { resolveThemeName as Ge, themeMode as Qe, readPersistedTheme as Ze, applyTheme as re, listThemes as et, clearAppliedTokens as tt } from "../theme.js";
9
- import { Modal as ue, confirmModal as at } from "../core/modal.js";
10
- import { b as rt, D as nt, a as lt } from "./data-table-toolbar-BUy2EWPy.js";
11
- import { Textarea as st, Input as H } from "../core/input.js";
12
- import { Label as it } from "../core/label.js";
13
- import { Select as ce } from "../core/select.js";
14
- import { Switch as de } from "../core/switch.js";
15
- import { Card as me, CardHeader as pe, CardDescription as fe, CardTitle as he, CardContent as be } from "../core/card.js";
16
- const ot = [
8
+ import { resolveThemeName as Qe, themeMode as Ze, readPersistedTheme as et, applyTheme as le, listThemes as tt, clearAppliedTokens as at } from "../theme.js";
9
+ import { Modal as me, confirmModal as rt } from "../core/modal.js";
10
+ import { b as nt, D as lt, a as st } from "./data-table-toolbar-BUy2EWPy.js";
11
+ import { Textarea as it, Input as W } from "../core/input.js";
12
+ import { Label as ot } from "../core/label.js";
13
+ import { Select as pe } from "../core/select.js";
14
+ import { Switch as fe } from "../core/switch.js";
15
+ import { Card as he, CardHeader as be, CardDescription as ve, CardTitle as ge, CardContent as xe } from "../core/card.js";
16
+ const dt = [
17
17
  { path: "/login", name: "login" },
18
18
  { path: "/register", name: "register" },
19
19
  { path: "/forgot-password", name: "forgotPassword" },
@@ -29,43 +29,43 @@ const ot = [
29
29
  ];
30
30
  function ct({ mode: t, config: r, children: n }) {
31
31
  const a = t === "auth" || t === "auth+utility", l = t === "utility" || t === "auth+utility", m = [
32
- ...a ? ot : [],
32
+ ...a ? dt : [],
33
33
  ...l ? ut : []
34
34
  ], [f, g] = s.useState(null);
35
35
  return s.useEffect(() => {
36
36
  let x = !1;
37
- return import("../pages.js").then((c) => {
38
- x || g(c.PagesRegistry);
37
+ return import("../pages.js").then((u) => {
38
+ x || g(u.PagesRegistry);
39
39
  }), () => {
40
40
  x = !0;
41
41
  };
42
- }, []), f ? /* @__PURE__ */ p(Me, { children: [
43
- m.map(({ path: x, name: c }) => {
44
- const y = f[c];
45
- return y ? /* @__PURE__ */ e(ae, { path: x, element: /* @__PURE__ */ e(y, { ...(r == null ? void 0 : r[c]) ?? {} }) }, x) : null;
42
+ }, []), f ? /* @__PURE__ */ p(Ae, { children: [
43
+ m.map(({ path: x, name: u }) => {
44
+ const w = f[u];
45
+ return w ? /* @__PURE__ */ e(ae, { path: x, element: /* @__PURE__ */ e(w, { ...(r == null ? void 0 : r[u]) ?? {} }) }, x) : null;
46
46
  }),
47
47
  n,
48
- a ? /* @__PURE__ */ e(ae, { path: "*", element: /* @__PURE__ */ e($e, { to: "/login", replace: !0 }) }) : null
48
+ a ? /* @__PURE__ */ e(ae, { path: "*", element: /* @__PURE__ */ e(De, { to: "/login", replace: !0 }) }) : null
49
49
  ] }) : /* @__PURE__ */ e("div", { className: "p-8 text-center text-sm text-[var(--prui-dim)]", children: "Loading…" });
50
50
  }
51
- const dt = s.lazy(
51
+ const mt = s.lazy(
52
52
  () => Promise.resolve().then(() => Pt).then((t) => ({ default: t.SessionTimeout }))
53
53
  );
54
- function mt(t) {
55
- const r = t !== !1, n = typeof t == "object" ? t : {}, a = n.persist !== !1, l = Ge(n.default ?? "control"), m = Qe(l), [f, g] = s.useState(() => (a ? Ze() : null) ?? { theme: l, mode: m }), x = s.useCallback(
56
- (c) => {
57
- g(c), re({ theme: c.theme, mode: c.mode, storageKey: a ? "prui:theme" : null });
54
+ function pt(t) {
55
+ const r = t !== !1, n = typeof t == "object" ? t : {}, a = n.persist !== !1, l = Qe(n.default ?? "control"), m = Ze(l), [f, g] = s.useState(() => (a ? et() : null) ?? { theme: l, mode: m }), x = s.useCallback(
56
+ (u) => {
57
+ g(u), le({ theme: u.theme, mode: u.mode, storageKey: a ? "prui:theme" : null });
58
58
  },
59
59
  [a]
60
60
  );
61
61
  return s.useEffect(() => {
62
- re({ theme: f.theme, mode: f.mode, storageKey: a ? "prui:theme" : null });
62
+ le({ theme: f.theme, mode: f.mode, storageKey: a ? "prui:theme" : null });
63
63
  }, [f, a]), { enabled: r, state: f, setTheme: x };
64
64
  }
65
- function pt({ config: t }) {
66
- const { enabled: r, state: n, setTheme: a } = mt(t);
65
+ function ft({ config: t }) {
66
+ const { enabled: r, state: n, setTheme: a } = pt(t);
67
67
  return r ? /* @__PURE__ */ e(
68
- Xe,
68
+ Ge,
69
69
  {
70
70
  align: "end",
71
71
  trigger: /* @__PURE__ */ e(
@@ -76,24 +76,24 @@ function pt({ config: t }) {
76
76
  title: `Theme: ${n.theme}`,
77
77
  "data-testid": "theme-toggle",
78
78
  className: "inline-flex h-8 w-8 items-center justify-center rounded-[var(--prui-radius)] text-[var(--prui-dim)] hover:bg-[var(--prui-raise)] hover:text-[var(--prui-fg)] cursor-pointer",
79
- children: /* @__PURE__ */ e(Ue, { className: "h-4 w-4", "aria-hidden": !0 })
79
+ children: /* @__PURE__ */ e(Ve, { className: "h-4 w-4", "aria-hidden": !0 })
80
80
  }
81
81
  ),
82
- items: et().map((l) => ({
82
+ items: tt().map((l) => ({
83
83
  label: `${l}${l === n.theme ? " (active)" : ""}`,
84
84
  onSelect: () => {
85
- tt(), a({ theme: l, mode: l === "daylight" ? "light" : "dark" });
85
+ at(), a({ theme: l, mode: l === "daylight" ? "light" : "dark" });
86
86
  }
87
87
  }))
88
88
  }
89
89
  ) : null;
90
90
  }
91
- function ne(t, r) {
91
+ function se(t, r) {
92
92
  return r === "/" ? t === "/" : t === r || t.startsWith(r + "/");
93
93
  }
94
- function ft({ item: t, onNavigate: r, expandAllOn: n, collapsed: a }) {
95
- const { pathname: l } = oe(), m = (t.items ?? []).some(
96
- (c) => c.href ? ne(l, c.href) : (c.items ?? []).some((y) => y.href && ne(l, y.href))
94
+ function ht({ item: t, onNavigate: r, expandAllOn: n, collapsed: a }) {
95
+ const { pathname: l } = ce(), m = (t.items ?? []).some(
96
+ (u) => u.href ? se(l, u.href) : (u.items ?? []).some((w) => w.href && se(l, w.href))
97
97
  ), [f, g] = s.useState(m || n !== void 0 && l === n);
98
98
  s.useEffect(() => {
99
99
  m && g(!0);
@@ -105,52 +105,52 @@ function ft({ item: t, onNavigate: r, expandAllOn: n, collapsed: a }) {
105
105
  {
106
106
  type: "button",
107
107
  "aria-expanded": f,
108
- onClick: () => g((c) => !c),
109
- className: w(
108
+ onClick: () => g((u) => !u),
109
+ className: S(
110
110
  "flex w-full items-center gap-2 rounded-[var(--prui-radius)] px-2.5 py-1.5 text-sm cursor-pointer",
111
111
  m ? "text-[var(--prui-fg)]" : "text-[var(--prui-dim)] hover:text-[var(--prui-fg)]"
112
112
  ),
113
113
  children: [
114
- x ? /* @__PURE__ */ e(x, { className: "h-4 w-4 shrink-0", "aria-hidden": !0 }) : /* @__PURE__ */ e("span", { className: w("prui-nav-mono text-[10px] font-semibold"), children: t.label.slice(0, 2).toUpperCase() }),
115
- /* @__PURE__ */ e("span", { className: w("flex-1 text-left truncate", "prui-nav-label"), children: t.label }),
116
- /* @__PURE__ */ e(Ve, { className: w("prui-nav-chevron h-4 w-4 transition-transform", !f && "-rotate-90"), "aria-hidden": !0 })
114
+ x ? /* @__PURE__ */ e(x, { className: "h-4 w-4 shrink-0", "aria-hidden": !0 }) : /* @__PURE__ */ e("span", { className: S("prui-nav-mono text-[10px] font-semibold"), children: t.label.slice(0, 2).toUpperCase() }),
115
+ /* @__PURE__ */ e("span", { className: S("flex-1 text-left truncate", "prui-nav-label"), children: t.label }),
116
+ /* @__PURE__ */ e(He, { className: S("prui-nav-chevron h-4 w-4 transition-transform", !f && "-rotate-90"), "aria-hidden": !0 })
117
117
  ]
118
118
  }
119
119
  ),
120
- f ? /* @__PURE__ */ e("ul", { className: "ml-4 mt-0.5 flex flex-col gap-0.5 border-l border-[var(--prui-line)] pl-2", children: (t.items ?? []).map((c) => /* @__PURE__ */ e(ve, { item: c, onNavigate: r, nested: !0, expandAllOn: n, collapsed: a }, c.href ?? c.label)) }) : null
120
+ f ? /* @__PURE__ */ e("ul", { className: "ml-4 mt-0.5 flex flex-col gap-0.5 border-l border-[var(--prui-line)] pl-2", children: (t.items ?? []).map((u) => /* @__PURE__ */ e(ye, { item: u, onNavigate: r, nested: !0, expandAllOn: n, collapsed: a }, u.href ?? u.label)) }) : null
121
121
  ] });
122
122
  }
123
- function ht({ label: t }) {
123
+ function bt({ label: t }) {
124
124
  return /* @__PURE__ */ e("li", { className: "px-2.5 pb-1 pt-3 text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--prui-dim)]", "data-testid": "nav-subgroup", children: t });
125
125
  }
126
- function ve({ item: t, onNavigate: r, nested: n, expandAllOn: a, collapsed: l }) {
127
- return t.items && t.items.length > 0 ? /* @__PURE__ */ e(ft, { item: t, onNavigate: r, expandAllOn: a, collapsed: l }) : t.heading || !t.href && !t.items ? /* @__PURE__ */ e(ht, { label: t.label }) : t.href ? /* @__PURE__ */ e("li", { children: /* @__PURE__ */ p(
128
- Le,
126
+ function ye({ item: t, onNavigate: r, nested: n, expandAllOn: a, collapsed: l }) {
127
+ return t.items && t.items.length > 0 ? /* @__PURE__ */ e(ht, { item: t, onNavigate: r, expandAllOn: a, collapsed: l }) : t.heading || !t.href && !t.items ? /* @__PURE__ */ e(bt, { label: t.label }) : t.href ? /* @__PURE__ */ e("li", { children: /* @__PURE__ */ p(
128
+ _e,
129
129
  {
130
130
  to: t.href,
131
131
  onClick: r,
132
- className: ({ isActive: m }) => w(
132
+ className: ({ isActive: m }) => S(
133
133
  "flex items-center gap-2 rounded-[var(--prui-radius)] px-2.5 py-1.5 text-sm",
134
134
  n && "pl-2.5",
135
135
  m ? "bg-[var(--prui-brand)]/15 text-[var(--prui-brand)] font-medium" : "text-[var(--prui-dim)] hover:text-[var(--prui-fg)] hover:bg-[var(--prui-raise)]"
136
136
  ),
137
137
  children: [
138
- t.icon && !n ? /* @__PURE__ */ e(t.icon, { className: "h-4 w-4 shrink-0", "aria-hidden": !0 }) : l ? /* @__PURE__ */ e("span", { className: w("prui-nav-mono text-[10px] font-semibold"), children: t.label.slice(0, 2).toUpperCase() }) : null,
139
- /* @__PURE__ */ e("span", { className: w("truncate", l && n && "prui-nav-label", "prui-nav-label"), children: t.label })
138
+ t.icon && !n ? /* @__PURE__ */ e(t.icon, { className: "h-4 w-4 shrink-0", "aria-hidden": !0 }) : l ? /* @__PURE__ */ e("span", { className: S("prui-nav-mono text-[10px] font-semibold"), children: t.label.slice(0, 2).toUpperCase() }) : null,
139
+ /* @__PURE__ */ e("span", { className: S("truncate", l && n && "prui-nav-label", "prui-nav-label"), children: t.label })
140
140
  ]
141
141
  }
142
142
  ) }) : null;
143
143
  }
144
- function le({ nav: t, onNavigate: r, expandAllOn: n, collapsed: a }) {
145
- return /* @__PURE__ */ e("nav", { "aria-label": "Main", className: "prui-app-nav", children: /* @__PURE__ */ e("ul", { className: "flex flex-col gap-0.5", children: t.map((l) => /* @__PURE__ */ e(ve, { item: l, onNavigate: r, expandAllOn: n, collapsed: a }, l.href ?? l.label)) }) });
144
+ function ie({ nav: t, onNavigate: r, expandAllOn: n, collapsed: a }) {
145
+ return /* @__PURE__ */ e("nav", { "aria-label": "Main", className: "prui-app-nav", children: /* @__PURE__ */ e("ul", { className: "flex flex-col gap-0.5", children: t.map((l) => /* @__PURE__ */ e(ye, { item: l, onNavigate: r, expandAllOn: n, collapsed: a }, l.href ?? l.label)) }) });
146
146
  }
147
- function bt({ brand: t }) {
147
+ function oe({ brand: t }) {
148
148
  if (!t) return null;
149
- const r = /* @__PURE__ */ p(je, { children: [
149
+ const r = /* @__PURE__ */ p(Oe, { children: [
150
150
  t.mark ? /* @__PURE__ */ e("img", { src: t.mark, alt: "", className: "h-6 w-6 rounded-[var(--prui-radius-1)] object-cover" }) : null,
151
151
  /* @__PURE__ */ e("span", { className: "prui-nav-label truncate font-semibold text-[var(--prui-fg)]", children: t.name })
152
152
  ] }), n = "flex items-center gap-2 px-1 py-1 min-w-0";
153
- return t.href === null ? /* @__PURE__ */ e("div", { className: n, children: r }) : /* @__PURE__ */ e(Fe, { to: t.href ?? "/", className: n, "aria-label": t.name, children: r });
153
+ return t.href === null ? /* @__PURE__ */ e("div", { className: n, children: r }) : /* @__PURE__ */ e(Be, { to: t.href ?? "/", className: n, "aria-label": t.name, children: r });
154
154
  }
155
155
  function vt({
156
156
  open: t,
@@ -159,12 +159,12 @@ function vt({
159
159
  placeholder: a = "Type a command or search...",
160
160
  onNavigate: l
161
161
  }) {
162
- const [m, f] = s.useState(""), [g, x] = s.useState(0), c = s.useMemo(() => {
162
+ const [m, f] = s.useState(""), [g, x] = s.useState(0), u = s.useMemo(() => {
163
163
  const o = m.trim().toLowerCase();
164
164
  return o ? n.filter((b) => b.label.toLowerCase().includes(o)) : n;
165
165
  }, [n, m]);
166
166
  if (s.useEffect(() => x(0), [m]), !t) return null;
167
- const y = (o) => {
167
+ const w = (o) => {
168
168
  r(!1), o.onSelect ? o.onSelect() : o.href && (l == null || l(o.href));
169
169
  };
170
170
  return /* @__PURE__ */ e(
@@ -192,28 +192,28 @@ function vt({
192
192
  role: "combobox",
193
193
  "aria-expanded": "true",
194
194
  "aria-label": "Command palette search",
195
- "aria-activedescendant": c[g] ? `palette-option-${g}` : void 0,
195
+ "aria-activedescendant": u[g] ? `palette-option-${g}` : void 0,
196
196
  placeholder: a,
197
197
  value: m,
198
198
  onChange: (o) => f(o.target.value),
199
199
  onKeyDown: (o) => {
200
- if (o.key === "Escape" && r(!1), o.key === "ArrowDown" && (o.preventDefault(), x((b) => Math.min(b + 1, c.length - 1))), o.key === "ArrowUp" && (o.preventDefault(), x((b) => Math.max(b - 1, 0))), o.key === "Enter") {
201
- const b = c[g];
200
+ if (o.key === "Escape" && r(!1), o.key === "ArrowDown" && (o.preventDefault(), x((b) => Math.min(b + 1, u.length - 1))), o.key === "ArrowUp" && (o.preventDefault(), x((b) => Math.max(b - 1, 0))), o.key === "Enter") {
201
+ const b = u[g];
202
202
  b && (r(!1), b.onSelect ? b.onSelect() : b.href && (l == null || l(b.href)));
203
203
  }
204
204
  },
205
205
  className: "w-full bg-transparent px-4 py-3 text-sm text-[var(--prui-fg)] placeholder:text-[var(--prui-dim)] outline-none border-b border-[var(--prui-line)] rounded-t-[var(--prui-radius)]"
206
206
  }
207
207
  ),
208
- /* @__PURE__ */ e("ul", { role: "listbox", className: "max-h-64 overflow-auto p-1", children: c.length === 0 ? /* @__PURE__ */ e("li", { className: "px-3 py-2 text-sm text-[var(--prui-dim)]", children: "No matches." }) : c.map((o, b) => /* @__PURE__ */ p(
208
+ /* @__PURE__ */ e("ul", { role: "listbox", className: "max-h-64 overflow-auto p-1", children: u.length === 0 ? /* @__PURE__ */ e("li", { className: "px-3 py-2 text-sm text-[var(--prui-dim)]", children: "No matches." }) : u.map((o, b) => /* @__PURE__ */ p(
209
209
  "li",
210
210
  {
211
211
  id: `palette-option-${b}`,
212
212
  role: "option",
213
213
  "aria-selected": b === g,
214
214
  onMouseEnter: () => x(b),
215
- onClick: () => y(o),
216
- className: w(
215
+ onClick: () => w(o),
216
+ className: S(
217
217
  "cursor-pointer rounded-[calc(var(--prui-radius)-1px)] px-3 py-2 text-sm text-[var(--prui-fg)]",
218
218
  b === g && "bg-[var(--prui-raise)]"
219
219
  ),
@@ -240,63 +240,64 @@ function gt(t) {
240
240
  sidebar: f = {},
241
241
  header: g,
242
242
  pages: x,
243
- pagesConfig: c,
244
- expandAllOn: y,
243
+ pagesConfig: u,
244
+ expandAllOn: w,
245
245
  layoutType: o = "A",
246
- sidebarFooter: b,
247
- children: z
248
- } = t, E = typeof a == "object" ? a : { enabled: a !== !1 }, R = E.enabled !== !1, N = E.hotkey ?? "/", O = f.collapsible !== !1, [P, S] = s.useState(f.defaultOpen === !0), [F, T] = s.useState(!1), [i, h] = s.useState(!1), v = oe(), d = ze(), k = s.useMemo(
246
+ sidebarHeader: b,
247
+ sidebarFooter: z,
248
+ children: j
249
+ } = t, P = typeof a == "object" ? a : { enabled: a !== !1 }, N = P.enabled !== !1, M = P.hotkey ?? "/", R = f.collapsible !== !1, [C, $] = s.useState(f.defaultOpen === !0), [T, i] = s.useState(!0), [h, v] = s.useState(!1), c = ce(), F = Le(), y = s.useMemo(
249
250
  () => m === !1 ? null : m === !0 ? {} : m,
250
251
  [m]
251
- ), M = s.useCallback(() => {
252
- k != null && k.onTimeout ? k.onTimeout() : d((k == null ? void 0 : k.loginPath) ?? "/login");
253
- }, [k, d]), q = s.useMemo(() => {
254
- const j = [];
255
- for (const C of n)
256
- if (C.items)
257
- for (const $ of C.items)
258
- $.href && j.push({ label: `${C.label} / ${$.label}`, href: $.href, group: C.label });
259
- else C.href && j.push({ label: C.label, href: C.href });
260
- return j;
252
+ ), K = s.useCallback(() => {
253
+ y != null && y.onTimeout ? y.onTimeout() : F((y == null ? void 0 : y.loginPath) ?? "/login");
254
+ }, [y, F]), B = s.useMemo(() => {
255
+ const E = [];
256
+ for (const k of n)
257
+ if (k.items)
258
+ for (const O of k.items)
259
+ O.href && E.push({ label: `${k.label} / ${O.label}`, href: O.href, group: k.label });
260
+ else k.href && E.push({ label: k.label, href: k.href });
261
+ return E;
261
262
  }, [n]);
262
263
  s.useEffect(() => {
263
- if (!R) return;
264
- const j = (C) => {
265
- const $ = C.target, K = $ && ($.tagName === "INPUT" || $.tagName === "TEXTAREA" || $.isContentEditable);
266
- C.key === N && !K && !C.metaKey && !C.ctrlKey && !C.altKey && (C.preventDefault(), h(!0));
264
+ if (!N) return;
265
+ const E = (k) => {
266
+ const O = k.target, V = O && (O.tagName === "INPUT" || O.tagName === "TEXTAREA" || O.isContentEditable);
267
+ k.key === M && !V && !k.metaKey && !k.ctrlKey && !k.altKey && (k.preventDefault(), v(!0));
267
268
  };
268
- return document.addEventListener("keydown", j), () => document.removeEventListener("keydown", j);
269
- }, [N, R]);
270
- const I = s.useRef(v.pathname);
269
+ return document.addEventListener("keydown", E), () => document.removeEventListener("keydown", E);
270
+ }, [M, N]);
271
+ const U = s.useRef(c.pathname);
271
272
  s.useEffect(() => {
272
- I.current !== v.pathname && (I.current = v.pathname, S(!1));
273
- }, [v.pathname]), s.useEffect(() => {
274
- if (!P) return;
275
- const j = document.body.style.overflow;
273
+ U.current !== c.pathname && (U.current = c.pathname, $(!1));
274
+ }, [c.pathname]), s.useEffect(() => {
275
+ if (!C) return;
276
+ const E = document.body.style.overflow;
276
277
  return document.body.style.overflow = "hidden", () => {
277
- document.body.style.overflow = j;
278
+ document.body.style.overflow = E;
278
279
  };
279
- }, [P]);
280
- const J = f.width ?? 240, A = o === "C" && !F;
280
+ }, [C]);
281
+ const _ = f.width ?? 240, A = !T && o !== "D";
281
282
  return /* @__PURE__ */ p(
282
283
  "div",
283
284
  {
284
285
  className: "prui-app prui-shell min-h-dvh bg-[var(--prui-background)] text-[var(--prui-fg)]",
285
286
  "data-layout": o,
286
287
  "data-collapsed": A ? "true" : void 0,
287
- style: { "--prui-shell-sidebar": A ? "var(--prui-rail-width, 64px)" : `${J}px` },
288
+ style: { "--prui-shell-sidebar": A ? "var(--prui-rail-width, 64px)" : `${_}px` },
288
289
  children: [
289
290
  /* @__PURE__ */ p("aside", { "data-testid": "sidebar", className: "prui-shell-sidebar hidden md:flex md:flex-col md:min-h-0", children: [
290
- /* @__PURE__ */ e("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto p-2 pt-4 scrollbar-thin", children: /* @__PURE__ */ e(le, { nav: n, expandAllOn: y, collapsed: A }) }),
291
- b ? /* @__PURE__ */ e(
291
+ /* @__PURE__ */ e("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto p-2 pt-4 scrollbar-thin", children: /* @__PURE__ */ e(ie, { nav: n, expandAllOn: w, collapsed: A }) }),
292
+ z ? /* @__PURE__ */ e(
292
293
  "div",
293
294
  {
294
- className: w("border-t border-[var(--prui-line)] p-2", A && "flex justify-center px-1"),
295
+ className: S("border-t border-[var(--prui-line)] p-2", A && "flex justify-center px-1"),
295
296
  "data-testid": "sidebar-footer",
296
- children: b
297
+ children: z
297
298
  }
298
299
  ) : null,
299
- o === "C" ? /* @__PURE__ */ e("div", { className: "border-t border-[var(--prui-line)] p-2", children: /* @__PURE__ */ e(
300
+ o !== "D" ? /* @__PURE__ */ e("div", { className: "border-t border-[var(--prui-line)] p-2", children: /* @__PURE__ */ e(
300
301
  D,
301
302
  {
302
303
  variant: "ghost",
@@ -304,18 +305,18 @@ function gt(t) {
304
305
  className: "w-full justify-center",
305
306
  "aria-label": A ? "Expand sidebar" : "Collapse sidebar",
306
307
  "data-testid": "sidebar-toggle",
307
- onClick: () => T((j) => !j),
308
- children: A ? /* @__PURE__ */ e(Ie, { className: "h-4 w-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(Be, { className: "h-4 w-4", "aria-hidden": !0 })
308
+ onClick: () => i((E) => !E),
309
+ children: A ? /* @__PURE__ */ e(re, { className: "h-4 w-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(ne, { className: "h-4 w-4", "aria-hidden": !0 })
309
310
  }
310
311
  ) }) : null
311
312
  ] }),
312
- P ? /* @__PURE__ */ p("div", { className: "md:hidden fixed inset-0 z-40", "data-testid": "mobile-drawer", children: [
313
+ C ? /* @__PURE__ */ p("div", { className: "md:hidden fixed inset-0 z-40", "data-testid": "mobile-drawer", children: [
313
314
  /* @__PURE__ */ e(
314
315
  "div",
315
316
  {
316
317
  className: "absolute inset-0",
317
318
  style: { backgroundColor: "rgba(0,0,0,0.55)" },
318
- onClick: () => S(!1),
319
+ onClick: () => $(!1),
319
320
  "data-testid": "drawer-backdrop"
320
321
  }
321
322
  ),
@@ -332,73 +333,93 @@ function gt(t) {
332
333
  {
333
334
  type: "button",
334
335
  "aria-label": "Close navigation",
335
- onClick: () => S(!1),
336
+ onClick: () => $(!1),
336
337
  className: "rounded-[var(--prui-radius)] p-1 text-[var(--prui-dim)] hover:text-[var(--prui-fg)] cursor-pointer",
337
- children: /* @__PURE__ */ e(_e, { className: "h-4 w-4", "aria-hidden": !0 })
338
+ children: /* @__PURE__ */ e(qe, { className: "h-4 w-4", "aria-hidden": !0 })
338
339
  }
339
340
  ) }),
340
- /* @__PURE__ */ e(le, { nav: n, onNavigate: () => S(!1), expandAllOn: y, collapsed: !1 })
341
+ /* @__PURE__ */ e(ie, { nav: n, onNavigate: () => $(!1), expandAllOn: w, collapsed: !1 })
341
342
  ]
342
343
  }
343
344
  )
344
345
  ] }) : null,
346
+ o === "C" ? /* @__PURE__ */ e(
347
+ "div",
348
+ {
349
+ "data-testid": "sidebar-header",
350
+ className: "prui-shell-sidehead hidden h-14 items-center gap-2 border-b border-[var(--prui-line)] bg-[var(--prui-surface)] px-4 md:flex",
351
+ children: b ?? /* @__PURE__ */ e(oe, { brand: r })
352
+ }
353
+ ) : null,
345
354
  /* @__PURE__ */ p(
346
355
  "header",
347
356
  {
348
357
  "data-testid": "app-header",
349
358
  className: "prui-shell-header sticky top-0 z-30 grid h-14 grid-cols-[1fr_auto_1fr] items-center gap-4 border-b border-[var(--prui-line)] bg-[var(--prui-surface)] px-4 md:px-6",
350
359
  children: [
351
- O ? /* @__PURE__ */ e(
360
+ R ? /* @__PURE__ */ e(
352
361
  D,
353
362
  {
354
363
  variant: "ghost",
355
364
  size: "icon",
356
365
  "aria-label": "Open navigation",
357
366
  className: "md:hidden",
358
- onClick: () => S(!0),
367
+ onClick: () => $(!0),
359
368
  "data-testid": "drawer-toggle",
360
- children: /* @__PURE__ */ e(qe, { className: "h-4 w-4", "aria-hidden": !0 })
369
+ children: /* @__PURE__ */ e(Ke, { className: "h-4 w-4", "aria-hidden": !0 })
361
370
  }
362
371
  ) : null,
363
- /* @__PURE__ */ e("div", { className: "min-w-0 justify-self-start", children: /* @__PURE__ */ e(bt, { brand: r }) }),
364
- R ? /* @__PURE__ */ p(
372
+ R && o !== "D" ? /* @__PURE__ */ e(
373
+ D,
374
+ {
375
+ variant: "ghost",
376
+ size: "icon",
377
+ "aria-label": A ? "Show sidebar rail" : "Hide sidebar rail",
378
+ className: "md:hidden",
379
+ onClick: () => i((E) => !E),
380
+ "data-testid": "rail-toggle-mobile",
381
+ children: A ? /* @__PURE__ */ e(re, { className: "h-4 w-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(ne, { className: "h-4 w-4", "aria-hidden": !0 })
382
+ }
383
+ ) : null,
384
+ /* @__PURE__ */ e("div", { className: "min-w-0 justify-self-start", children: /* @__PURE__ */ e(oe, { brand: r }) }),
385
+ N ? /* @__PURE__ */ p(
365
386
  "button",
366
387
  {
367
388
  type: "button",
368
- onClick: () => h(!0),
389
+ onClick: () => v(!0),
369
390
  "data-testid": "search-trigger",
370
391
  className: "hidden h-8 w-[min(420px,34vw)] items-center gap-2 rounded-[var(--prui-radius)] border border-[var(--prui-line)] bg-[var(--prui-background)] px-3.5 text-sm text-[var(--prui-dim)] hover:border-[var(--prui-dim)] cursor-pointer md:flex",
371
392
  children: [
372
- /* @__PURE__ */ e(Ke, { className: "h-4 w-4", "aria-hidden": !0 }),
373
- /* @__PURE__ */ e("span", { className: "flex-1 text-left", children: E.placeholder ?? "Search..." }),
374
- /* @__PURE__ */ e("kbd", { className: "ml-auto rounded-[var(--prui-radius-1)] border border-[var(--prui-line)] bg-[var(--prui-raise)] px-1.5 py-0.5 text-xs", children: N })
393
+ /* @__PURE__ */ e(Ue, { className: "h-4 w-4", "aria-hidden": !0 }),
394
+ /* @__PURE__ */ e("span", { className: "flex-1 text-left", children: P.placeholder ?? "Search..." }),
395
+ /* @__PURE__ */ e("kbd", { className: "ml-auto rounded-[var(--prui-radius-1)] border border-[var(--prui-line)] bg-[var(--prui-raise)] px-1.5 py-0.5 text-xs", children: M })
375
396
  ]
376
397
  }
377
398
  ) : null,
378
399
  /* @__PURE__ */ p("div", { className: "flex items-center gap-2 justify-self-end", children: [
379
400
  g,
380
- /* @__PURE__ */ e(pt, { config: l })
401
+ /* @__PURE__ */ e(ft, { config: l })
381
402
  ] })
382
403
  ]
383
404
  }
384
405
  ),
385
- /* @__PURE__ */ e("main", { "data-testid": "app-content", className: "prui-shell-content min-h-0 flex-1 p-4 md:p-6", children: x ? /* @__PURE__ */ e(ct, { mode: x, config: c, children: z }) : z ?? /* @__PURE__ */ e(De, {}) }),
386
- k ? /* @__PURE__ */ e(s.Suspense, { fallback: null, children: /* @__PURE__ */ e(
387
- dt,
406
+ /* @__PURE__ */ e("main", { "data-testid": "app-content", className: "prui-shell-content min-h-0 flex-1 p-4 md:p-6", children: x ? /* @__PURE__ */ e(ct, { mode: x, config: u, children: j }) : j ?? /* @__PURE__ */ e(Ie, {}) }),
407
+ y ? /* @__PURE__ */ e(s.Suspense, { fallback: null, children: /* @__PURE__ */ e(
408
+ mt,
388
409
  {
389
- timeout: k.sessionTimeout,
390
- warningTime: k.warningTime,
391
- onTimeout: M
410
+ timeout: y.sessionTimeout,
411
+ warningTime: y.warningTime,
412
+ onTimeout: K
392
413
  }
393
414
  ) }) : null,
394
- R ? /* @__PURE__ */ e(vt, { open: i, onOpenChange: h, entries: q, placeholder: E.placeholder, onNavigate: d }) : null
415
+ N ? /* @__PURE__ */ e(vt, { open: h, onOpenChange: v, entries: B, placeholder: P.placeholder, onNavigate: F }) : null
395
416
  ]
396
417
  }
397
418
  );
398
419
  }
399
420
  function Kt(t) {
400
421
  const { router: r = "browser", initialEntries: n } = t;
401
- return /* @__PURE__ */ e(r === "memory" ? Oe : Ae, { initialEntries: n, children: /* @__PURE__ */ e(gt, { ...t }) });
422
+ return /* @__PURE__ */ e(r === "memory" ? ze : Fe, { initialEntries: n, children: /* @__PURE__ */ e(gt, { ...t }) });
402
423
  }
403
424
  const Ut = {
404
425
  name: "App",
@@ -414,6 +435,7 @@ const Ut = {
414
435
  { name: "pages", type: "'auth' | 'utility' | 'auth+utility'", default: "undefined", control: "select", options: ["auth", "utility", "auth+utility"] },
415
436
  { name: "expandAllOn", type: "string (pathname)", default: "undefined", control: "text" },
416
437
  { name: "layoutType", type: "'A' | 'B' | 'C' | 'D'", default: "'A'", control: "select", options: ["A", "B", "C", "D"] },
438
+ { name: "sidebarHeader", type: "ReactNode (layout C sidebar header)", default: "brand", control: "none" },
417
439
  { name: "sidebarFooter", type: "ReactNode", default: null, control: "none" },
418
440
  { name: "header", type: "ReactNode", default: null, control: "none" },
419
441
  { name: "children", type: "ReactNode", default: "Outlet", control: "none" }
@@ -426,7 +448,7 @@ function yt(t) {
426
448
  if (t)
427
449
  return t.map((r) => typeof r == "string" || typeof r == "number" ? { label: String(r), value: String(r) } : r);
428
450
  }
429
- function se(t, r) {
451
+ function de(t, r) {
430
452
  const n = {};
431
453
  for (const a of t.fields)
432
454
  r && a.name in r ? n[a.name] = r[a.name] : a.defaultValue !== void 0 ? n[a.name] = a.defaultValue : a.type === "boolean" ? n[a.name] = !1 : n[a.name] = "";
@@ -443,107 +465,107 @@ function Nt({
443
465
  error: g,
444
466
  className: x
445
467
  }) {
446
- const c = s.useMemo(() => xt(t), [t]), y = r ?? n, [o, b] = s.useState(() => se(c, y)), [z, E] = s.useState({}), [R, N] = s.useState(null), [O, P] = s.useState(!1);
468
+ const u = s.useMemo(() => xt(t), [t]), w = r ?? n, [o, b] = s.useState(() => de(u, w)), [z, j] = s.useState({}), [P, N] = s.useState(null), [M, R] = s.useState(!1);
447
469
  s.useEffect(() => {
448
- b(se(c, y));
449
- }, [JSON.stringify(c), JSON.stringify(y ?? {})]);
450
- const S = (i, h) => {
451
- b((v) => ({ ...v, [i]: h })), E((v) => {
470
+ b(de(u, w));
471
+ }, [JSON.stringify(u), JSON.stringify(w ?? {})]);
472
+ const C = (i, h) => {
473
+ b((v) => ({ ...v, [i]: h })), j((v) => {
452
474
  if (!v[i]) return v;
453
- const d = { ...v };
454
- return delete d[i], d;
475
+ const c = { ...v };
476
+ return delete c[i], c;
455
477
  });
456
- }, F = async (i) => {
478
+ }, $ = async (i) => {
457
479
  var v;
458
480
  i.preventDefault();
459
481
  const h = {};
460
- for (const d of c.fields) {
461
- if (d.required) {
462
- const M = o[d.name];
463
- (M === "" || M == null || Array.isArray(M) && M.length === 0) && (h[d.name] = d.name === void 0 ? "Required" : `${d.label} is required.`);
482
+ for (const c of u.fields) {
483
+ if (c.required) {
484
+ const y = o[c.name];
485
+ (y === "" || y == null || Array.isArray(y) && y.length === 0) && (h[c.name] = c.name === void 0 ? "Required" : `${c.label} is required.`);
464
486
  }
465
- const k = (v = d.validate) == null ? void 0 : v.call(d, o[d.name], o);
466
- k && (h[d.name] = k);
487
+ const F = (v = c.validate) == null ? void 0 : v.call(c, o[c.name], o);
488
+ F && (h[c.name] = F);
467
489
  }
468
- if (E(h), !(Object.keys(h).length > 0)) {
490
+ if (j(h), !(Object.keys(h).length > 0)) {
469
491
  N(null);
470
492
  try {
471
- const d = a == null ? void 0 : a({ ...o });
472
- d && typeof d.then == "function" && (P(!0), await d);
473
- } catch (d) {
474
- N(d instanceof Error ? d.message : String(d));
493
+ const c = a == null ? void 0 : a({ ...o });
494
+ c && typeof c.then == "function" && (R(!0), await c);
495
+ } catch (c) {
496
+ N(c instanceof Error ? c.message : String(c));
475
497
  } finally {
476
- P(!1);
498
+ R(!1);
477
499
  }
478
500
  }
479
- }, T = f || O;
480
- return /* @__PURE__ */ p("form", { onSubmit: F, className: w("prui-form flex flex-col gap-4", x), noValidate: !0, children: [
481
- /* @__PURE__ */ e("div", { className: w("grid gap-4", c.columns === 2 && "md:grid-cols-2"), children: c.fields.map((i) => {
501
+ }, T = f || M;
502
+ return /* @__PURE__ */ p("form", { onSubmit: $, className: S("prui-form flex flex-col gap-4", x), noValidate: !0, children: [
503
+ /* @__PURE__ */ e("div", { className: S("grid gap-4", u.columns === 2 && "md:grid-cols-2"), children: u.fields.map((i) => {
482
504
  const h = z[i.name], v = {
483
505
  id: `prui-form-${i.name}`,
484
506
  "aria-invalid": h ? !0 : void 0,
485
507
  "aria-describedby": h ? `prui-form-${i.name}-error` : void 0
486
508
  };
487
- return /* @__PURE__ */ p("div", { className: w("flex flex-col gap-1.5", i.colSpan === 2 && "md:col-span-2", i.className), children: [
488
- /* @__PURE__ */ p(it, { htmlFor: v.id, children: [
509
+ return /* @__PURE__ */ p("div", { className: S("flex flex-col gap-1.5", i.colSpan === 2 && "md:col-span-2", i.className), children: [
510
+ /* @__PURE__ */ p(ot, { htmlFor: v.id, children: [
489
511
  i.label,
490
512
  i.required ? /* @__PURE__ */ e("span", { className: "ml-0.5 text-[var(--prui-danger)]", children: "*" }) : null
491
513
  ] }),
492
514
  i.type === "textarea" ? /* @__PURE__ */ e(
493
- st,
515
+ it,
494
516
  {
495
517
  ...v,
496
518
  placeholder: i.placeholder,
497
519
  disabled: i.disabled || T,
498
520
  value: String(o[i.name] ?? ""),
499
- onChange: (d) => S(i.name, d.target.value)
521
+ onChange: (c) => C(i.name, c.target.value)
500
522
  }
501
523
  ) : i.type === "select" ? /* @__PURE__ */ e(
502
- ce,
524
+ pe,
503
525
  {
504
526
  ...v,
505
527
  options: yt(i.options),
506
528
  placeholder: i.placeholder,
507
529
  disabled: i.disabled || T,
508
530
  value: String(o[i.name] ?? ""),
509
- onChange: (d) => S(i.name, d)
531
+ onChange: (c) => C(i.name, c)
510
532
  }
511
533
  ) : i.type === "date" ? /* @__PURE__ */ e(
512
- H,
534
+ W,
513
535
  {
514
536
  ...v,
515
537
  type: "date",
516
538
  placeholder: i.placeholder,
517
539
  disabled: i.disabled || T,
518
540
  value: String(o[i.name] ?? ""),
519
- onChange: (d) => S(i.name, d.target.value)
541
+ onChange: (c) => C(i.name, c.target.value)
520
542
  }
521
543
  ) : i.type === "boolean" ? /* @__PURE__ */ e(
522
- de,
544
+ fe,
523
545
  {
524
546
  ...v,
525
547
  disabled: i.disabled || T,
526
548
  checked: !!o[i.name],
527
- onChange: (d) => S(i.name, d)
549
+ onChange: (c) => C(i.name, c)
528
550
  }
529
551
  ) : /* @__PURE__ */ e(
530
- H,
552
+ W,
531
553
  {
532
554
  ...v,
533
555
  type: i.type ?? "text",
534
556
  placeholder: i.placeholder,
535
557
  disabled: i.disabled || T,
536
558
  value: String(o[i.name] ?? ""),
537
- onChange: (d) => S(i.name, i.type === "number" ? d.target.value === "" ? "" : Number(d.target.value) : d.target.value)
559
+ onChange: (c) => C(i.name, i.type === "number" ? c.target.value === "" ? "" : Number(c.target.value) : c.target.value)
538
560
  }
539
561
  ),
540
562
  h ? /* @__PURE__ */ e("p", { id: `prui-form-${i.name}-error`, role: "alert", className: "text-xs text-[var(--prui-danger)]", children: h }) : null
541
563
  ] }, i.name);
542
564
  }) }),
543
- g ?? R ? /* @__PURE__ */ e("p", { role: "alert", "data-testid": "form-error", className: "rounded-[var(--prui-radius)] border border-[var(--prui-danger)]/40 bg-[var(--prui-danger)]/10 px-3 py-2 text-sm text-[var(--prui-danger)]", children: g ?? R }) : null,
565
+ g ?? P ? /* @__PURE__ */ e("p", { role: "alert", "data-testid": "form-error", className: "rounded-[var(--prui-radius)] border border-[var(--prui-danger)]/40 bg-[var(--prui-danger)]/10 px-3 py-2 text-sm text-[var(--prui-danger)]", children: g ?? P }) : null,
544
566
  /* @__PURE__ */ p("div", { className: "flex items-center justify-end gap-2", children: [
545
567
  l ? /* @__PURE__ */ e(D, { type: "button", variant: "ghost", onClick: l, disabled: T, children: m }) : null,
546
- /* @__PURE__ */ e(D, { type: "submit", variant: "primary", loading: T, children: c.submitLabel ?? "Submit" })
568
+ /* @__PURE__ */ e(D, { type: "submit", variant: "primary", loading: T, children: u.submitLabel ?? "Submit" })
547
569
  ] })
548
570
  ] });
549
571
  }
@@ -558,7 +580,7 @@ const Vt = {
558
580
  { name: "error", type: "string | null", default: "null", control: "text" }
559
581
  ]
560
582
  };
561
- function ge(t) {
583
+ function Ne(t) {
562
584
  if (t)
563
585
  return t.map((r) => typeof r == "string" || typeof r == "number" ? { label: String(r), value: String(r) } : r);
564
586
  }
@@ -569,7 +591,7 @@ function wt(t, r) {
569
591
  name: a.key,
570
592
  label: typeof a.label == "string" ? a.label : a.key,
571
593
  type: St(a, r),
572
- options: (l = ge(a.filterOptions ?? a.options)) == null ? void 0 : l.map((m) => ({ label: m.label, value: m.value })),
594
+ options: (l = Ne(a.filterOptions ?? a.options)) == null ? void 0 : l.map((m) => ({ label: m.label, value: m.value })),
573
595
  required: !1
574
596
  };
575
597
  }), submitLabel: r ? "Save" : "Create" };
@@ -577,7 +599,7 @@ function wt(t, r) {
577
599
  function St(t, r) {
578
600
  return t.filter === "select" ? "select" : typeof (r == null ? void 0 : r[t.key]) == "number" || t.filter === "number" || t.filter === "numberrange" || t.filter === "price" ? "number" : t.filter === "date" || t.filter === "daterange" ? "date" : "text";
579
601
  }
580
- function Jt({
602
+ function Ht({
581
603
  name: t,
582
604
  columns: r,
583
605
  list: n,
@@ -587,127 +609,127 @@ function Jt({
587
609
  delete: f,
588
610
  actions: g,
589
611
  form: x,
590
- formSchema: c,
591
- rowKey: y,
612
+ formSchema: u,
613
+ rowKey: w,
592
614
  searchPlaceholder: o,
593
615
  pageSize: b = 20,
594
616
  className: z
595
617
  }) {
596
- const E = m ?? f, R = g ?? ["create", "edit", "delete"], N = (u) => R.includes(u) && (u === "create" ? !!a : u === "edit" ? !!l : !!E), [O, P] = s.useState([]), [S, F] = s.useState(null), [T, i] = s.useState(1), [h, v] = s.useState(b), [d, k] = s.useState([null]), [M, q] = s.useState(""), [I, J] = s.useState({}), [A, j] = s.useState(null), [C, $] = s.useState(!0), [K, W] = s.useState(null), [L, X] = s.useState(null), [xe, _] = s.useState(!1), [ye, G] = s.useState(!1), Q = d[T - 1] ?? null, Z = JSON.stringify(I), U = s.useCallback(async () => {
597
- $(!0), W(null);
618
+ const j = m ?? f, P = g ?? ["create", "edit", "delete"], N = (d) => P.includes(d) && (d === "create" ? !!a : d === "edit" ? !!l : !!j), [M, R] = s.useState([]), [C, $] = s.useState(null), [T, i] = s.useState(1), [h, v] = s.useState(b), [c, F] = s.useState([null]), [y, K] = s.useState(""), [B, U] = s.useState({}), [_, A] = s.useState(null), [E, k] = s.useState(!0), [O, V] = s.useState(null), [L, X] = s.useState(null), [we, q] = s.useState(!1), [Se, G] = s.useState(!1), Q = c[T - 1] ?? null, Z = JSON.stringify(B), H = s.useCallback(async () => {
619
+ k(!0), V(null);
598
620
  try {
599
- const u = await n({ search: M, cursor: Q, pageSize: h, sort: A, filters: I });
600
- P(u.rows), F(u.nextCursor ?? u.cursor ?? null);
601
- } catch (u) {
602
- W(u instanceof Error ? u.message : String(u)), P([]), F(null);
621
+ const d = await n({ search: y, cursor: Q, pageSize: h, sort: _, filters: B });
622
+ R(d.rows), $(d.nextCursor ?? d.cursor ?? null);
623
+ } catch (d) {
624
+ V(d instanceof Error ? d.message : String(d)), R([]), $(null);
603
625
  } finally {
604
- $(!1);
626
+ k(!1);
605
627
  }
606
- }, [M, Q, h, A, Z, n]);
628
+ }, [y, Q, h, _, Z, n]);
607
629
  s.useEffect(() => {
608
- U();
609
- }, [U]), s.useEffect(() => {
610
- i(1), k([null]);
611
- }, [M, h, Z]);
612
- const Ne = r.filter((u) => u.filter).map((u) => ({
613
- key: u.key,
614
- label: typeof u.label == "string" ? u.label : u.key,
615
- type: u.filter === "numberrange" ? "number" : u.filter,
616
- options: ge(u.filterOptions ?? u.options)
617
- })), we = (u, V) => {
618
- J((Y) => ({ ...Y, [u]: V }));
619
- }, Se = () => {
620
- X(null), _(!0);
621
- }, ke = (u) => {
622
- X(u), _(!0);
623
- }, Ce = async (u) => {
624
- if (!(!await at({
625
- title: `Delete ${B}?`,
630
+ H();
631
+ }, [H]), s.useEffect(() => {
632
+ i(1), F([null]);
633
+ }, [y, h, Z]);
634
+ const ke = r.filter((d) => d.filter).map((d) => ({
635
+ key: d.key,
636
+ label: typeof d.label == "string" ? d.label : d.key,
637
+ type: d.filter === "numberrange" ? "number" : d.filter,
638
+ options: Ne(d.filterOptions ?? d.options)
639
+ })), Ce = (d, J) => {
640
+ U((Y) => ({ ...Y, [d]: J }));
641
+ }, Te = () => {
642
+ X(null), q(!0);
643
+ }, Ee = (d) => {
644
+ X(d), q(!0);
645
+ }, Pe = async (d) => {
646
+ if (!(!await rt({
647
+ title: `Delete ${I}?`,
626
648
  message: "This action cannot be undone.",
627
649
  confirmText: "Delete",
628
650
  cancelText: "Cancel",
629
651
  type: "danger"
630
- }) || !E)) {
652
+ }) || !j)) {
631
653
  G(!0);
632
654
  try {
633
- await E(u), await U();
655
+ await j(d), await H();
634
656
  } finally {
635
657
  G(!1);
636
658
  }
637
659
  }
638
- }, Te = (u, V) => {
639
- if (V === "next") {
640
- const Y = S;
641
- k((Re) => {
642
- const te = [...Re];
643
- return te[u - 1] = Y, te;
660
+ }, Re = (d, J) => {
661
+ if (J === "next") {
662
+ const Y = C;
663
+ F(($e) => {
664
+ const te = [...$e];
665
+ return te[d - 1] = Y, te;
644
666
  });
645
667
  }
646
- i(u);
647
- }, Ee = [
648
- ...r.filter((u) => !u.hidden),
668
+ i(d);
669
+ }, je = [
670
+ ...r.filter((d) => !d.hidden),
649
671
  ...N("edit") || N("delete") ? [
650
672
  {
651
673
  key: "actions",
652
674
  label: "",
653
675
  align: "right",
654
- render: (u) => /* @__PURE__ */ p("div", { className: "flex items-center justify-end gap-1", children: [
655
- N("edit") ? /* @__PURE__ */ e(D, { variant: "ghost", size: "icon", "aria-label": "Edit", onClick: () => ke(u), "data-testid": "resource-edit", children: /* @__PURE__ */ e(Je, { className: "h-3.5 w-3.5", "aria-hidden": !0 }) }) : null,
656
- N("delete") ? /* @__PURE__ */ e(D, { variant: "ghost", size: "icon", "aria-label": "Delete", disabled: ye, onClick: () => void Ce(u), "data-testid": "resource-delete", children: /* @__PURE__ */ e(Ye, { className: "h-3.5 w-3.5 text-[var(--prui-danger)]", "aria-hidden": !0 }) }) : null
676
+ render: (d) => /* @__PURE__ */ p("div", { className: "flex items-center justify-end gap-1", children: [
677
+ N("edit") ? /* @__PURE__ */ e(D, { variant: "ghost", size: "icon", "aria-label": "Edit", onClick: () => Ee(d), "data-testid": "resource-edit", children: /* @__PURE__ */ e(Je, { className: "h-3.5 w-3.5", "aria-hidden": !0 }) }) : null,
678
+ N("delete") ? /* @__PURE__ */ e(D, { variant: "ghost", size: "icon", "aria-label": "Delete", disabled: Se, onClick: () => void Pe(d), "data-testid": "resource-delete", children: /* @__PURE__ */ e(Ye, { className: "h-3.5 w-3.5 text-[var(--prui-danger)]", "aria-hidden": !0 }) }) : null
657
679
  ] })
658
680
  }
659
681
  ] : []
660
- ], ee = c ?? wt(r, L), Pe = L ? Object.fromEntries(
661
- ee.fields.map((u) => [u.name, L[u.name] ?? ""])
662
- ) : void 0, B = t.replace(/s$/, "");
663
- return /* @__PURE__ */ p("div", { className: w("prui-resource flex flex-col gap-2", z), "data-testid": "resource", children: [
682
+ ], ee = u ?? wt(r, L), Me = L ? Object.fromEntries(
683
+ ee.fields.map((d) => [d.name, L[d.name] ?? ""])
684
+ ) : void 0, I = t.replace(/s$/, "");
685
+ return /* @__PURE__ */ p("div", { className: S("prui-resource flex flex-col gap-2", z), "data-testid": "resource", children: [
664
686
  /* @__PURE__ */ e("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ e("h1", { className: "text-xl font-semibold capitalize text-[var(--prui-fg)]", children: t }) }),
665
687
  /* @__PURE__ */ e(
666
- rt,
688
+ nt,
667
689
  {
668
690
  searchPlaceholder: o ?? `Search ${t}...`,
669
- searchValue: M,
670
- onSearchChange: q,
671
- filters: Ne,
672
- filterValues: I,
673
- onFilterChange: we,
674
- actions: N("create") ? /* @__PURE__ */ p(D, { variant: "primary", size: "sm", onClick: Se, "data-testid": "resource-create", children: [
675
- /* @__PURE__ */ e(He, { className: "h-4 w-4", "aria-hidden": !0 }),
691
+ searchValue: y,
692
+ onSearchChange: K,
693
+ filters: ke,
694
+ filterValues: B,
695
+ onFilterChange: Ce,
696
+ actions: N("create") ? /* @__PURE__ */ p(D, { variant: "primary", size: "sm", onClick: Te, "data-testid": "resource-create", children: [
697
+ /* @__PURE__ */ e(We, { className: "h-4 w-4", "aria-hidden": !0 }),
676
698
  "New ",
677
- B
699
+ I
678
700
  ] }) : void 0
679
701
  }
680
702
  ),
681
- K ? /* @__PURE__ */ e("div", { role: "alert", "data-testid": "resource-error", className: "rounded-[var(--prui-radius)] border border-[var(--prui-danger)]/40 bg-[var(--prui-danger)]/10 px-3 py-2 text-sm text-[var(--prui-danger)]", children: K }) : null,
682
- /* @__PURE__ */ e(nt, { columns: Ee, rows: O, rowKey: y, sort: A, onSortChange: j, loading: C }),
703
+ O ? /* @__PURE__ */ e("div", { role: "alert", "data-testid": "resource-error", className: "rounded-[var(--prui-radius)] border border-[var(--prui-danger)]/40 bg-[var(--prui-danger)]/10 px-3 py-2 text-sm text-[var(--prui-danger)]", children: O }) : null,
704
+ /* @__PURE__ */ e(lt, { columns: je, rows: M, rowKey: w, sort: _, onSortChange: A, loading: E }),
683
705
  /* @__PURE__ */ e(
684
- lt,
706
+ st,
685
707
  {
686
708
  page: T,
687
709
  pageSize: h,
688
- hasNextPage: S != null,
710
+ hasNextPage: C != null,
689
711
  hasPreviousPage: T > 1,
690
- onPageChange: Te,
691
- onPageSizeChange: (u) => v(u)
712
+ onPageChange: Re,
713
+ onPageSizeChange: (d) => v(d)
692
714
  }
693
715
  ),
694
- /* @__PURE__ */ p(ue, { open: xe, onClose: () => _(!1), size: "sm", ariaLabel: L ? `Edit ${B}` : `New ${B}`, noPadding: !0, children: [
695
- /* @__PURE__ */ e("div", { className: "px-8 pt-8 pb-2", children: /* @__PURE__ */ e("h2", { className: "text-lg font-semibold", style: { color: "var(--prui-fg)" }, children: L ? `Edit ${B}` : `New ${B}` }) }),
716
+ /* @__PURE__ */ p(me, { open: we, onClose: () => q(!1), size: "sm", ariaLabel: L ? `Edit ${I}` : `New ${I}`, noPadding: !0, children: [
717
+ /* @__PURE__ */ e("div", { className: "px-8 pt-8 pb-2", children: /* @__PURE__ */ e("h2", { className: "text-lg font-semibold", style: { color: "var(--prui-fg)" }, children: L ? `Edit ${I}` : `New ${I}` }) }),
696
718
  /* @__PURE__ */ e("div", { className: "px-8 pb-8", children: x ?? /* @__PURE__ */ e(
697
719
  Nt,
698
720
  {
699
721
  schema: ee,
700
- initialValues: Pe,
701
- onCancel: () => _(!1),
702
- onSubmit: async (u) => {
703
- L ? await (l == null ? void 0 : l(L, u)) : await (a == null ? void 0 : a(u)), _(!1), await U();
722
+ initialValues: Me,
723
+ onCancel: () => q(!1),
724
+ onSubmit: async (d) => {
725
+ L ? await (l == null ? void 0 : l(L, d)) : await (a == null ? void 0 : a(d)), q(!1), await H();
704
726
  }
705
727
  }
706
728
  ) })
707
729
  ] })
708
730
  ] });
709
731
  }
710
- const Yt = {
732
+ const Jt = {
711
733
  name: "Resource",
712
734
  props: [
713
735
  { name: "name", type: "string", default: null, control: "text" },
@@ -723,21 +745,21 @@ const Yt = {
723
745
  { name: "pageSize", type: "number", default: "20", control: "number" }
724
746
  ]
725
747
  };
726
- function Ht({ items: t, className: r }) {
727
- return /* @__PURE__ */ e("div", { className: w("prui-stat-row grid gap-3 sm:grid-cols-2 lg:grid-cols-4", r), children: t.map((n, a) => {
748
+ function Yt({ items: t, className: r }) {
749
+ return /* @__PURE__ */ e("div", { className: S("prui-stat-row grid gap-3 sm:grid-cols-2 lg:grid-cols-4", r), children: t.map((n, a) => {
728
750
  const l = n.icon;
729
- return /* @__PURE__ */ p(me, { "data-testid": "stat-card", children: [
730
- /* @__PURE__ */ p(pe, { className: "pb-2", children: [
731
- /* @__PURE__ */ p(fe, { className: "flex items-center gap-1.5 text-xs", children: [
751
+ return /* @__PURE__ */ p(he, { "data-testid": "stat-card", children: [
752
+ /* @__PURE__ */ p(be, { className: "pb-2", children: [
753
+ /* @__PURE__ */ p(ve, { className: "flex items-center gap-1.5 text-xs", children: [
732
754
  l ? /* @__PURE__ */ e(l, { className: "h-3.5 w-3.5", "aria-hidden": !0 }) : null,
733
755
  n.label
734
756
  ] }),
735
- /* @__PURE__ */ e(he, { className: "text-2xl", children: n.value })
757
+ /* @__PURE__ */ e(ge, { className: "text-2xl", children: n.value })
736
758
  ] }),
737
- n.delta ? /* @__PURE__ */ e(be, { className: "pb-3", children: /* @__PURE__ */ e(
759
+ n.delta ? /* @__PURE__ */ e(xe, { className: "pb-3", children: /* @__PURE__ */ e(
738
760
  "span",
739
761
  {
740
- className: w(
762
+ className: S(
741
763
  "text-xs font-medium",
742
764
  n.trend === "up" && "text-[var(--prui-ok)]",
743
765
  n.trend === "down" && "text-[var(--prui-danger)]",
@@ -765,7 +787,7 @@ function Ct({ field: t }) {
765
787
  if (!n || !r) return null;
766
788
  const m = `prui-settings-${r}`;
767
789
  return n === "switch" ? /* @__PURE__ */ e("label", { className: "flex items-center gap-2", htmlFor: m, children: /* @__PURE__ */ e(
768
- de,
790
+ fe,
769
791
  {
770
792
  id: m,
771
793
  checked: !!a,
@@ -773,7 +795,7 @@ function Ct({ field: t }) {
773
795
  "aria-label": t.label
774
796
  }
775
797
  ) }) : n === "select" ? /* @__PURE__ */ e(
776
- ce,
798
+ pe,
777
799
  {
778
800
  id: m,
779
801
  className: "w-56",
@@ -783,7 +805,7 @@ function Ct({ field: t }) {
783
805
  "aria-label": t.label
784
806
  }
785
807
  ) : /* @__PURE__ */ e(
786
- H,
808
+ W,
787
809
  {
788
810
  id: m,
789
811
  type: n === "number" ? "number" : "text",
@@ -795,7 +817,7 @@ function Ct({ field: t }) {
795
817
  );
796
818
  }
797
819
  function Xt({ title: t = "Settings", sections: r, className: n }) {
798
- return /* @__PURE__ */ p("div", { className: w("prui-settings mx-auto flex w-full max-w-4xl flex-col gap-6", n), children: [
820
+ return /* @__PURE__ */ p("div", { className: S("prui-settings mx-auto flex w-full max-w-4xl flex-col gap-6", n), children: [
799
821
  /* @__PURE__ */ e("h1", { className: "text-xl font-semibold text-[var(--prui-fg)]", children: t }),
800
822
  /* @__PURE__ */ p("div", { className: "flex flex-col gap-6 md:flex-row", children: [
801
823
  /* @__PURE__ */ e("nav", { "aria-label": "Settings sections", className: "md:w-56 md:shrink-0", children: /* @__PURE__ */ e("ul", { className: "flex flex-row flex-wrap gap-1 md:flex-col", children: r.map((a) => /* @__PURE__ */ e("li", { children: /* @__PURE__ */ e(
@@ -806,12 +828,12 @@ function Xt({ title: t = "Settings", sections: r, className: n }) {
806
828
  children: a.title ?? a.label ?? a.id
807
829
  }
808
830
  ) }, a.id)) }) }),
809
- /* @__PURE__ */ e("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: r.map((a) => /* @__PURE__ */ p(me, { id: `settings-${a.id}`, "data-testid": "settings-section", children: [
810
- /* @__PURE__ */ p(pe, { children: [
811
- /* @__PURE__ */ e(he, { children: a.title ?? a.label ?? a.id }),
812
- a.description ? /* @__PURE__ */ e(fe, { children: a.description }) : null
831
+ /* @__PURE__ */ e("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: r.map((a) => /* @__PURE__ */ p(he, { id: `settings-${a.id}`, "data-testid": "settings-section", children: [
832
+ /* @__PURE__ */ p(be, { children: [
833
+ /* @__PURE__ */ e(ge, { children: a.title ?? a.label ?? a.id }),
834
+ a.description ? /* @__PURE__ */ e(ve, { children: a.description }) : null
813
835
  ] }),
814
- /* @__PURE__ */ e(be, { children: a.content ?? /* @__PURE__ */ e("dl", { className: "flex flex-col divide-y divide-[var(--prui-line)]", children: (a.fields ?? []).map((l, m) => /* @__PURE__ */ p("div", { className: "flex flex-col gap-2 py-3 first:pt-0 last:pb-0 sm:flex-row sm:items-center sm:justify-between", children: [
836
+ /* @__PURE__ */ e(xe, { children: a.content ?? /* @__PURE__ */ e("dl", { className: "flex flex-col divide-y divide-[var(--prui-line)]", children: (a.fields ?? []).map((l, m) => /* @__PURE__ */ p("div", { className: "flex flex-col gap-2 py-3 first:pt-0 last:pb-0 sm:flex-row sm:items-center sm:justify-between", children: [
815
837
  /* @__PURE__ */ p("div", { className: "min-w-0", children: [
816
838
  /* @__PURE__ */ e("dt", { className: "text-sm font-medium text-[var(--prui-fg)]", children: l.label }),
817
839
  l.description ? /* @__PURE__ */ e("dd", { className: "text-xs text-[var(--prui-dim)]", children: l.description }) : null
@@ -828,7 +850,7 @@ const Gt = {
828
850
  { name: "title", type: "string", default: "'Settings'", control: "text" },
829
851
  { name: "sections", type: "SettingsSection[]", default: null, control: "object" }
830
852
  ]
831
- }, ie = ["mousedown", "keydown", "scroll", "touchstart", "click"];
853
+ }, ue = ["mousedown", "keydown", "scroll", "touchstart", "click"];
832
854
  function Tt({
833
855
  timeout: t = 15,
834
856
  warningTime: r = 2,
@@ -837,48 +859,48 @@ function Tt({
837
859
  title: l = "Session expiring soon",
838
860
  message: m = "Your session is about to expire due to inactivity."
839
861
  }) {
840
- const f = Math.max(0, t) * 6e4, g = Math.min(Math.max(0, r) * 6e4, f), [x, c] = s.useState(!1), [y, o] = s.useState(g), b = s.useRef(null), z = s.useRef(null), E = s.useRef(null), R = s.useRef(!1), N = s.useCallback(() => {
841
- for (const h of [b, z, E])
862
+ const f = Math.max(0, t) * 6e4, g = Math.min(Math.max(0, r) * 6e4, f), [x, u] = s.useState(!1), [w, o] = s.useState(g), b = s.useRef(null), z = s.useRef(null), j = s.useRef(null), P = s.useRef(!1), N = s.useCallback(() => {
863
+ for (const h of [b, z, j])
842
864
  h.current != null && (clearInterval(h.current), clearTimeout(h.current), h.current = null);
843
- }, []), O = s.useCallback(() => {
844
- N(), c(!1), n == null || n();
845
- }, [N, n]), P = s.useCallback(() => {
846
- N(), c(!1), R.current = !1, b.current = window.setTimeout(() => {
847
- R.current = !0, o(g), c(!0), E.current = window.setInterval(() => {
848
- o((h) => h <= 1e3 ? (O(), 0) : h - 1e3);
865
+ }, []), M = s.useCallback(() => {
866
+ N(), u(!1), n == null || n();
867
+ }, [N, n]), R = s.useCallback(() => {
868
+ N(), u(!1), P.current = !1, b.current = window.setTimeout(() => {
869
+ P.current = !0, o(g), u(!0), j.current = window.setInterval(() => {
870
+ o((h) => h <= 1e3 ? (M(), 0) : h - 1e3);
849
871
  }, 1e3);
850
- }, f - g), z.current = window.setTimeout(O, f);
851
- }, [N, O, f, g]);
872
+ }, f - g), z.current = window.setTimeout(M, f);
873
+ }, [N, M, f, g]);
852
874
  s.useEffect(() => {
853
875
  const h = () => {
854
- R.current || P();
876
+ P.current || R();
855
877
  };
856
- for (const v of ie) document.addEventListener(v, h, { passive: !0 });
857
- return P(), () => {
878
+ for (const v of ue) document.addEventListener(v, h, { passive: !0 });
879
+ return R(), () => {
858
880
  N();
859
- for (const v of ie) document.removeEventListener(v, h);
881
+ for (const v of ue) document.removeEventListener(v, h);
860
882
  };
861
- }, [P, N]);
862
- const S = () => {
863
- a == null || a(), P();
864
- }, F = Math.floor(y / 6e4), T = Math.floor(y % 6e4 / 1e3), i = `${F}:${String(T).padStart(2, "0")}`;
883
+ }, [R, N]);
884
+ const C = () => {
885
+ a == null || a(), R();
886
+ }, $ = Math.floor(w / 6e4), T = Math.floor(w % 6e4 / 1e3), i = `${$}:${String(T).padStart(2, "0")}`;
865
887
  return /* @__PURE__ */ p(
866
- ue,
888
+ me,
867
889
  {
868
890
  open: x,
869
- onClose: S,
891
+ onClose: C,
870
892
  size: "sm",
871
893
  ariaLabel: l,
872
894
  children: [
873
895
  /* @__PURE__ */ p("div", { className: "flex flex-col items-center gap-1 px-8 pb-2 pt-8 text-center", children: [
874
- /* @__PURE__ */ e("div", { className: "mb-2 flex h-12 w-12 items-center justify-center rounded-full bg-[var(--prui-warn)]/15", children: /* @__PURE__ */ e(We, { className: "h-6 w-6 text-[var(--prui-warn)]", "aria-hidden": !0 }) }),
896
+ /* @__PURE__ */ e("div", { className: "mb-2 flex h-12 w-12 items-center justify-center rounded-full bg-[var(--prui-warn)]/15", children: /* @__PURE__ */ e(Xe, { className: "h-6 w-6 text-[var(--prui-warn)]", "aria-hidden": !0 }) }),
875
897
  /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-[var(--prui-fg)]", children: l }),
876
898
  /* @__PURE__ */ e("p", { className: "text-sm text-[var(--prui-dim)]", children: m }),
877
899
  /* @__PURE__ */ e("div", { className: "py-4 font-mono text-4xl font-bold text-[var(--prui-fg)]", "data-testid": "session-countdown", children: i })
878
900
  ] }),
879
901
  /* @__PURE__ */ p("div", { className: "flex flex-col gap-2 px-8 pb-8 sm:flex-row", children: [
880
- /* @__PURE__ */ e(D, { variant: "default", className: "flex-1", onClick: O, "data-testid": "session-logout", children: "Log out now" }),
881
- /* @__PURE__ */ e(D, { variant: "primary", className: "flex-1", onClick: S, "data-testid": "session-extend", children: "Continue session" })
902
+ /* @__PURE__ */ e(D, { variant: "default", className: "flex-1", onClick: M, "data-testid": "session-logout", children: "Log out now" }),
903
+ /* @__PURE__ */ e(D, { variant: "primary", className: "flex-1", onClick: C, "data-testid": "session-extend", children: "Continue session" })
882
904
  ] })
883
905
  ]
884
906
  }
@@ -898,7 +920,7 @@ const Et = {
898
920
  sessionTimeoutPropsMeta: Et
899
921
  }, Symbol.toStringTag, { value: "Module" }));
900
922
  function Qt({ title: t, description: r, brand: n, width: a = "max-w-sm", footer: l, children: m, className: f }) {
901
- return /* @__PURE__ */ e("div", { className: w("prui-auth-shell flex min-h-[100dvh] items-center justify-center bg-[var(--prui-background)] p-4", f), "data-testid": "auth-shell", children: /* @__PURE__ */ p("div", { className: w("w-full", a), children: [
923
+ return /* @__PURE__ */ e("div", { className: S("prui-auth-shell flex min-h-[100dvh] items-center justify-center bg-[var(--prui-background)] p-4", f), "data-testid": "auth-shell", children: /* @__PURE__ */ p("div", { className: S("w-full", a), children: [
902
924
  n ? /* @__PURE__ */ p("div", { className: "mb-6 flex items-center justify-center gap-2", "data-testid": "auth-shell-brand", children: [
903
925
  n.mark ? /* @__PURE__ */ e("img", { src: n.mark, alt: "", className: "h-8 w-8 rounded-[var(--prui-radius-1)] object-cover" }) : null,
904
926
  /* @__PURE__ */ e("span", { className: "text-lg font-semibold text-[var(--prui-fg)]", children: n.name })
@@ -928,20 +950,20 @@ export {
928
950
  Kt as A,
929
951
  vt as C,
930
952
  Nt as F,
931
- Jt as R,
953
+ Ht as R,
932
954
  Tt as S,
933
955
  gt as a,
934
956
  Qt as b,
935
957
  ct as c,
936
958
  Xt as d,
937
- le as e,
938
- Ht as f,
959
+ ie as e,
960
+ Yt as f,
939
961
  Ut as g,
940
962
  Zt as h,
941
963
  Vt as i,
942
964
  Gt as j,
943
965
  Wt as k,
944
- Yt as r,
966
+ Jt as r,
945
967
  Et as s,
946
- mt as u
968
+ pt as u
947
969
  };