@aortl/admin-react 0.7.0 → 0.8.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.
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export { Breadcrumbs, type BreadcrumbsProps, type BreadcrumbItemProps, type Brea
10
10
  export { Input, type InputProps, type InputVariant, type InputSize } from './Input';
11
11
  export { FileInput, type FileInputProps, type FileInputVariant, type FileInputSize, } from './FileInput';
12
12
  export { InputGroup, type InputGroupProps, type InputGroupAddonProps } from './InputGroup';
13
+ export { Indicator, type IndicatorProps, type IndicatorPlacement, type IndicatorVertical, type IndicatorHorizontal, } from './Indicator';
13
14
  export { Pagination, getPaginationItems, type PaginationProps, type PaginationItem, } from './Pagination';
14
15
  export { Textarea, type TextareaProps, type TextareaVariant, type TextareaSize } from './Textarea';
15
16
  export { Checkbox, type CheckboxProps, type CheckboxIndicatorProps } from './Checkbox';
@@ -25,6 +26,8 @@ export { Footer, type FooterProps, type FooterLinksProps, type FooterLinkProps,
25
26
  export { Menu, type MenuProps, type MenuTriggerProps, type MenuPopupProps, type MenuItemProps, type MenuSeparatorProps, type MenuGroupProps, type MenuGroupLabelProps, } from './Menu';
26
27
  export { Navbar, type NavbarProps, type NavbarBrandProps, type NavbarItemsProps, type NavbarItemProps, type NavbarDropdownProps, type NavbarActionsProps, type NavbarMobileToggleProps, } from './Navbar';
27
28
  export { Tabs, type TabsProps, type TabsVariant, type TabsSize, type TabsListProps, type TabsTabProps, type TabsPanelProps, type TabsIndicatorProps, } from './Tabs';
29
+ export { Kbd, type KbdProps } from './Kbd';
30
+ export { useHotkey, type HotkeyOptions } from './useHotkey';
28
31
  export { Tooltip, type TooltipProps, type TooltipProviderProps, type TooltipRootProps, type TooltipTriggerProps, type TooltipPopupProps, type TooltipSize, } from './Tooltip';
29
32
  export { PropertyList, type PropertyListProps, type PropertyListItemProps, type PropertyListLabelProps, type PropertyListValueProps, } from './PropertyList';
30
33
  export { Table, type TableProps, type TableAlign, type TableHeadProps, type TableBodyProps, type TableFootProps, type TableRowProps, type TableHeaderCellProps, type TableCellProps, } from './Table';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -80,14 +80,16 @@ function AdminRoot({ className, theme, systemAccent, style, ...rest }) {
80
80
  //#endregion
81
81
  //#region src/icon.ts
82
82
  /**
83
- * Render an `IconProp` to a React node, defaulting to `size={16} aria-hidden`
84
- * when given a component reference.
83
+ * Render an `IconProp` to a React node, defaulting to `size="1em" aria-hidden`
84
+ * when given a component reference. The `"1em"` default makes SVG icons inherit
85
+ * the host's `font-size`, matching how the Tabler webfont (`<i class="ti …">`)
86
+ * renders in the vanilla bundle — so both previews end up the same size.
85
87
  *
86
88
  * Anything that is not `null`/`undefined` and not already a React element is
87
89
  * treated as a component type — `createElement` accepts function components,
88
90
  * `forwardRef`s (e.g. `@tabler/icons-react`), `memo`, etc.
89
91
  */
90
- function renderIcon(icon, size = 16) {
92
+ function renderIcon(icon, size = "1em") {
91
93
  if (icon == null) return null;
92
94
  if (isValidElement(icon)) return icon;
93
95
  return createElement(icon, {
@@ -198,13 +200,261 @@ function BrandTile({ monogram, icon, className, children, ...rest }) {
198
200
  });
199
201
  }
200
202
  //#endregion
203
+ //#region src/hotkey-parse.ts
204
+ var MOD_ORDER = [
205
+ "ctrl",
206
+ "shift",
207
+ "alt",
208
+ "meta"
209
+ ];
210
+ function tokenToMod(token) {
211
+ switch (token) {
212
+ case "mod":
213
+ case "ctrl":
214
+ case "control": return "ctrl";
215
+ case "shift": return "shift";
216
+ case "alt": return "alt";
217
+ case "meta": return "meta";
218
+ default: return null;
219
+ }
220
+ }
221
+ function parseChord(input) {
222
+ const tokens = input.trim().toLowerCase().split("+").map((t) => t.trim()).filter(Boolean);
223
+ if (tokens.length === 0) throw new Error(`Invalid hotkey: empty string`);
224
+ const mods = /* @__PURE__ */ new Set();
225
+ let key = null;
226
+ for (const token of tokens) {
227
+ const mod = tokenToMod(token);
228
+ if (mod !== null) {
229
+ mods.add(mod);
230
+ continue;
231
+ }
232
+ if (key !== null) throw new Error(`Invalid hotkey "${input}": multiple non-modifier keys`);
233
+ key = token;
234
+ }
235
+ if (key === null) throw new Error(`Invalid hotkey "${input}": missing key`);
236
+ return {
237
+ mods,
238
+ key
239
+ };
240
+ }
241
+ function parseKeys(keys) {
242
+ return (typeof keys === "string" ? [keys] : keys).map(parseChord);
243
+ }
244
+ /** Canonical wire form used as a map key in the registry. */
245
+ function canonicalize(chord) {
246
+ const parts = [];
247
+ for (const mod of MOD_ORDER) if (chord.mods.has(mod)) parts.push(mod);
248
+ parts.push(chord.key);
249
+ return parts.join("+");
250
+ }
251
+ /**
252
+ * Normalize a keyboard event to its canonical chord string. Returns `null`
253
+ * if the event is a bare modifier press (`Shift` by itself, etc.) so callers
254
+ * can short-circuit before a map lookup.
255
+ */
256
+ function normalizeEvent(e) {
257
+ const key = e.key.toLowerCase();
258
+ if (key === "control" || key === "shift" || key === "alt" || key === "meta") return null;
259
+ const mods = /* @__PURE__ */ new Set();
260
+ if (e.ctrlKey) mods.add("ctrl");
261
+ if (e.shiftKey) mods.add("shift");
262
+ if (e.altKey) mods.add("alt");
263
+ if (e.metaKey) mods.add("meta");
264
+ return canonicalize({
265
+ mods,
266
+ key
267
+ });
268
+ }
269
+ var SPECIAL_KEY_LABELS = {
270
+ escape: "Esc",
271
+ esc: "Esc",
272
+ enter: "Enter",
273
+ return: "Enter",
274
+ tab: "Tab",
275
+ " ": "Space",
276
+ space: "Space",
277
+ arrowup: "↑",
278
+ arrowdown: "↓",
279
+ arrowleft: "←",
280
+ arrowright: "→",
281
+ backspace: "Backspace",
282
+ delete: "Del"
283
+ };
284
+ var MOD_LABELS = {
285
+ ctrl: "Ctrl",
286
+ shift: "Shift",
287
+ alt: "Alt",
288
+ meta: "Meta"
289
+ };
290
+ /** Visual chips for a chord — one entry per modifier and the final key. */
291
+ function formatChord(chord) {
292
+ const parts = [];
293
+ for (const mod of MOD_ORDER) if (chord.mods.has(mod)) parts.push(MOD_LABELS[mod]);
294
+ const special = SPECIAL_KEY_LABELS[chord.key];
295
+ if (special !== void 0) parts.push(special);
296
+ else if (chord.key.length === 1) parts.push(chord.key.toUpperCase());
297
+ else parts.push(chord.key.charAt(0).toUpperCase() + chord.key.slice(1));
298
+ return parts;
299
+ }
300
+ var ARIA_MOD_LABELS = {
301
+ ctrl: "Control",
302
+ shift: "Shift",
303
+ alt: "Alt",
304
+ meta: "Meta"
305
+ };
306
+ function toAriaPart(chord) {
307
+ const parts = [];
308
+ for (const mod of MOD_ORDER) if (chord.mods.has(mod)) parts.push(ARIA_MOD_LABELS[mod]);
309
+ parts.push(chord.key.length === 1 ? chord.key.toUpperCase() : chord.key);
310
+ return parts.join("+");
311
+ }
312
+ /**
313
+ * Serialize one or more chords to the `aria-keyshortcuts` format
314
+ * (space-separated alternatives, modifiers as `Control`/`Shift`/etc.).
315
+ */
316
+ function toAriaKeyShortcuts(chords) {
317
+ return chords.map(toAriaPart).join(" ");
318
+ }
319
+ //#endregion
320
+ //#region src/Kbd.tsx
321
+ /**
322
+ * Visual representation of a keyboard shortcut. Two shapes:
323
+ *
324
+ * ```tsx
325
+ * <Kbd keys="mod+s" /> // parsed: <Ctrl><S> in a .kbd-group
326
+ * <Kbd>Esc</Kbd> // literal: single <kbd>Esc</kbd>
327
+ * ```
328
+ *
329
+ * Render outside of action surfaces (tooltips, help dialogs) or inside them
330
+ * via the `hotkey` prop on `<Button>` / `<Menu.Item>`.
331
+ */
332
+ function Kbd({ keys, children, className, ...rest }) {
333
+ if (keys != null) {
334
+ const chord = parseKeys(keys)[0];
335
+ if (!chord) return null;
336
+ const parts = formatChord(chord);
337
+ return /* @__PURE__ */ jsx("span", {
338
+ className: cn("kbd-group", className),
339
+ ...rest,
340
+ children: parts.map((part, i) => /* @__PURE__ */ jsx("kbd", {
341
+ className: cn("kbd", void 0),
342
+ children: part
343
+ }, `${i}-${part}`))
344
+ });
345
+ }
346
+ return /* @__PURE__ */ jsx("kbd", {
347
+ className: cn("kbd", className),
348
+ ...rest,
349
+ children
350
+ });
351
+ }
352
+ //#endregion
353
+ //#region src/hotkey-registry.ts
354
+ var registry = /* @__PURE__ */ new Map();
355
+ var listenerAttached = false;
356
+ function ensureListener() {
357
+ if (listenerAttached || typeof window === "undefined") return;
358
+ window.addEventListener("keydown", dispatch);
359
+ listenerAttached = true;
360
+ }
361
+ function maybeDetachListener() {
362
+ if (!listenerAttached || typeof window === "undefined") return;
363
+ if (registry.size > 0) return;
364
+ window.removeEventListener("keydown", dispatch);
365
+ listenerAttached = false;
366
+ }
367
+ function isEditableTarget(target) {
368
+ if (!(target instanceof HTMLElement)) return false;
369
+ if (target.isContentEditable) return true;
370
+ const tag = target.tagName;
371
+ return tag === "INPUT" || tag === "TEXTAREA";
372
+ }
373
+ function dispatch(e) {
374
+ const chord = normalizeEvent(e);
375
+ if (chord === null) return;
376
+ const bucket = registry.get(chord);
377
+ if (!bucket || bucket.size === 0) return;
378
+ if (isEditableTarget(e.target) && !chord.includes("+") && chord !== "escape") return;
379
+ e.preventDefault();
380
+ for (const entry of bucket) entry.handlerRef.current?.(e);
381
+ }
382
+ /**
383
+ * Register a hotkey entry under each of its canonical chord strings.
384
+ * Returns an unregister function that removes the entry from every bucket
385
+ * and detaches the listener if the registry is empty.
386
+ */
387
+ function register(canonicalChords, entry) {
388
+ for (const chord of canonicalChords) {
389
+ let bucket = registry.get(chord);
390
+ if (!bucket) {
391
+ bucket = /* @__PURE__ */ new Set();
392
+ registry.set(chord, bucket);
393
+ }
394
+ bucket.add(entry);
395
+ }
396
+ ensureListener();
397
+ return () => {
398
+ for (const chord of canonicalChords) {
399
+ const bucket = registry.get(chord);
400
+ if (!bucket) continue;
401
+ bucket.delete(entry);
402
+ if (bucket.size === 0) registry.delete(chord);
403
+ }
404
+ maybeDetachListener();
405
+ };
406
+ }
407
+ //#endregion
408
+ //#region src/useHotkey.ts
409
+ /**
410
+ * Register a keyboard shortcut. The handler is latched in a ref internally so
411
+ * callers don't need to memoize it. Passing nullish `keys` is a no-op, so
412
+ * the hook is safe to call unconditionally from components that may or may
413
+ * not have a binding (e.g. the `hotkey` prop on `<Button>`).
414
+ *
415
+ * @example
416
+ * useHotkey("mod+s", save);
417
+ * useHotkey(["mod+s", "mod+enter"], save, { enabled: !isLoading });
418
+ *
419
+ * Returns derived strings for rendering — see {@link HotkeyInfo}.
420
+ */
421
+ function useHotkey(keys, handler, options) {
422
+ const enabled = options?.enabled ?? true;
423
+ const handlerRef = useRef(handler);
424
+ handlerRef.current = handler;
425
+ const keyId = keys == null ? "" : Array.isArray(keys) ? keys.join("|") : keys;
426
+ const derived = useMemo(() => {
427
+ if (keyId === "") return {
428
+ canonicalChords: [],
429
+ ariaKeyShortcuts: void 0,
430
+ primaryChord: void 0
431
+ };
432
+ const parsed = parseKeys(keys);
433
+ const cans = parsed.map(canonicalize);
434
+ return {
435
+ canonicalChords: cans,
436
+ ariaKeyShortcuts: toAriaKeyShortcuts(parsed),
437
+ primaryChord: cans[0]
438
+ };
439
+ }, [keyId]);
440
+ useEffect(() => {
441
+ if (!enabled || derived.canonicalChords.length === 0) return;
442
+ const entry = { handlerRef };
443
+ return register(derived.canonicalChords, entry);
444
+ }, [derived, enabled]);
445
+ return derived;
446
+ }
447
+ //#endregion
201
448
  //#region src/Button.tsx
202
- function Button({ variant = "primary", size = "md", fullWidth, loading, icon, iconTrailing, className, type = "button", disabled, children, ...rest }) {
449
+ function Button({ variant = "primary", size = "md", fullWidth, loading, icon, iconTrailing, hotkey, className, type = "button", disabled, children, onClick, ...rest }) {
450
+ const { ariaKeyShortcuts, primaryChord } = useHotkey(hotkey, (e) => onClick?.(e), { enabled: !disabled && !loading });
203
451
  const iconOnly = children == null && (icon != null || iconTrailing != null);
204
452
  return /* @__PURE__ */ jsxs(Button$1, {
453
+ onClick,
205
454
  type,
206
455
  disabled: disabled || loading,
207
456
  "aria-busy": loading || void 0,
457
+ "aria-keyshortcuts": ariaKeyShortcuts,
208
458
  className: cn([
209
459
  "btn",
210
460
  `btn-${variant}`,
@@ -217,7 +467,8 @@ function Button({ variant = "primary", size = "md", fullWidth, loading, icon, ic
217
467
  children: [
218
468
  loading ? null : renderIcon(icon),
219
469
  children,
220
- renderIcon(iconTrailing)
470
+ renderIcon(iconTrailing),
471
+ primaryChord !== void 0 ? /* @__PURE__ */ jsx(Kbd, { keys: primaryChord }) : null
221
472
  ]
222
473
  });
223
474
  }
@@ -314,6 +565,38 @@ function InputGroupAddon({ className, ...rest }) {
314
565
  }
315
566
  var InputGroup = Object.assign(InputGroupRoot, { Addon: InputGroupAddon });
316
567
  //#endregion
568
+ //#region src/Indicator.tsx
569
+ function Indicator({ label, variant = "neutral", size = "sm", icon, placement = "top-end", offset, className, "aria-label": ariaLabel, children }) {
570
+ const [vertical, horizontal] = placement.split("-");
571
+ const placementClasses = [
572
+ "indicator-item",
573
+ vertical !== "top" && `indicator-${vertical}`,
574
+ horizontal !== "end" && `indicator-${horizontal}`
575
+ ];
576
+ const hasContent = label !== void 0 || icon !== void 0;
577
+ const style = offset !== void 0 ? { "--indicator-offset": `${offset}px` } : void 0;
578
+ return /* @__PURE__ */ jsxs("div", {
579
+ className: cn("indicator", className),
580
+ style,
581
+ children: [hasContent ? /* @__PURE__ */ jsx(Badge, {
582
+ className: cn(placementClasses, void 0),
583
+ variant,
584
+ size,
585
+ icon,
586
+ "aria-label": ariaLabel,
587
+ children: label
588
+ }) : /* @__PURE__ */ jsx("span", {
589
+ className: cn([
590
+ ...placementClasses,
591
+ "indicator-dot",
592
+ variant !== "neutral" && `indicator-dot-${variant}`
593
+ ], void 0),
594
+ role: ariaLabel !== void 0 ? "status" : void 0,
595
+ "aria-label": ariaLabel
596
+ }), children]
597
+ });
598
+ }
599
+ //#endregion
317
600
  //#region src/Pagination.tsx
318
601
  /**
319
602
  * Compute the items to render for a given `page` / `total`. Always returns:
@@ -577,6 +860,16 @@ function SwitchThumb({ className, ...rest }) {
577
860
  }
578
861
  var Switch = Object.assign(SwitchRoot, { Thumb: SwitchThumb });
579
862
  //#endregion
863
+ //#region src/portal-context.ts
864
+ /**
865
+ * Container that Base UI popups (Select, Tooltip, etc.) should portal into.
866
+ * When a `<Dialog>` ancestor publishes its `<dialog>` element through this
867
+ * context, popups render inside that top-layer dialog so they paint above
868
+ * the backdrop and escape its `overflow: hidden`. Outside a dialog the
869
+ * context is null and popups portal to `document.body` as before.
870
+ */
871
+ var PortalContainerContext = createContext(null);
872
+ //#endregion
580
873
  //#region src/Select.tsx
581
874
  function SelectRoot(props) {
582
875
  return /* @__PURE__ */ jsx(Select$1.Root, { ...props });
@@ -602,14 +895,19 @@ function SelectIcon({ className, children, ...rest }) {
602
895
  });
603
896
  }
604
897
  function SelectPopup({ className, sideOffset = 4, children, ...rest }) {
605
- return /* @__PURE__ */ jsx(Select$1.Portal, { children: /* @__PURE__ */ jsx(Select$1.Positioner, {
606
- sideOffset,
607
- children: /* @__PURE__ */ jsx(Select$1.Popup, {
608
- className: cn("select-popup", className),
609
- ...rest,
610
- children
898
+ const portalContainer = useContext(PortalContainerContext);
899
+ return /* @__PURE__ */ jsx(Select$1.Portal, {
900
+ container: portalContainer ?? void 0,
901
+ children: /* @__PURE__ */ jsx(Select$1.Positioner, {
902
+ sideOffset,
903
+ alignItemWithTrigger: false,
904
+ children: /* @__PURE__ */ jsx(Select$1.Popup, {
905
+ className: cn("select-popup", className),
906
+ ...rest,
907
+ children
908
+ })
611
909
  })
612
- }) });
910
+ });
613
911
  }
614
912
  function SelectItem({ className, ...rest }) {
615
913
  return /* @__PURE__ */ jsx(Select$1.Item, {
@@ -801,12 +1099,15 @@ function DialogContainer({ open, onOpenChange, size = "md", closedby = "any", cl
801
1099
  }, []);
802
1100
  return /* @__PURE__ */ jsx(DialogContext.Provider, {
803
1101
  value: { close: () => ref.current?.close() },
804
- children: /* @__PURE__ */ jsx("dialog", {
805
- ref,
806
- className: cn(["dialog", size !== "md" && `dialog-${size}`], className),
807
- closedby,
808
- ...rest,
809
- children
1102
+ children: /* @__PURE__ */ jsx(PortalContainerContext.Provider, {
1103
+ value: ref,
1104
+ children: /* @__PURE__ */ jsx("dialog", {
1105
+ ref,
1106
+ className: cn(["dialog", size !== "md" && `dialog-${size}`], className),
1107
+ closedby,
1108
+ ...rest,
1109
+ children
1110
+ })
810
1111
  })
811
1112
  });
812
1113
  }
@@ -971,22 +1272,37 @@ function MenuPopup({ className, role = "menu", ...rest }) {
971
1272
  });
972
1273
  }
973
1274
  function MenuItem(props) {
1275
+ const ref = useRef(null);
1276
+ const hotkey = props.hotkey;
1277
+ const { ariaKeyShortcuts, primaryChord } = useHotkey(hotkey, () => ref.current?.click(), { enabled: !("disabled" in props && props.disabled) });
974
1278
  if (props.href !== void 0) {
975
- const { className, role = "menuitem", icon, children, ...rest } = props;
1279
+ const { className, role = "menuitem", icon, children, hotkey: _hk, ...rest } = props;
976
1280
  return /* @__PURE__ */ jsxs("a", {
1281
+ ref,
977
1282
  role,
1283
+ "aria-keyshortcuts": ariaKeyShortcuts,
978
1284
  className: cn("menu-item", className),
979
1285
  ...rest,
980
- children: [renderIcon(icon), children]
1286
+ children: [
1287
+ renderIcon(icon),
1288
+ children,
1289
+ primaryChord !== void 0 ? /* @__PURE__ */ jsx(Kbd, { keys: primaryChord }) : null
1290
+ ]
981
1291
  });
982
1292
  }
983
- const { className, type = "button", role = "menuitem", icon, children, ...rest } = props;
1293
+ const { className, type = "button", role = "menuitem", icon, children, hotkey: _hk, ...rest } = props;
984
1294
  return /* @__PURE__ */ jsxs("button", {
1295
+ ref,
985
1296
  type,
986
1297
  role,
1298
+ "aria-keyshortcuts": ariaKeyShortcuts,
987
1299
  className: cn("menu-item", className),
988
1300
  ...rest,
989
- children: [renderIcon(icon), children]
1301
+ children: [
1302
+ renderIcon(icon),
1303
+ children,
1304
+ primaryChord !== void 0 ? /* @__PURE__ */ jsx(Kbd, { keys: primaryChord }) : null
1305
+ ]
990
1306
  });
991
1307
  }
992
1308
  function MenuSeparator({ className, ...rest }) {
@@ -1135,17 +1451,21 @@ function TooltipTrigger(props) {
1135
1451
  return /* @__PURE__ */ jsx(Tooltip$1.Trigger, { ...props });
1136
1452
  }
1137
1453
  function TooltipPopup({ size = "md", side = "top", align = "center", sideOffset = 6, role = "tooltip", className, children, ...rest }) {
1138
- return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(Tooltip$1.Positioner, {
1139
- sideOffset,
1140
- side,
1141
- align,
1142
- children: /* @__PURE__ */ jsx(Tooltip$1.Popup, {
1143
- role,
1144
- className: cn(["tooltip", size !== "md" && `tooltip-${size}`], className),
1145
- ...rest,
1146
- children
1454
+ const portalContainer = useContext(PortalContainerContext);
1455
+ return /* @__PURE__ */ jsx(Tooltip$1.Portal, {
1456
+ container: portalContainer ?? void 0,
1457
+ children: /* @__PURE__ */ jsx(Tooltip$1.Positioner, {
1458
+ sideOffset,
1459
+ side,
1460
+ align,
1461
+ children: /* @__PURE__ */ jsx(Tooltip$1.Popup, {
1462
+ role,
1463
+ className: cn(["tooltip", size !== "md" && `tooltip-${size}`], className),
1464
+ ...rest,
1465
+ children
1466
+ })
1147
1467
  })
1148
- }) });
1468
+ });
1149
1469
  }
1150
1470
  function TooltipShorthand({ content, side, align, sideOffset, size, children, ...rootProps }) {
1151
1471
  return /* @__PURE__ */ jsxs(TooltipRoot, {
@@ -1199,12 +1519,12 @@ function CheckGlyph({ className }) {
1199
1519
  children: /* @__PURE__ */ jsx("path", { d: "M5 12l5 5l10 -10" })
1200
1520
  });
1201
1521
  }
1202
- function PropertyListRoot({ striped, copyable, hideIfAllEmpty, title, className, children, ...rest }) {
1522
+ function PropertyListRoot({ striped, compact, hideIfAllEmpty, title, className, children, ...rest }) {
1203
1523
  return /* @__PURE__ */ jsxs("section", {
1204
1524
  className: cn([
1205
1525
  "property-list",
1206
1526
  striped && "property-list-striped",
1207
- copyable && "property-list-copyable",
1527
+ compact && "property-list-compact",
1208
1528
  hideIfAllEmpty && "property-list-hide-if-empty"
1209
1529
  ], className),
1210
1530
  ...rest,
@@ -1506,6 +1826,6 @@ var Sidebar = Object.assign(SidebarRoot, {
1506
1826
  CollapseToggle: SidebarCollapseToggle
1507
1827
  });
1508
1828
  //#endregion
1509
- export { Accordion, AdminRoot, Alert, AppShell, Badge, BrandTile, Breadcrumbs, Button, ButtonGroup, Card, Checkbox, Dialog, Field, FileInput, Footer, Input, InputGroup, Menu, Navbar, Pagination, Progress, PropertyList, Radio, RadioGroup, Select, Sidebar, Spinner, Switch, Table, Tabs, Textarea, Tooltip, getPaginationItems, useAppShell };
1829
+ export { Accordion, AdminRoot, Alert, AppShell, Badge, BrandTile, Breadcrumbs, Button, ButtonGroup, Card, Checkbox, Dialog, Field, FileInput, Footer, Indicator, Input, InputGroup, Kbd, Menu, Navbar, Pagination, Progress, PropertyList, Radio, RadioGroup, Select, Sidebar, Spinner, Switch, Table, Tabs, Textarea, Tooltip, getPaginationItems, useAppShell, useHotkey };
1510
1830
 
1511
1831
  //# sourceMappingURL=index.mjs.map