@apliteni/apliteni-ui 0.27.0 → 0.31.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 (44) hide show
  1. package/package.json +1 -1
  2. package/react/README.md +49 -1
  3. package/react/dist/index.css +11 -1
  4. package/react/dist/index.d.ts +61 -2
  5. package/react/dist/index.js +514 -121
  6. package/src/components/back.js +57 -0
  7. package/src/components/command-palette.js +597 -0
  8. package/src/components/confirm.js +3 -2
  9. package/src/components/drawer.js +31 -2
  10. package/src/components/dropdown.js +192 -17
  11. package/src/components/feedback.js +2 -2
  12. package/src/components/index.js +5 -2
  13. package/src/components/loading.js +3 -2
  14. package/src/components/nav.js +15 -7
  15. package/src/components/overlay.js +67 -14
  16. package/src/components/shell.js +11 -2
  17. package/src/components/tabs.js +7 -1
  18. package/src/components/tooltip.js +237 -0
  19. package/src/components/topbar.js +9 -4
  20. package/src/index.css +3 -0
  21. package/src/index.js +3 -0
  22. package/src/inline.js +6 -0
  23. package/src/motion.js +43 -2
  24. package/src/styles/back.css +42 -0
  25. package/src/styles/badge.css +5 -7
  26. package/src/styles/base.css +8 -7
  27. package/src/styles/card.css +12 -8
  28. package/src/styles/code.css +3 -4
  29. package/src/styles/command-palette.css +321 -0
  30. package/src/styles/confirm.css +11 -11
  31. package/src/styles/drawer.css +57 -15
  32. package/src/styles/dropdown.css +70 -11
  33. package/src/styles/feedback.css +2 -0
  34. package/src/styles/footer.css +3 -4
  35. package/src/styles/input.css +1 -1
  36. package/src/styles/layout.css +3 -2
  37. package/src/styles/loading.css +5 -0
  38. package/src/styles/nav.css +12 -8
  39. package/src/styles/success.css +3 -2
  40. package/src/styles/table.css +4 -5
  41. package/src/styles/tabs.css +3 -0
  42. package/src/styles/tooltip.css +65 -0
  43. package/src/styles/topbar.css +3 -4
  44. package/src/tokens/tokens.css +8 -8
