@orianatech/pire 0.16.0 → 0.17.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.cjs CHANGED
@@ -45,12 +45,17 @@ __export(src_exports, {
45
45
  DateRangePicker: () => DateRangePicker,
46
46
  DescriptionList: () => DescriptionList,
47
47
  Dialog: () => Dialog,
48
+ DialogActions: () => DialogActions,
49
+ DialogBody: () => DialogBody,
50
+ DialogDescription: () => DialogDescription,
51
+ DialogTitle: () => DialogTitle,
48
52
  DialogTrigger: () => import_react_aria_components34.DialogTrigger,
49
53
  DonutChart: () => DonutChart,
50
54
  EmptyState: () => EmptyState,
51
55
  FileDropZone: () => FileDropZone,
52
56
  FileUpload: () => FileUpload,
53
57
  FilterBar: () => FilterBar,
58
+ Focusable: () => import_react_aria_components35.Focusable,
54
59
  FooterBar: () => FooterBar,
55
60
  FormField: () => FormField,
56
61
  Heading: () => Heading,
@@ -524,15 +529,17 @@ var Button = React.forwardRef(function Button2({ children, variant = "secondary"
524
529
  });
525
530
 
526
531
  // src/components/core/IconButton.tsx
527
- var React2 = __toESM(require("react"), 1);
532
+ var React3 = __toESM(require("react"), 1);
528
533
  var import_react_aria_components3 = require("react-aria-components");
529
534
 
530
535
  // src/components/feedback/Tooltip.tsx
536
+ var React2 = __toESM(require("react"), 1);
531
537
  var import_react_aria_components2 = require("react-aria-components");
532
538
  var import_jsx_runtime3 = require("react/jsx-runtime");
533
539
  function Tooltip({ label, placement = "top", delay = 500, children }) {
540
+ const target = React2.isValidElement(children) ? React2.cloneElement(children, { className: cx(children.props.className, "pire-tooltip-target") }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pire-tooltip-target", children });
534
541
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_aria_components2.TooltipTrigger, { delay, closeDelay: 0, children: [
535
- children,
542
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_aria_components2.Focusable, { children: target }),
536
543
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_aria_components2.Tooltip, { className: "pire-tooltip", placement, offset: 6, children: [
537
544
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_aria_components2.OverlayArrow, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", {}) }),
538
545
  label
@@ -542,7 +549,7 @@ function Tooltip({ label, placement = "top", delay = 500, children }) {
542
549
 
543
550
  // src/components/core/IconButton.tsx
544
551
  var import_jsx_runtime4 = require("react/jsx-runtime");
545
- var IconButton = React2.forwardRef(function IconButton2({
552
+ var IconButton = React3.forwardRef(function IconButton2({
546
553
  icon,
547
554
  label,
548
555
  size = "md",
@@ -630,11 +637,11 @@ function Card({ title, subtitle, icon, actions, footer, interactive, children, c
630
637
  }
631
638
 
632
639
  // src/components/core/Avatar.tsx
633
- var React3 = __toESM(require("react"), 1);
640
+ var React4 = __toESM(require("react"), 1);
634
641
  var import_jsx_runtime8 = require("react/jsx-runtime");
635
642
  var initials = (name) => name.trim().split(/\s+/).slice(0, 2).map((p) => p[0]).join("").toUpperCase();
636
643
  function Avatar({ name, size = "md", src, className, ...rest }) {
637
- const [failed, setFailed] = React3.useState(false);
644
+ const [failed, setFailed] = React4.useState(false);
638
645
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: cx("pire-avatar", className), "data-size": size, role: "img", "aria-label": name, ...rest, children: src && !failed ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
639
646
  "img",
640
647
  {
@@ -647,7 +654,7 @@ function Avatar({ name, size = "md", src, className, ...rest }) {
647
654
  }
648
655
 
649
656
  // src/components/core/SegmentedControl.tsx
650
- var React4 = __toESM(require("react"), 1);
657
+ var React5 = __toESM(require("react"), 1);
651
658
  var import_react_aria_components5 = require("react-aria-components");
652
659
  var import_jsx_runtime9 = require("react/jsx-runtime");
653
660
  function SegmentedControl({
@@ -661,7 +668,7 @@ function SegmentedControl({
661
668
  style,
662
669
  ...rest
663
670
  }) {
664
- const selected = React4.useMemo(() => new Set(value ? [value] : defaultValue ? [defaultValue] : []), [value, defaultValue]);
671
+ const selected = React5.useMemo(() => new Set(value ? [value] : defaultValue ? [defaultValue] : []), [value, defaultValue]);
665
672
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
666
673
  import_react_aria_components5.ToggleButtonGroup,
667
674
  {
@@ -823,11 +830,11 @@ function FormField({ label, htmlFor, isRequired, hint, error, layout = "stacked"
823
830
  }
824
831
 
825
832
  // src/components/forms/Input.tsx
826
- var React6 = __toESM(require("react"), 1);
833
+ var React7 = __toESM(require("react"), 1);
827
834
  var import_react_aria_components9 = require("react-aria-components");
828
835
 
829
836
  // src/i18n/PireIntlProvider.tsx
830
- var React5 = __toESM(require("react"), 1);
837
+ var React6 = __toESM(require("react"), 1);
831
838
 
832
839
  // src/i18n/messages.ts
833
840
  var enMessages = {
@@ -837,6 +844,7 @@ var enMessages = {
837
844
  dataTableSelectAll: "Select all rows",
838
845
  dataTableSelectRow: "Select row",
839
846
  dataTableLoading: "Loading records",
847
+ dataTableSummaryRow: "Summary",
840
848
  dialogClose: "Close",
841
849
  sidePanelClose: "Close panel",
842
850
  inlineMessageDismiss: "Dismiss message",
@@ -892,6 +900,7 @@ var esMessages = {
892
900
  dataTableSelectAll: "Seleccionar todas las filas",
893
901
  dataTableSelectRow: "Seleccionar fila",
894
902
  dataTableLoading: "Cargando registros",
903
+ dataTableSummaryRow: "Resumen",
895
904
  dialogClose: "Cerrar",
896
905
  sidePanelClose: "Cerrar panel",
897
906
  inlineMessageDismiss: "Descartar mensaje",
@@ -943,19 +952,19 @@ var esMessages = {
943
952
 
944
953
  // src/i18n/PireIntlProvider.tsx
945
954
  var import_jsx_runtime16 = require("react/jsx-runtime");
946
- var MessagesContext = React5.createContext(enMessages);
955
+ var MessagesContext = React6.createContext(enMessages);
947
956
  function PireIntlProvider({ messages, children }) {
948
- const value = React5.useMemo(
957
+ const value = React6.useMemo(
949
958
  () => messages ? { ...enMessages, ...messages } : enMessages,
950
959
  [messages]
951
960
  );
952
961
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessagesContext.Provider, { value, children });
953
962
  }
954
963
  function usePireMessages() {
955
- return React5.useContext(MessagesContext);
964
+ return React6.useContext(MessagesContext);
956
965
  }
957
966
  function useMessage(key, override) {
958
- const messages = React5.useContext(MessagesContext);
967
+ const messages = React6.useContext(MessagesContext);
959
968
  return override ?? messages[key];
960
969
  }
961
970
 
@@ -980,7 +989,7 @@ function Input({
980
989
  }) {
981
990
  const msg = usePireMessages();
982
991
  const isControlled = rest.value !== void 0;
983
- const [ownValue, setOwnValue] = React6.useState(rest.defaultValue ?? "");
992
+ const [ownValue, setOwnValue] = React7.useState(rest.defaultValue ?? "");
984
993
  const currentValue = isControlled ? rest.value : ownValue;
985
994
  const handleChange = (next) => {
986
995
  setOwnValue(next);
@@ -1027,10 +1036,10 @@ function Input({
1027
1036
  }
1028
1037
 
1029
1038
  // src/components/forms/TextArea.tsx
1030
- var React7 = __toESM(require("react"), 1);
1039
+ var React8 = __toESM(require("react"), 1);
1031
1040
  var import_react_aria_components10 = require("react-aria-components");
1032
1041
  var import_jsx_runtime18 = require("react/jsx-runtime");
1033
- var useIsomorphicLayoutEffect = typeof document === "undefined" ? React7.useEffect : React7.useLayoutEffect;
1042
+ var useIsomorphicLayoutEffect = typeof document === "undefined" ? React8.useEffect : React8.useLayoutEffect;
1034
1043
  function TextArea({
1035
1044
  label,
1036
1045
  description,
@@ -1046,13 +1055,13 @@ function TextArea({
1046
1055
  onChange,
1047
1056
  ...rest
1048
1057
  }) {
1049
- const innerRef = React7.useRef(null);
1050
- const ref = React7.useCallback((node) => {
1058
+ const innerRef = React8.useRef(null);
1059
+ const ref = React8.useCallback((node) => {
1051
1060
  innerRef.current = node;
1052
1061
  if (typeof textAreaRef === "function") textAreaRef(node);
1053
1062
  else if (textAreaRef) textAreaRef.current = node;
1054
1063
  }, [textAreaRef]);
1055
- const grow = React7.useCallback(() => {
1064
+ const grow = React8.useCallback(() => {
1056
1065
  const el = innerRef.current;
1057
1066
  if (!el || !autoGrow) return;
1058
1067
  const styles = getComputedStyle(el);
@@ -1312,7 +1321,7 @@ function ComboBox({
1312
1321
  }
1313
1322
 
1314
1323
  // src/components/forms/MultiComboBox.tsx
1315
- var React8 = __toESM(require("react"), 1);
1324
+ var React9 = __toESM(require("react"), 1);
1316
1325
  var import_react_aria_components16 = require("react-aria-components");
1317
1326
  var import_jsx_runtime24 = require("react/jsx-runtime");
1318
1327
  var norm3 = (o) => typeof o === "string" ? { value: o, label: o } : o;
@@ -1338,15 +1347,15 @@ function MultiComboBox({
1338
1347
  ...rest
1339
1348
  }) {
1340
1349
  const msg = usePireMessages();
1341
- const items = React8.useMemo(() => options.map(norm3), [options]);
1350
+ const items = React9.useMemo(() => options.map(norm3), [options]);
1342
1351
  const collection = isFilteredExternally ? { items } : { defaultItems: items };
1343
1352
  const showsStatus = isLoading || isFilteredExternally && items.length === 0 && emptyLabel != null;
1344
- const [uncontrolled, setUncontrolled] = React8.useState(defaultValue ?? []);
1345
- const [announcement, setAnnouncement] = React8.useState("");
1346
- const inputRef = React8.useRef(null);
1353
+ const [uncontrolled, setUncontrolled] = React9.useState(defaultValue ?? []);
1354
+ const [announcement, setAnnouncement] = React9.useState("");
1355
+ const inputRef = React9.useRef(null);
1347
1356
  const raw = value ?? uncontrolled;
1348
1357
  const contentKey = raw.join("\0");
1349
- const values = React8.useMemo(() => raw, [contentKey]);
1358
+ const values = React9.useMemo(() => raw, [contentKey]);
1350
1359
  const labelOf = (v) => items.find((o) => o.value === v)?.label ?? v;
1351
1360
  const isEditable = !rest.isDisabled && !rest.isReadOnly;
1352
1361
  const commit = (next) => {
@@ -1662,14 +1671,27 @@ function DateRangePicker({
1662
1671
  }
1663
1672
 
1664
1673
  // src/components/forms/ValueHelpField.tsx
1665
- var React10 = __toESM(require("react"), 1);
1674
+ var React12 = __toESM(require("react"), 1);
1666
1675
 
1667
1676
  // src/components/patterns/ValueHelpDialog.tsx
1668
- var React9 = __toESM(require("react"), 1);
1677
+ var React11 = __toESM(require("react"), 1);
1669
1678
 
1670
1679
  // src/components/feedback/Dialog.tsx
1680
+ var React10 = __toESM(require("react"), 1);
1671
1681
  var import_react_aria_components20 = require("react-aria-components");
1672
1682
  var import_jsx_runtime28 = require("react/jsx-runtime");
1683
+ function DialogTitle({ children, className }) {
1684
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_aria_components20.Heading, { slot: "title", className: cx("pire-dialog-title", className), children });
1685
+ }
1686
+ function DialogDescription({ children, className }) {
1687
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: cx("pire-dialog-sub", className), style: { margin: 0 }, children });
1688
+ }
1689
+ function DialogBody({ children, className }) {
1690
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cx("pire-dialog-body", className), children });
1691
+ }
1692
+ function DialogActions({ children, className }) {
1693
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("footer", { className: cx("pire-dialog-foot", className), children });
1694
+ }
1673
1695
  function Dialog({
1674
1696
  isOpen,
1675
1697
  onOpenChange,
@@ -1689,6 +1711,18 @@ function Dialog({
1689
1711
  onClose?.();
1690
1712
  onOpenChange?.(false);
1691
1713
  };
1714
+ const parts = React10.Children.toArray(children);
1715
+ const slotOf = (type) => parts.find((node) => React10.isValidElement(node) && node.type === type);
1716
+ const titleSlot = slotOf(DialogTitle);
1717
+ const descriptionSlot = slotOf(DialogDescription);
1718
+ const bodySlot = slotOf(DialogBody);
1719
+ const actionsSlot = slotOf(DialogActions);
1720
+ const slots = [titleSlot, descriptionSlot, bodySlot, actionsSlot];
1721
+ const loose = parts.filter((node) => !slots.includes(node));
1722
+ const heading = titleSlot ?? (title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_aria_components20.Heading, { slot: "title", className: "pire-dialog-title", children: title }) : null);
1723
+ const description = descriptionSlot ?? (subtitle ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null);
1724
+ const actions = actionsSlot ?? (footer ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null);
1725
+ const body = bodySlot ?? (loose.length ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "pire-dialog-body", children: loose }) : null);
1692
1726
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1693
1727
  import_react_aria_components20.ModalOverlay,
1694
1728
  {
@@ -1699,15 +1733,15 @@ function Dialog({
1699
1733
  if (!o) close();
1700
1734
  },
1701
1735
  children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_aria_components20.Modal, { className: cx("pire-modal", className), "data-size": size, style, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_aria_components20.Dialog, { className: "pire-dialog", children: [
1702
- title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("header", { className: "pire-dialog-head", children: [
1736
+ heading || description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("header", { className: "pire-dialog-head", children: [
1703
1737
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1704
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_aria_components20.Heading, { slot: "title", className: "pire-dialog-title", children: title }),
1705
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
1738
+ heading,
1739
+ description
1706
1740
  ] }),
1707
1741
  showClose ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(IconButton, { icon: "x", label: msg.dialogClose, size: "sm", onPress: close }) : null
1708
1742
  ] }) : null,
1709
- children ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "pire-dialog-body", children }) : null,
1710
- footer ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null
1743
+ body,
1744
+ actions
1711
1745
  ] }) })
1712
1746
  }
1713
1747
  );
@@ -1778,6 +1812,10 @@ function DataTable({
1778
1812
  isLoading,
1779
1813
  loadingRowCount,
1780
1814
  loadingLabel,
1815
+ footer,
1816
+ rowProps,
1817
+ renderExpanded,
1818
+ expandedIds,
1781
1819
  className,
1782
1820
  style,
1783
1821
  ...rest
@@ -1794,6 +1832,11 @@ function DataTable({
1794
1832
  ...columns.map((c) => ({ width: c.width, align: c.align, numeric: c.numeric }))
1795
1833
  ];
1796
1834
  const body = isLoading ? [] : rows;
1835
+ const presentation = new Map(rows.map((row) => [row.id, rowProps?.(row) ?? {}]));
1836
+ const disabledKeys = rows.filter((row) => presentation.get(row.id)?.isDisabled).map((row) => row.id);
1837
+ const expanded = new Set((expandedIds ?? []).map(String));
1838
+ const spanAll = columns.length + (selectable ? 1 : 0);
1839
+ const expandedKey = (id) => `${id}::__pire_expanded__`;
1797
1840
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1798
1841
  "div",
1799
1842
  {
@@ -1808,6 +1851,7 @@ function DataTable({
1808
1851
  "data-density": density,
1809
1852
  "data-sticky": String(stickyHeader),
1810
1853
  "aria-label": rest["aria-label"],
1854
+ disabledKeys: disabledKeys.length ? new Set(disabledKeys) : void 0,
1811
1855
  selectionMode: selectable ? "multiple" : "none",
1812
1856
  selectedKeys: selected ? new Set(selected) : void 0,
1813
1857
  onSelectionChange: handleSelection,
@@ -1830,7 +1874,7 @@ function DataTable({
1830
1874
  width: c.width,
1831
1875
  "data-align": c.numeric || c.align === "right" ? "right" : c.align,
1832
1876
  "data-allows-sorting": c.sortable ? "true" : void 0,
1833
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "pire-th-inner", children: [
1877
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: cx("pire-th-inner", c.hideLabel && "pire-sr-only"), children: [
1834
1878
  c.label,
1835
1879
  c.sortable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1836
1880
  Icon,
@@ -1851,19 +1895,46 @@ function DataTable({
1851
1895
  // biome-ignore lint/suspicious/noArrayIndexKey: placeholder rows are positional.
1852
1896
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SkeletonTableRow, { columns: skeletonColumns, density }, i)
1853
1897
  ))
1854
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "pire-table-empty", children: emptyLabel }), children: body.map((row) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react_aria_components21.Row, { id: row.id, className: "pire-tr", "data-pressable": onRowAction ? "true" : void 0, children: [
1855
- selectable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_aria_components21.Cell, { className: "pire-td", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Checkbox, { slot: "selection", "aria-label": msg.dataTableSelectRow }) }) : null,
1856
- columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1898
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "pire-table-empty", children: emptyLabel }), children: body.flatMap((row) => {
1899
+ const rowIsDisabled = presentation.get(row.id)?.isDisabled;
1900
+ const record = /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1901
+ import_react_aria_components21.Row,
1902
+ {
1903
+ id: row.id,
1904
+ className: cx("pire-tr", presentation.get(row.id)?.className),
1905
+ "data-pressable": onRowAction && !rowIsDisabled ? "true" : void 0,
1906
+ children: [
1907
+ selectable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_aria_components21.Cell, { className: "pire-td", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Checkbox, { slot: "selection", "aria-label": msg.dataTableSelectRow }) }) : null,
1908
+ columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1909
+ import_react_aria_components21.Cell,
1910
+ {
1911
+ className: "pire-td",
1912
+ "data-numeric": c.numeric ? "true" : void 0,
1913
+ style: { textAlign: c.align && !c.numeric ? c.align : void 0 },
1914
+ children: c.render ? c.render(row) : row[c.key]
1915
+ },
1916
+ c.key
1917
+ ))
1918
+ ]
1919
+ },
1920
+ row.id
1921
+ );
1922
+ if (!renderExpanded || !expanded.has(String(row.id))) return [record];
1923
+ return [record, /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_aria_components21.Row, { id: expandedKey(row.id), className: "pire-tr-expanded", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_aria_components21.Cell, { className: "pire-td-expanded", colSpan: spanAll, children: renderExpanded(row) }) }, expandedKey(row.id))];
1924
+ }) }),
1925
+ footer && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_aria_components21.TableFooter, { className: "pire-tfoot", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react_aria_components21.Row, { id: "__pire_footer__", className: "pire-tr-footer", children: [
1926
+ selectable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_aria_components21.Cell, { className: "pire-tf" }) : null,
1927
+ columns.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1857
1928
  import_react_aria_components21.Cell,
1858
1929
  {
1859
- className: "pire-td",
1930
+ className: "pire-tf",
1860
1931
  "data-numeric": c.numeric ? "true" : void 0,
1861
1932
  style: { textAlign: c.align && !c.numeric ? c.align : void 0 },
1862
- children: c.render ? c.render(row) : row[c.key]
1933
+ children: footer[c.key] ?? (i === 0 && !selectable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "pire-sr-only", children: msg.dataTableSummaryRow }) : null)
1863
1934
  },
1864
1935
  c.key
1865
1936
  ))
1866
- ] }, row.id)) })
1937
+ ] }) }) : null
1867
1938
  ]
1868
1939
  }
1869
1940
  )
@@ -1888,11 +1959,11 @@ function ValueHelpDialog({
1888
1959
  onClose
1889
1960
  }) {
1890
1961
  const msg = usePireMessages();
1891
- const [query, setQuery] = React9.useState("");
1892
- React9.useEffect(() => {
1962
+ const [query, setQuery] = React11.useState("");
1963
+ React11.useEffect(() => {
1893
1964
  if (isOpen) setQuery("");
1894
1965
  }, [isOpen]);
1895
- const filtered = React9.useMemo(() => {
1966
+ const filtered = React11.useMemo(() => {
1896
1967
  if (isFilteredExternally) return rows;
1897
1968
  const q = query.trim().toLowerCase();
1898
1969
  if (!q) return rows;
@@ -1974,7 +2045,7 @@ function ValueHelpField({
1974
2045
  style
1975
2046
  }) {
1976
2047
  const msg = usePireMessages();
1977
- const [open, setOpen] = React10.useState(false);
2048
+ const [open, setOpen] = React12.useState(false);
1978
2049
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cx(className), style, children: [
1979
2050
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1980
2051
  Input,
@@ -2030,7 +2101,7 @@ function ValueHelpField({
2030
2101
  }
2031
2102
 
2032
2103
  // src/components/forms/FileUpload.tsx
2033
- var React11 = __toESM(require("react"), 1);
2104
+ var React13 = __toESM(require("react"), 1);
2034
2105
  var import_react_aria_components23 = require("react-aria-components");
2035
2106
 
2036
2107
  // src/components/feedback/ProgressBar.tsx
@@ -2120,10 +2191,10 @@ function FileUpload({
2120
2191
  style
2121
2192
  }) {
2122
2193
  const msg = usePireMessages();
2123
- const [uncontrolled, setUncontrolled] = React11.useState(defaultValue ?? []);
2194
+ const [uncontrolled, setUncontrolled] = React13.useState(defaultValue ?? []);
2124
2195
  const files = value ?? uncontrolled;
2125
- const created = React11.useRef([]);
2126
- React11.useEffect(() => () => {
2196
+ const created = React13.useRef([]);
2197
+ React13.useEffect(() => () => {
2127
2198
  for (const url of created.current) URL.revokeObjectURL(url);
2128
2199
  }, []);
2129
2200
  const commit = (next) => {
@@ -2234,7 +2305,7 @@ function ShellBar({
2234
2305
  }
2235
2306
 
2236
2307
  // src/components/navigation/SideNav.tsx
2237
- var React12 = __toESM(require("react"), 1);
2308
+ var React14 = __toESM(require("react"), 1);
2238
2309
  var import_react_aria_components26 = require("react-aria-components");
2239
2310
 
2240
2311
  // src/components/navigation/Menu.tsx
@@ -2321,10 +2392,10 @@ function SideNav({
2321
2392
  const msg = usePireMessages();
2322
2393
  const activeParent = findActiveParent(groups, value);
2323
2394
  const isControlled = expandedIds != null;
2324
- const [ownExpanded, setOwnExpanded] = React12.useState(
2395
+ const [ownExpanded, setOwnExpanded] = React14.useState(
2325
2396
  () => new Set(defaultExpandedIds ?? (activeParent ? [activeParent] : []))
2326
2397
  );
2327
- const [lastValue, setLastValue] = React12.useState(value);
2398
+ const [lastValue, setLastValue] = React14.useState(value);
2328
2399
  if (value !== lastValue) {
2329
2400
  setLastValue(value);
2330
2401
  if (!isControlled && activeParent && !ownExpanded.has(activeParent)) {
@@ -2588,7 +2659,7 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
2588
2659
  }
2589
2660
 
2590
2661
  // src/components/feedback/Toast.tsx
2591
- var React13 = __toESM(require("react"), 1);
2662
+ var React15 = __toESM(require("react"), 1);
2592
2663
  var import_jsx_runtime42 = require("react/jsx-runtime");
2593
2664
  var KIND_ICON2 = {
2594
2665
  info: "info",
@@ -2614,26 +2685,26 @@ function Toast({ kind = "success", onClose, position = "bottom-center", children
2614
2685
  }
2615
2686
  );
2616
2687
  }
2617
- var ToastContext = React13.createContext(null);
2688
+ var ToastContext = React15.createContext(null);
2618
2689
  function ToastProvider({ children, timeout = 6e3 }) {
2619
2690
  const msg = usePireMessages();
2620
- const [toasts, setToasts] = React13.useState([]);
2621
- const close = React13.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2622
- const add = React13.useCallback((toast) => {
2691
+ const [toasts, setToasts] = React15.useState([]);
2692
+ const close = React15.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2693
+ const add = React15.useCallback((toast) => {
2623
2694
  const id = Math.random().toString(36).slice(2);
2624
2695
  setToasts((t) => [...t, { ...toast, id }]);
2625
2696
  const ms = toast.timeout ?? timeout;
2626
2697
  if (ms > 0) setTimeout(() => close(id), ms);
2627
2698
  return id;
2628
2699
  }, [close, timeout]);
2629
- const value = React13.useMemo(() => ({ add, close }), [add, close]);
2700
+ const value = React15.useMemo(() => ({ add, close }), [add, close]);
2630
2701
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(ToastContext.Provider, { value, children: [
2631
2702
  children,
2632
2703
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2633
2704
  ] });
2634
2705
  }
2635
2706
  function useToast() {
2636
- const ctx = React13.useContext(ToastContext);
2707
+ const ctx = React15.useContext(ToastContext);
2637
2708
  if (!ctx) throw new Error("useToast must be used inside <ToastProvider>");
2638
2709
  return ctx;
2639
2710
  }
@@ -2983,14 +3054,14 @@ function BarChart({
2983
3054
  }
2984
3055
 
2985
3056
  // src/components/data/LineChart.tsx
2986
- var React14 = __toESM(require("react"), 1);
3057
+ var React16 = __toESM(require("react"), 1);
2987
3058
  var import_jsx_runtime50 = require("react/jsx-runtime");
2988
3059
  var PLOT_INSET = { top: 10, right: 14, bottom: 24, left: 58 };
2989
3060
  var MARKER_LIMIT = 20;
2990
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React14.useEffect : React14.useLayoutEffect;
3061
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React16.useEffect : React16.useLayoutEffect;
2991
3062
  function useMeasuredWidth() {
2992
- const ref = React14.useRef(null);
2993
- const [width, setWidth] = React14.useState(0);
3063
+ const ref = React16.useRef(null);
3064
+ const [width, setWidth] = React16.useState(0);
2994
3065
  useIsomorphicLayoutEffect2(() => {
2995
3066
  const element = ref.current;
2996
3067
  if (!element) return;
@@ -3153,7 +3224,7 @@ function LineChart({
3153
3224
  }
3154
3225
 
3155
3226
  // src/components/data/DonutChart.tsx
3156
- var React15 = __toESM(require("react"), 1);
3227
+ var React17 = __toESM(require("react"), 1);
3157
3228
  var import_jsx_runtime51 = require("react/jsx-runtime");
3158
3229
  var SEGMENT_GAP_DEGREES = 1.5;
3159
3230
  function DonutChart({
@@ -3174,7 +3245,7 @@ function DonutChart({
3174
3245
  }) {
3175
3246
  const label = rest["aria-label"];
3176
3247
  const msg = usePireMessages();
3177
- const [hoveredIndex, setHoveredIndex] = React15.useState(null);
3248
+ const [hoveredIndex, setHoveredIndex] = React17.useState(null);
3178
3249
  warnOnDonutShape(series, categories.length, label);
3179
3250
  const values = (series[0]?.values ?? []).slice(0, categories.length);
3180
3251
  const segments = categories.map((category, index) => ({ category, index, value: values[index] ?? 0 })).filter((segment) => segment.value > 0);
@@ -3376,7 +3447,7 @@ function ConfirmDialog({
3376
3447
  }
3377
3448
 
3378
3449
  // src/components/patterns/CommandPalette.tsx
3379
- var React16 = __toESM(require("react"), 1);
3450
+ var React18 = __toESM(require("react"), 1);
3380
3451
  var import_react_aria_components31 = require("react-aria-components");
3381
3452
  var import_jsx_runtime59 = require("react/jsx-runtime");
3382
3453
  var RESULTS_SECTION_KEY = "__pire_results__";
@@ -3399,17 +3470,17 @@ function CommandPalette({
3399
3470
  style
3400
3471
  }) {
3401
3472
  const msg = usePireMessages();
3402
- const [query, setQuery] = React16.useState("");
3473
+ const [query, setQuery] = React18.useState("");
3403
3474
  const { contains } = (0, import_react_aria_components31.useFilter)({ sensitivity: "base" });
3404
- React16.useEffect(() => {
3475
+ React18.useEffect(() => {
3405
3476
  if (isOpen) setQuery("");
3406
3477
  }, [isOpen]);
3407
- const searchableById = React16.useMemo(() => {
3478
+ const searchableById = React18.useMemo(() => {
3408
3479
  const byId = /* @__PURE__ */ new Map();
3409
3480
  for (const group of groups) for (const item of group.items) byId.set(item.id, searchableText(item));
3410
3481
  return byId;
3411
3482
  }, [groups]);
3412
- const filter = React16.useCallback((textValue, inputValue, node) => {
3483
+ const filter = React18.useCallback((textValue, inputValue, node) => {
3413
3484
  if (node.parentKey === RESULTS_SECTION_KEY) return true;
3414
3485
  return contains(searchableById.get(String(node.key)) ?? textValue, inputValue);
3415
3486
  }, [contains, searchableById]);
@@ -3492,9 +3563,9 @@ function CommandPalette({
3492
3563
  );
3493
3564
  }
3494
3565
  function useCommandPaletteShortcut(onTrigger, { key = "k", isDisabled } = {}) {
3495
- const handler = React16.useRef(onTrigger);
3566
+ const handler = React18.useRef(onTrigger);
3496
3567
  handler.current = onTrigger;
3497
- React16.useEffect(() => {
3568
+ React18.useEffect(() => {
3498
3569
  if (isDisabled) return;
3499
3570
  const onKeyDown = (event) => {
3500
3571
  if (!(event.metaKey || event.ctrlKey) || event.altKey) return;
@@ -3548,7 +3619,7 @@ function EmptyState({ icon = "file-text", title, action, compact, children, clas
3548
3619
  }
3549
3620
 
3550
3621
  // src/components/patterns/FileDropZone.tsx
3551
- var React17 = __toESM(require("react"), 1);
3622
+ var React19 = __toESM(require("react"), 1);
3552
3623
  var import_react_aria_components33 = require("react-aria-components");
3553
3624
  var import_jsx_runtime62 = require("react/jsx-runtime");
3554
3625
  var isImage2 = (file) => file.type.startsWith("image/");
@@ -3576,10 +3647,10 @@ function FileDropZone({
3576
3647
  style
3577
3648
  }) {
3578
3649
  const msg = usePireMessages();
3579
- const [uncontrolled, setUncontrolled] = React17.useState(defaultValue ?? []);
3650
+ const [uncontrolled, setUncontrolled] = React19.useState(defaultValue ?? []);
3580
3651
  const files = value ?? uncontrolled;
3581
- const created = React17.useRef([]);
3582
- React17.useEffect(() => () => {
3652
+ const created = React19.useRef([]);
3653
+ React19.useEffect(() => () => {
3583
3654
  for (const url of created.current) URL.revokeObjectURL(url);
3584
3655
  }, []);
3585
3656
  const commit = (next) => {
@@ -3653,6 +3724,7 @@ function FileDropZone({
3653
3724
 
3654
3725
  // src/index.ts
3655
3726
  var import_react_aria_components34 = require("react-aria-components");
3727
+ var import_react_aria_components35 = require("react-aria-components");
3656
3728
  // Annotate the CommonJS export names for ESM import in node:
3657
3729
  0 && (module.exports = {
3658
3730
  Avatar,
@@ -3670,12 +3742,17 @@ var import_react_aria_components34 = require("react-aria-components");
3670
3742
  DateRangePicker,
3671
3743
  DescriptionList,
3672
3744
  Dialog,
3745
+ DialogActions,
3746
+ DialogBody,
3747
+ DialogDescription,
3748
+ DialogTitle,
3673
3749
  DialogTrigger,
3674
3750
  DonutChart,
3675
3751
  EmptyState,
3676
3752
  FileDropZone,
3677
3753
  FileUpload,
3678
3754
  FilterBar,
3755
+ Focusable,
3679
3756
  FooterBar,
3680
3757
  FormField,
3681
3758
  Heading,