@@ -20,7 +20,7 @@ var cx = (...a) => a.filter(Boolean).join(" ");
20
20
  function Button({
21
21
  variant = "secondary",
22
22
  size = "md",
23
- icon: icon2,
23
+ icon: icon3,
24
24
  iconRight,
25
25
  iconOnly,
26
26
  block,
@@ -38,7 +38,7 @@ function Button({
38
38
  iconOnly && "ui-btn--icon"
39
39
  );
40
40
  const labelled = rest["aria-label"] != null || rest["aria-labelledby"] != null;
41
- const fallback = typeof children === "string" && children.trim() ? children.trim() : icon2;
41
+ const fallback = typeof children === "string" && children.trim() ? children.trim() : icon3;
42
42
  const named = iconOnly && !labelled && fallback ? { "aria-label": fallback, title: rest.title ?? fallback } : {};
43
43
  return /* @__PURE__ */ jsxs(
44
44
  "button",
@@ -51,7 +51,7 @@ function Button({
51
51
  ...rest,
52
52
  ...named,
53
53
  children: [
54
- icon2 && /* @__PURE__ */ jsx2(Icon, { name: icon2 }),
54
+ icon3 && /* @__PURE__ */ jsx2(Icon, { name: icon3 }),
55
55
  !iconOnly && children != null && /* @__PURE__ */ jsx2("span", { children }),
56
56
  iconRight && /* @__PURE__ */ jsx2(Icon, { name: iconRight }),
57
57
  busy && /* @__PURE__ */ jsxs("span", { className: "ui-btn__bars", children: [
@@ -72,18 +72,30 @@ function Badge({ variant = "neutral", children }) {
72
72
 
73
73
  // src/primitives/Card.tsx
74
74
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
75
- function Card({ title, sub, children }) {
75
+ function Card({ title, sub, level = 2, children }) {
76
+ const n = Number(level);
77
+ const Heading = `h${[2, 3, 4, 5, 6].includes(n) ? n : 2}`;
78
+ const titled = title != null && title !== false && title !== "";
76
79
  return /* @__PURE__ */ jsxs2("div", { className: "ui-card", children: [
77
- title != null && /* @__PURE__ */ jsx4("div", { className: "ui-card__title", children: title }),
80
+ titled && /* @__PURE__ */ jsx4(Heading, { className: "ui-card__title", children: title }),
78
81
  sub != null && /* @__PURE__ */ jsx4("div", { className: "ui-card__sub", children: sub }),
79
82
  children
80
83
  ] });
81
84
  }
82
85
 
83
86
  // src/Modal.tsx
84
- import { useEffect, useRef } from "react";
87
+ import { useRef as useRef2 } from "react";
85
88
  import { createPortal } from "react-dom";
86
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
89
+
90
+ // src/dialog.ts
91
+ import {
92
+ createContext,
93
+ useContext,
94
+ useEffect,
95
+ useLayoutEffect,
96
+ useRef,
97
+ useState
98
+ } from "react";
87
99
  var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]), details > summary:first-of-type';
88
100
  function tabbable(el) {
89
101
  const tabindex = el.getAttribute("tabindex");
@@ -103,83 +115,462 @@ var dismissOnScrim = (onClose) => (e) => {
103
115
  e.preventDefault();
104
116
  onClose();
105
117
  };
106
- function Modal({ open, title, onClose, footer, children }) {
107
- const panel = useRef(null);
108
- useEffect(() => {
109
- if (!open) return;
110
- const onKey = (e) => {
111
- if (e.key === "Escape") {
112
- onClose();
113
- return;
114
- }
115
- if (e.key !== "Tab" || !panel.current) return;
116
- const items = tabbablesIn(panel.current);
117
- if (items.length === 0) {
118
- e.preventDefault();
119
- panel.current.focus();
120
- return;
121
- }
122
- const first = items[0];
123
- const last = items[items.length - 1];
124
- const active = document.activeElement;
125
- if (!panel.current.contains(active)) {
126
- e.preventDefault();
127
- first.focus();
128
- return;
129
- }
130
- if (!e.shiftKey && active === last) {
131
- e.preventDefault();
132
- first.focus();
133
- } else if (e.shiftKey && (active === first || active === panel.current)) {
134
- e.preventDefault();
135
- last.focus();
136
- }
118
+ var useIsoLayoutEffect = typeof document === "undefined" ? useEffect : useLayoutEffect;
119
+ function transitionMs(el) {
120
+ const cs = getComputedStyle(el);
121
+ const times = (list) => list.split(",").map((t) => {
122
+ const n = Number.parseFloat(t);
123
+ if (!Number.isFinite(n)) return 0;
124
+ return t.trim().endsWith("ms") ? n : n * 1e3;
125
+ });
126
+ const durations = times(cs.transitionDuration);
127
+ const delays = times(cs.transitionDelay);
128
+ return Math.max(0, ...durations.map((d, i) => d + delays[i % delays.length]));
129
+ }
130
+ var DialogScope = createContext(null);
131
+ var stack = [];
132
+ var leaving = /* @__PURE__ */ new Set();
133
+ var marked = [];
134
+ var listening = false;
135
+ var firstIn = (entry) => (entry.body ? tabbablesIn(entry.body) : [])[0] || entry.panel;
136
+ function trapTab(panel, e) {
137
+ const items = tabbablesIn(panel);
138
+ if (items.length === 0) {
139
+ e.preventDefault();
140
+ panel.focus();
141
+ return;
142
+ }
143
+ const first = items[0];
144
+ const last = items[items.length - 1];
145
+ const focused = document.activeElement;
146
+ if (!panel.contains(focused)) {
147
+ e.preventDefault();
148
+ first.focus();
149
+ return;
150
+ }
151
+ if (!e.shiftKey && focused === last) {
152
+ e.preventDefault();
153
+ first.focus();
154
+ } else if (e.shiftKey && (focused === first || focused === panel)) {
155
+ e.preventDefault();
156
+ last.focus();
157
+ }
158
+ }
159
+ function onKey(e) {
160
+ const top = stack[stack.length - 1];
161
+ if (!top) return;
162
+ if (e.key === "Escape") top.close();
163
+ else if (e.key === "Tab") trapTab(top.panel, e);
164
+ }
165
+ function sync() {
166
+ for (const [el, was] of marked) if (!was) el.removeAttribute("inert");
167
+ marked = [];
168
+ const top = stack[stack.length - 1];
169
+ for (let node = top?.root; node?.parentElement && node !== document.body; node = node.parentElement) {
170
+ for (const sib of Array.from(node.parentElement.children)) {
171
+ if (sib === node || leaving.has(sib)) continue;
172
+ marked.push([sib, sib.hasAttribute("inert")]);
173
+ sib.setAttribute("inert", "");
174
+ }
175
+ }
176
+ leaving.forEach((el) => {
177
+ el.toggleAttribute("inert", true);
178
+ if (el.getAttribute("aria-hidden") !== "true") el.setAttribute("aria-hidden", "true");
179
+ });
180
+ if (Boolean(top) !== listening) {
181
+ listening = Boolean(top);
182
+ if (listening) document.addEventListener("keydown", onKey);
183
+ else document.removeEventListener("keydown", onKey);
184
+ }
185
+ }
186
+ function returnFocus(opener) {
187
+ const live = opener && !opener.isConnected && opener.id ? document.getElementById(opener.id) : opener;
188
+ if (live?.isConnected) live.focus?.();
189
+ if (document.activeElement !== live) document.activeElement?.blur?.();
190
+ }
191
+ function enter(entry) {
192
+ const at = stack.findIndex((e) => {
193
+ for (let s = e.scope.parent; s; s = s.parent) if (s === entry.scope) return true;
194
+ return false;
195
+ });
196
+ if (at !== -1) {
197
+ entry.opener = stack[at].opener;
198
+ stack[at].opener = null;
199
+ stack.splice(at, 0, entry);
200
+ sync();
201
+ return;
202
+ }
203
+ const covered = stack[stack.length - 1];
204
+ if (covered?.panel.contains(document.activeElement)) covered.resume = document.activeElement;
205
+ stack.push(entry);
206
+ sync();
207
+ firstIn(entry).focus();
208
+ }
209
+ function exit(entry) {
210
+ const at = stack.indexOf(entry);
211
+ if (at === -1) return;
212
+ stack.splice(at, 1);
213
+ const above = stack[at];
214
+ if (above && (!above.opener || entry.root.contains(above.opener))) above.opener = entry.opener;
215
+ sync();
216
+ if (above) return;
217
+ const next = stack[stack.length - 1];
218
+ if (!next) {
219
+ returnFocus(entry.opener);
220
+ return;
221
+ }
222
+ const back = [entry.opener, next.resume].find((el) => el?.isConnected && next.panel.contains(el));
223
+ (back ?? firstIn(next)).focus();
224
+ }
225
+ var EXIT_SLACK_MS = 50;
226
+ function usePresence(open, root, panel) {
227
+ const [present, setPresent] = useState(open);
228
+ const [entered, setEntered] = useState(false);
229
+ if (open && !present) setPresent(true);
230
+ const shown = open && entered;
231
+ useIsoLayoutEffect(() => {
232
+ if (!open || entered || !panel.current) return;
233
+ panel.current.getBoundingClientRect();
234
+ setEntered(true);
235
+ }, [open, entered]);
236
+ useIsoLayoutEffect(() => {
237
+ const el = root.current;
238
+ if (open || !present || !el) return;
239
+ leaving.add(el);
240
+ sync();
241
+ return () => {
242
+ leaving.delete(el);
243
+ el.removeAttribute("inert");
244
+ el.removeAttribute("aria-hidden");
245
+ sync();
137
246
  };
138
- document.addEventListener("keydown", onKey);
139
- return () => document.removeEventListener("keydown", onKey);
140
- }, [open, onClose]);
141
- useEffect(() => {
142
- if (!open) return;
143
- const opener = document.activeElement;
144
- const portalRoot = panel.current?.closest(".rx-scrim");
145
- const muted = Array.from(document.body.children).filter((el) => el !== portalRoot && !el.hasAttribute("inert"));
146
- muted.forEach((el) => el.setAttribute("inert", ""));
247
+ }, [open, present]);
248
+ useIsoLayoutEffect(() => {
249
+ if (open || !present) return;
250
+ let done = false;
251
+ const finish = () => {
252
+ if (done) return;
253
+ done = true;
254
+ setPresent(false);
255
+ setEntered(false);
256
+ };
257
+ const el = panel.current;
258
+ if (!el) {
259
+ finish();
260
+ return;
261
+ }
262
+ const onEnd = (e) => {
263
+ if (e.target === el) finish();
264
+ };
265
+ el.addEventListener("transitionend", onEnd);
266
+ const timer = setTimeout(finish, transitionMs(el) + EXIT_SLACK_MS);
147
267
  return () => {
148
- muted.forEach((el) => el.removeAttribute("inert"));
149
- if (opener && document.contains(opener)) opener.focus();
268
+ done = true;
269
+ el.removeEventListener("transitionend", onEnd);
270
+ clearTimeout(timer);
150
271
  };
151
- }, [open]);
272
+ }, [open, present]);
273
+ return { mounted: present, shown };
274
+ }
275
+ function useDialog(active, { root, panel, body }, onClose) {
276
+ const parent = useContext(DialogScope);
277
+ const [scope] = useState(() => ({ parent }));
278
+ const close = useRef(onClose);
279
+ useIsoLayoutEffect(() => {
280
+ close.current = onClose;
281
+ });
152
282
  useEffect(() => {
153
- if (!open) return;
154
- const body = panel.current?.querySelector(".rx-modal__body");
155
- const target = (body ? tabbablesIn(body) : [])[0] || panel.current;
156
- target?.focus();
157
- }, [open]);
158
- if (!open) return null;
283
+ if (!active || !root.current || !panel.current) return;
284
+ const entry = {
285
+ scope,
286
+ root: root.current,
287
+ panel: panel.current,
288
+ body: body.current,
289
+ close: () => close.current(),
290
+ opener: document.activeElement,
291
+ resume: null
292
+ };
293
+ enter(entry);
294
+ return () => exit(entry);
295
+ }, [active]);
296
+ return scope;
297
+ }
298
+
299
+ // src/Modal.tsx
300
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
301
+ function Modal({ open, title, onClose, footer, children }) {
302
+ const root = useRef2(null);
303
+ const panel = useRef2(null);
304
+ const body = useRef2(null);
305
+ const { mounted, shown } = usePresence(open, root, panel);
306
+ const scope = useDialog(shown, { root, panel, body }, onClose);
307
+ if (!mounted) return null;
159
308
  return createPortal(
160
- /* @__PURE__ */ jsx5("div", { className: "rx-scrim", onMouseDown: dismissOnScrim(onClose), children: /* @__PURE__ */ jsxs3("div", { className: "rx-modal", role: "dialog", "aria-modal": "true", "aria-label": title, tabIndex: -1, ref: panel, children: [
309
+ /* @__PURE__ */ jsx5(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsx5("div", { className: shown ? "rx-scrim is-open" : "rx-scrim", ref: root, onMouseDown: dismissOnScrim(onClose), children: /* @__PURE__ */ jsxs3("div", { className: "rx-modal", role: "dialog", "aria-modal": "true", "aria-label": title, tabIndex: -1, ref: panel, children: [
161
310
  /* @__PURE__ */ jsxs3("div", { className: "rx-modal__head", children: [
162
311
  /* @__PURE__ */ jsx5("div", { className: "rx-modal__title", children: title }),
163
312
  /* @__PURE__ */ jsx5(Button, { variant: "ghost", size: "sm", iconOnly: true, icon: "x", "aria-label": "Close", onClick: onClose })
164
313
  ] }),
165
- /* @__PURE__ */ jsx5("div", { className: "rx-modal__body", children }),
314
+ /* @__PURE__ */ jsx5("div", { className: "rx-modal__body", ref: body, children }),
166
315
  footer && /* @__PURE__ */ jsx5("div", { className: "rx-modal__foot", children: footer })
316
+ ] }) }) }),
317
+ document.body
318
+ );
319
+ }
320
+
321
+ // src/Drawer.tsx
322
+ import { useId, useRef as useRef3 } from "react";
323
+ import { createPortal as createPortal2 } from "react-dom";
324
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
325
+ function Drawer({
326
+ open,
327
+ title,
328
+ onClose,
329
+ side = "right",
330
+ size = "md",
331
+ footer,
332
+ children,
333
+ closeLabel = "Close"
334
+ }) {
335
+ const root = useRef3(null);
336
+ const panel = useRef3(null);
337
+ const body = useRef3(null);
338
+ const titleId = useId();
339
+ const { mounted, shown } = usePresence(open, root, panel);
340
+ const scope = useDialog(shown, { root, panel, body }, onClose);
341
+ if (!mounted) return null;
342
+ const cls = ["ui-drawer", `ui-drawer--${side}`, `ui-drawer--${size}`, shown && "is-open"].filter(Boolean).join(" ");
343
+ return createPortal2(
344
+ /* @__PURE__ */ jsx6(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsxs4("div", { className: cls, ref: root, children: [
345
+ /* @__PURE__ */ jsx6("div", { className: "ui-drawer__scrim", onMouseDown: dismissOnScrim(onClose) }),
346
+ /* @__PURE__ */ jsxs4(
347
+ "aside",
348
+ {
349
+ className: "ui-drawer__panel",
350
+ role: "dialog",
351
+ "aria-modal": "true",
352
+ "aria-labelledby": titleId,
353
+ tabIndex: -1,
354
+ ref: panel,
355
+ children: [
356
+ /* @__PURE__ */ jsxs4("header", { className: "ui-drawer__header", children: [
357
+ /* @__PURE__ */ jsx6("h2", { className: "ui-drawer__title", id: titleId, children: title }),
358
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "ui-drawer__close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx6(Icon, { name: "x" }) })
359
+ ] }),
360
+ /* @__PURE__ */ jsx6("div", { className: "ui-drawer__body", ref: body, children }),
361
+ footer && /* @__PURE__ */ jsx6("footer", { className: "ui-drawer__footer", children: footer })
362
+ ]
363
+ }
364
+ )
365
+ ] }) }),
366
+ document.body
367
+ );
368
+ }
369
+
370
+ // src/CommandPalette.tsx
371
+ import { useCallback, useEffect as useEffect2, useId as useId2, useMemo, useRef as useRef4, useState as useState2 } from "react";
372
+ import { createPortal as createPortal3 } from "react-dom";
373
+ import { rankGroups, icon as icon2 } from "@apliteni/apliteni-ui";
374
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
375
+ var cx2 = (...a) => a.filter(Boolean).join(" ");
376
+ var Glyph = ({ name, className }) => /* @__PURE__ */ jsx7("span", { className, "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon2(name) } });
377
+ var keysOf = (shortcut) => shortcut == null ? [] : Array.isArray(shortcut) ? shortcut : [shortcut];
378
+ function CommandPalette({
379
+ open,
380
+ onClose,
381
+ groups,
382
+ onSelect,
383
+ label = "Command palette",
384
+ placeholder = "Search or run a command\u2026",
385
+ empty = "No matches",
386
+ density = "compact",
387
+ hint = true,
388
+ rank = true,
389
+ onQueryChange
390
+ }) {
391
+ const uid = useId2().replace(/:/g, "");
392
+ const root = useRef4(null);
393
+ const panel = useRef4(null);
394
+ const search = useRef4(null);
395
+ const [query, setQuery] = useState2("");
396
+ const [at, setAt] = useState2(0);
397
+ useEffect2(() => {
398
+ if (open) {
399
+ setQuery("");
400
+ setAt(0);
401
+ }
402
+ }, [open]);
403
+ const shown = useMemo(
404
+ () => (rank ? rankGroups(groups, query) : groups).filter((g) => g.items.length),
405
+ [groups, query, rank]
406
+ );
407
+ const rows = useMemo(() => shown.flatMap((g) => g.items).filter((it) => !isDisabled(it)), [shown]);
408
+ const active = rows[Math.min(at, rows.length - 1)];
409
+ useEffect2(() => {
410
+ setAt(0);
411
+ }, [query]);
412
+ const scope = useDialog(open, { root, panel, body: search }, onClose);
413
+ const run = useCallback((item, newTab) => {
414
+ if (isDisabled(item)) return;
415
+ onSelect?.(item, { newTab });
416
+ if (item.danger && item.onConfirm) {
417
+ item.onConfirm();
418
+ return;
419
+ }
420
+ onClose();
421
+ if (!item.href) return;
422
+ if (newTab) window.open(item.href, "_blank", "noopener");
423
+ else window.location.href = item.href;
424
+ }, [onClose, onSelect]);
425
+ const onKeyDown = (e) => {
426
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
427
+ if (!rows.length) return;
428
+ e.preventDefault();
429
+ const step = e.key === "ArrowDown" ? 1 : -1;
430
+ setAt((was) => (was + step + rows.length) % rows.length);
431
+ } else if (e.key === "Enter") {
432
+ if (!active) return;
433
+ e.preventDefault();
434
+ run(active, e.metaKey || e.ctrlKey);
435
+ }
436
+ };
437
+ if (!open) return null;
438
+ const listId = `${uid}-list`;
439
+ let n = 0;
440
+ return createPortal3(
441
+ /* @__PURE__ */ jsx7(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsxs5("div", { className: cx2("ui-cmdk", density === "roomy" && "ui-cmdk--roomy", "is-open"), ref: root, children: [
442
+ /* @__PURE__ */ jsx7("div", { className: "ui-cmdk__scrim", onMouseDown: dismissOnScrim(onClose) }),
443
+ /* @__PURE__ */ jsxs5(
444
+ "div",
445
+ {
446
+ className: "ui-cmdk__panel",
447
+ role: "dialog",
448
+ "aria-modal": "true",
449
+ "aria-label": label,
450
+ tabIndex: -1,
451
+ ref: panel,
452
+ onKeyDown,
453
+ children: [
454
+ /* @__PURE__ */ jsxs5("div", { className: "ui-cmdk__search", ref: search, children: [
455
+ /* @__PURE__ */ jsx7(Glyph, { name: "search", className: "ui-cmdk__search-ic" }),
456
+ /* @__PURE__ */ jsx7(
457
+ "input",
458
+ {
459
+ className: "ui-cmdk__input",
460
+ type: "text",
461
+ role: "combobox",
462
+ "aria-autocomplete": "list",
463
+ "aria-expanded": true,
464
+ "aria-controls": listId,
465
+ "aria-label": label,
466
+ "aria-activedescendant": active ? rowId(uid, shown, active) : void 0,
467
+ placeholder,
468
+ value: query,
469
+ autoComplete: "off",
470
+ spellCheck: false,
471
+ onChange: (e) => {
472
+ setQuery(e.target.value);
473
+ onQueryChange?.(e.target.value);
474
+ }
475
+ }
476
+ )
477
+ ] }),
478
+ /* @__PURE__ */ jsx7("div", { className: "ui-cmdk__list", id: listId, role: "listbox", "aria-label": `${label} results`, children: shown.map((group, gi) => /* @__PURE__ */ jsxs5(
479
+ "div",
480
+ {
481
+ className: "ui-cmdk__group",
482
+ role: "group",
483
+ "aria-labelledby": group.label ? `${uid}-g${gi}` : void 0,
484
+ children: [
485
+ group.label && /* @__PURE__ */ jsx7("div", { className: "ui-cmdk__group-head", id: `${uid}-g${gi}`, children: group.label }),
486
+ group.items.map((item) => {
487
+ const disabled = isDisabled(item);
488
+ const id = `${uid}-o${n++}`;
489
+ const on = item === active;
490
+ return /* @__PURE__ */ jsxs5(
491
+ "div",
492
+ {
493
+ id,
494
+ className: cx2(
495
+ "ui-cmdk__item",
496
+ item.danger && !disabled && "is-danger",
497
+ disabled && "is-disabled",
498
+ on && "is-active"
499
+ ),
500
+ role: "option",
501
+ tabIndex: -1,
502
+ "aria-selected": on,
503
+ "aria-disabled": disabled || void 0,
504
+ "aria-haspopup": item.danger && item.onConfirm ? "dialog" : void 0,
505
+ onMouseMove: () => {
506
+ if (!disabled) setAt(rows.indexOf(item));
507
+ },
508
+ onClick: (e) => run(item, e.metaKey || e.ctrlKey),
509
+ children: [
510
+ item.icon && /* @__PURE__ */ jsx7(Glyph, { name: item.icon, className: "ui-cmdk__ic" }),
511
+ /* @__PURE__ */ jsxs5("span", { className: "ui-cmdk__main", children: [
512
+ /* @__PURE__ */ jsx7("span", { className: "ui-cmdk__label", children: item.label }),
513
+ item.description && /* @__PURE__ */ jsx7("span", { className: "ui-cmdk__desc", children: item.description })
514
+ ] }),
515
+ item.badge && /* @__PURE__ */ jsx7("span", { className: "ui-cmdk__badge", children: item.badge }),
516
+ keysOf(item.shortcut).length > 0 && /* @__PURE__ */ jsx7("span", { className: "ui-cmdk__keys", "aria-hidden": "true", children: keysOf(item.shortcut).map((k) => /* @__PURE__ */ jsx7("kbd", { className: "ui-cmdk__key", children: k }, k)) })
517
+ ]
518
+ },
519
+ item.id
520
+ );
521
+ })
522
+ ]
523
+ },
524
+ group.label ?? `g${gi}`
525
+ )) }),
526
+ /* @__PURE__ */ jsx7("p", { className: "ui-cmdk__empty", hidden: countOf(shown) > 0, children: empty }),
527
+ /* @__PURE__ */ jsx7("p", { className: "ui-sr", role: "status", "aria-live": "polite", children: countOf(shown) === 0 ? "No results" : `${countOf(shown)} result${countOf(shown) === 1 ? "" : "s"}` }),
528
+ hint && /* @__PURE__ */ jsxs5("div", { className: "ui-cmdk__foot", "aria-hidden": "true", children: [
529
+ /* @__PURE__ */ jsxs5("span", { children: [
530
+ /* @__PURE__ */ jsx7("kbd", { className: "ui-cmdk__key", children: "\u2191" }),
531
+ /* @__PURE__ */ jsx7("kbd", { className: "ui-cmdk__key", children: "\u2193" }),
532
+ " move"
533
+ ] }),
534
+ /* @__PURE__ */ jsxs5("span", { children: [
535
+ /* @__PURE__ */ jsx7("kbd", { className: "ui-cmdk__key", children: "\u21B5" }),
536
+ " run"
537
+ ] }),
538
+ /* @__PURE__ */ jsxs5("span", { children: [
539
+ /* @__PURE__ */ jsx7("kbd", { className: "ui-cmdk__key", children: "esc" }),
540
+ " close"
541
+ ] })
542
+ ] })
543
+ ]
544
+ }
545
+ )
167
546
  ] }) }),
168
547
  document.body
169
548
  );
170
549
  }
550
+ var isDisabled = (item) => !!item.disabled || !!item.danger && !item.onConfirm;
551
+ var countOf = (groups) => groups.reduce((t, g) => t + g.items.length, 0);
552
+ function rowId(uid, groups, item) {
553
+ let n = 0;
554
+ for (const group of groups) {
555
+ for (const it of group.items) {
556
+ if (it === item) return `${uid}-o${n}`;
557
+ n += 1;
558
+ }
559
+ }
560
+ return void 0;
561
+ }
171
562
 
172
563
  // src/DataTable.tsx
173
- import { useMemo, useState as useState2 } from "react";
564
+ import { useMemo as useMemo2, useState as useState4 } from "react";
174
565
  import { DEFAULT_PAGE_SIZE as DEFAULT_PAGE_SIZE2 } from "@apliteni/apliteni-ui";
175
566
 
176
567
  // src/Pagination.tsx
177
- import { useEffect as useEffect2, useId, useRef as useRef2, useState } from "react";
568
+ import { useEffect as useEffect3, useId as useId3, useRef as useRef5, useState as useState3 } from "react";
178
569
  import { DEFAULT_PAGE_SIZE } from "@apliteni/apliteni-ui";
179
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
570
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
180
571
  var GHOST_SM = "ui-btn ui-btn--ghost ui-btn--sm";
181
572
  var VARIANTS = ["steps", "numbered", "jump"];
182
- var cx2 = (...a) => a.filter(Boolean).join(" ");
573
+ var cx3 = (...a) => a.filter(Boolean).join(" ");
183
574
  var CAP = Number.MAX_SAFE_INTEGER;
184
575
  var int = (v, fallback) => {
185
576
  const raw = typeof v === "number" ? v : typeof v === "string" && v.trim() !== "" ? Number(v) : NaN;
@@ -218,11 +609,11 @@ function Pagination({
218
609
  onPageChange,
219
610
  onPageSizeChange
220
611
  }) {
221
- const auto = useId();
222
- const [draft, setDraft] = useState("");
223
- const [drafting, setDrafting] = useState(false);
224
- const nav = useRef2(null);
225
- const pressed = useRef2(null);
612
+ const auto = useId3();
613
+ const [draft, setDraft] = useState3("");
614
+ const [drafting, setDrafting] = useState3(false);
615
+ const nav = useRef5(null);
616
+ const pressed = useRef5(null);
226
617
  const uid = id ?? auto;
227
618
  const kind = VARIANTS.includes(variant) ? variant : "steps";
228
619
  const size = sizeOf(pageSize, DEFAULT_PAGE_SIZE);
@@ -231,7 +622,7 @@ function Pagination({
231
622
  const rows = counted ? Math.max(0, asRows) : null;
232
623
  const last = counted ? Math.max(1, Math.ceil(rows / size)) : null;
233
624
  const at = counted ? Math.min(Math.max(1, int(page, 1)), last) : Math.min(Math.max(1, int(page, 1)), CAP - 1);
234
- const [draftFor, setDraftFor] = useState(at);
625
+ const [draftFor, setDraftFor] = useState3(at);
235
626
  if (draftFor !== at) {
236
627
  setDraftFor(at);
237
628
  setDraft("");
@@ -239,7 +630,7 @@ function Pagination({
239
630
  }
240
631
  const offered = (Array.isArray(pageSizes) ? pageSizes : []).slice(0, 12).map((s) => int(s, 0)).filter((s) => s > 0);
241
632
  const sizes = offered.length ? [.../* @__PURE__ */ new Set([...offered, size])].sort((a, b) => a - b) : [];
242
- useEffect2(() => {
633
+ useEffect3(() => {
243
634
  const was = pressed.current;
244
635
  if (!was || loading) return;
245
636
  pressed.current = null;
@@ -268,7 +659,7 @@ function Pagination({
268
659
  const step = (label_, target, disabled) => (
269
660
  // A control at an end is disabled and stays where it is: removing it slides
270
661
  // the next control under a pointer already travelling toward it.
271
- /* @__PURE__ */ jsx6(
662
+ /* @__PURE__ */ jsx8(
272
663
  "button",
273
664
  {
274
665
  type: "button",
@@ -307,19 +698,19 @@ function Pagination({
307
698
  if (single) {
308
699
  steps = null;
309
700
  } else if (!counted) {
310
- steps = /* @__PURE__ */ jsxs4("div", { className: "ui-pager__steps", children: [
701
+ steps = /* @__PURE__ */ jsxs6("div", { className: "ui-pager__steps", children: [
311
702
  step("Prev", Math.max(1, at - 1), atStart),
312
703
  step("Next", at + 1, !hasMore)
313
704
  ] });
314
705
  } else {
315
706
  let middle = null;
316
707
  if (kind === "numbered") {
317
- middle = slotsFor(at, last).map((n, i) => n == null ? /* @__PURE__ */ jsx6("span", { className: "ui-pager__gap", "aria-hidden": "true", children: "\u2026" }, `gap${i}`) : /* @__PURE__ */ jsx6(
708
+ middle = slotsFor(at, last).map((n, i) => n == null ? /* @__PURE__ */ jsx8("span", { className: "ui-pager__gap", "aria-hidden": "true", children: "\u2026" }, `gap${i}`) : /* @__PURE__ */ jsx8(
318
709
  "button",
319
710
  {
320
711
  type: "button",
321
712
  "data-page": n,
322
- className: cx2(`${GHOST_SM} ui-pager__page`, n === at && "is-current"),
713
+ className: cx3(`${GHOST_SM} ui-pager__page`, n === at && "is-current"),
323
714
  "aria-current": n === at ? "page" : void 0,
324
715
  disabled: loading,
325
716
  "aria-disabled": loading ? true : void 0,
@@ -329,9 +720,9 @@ function Pagination({
329
720
  n
330
721
  ));
331
722
  } else if (kind === "jump") {
332
- middle = /* @__PURE__ */ jsxs4("span", { className: "ui-pager__jump", children: [
333
- /* @__PURE__ */ jsx6("label", { htmlFor: `${uid}-jump`, children: "Page" }),
334
- /* @__PURE__ */ jsx6(
723
+ middle = /* @__PURE__ */ jsxs6("span", { className: "ui-pager__jump", children: [
724
+ /* @__PURE__ */ jsx8("label", { htmlFor: `${uid}-jump`, children: "Page" }),
725
+ /* @__PURE__ */ jsx8(
335
726
  "input",
336
727
  {
337
728
  className: "ui-input ui-pager__jump-input",
@@ -354,13 +745,13 @@ function Pagination({
354
745
  }
355
746
  }
356
747
  ),
357
- /* @__PURE__ */ jsxs4("span", { className: "ui-pager__jump-of", children: [
748
+ /* @__PURE__ */ jsxs6("span", { className: "ui-pager__jump-of", children: [
358
749
  "of ",
359
750
  fmt(last)
360
751
  ] })
361
752
  ] });
362
753
  }
363
- steps = /* @__PURE__ */ jsxs4("div", { className: "ui-pager__steps", children: [
754
+ steps = /* @__PURE__ */ jsxs6("div", { className: "ui-pager__steps", children: [
364
755
  ends ? step("First", 1, atStart) : null,
365
756
  step("Prev", Math.max(1, at - 1), atStart),
366
757
  middle,
@@ -368,18 +759,18 @@ function Pagination({
368
759
  ends ? step("Last", last, atEnd) : null
369
760
  ] });
370
761
  }
371
- return /* @__PURE__ */ jsxs4(
762
+ return /* @__PURE__ */ jsxs6(
372
763
  "nav",
373
764
  {
374
765
  ref: nav,
375
- className: cx2("ui-pager", `ui-pager--${kind}`, !counted && "ui-pager--open", single && "ui-pager--single"),
766
+ className: cx3("ui-pager", `ui-pager--${kind}`, !counted && "ui-pager--open", single && "ui-pager--single"),
376
767
  "aria-label": label,
377
768
  "aria-busy": loading ? true : void 0,
378
769
  children: [
379
- /* @__PURE__ */ jsx6("p", { className: "ui-pager__status", "aria-live": "polite", "aria-atomic": "true", children: status }),
380
- sizes.length ? /* @__PURE__ */ jsxs4("div", { className: "ui-pager__size", children: [
381
- /* @__PURE__ */ jsx6("label", { className: "ui-pager__size-label", htmlFor: `${uid}-size`, children: "Rows" }),
382
- /* @__PURE__ */ jsx6(
770
+ /* @__PURE__ */ jsx8("p", { className: "ui-pager__status", "aria-live": "polite", "aria-atomic": "true", children: status }),
771
+ sizes.length ? /* @__PURE__ */ jsxs6("div", { className: "ui-pager__size", children: [
772
+ /* @__PURE__ */ jsx8("label", { className: "ui-pager__size-label", htmlFor: `${uid}-size`, children: "Rows" }),
773
+ /* @__PURE__ */ jsx8(
383
774
  "select",
384
775
  {
385
776
  className: "ui-select ui-pager__size-select",
@@ -387,7 +778,7 @@ function Pagination({
387
778
  disabled: loading,
388
779
  value: size,
389
780
  onChange: (e) => onPageSizeChange?.(Number(e.target.value)),
390
- children: sizes.map((s) => /* @__PURE__ */ jsx6("option", { value: s, children: fmt(s) }, s))
781
+ children: sizes.map((s) => /* @__PURE__ */ jsx8("option", { value: s, children: fmt(s) }, s))
391
782
  }
392
783
  )
393
784
  ] }) : null,
@@ -398,7 +789,7 @@ function Pagination({
398
789
  }
399
790
 
400
791
  // src/DataTable.tsx
401
- import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
792
+ import { Fragment, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
402
793
  var NO_SORT = { key: void 0, dir: -1 };
403
794
  function sortTableRows(rows, sort) {
404
795
  if (sort.key === void 0) return [...rows];
@@ -427,21 +818,21 @@ function DataTable({
427
818
  total,
428
819
  hasMore = false
429
820
  }) {
430
- const [localSort, setLocalSort] = useState2(
821
+ const [localSort, setLocalSort] = useState4(
431
822
  { key: columns.find((c) => c.sortable)?.key, dir: -1 }
432
823
  );
433
824
  const owned = controlledPage === void 0;
434
825
  const sort = controlledSort ?? (owned ? localSort : NO_SORT);
435
826
  const sortIsKnown = owned || controlledSort !== void 0;
436
- const [localPage, setLocalPage] = useState2(1);
437
- const [localSize, setLocalSize] = useState2(DEFAULT_PAGE_SIZE2);
827
+ const [localPage, setLocalPage] = useState4(1);
828
+ const [localSize, setLocalSize] = useState4(DEFAULT_PAGE_SIZE2);
438
829
  const size = sizeOf(pageSize, owned ? localSize : rows.length || DEFAULT_PAGE_SIZE2);
439
- const [pagedSort, setPagedSort] = useState2(sort);
830
+ const [pagedSort, setPagedSort] = useState4(sort);
440
831
  if (pagedSort.key !== sort.key || pagedSort.dir !== sort.dir) {
441
832
  setPagedSort(sort);
442
833
  setLocalPage(1);
443
834
  }
444
- const ordered = useMemo(
835
+ const ordered = useMemo2(
445
836
  () => owned ? sortTableRows(rows, sort) : rows,
446
837
  [owned, rows, sort.key, sort.dir]
447
838
  );
@@ -461,15 +852,15 @@ function DataTable({
461
852
  };
462
853
  const caret = (k) => sort.key === k ? sort.dir === 1 ? " \u25B2" : " \u25BC" : " \u2195";
463
854
  const pageAllOn = selectable && slice.length > 0 && slice.every((r) => selected.has(r.name));
464
- return /* @__PURE__ */ jsxs5(Fragment, { children: [
465
- /* @__PURE__ */ jsxs5(
855
+ return /* @__PURE__ */ jsxs7(Fragment, { children: [
856
+ /* @__PURE__ */ jsxs7(
466
857
  "table",
467
858
  {
468
859
  className: "ui-table ui-table--hover ui-table--zebra",
469
860
  "aria-busy": loading || void 0,
470
861
  children: [
471
- /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
472
- selectable ? /* @__PURE__ */ jsx7("th", { scope: "col", children: /* @__PURE__ */ jsx7(
862
+ /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs7("tr", { children: [
863
+ selectable ? /* @__PURE__ */ jsx9("th", { scope: "col", children: /* @__PURE__ */ jsx9(
473
864
  "input",
474
865
  {
475
866
  type: "checkbox",
@@ -482,23 +873,23 @@ function DataTable({
482
873
  // The sort control is a real <button> inside the header cell. It used to be
483
874
  // role="button" ON the <th>, which threw away the columnheader role and put
484
875
  // aria-sort on a role that forbids it.
485
- /* @__PURE__ */ jsx7(
876
+ /* @__PURE__ */ jsx9(
486
877
  "th",
487
878
  {
488
879
  scope: "col",
489
880
  className: [c.num && "ui-table__num", c.sortable && "rx-sortable"].filter(Boolean).join(" "),
490
881
  "aria-sort": sort.key === c.key ? sort.dir === 1 ? "ascending" : "descending" : c.sortable && sortIsKnown ? "none" : void 0,
491
- children: c.sortable ? /* @__PURE__ */ jsxs5("button", { type: "button", className: "rx-sort", onClick: () => onSort(c.key), children: [
882
+ children: c.sortable ? /* @__PURE__ */ jsxs7("button", { type: "button", className: "rx-sort", onClick: () => onSort(c.key), children: [
492
883
  c.label,
493
- /* @__PURE__ */ jsx7("span", { className: "rx-caret", "aria-hidden": "true", children: caret(c.key) })
884
+ /* @__PURE__ */ jsx9("span", { className: "rx-caret", "aria-hidden": "true", children: caret(c.key) })
494
885
  ] }) : c.label
495
886
  },
496
887
  c.key
497
888
  )
498
889
  ))
499
890
  ] }) }),
500
- /* @__PURE__ */ jsx7("tbody", { children: slice.map((r) => /* @__PURE__ */ jsxs5("tr", { children: [
501
- selectable ? /* @__PURE__ */ jsx7("td", { children: /* @__PURE__ */ jsx7(
891
+ /* @__PURE__ */ jsx9("tbody", { children: slice.map((r) => /* @__PURE__ */ jsxs7("tr", { children: [
892
+ selectable ? /* @__PURE__ */ jsx9("td", { children: /* @__PURE__ */ jsx9(
502
893
  "input",
503
894
  {
504
895
  type: "checkbox",
@@ -507,12 +898,12 @@ function DataTable({
507
898
  onChange: () => onToggle(r.name)
508
899
  }
509
900
  ) }) : null,
510
- columns.map((c) => /* @__PURE__ */ jsx7("td", { className: c.num ? "ui-table__num" : void 0, children: c.render ? c.render(r) : String(r[c.key]) }, c.key))
901
+ columns.map((c) => /* @__PURE__ */ jsx9("td", { className: c.num ? "ui-table__num" : void 0, children: c.render ? c.render(r) : String(r[c.key]) }, c.key))
511
902
  ] }, r.name)) })
512
903
  ]
513
904
  }
514
905
  ),
515
- pager ? /* @__PURE__ */ jsx7(
906
+ pager ? /* @__PURE__ */ jsx9(
516
907
  Pagination,
517
908
  {
518
909
  page,
@@ -537,8 +928,8 @@ function DataTable({
537
928
  import { PAGE_SIZES as KIT_PAGE_SIZES, DEFAULT_PAGE_SIZE as KIT_DEFAULT_PAGE_SIZE } from "@apliteni/apliteni-ui";
538
929
 
539
930
  // src/Loading.tsx
540
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
541
- var cx3 = (...a) => a.filter(Boolean).join(" ");
931
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
932
+ var cx4 = (...a) => a.filter(Boolean).join(" ");
542
933
  function Skeleton({ lines = 3, width, height, radius, className }) {
543
934
  const widths = Array.isArray(lines) ? lines : null;
544
935
  const n = widths ? widths.length : Math.max(1, lines);
@@ -547,19 +938,19 @@ function Skeleton({ lines = 3, width, height, radius, className }) {
547
938
  if (!w && !height && !radius) return void 0;
548
939
  return { ...w && { width: w }, ...height && { height }, ...radius && { borderRadius: radius } };
549
940
  };
550
- return /* @__PURE__ */ jsx8("div", { className: cx3("ui-skel", className), "aria-hidden": "true", children: Array.from({ length: n }, (_, i) => /* @__PURE__ */ jsx8("span", { className: "ui-skel__bar m-skeleton", style: styleFor(i) }, i)) });
941
+ return /* @__PURE__ */ jsx10("div", { className: cx4("ui-skel", className), "aria-hidden": "true", children: Array.from({ length: n }, (_, i) => /* @__PURE__ */ jsx10("span", { className: "ui-skel__bar m-skeleton", style: styleFor(i) }, i)) });
551
942
  }
552
943
  function SkeletonTable({ rows = 5, cols = 4, head = true }) {
553
- const cells = Array.from({ length: Math.max(1, cols) }, (_, i) => /* @__PURE__ */ jsx8("span", { className: "ui-skel__bar m-skeleton" }, i));
554
- return /* @__PURE__ */ jsxs6(
944
+ const cells = Array.from({ length: Math.max(1, cols) }, (_, i) => /* @__PURE__ */ jsx10("span", { className: "ui-skel__bar m-skeleton" }, i));
945
+ return /* @__PURE__ */ jsxs8(
555
946
  "div",
556
947
  {
557
948
  className: "ui-skel ui-skel--table",
558
949
  style: { "--skel-cols": Math.max(1, cols) },
559
950
  "aria-hidden": "true",
560
951
  children: [
561
- head && /* @__PURE__ */ jsx8("div", { className: "ui-skel__row ui-skel__row--head", children: cells }),
562
- Array.from({ length: Math.max(1, rows) }, (_, i) => /* @__PURE__ */ jsx8("div", { className: "ui-skel__row", children: cells }, i))
952
+ head && /* @__PURE__ */ jsx10("div", { className: "ui-skel__row ui-skel__row--head", children: cells }),
953
+ Array.from({ length: Math.max(1, rows) }, (_, i) => /* @__PURE__ */ jsx10("div", { className: "ui-skel__row", children: cells }, i))
563
954
  ]
564
955
  }
565
956
  );
@@ -572,16 +963,16 @@ function BusyRegion({
572
963
  className,
573
964
  children
574
965
  }) {
575
- return /* @__PURE__ */ jsxs6(
966
+ return /* @__PURE__ */ jsxs8(
576
967
  "div",
577
968
  {
578
- className: cx3("ui-busy", className),
969
+ className: cx4("ui-busy", className),
579
970
  role: "status",
580
971
  "aria-live": "polite",
581
972
  "aria-busy": busy,
582
973
  children: [
583
- /* @__PURE__ */ jsx8("span", { className: "ui-sr", children: busy ? label : message }),
584
- /* @__PURE__ */ jsx8("div", { className: "ui-busy__body", children: busy ? placeholder ?? /* @__PURE__ */ jsx8(Skeleton, { lines: 3 }) : children })
974
+ /* @__PURE__ */ jsx10("span", { className: "ui-sr", children: busy ? label : message }),
975
+ /* @__PURE__ */ jsx10("div", { className: "ui-busy__body", children: busy ? placeholder ?? /* @__PURE__ */ jsx10(Skeleton, { lines: 3 }) : children })
585
976
  ]
586
977
  }
587
978
  );
@@ -590,19 +981,19 @@ function Denied({
590
981
  title = "You don\u2019t have access",
591
982
  sub,
592
983
  need,
593
- icon: icon2 = "lock",
984
+ icon: icon3 = "lock",
594
985
  className,
595
986
  children
596
987
  }) {
597
- return /* @__PURE__ */ jsxs6("div", { className: cx3("ui-denied", className), children: [
598
- /* @__PURE__ */ jsx8("div", { className: "ui-denied__seal", children: /* @__PURE__ */ jsx8(Icon, { name: icon2 }) }),
599
- /* @__PURE__ */ jsx8("div", { className: "ui-denied__title", children: title }),
600
- sub && /* @__PURE__ */ jsx8("div", { className: "ui-denied__sub", children: sub }),
601
- need && /* @__PURE__ */ jsxs6("div", { className: "ui-denied__need", children: [
988
+ return /* @__PURE__ */ jsxs8("div", { className: cx4("ui-denied", className), children: [
989
+ /* @__PURE__ */ jsx10("div", { className: "ui-denied__seal", children: /* @__PURE__ */ jsx10(Icon, { name: icon3 }) }),
990
+ /* @__PURE__ */ jsx10("div", { className: "ui-denied__title", children: title }),
991
+ sub && /* @__PURE__ */ jsx10("div", { className: "ui-denied__sub", children: sub }),
992
+ need && /* @__PURE__ */ jsxs8("div", { className: "ui-denied__need", children: [
602
993
  "Needs ",
603
- /* @__PURE__ */ jsx8("code", { className: "ui-code", children: need })
994
+ /* @__PURE__ */ jsx10("code", { className: "ui-code", children: need })
604
995
  ] }),
605
- children && /* @__PURE__ */ jsx8("div", { className: "ui-denied__actions", children })
996
+ children && /* @__PURE__ */ jsx10("div", { className: "ui-denied__actions", children })
606
997
  ] });
607
998
  }
608
999
 
@@ -614,9 +1005,11 @@ export {
614
1005
  BusyRegion,
615
1006
  Button,
616
1007
  Card,
1008
+ CommandPalette,
617
1009
  DEFAULT_PAGE_SIZE3 as DEFAULT_PAGE_SIZE,
618
1010
  DataTable,
619
1011
  Denied,
1012
+ Drawer,
620
1013
  Icon,
621
1014
  Modal,
622
1015
  PAGE_SIZES,