@orianatech/pire 0.8.0 → 0.9.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
@@ -42,13 +42,15 @@ __export(src_exports, {
42
42
  DatePicker: () => DatePicker,
43
43
  DescriptionList: () => DescriptionList,
44
44
  Dialog: () => Dialog,
45
- DialogTrigger: () => import_react_aria_components29.DialogTrigger,
45
+ DialogTrigger: () => import_react_aria_components31.DialogTrigger,
46
46
  EmptyState: () => EmptyState,
47
+ FileDropZone: () => FileDropZone,
48
+ FileUpload: () => FileUpload,
47
49
  FilterBar: () => FilterBar,
48
50
  FooterBar: () => FooterBar,
49
51
  FormField: () => FormField,
50
52
  Heading: () => Heading,
51
- I18nProvider: () => import_react_aria_components29.I18nProvider,
53
+ I18nProvider: () => import_react_aria_components31.I18nProvider,
52
54
  Icon: () => Icon,
53
55
  IconButton: () => IconButton,
54
56
  InlineMessage: () => InlineMessage,
@@ -60,7 +62,7 @@ __export(src_exports, {
60
62
  MenuItem: () => MenuItem,
61
63
  MenuSection: () => MenuSection,
62
64
  MenuSeparator: () => MenuSeparator,
63
- MenuTrigger: () => import_react_aria_components29.MenuTrigger,
65
+ MenuTrigger: () => import_react_aria_components31.MenuTrigger,
64
66
  MultiComboBox: () => MultiComboBox,
65
67
  NumberField: () => NumberField,
66
68
  ObjectHeader: () => ObjectHeader,
@@ -68,11 +70,11 @@ __export(src_exports, {
68
70
  PageHeader: () => PageHeader,
69
71
  Pagination: () => Pagination,
70
72
  PireIntlProvider: () => PireIntlProvider,
71
- Popover: () => import_react_aria_components29.Popover,
73
+ Popover: () => import_react_aria_components31.Popover,
72
74
  ProgressBar: () => ProgressBar,
73
75
  Radio: () => Radio,
74
76
  RadioGroup: () => RadioGroup,
75
- RouterProvider: () => import_react_aria_components29.RouterProvider,
77
+ RouterProvider: () => import_react_aria_components31.RouterProvider,
76
78
  SectionHeader: () => SectionHeader,
77
79
  SegmentedControl: () => SegmentedControl,
78
80
  Select: () => Select,
@@ -84,7 +86,7 @@ __export(src_exports, {
84
86
  Skeleton: () => Skeleton,
85
87
  SkeletonTableRow: () => SkeletonTableRow,
86
88
  Strong: () => Strong,
87
- SubmenuTrigger: () => import_react_aria_components29.SubmenuTrigger,
89
+ SubmenuTrigger: () => import_react_aria_components31.SubmenuTrigger,
88
90
  Switch: () => Switch,
89
91
  Tabs: () => Tabs,
90
92
  Tag: () => Tag,
@@ -99,6 +101,7 @@ __export(src_exports, {
99
101
  configureIcons: () => configureIcons,
100
102
  enMessages: () => enMessages,
101
103
  esMessages: () => esMessages,
104
+ formatFileSize: () => formatFileSize,
102
105
  usePireMessages: () => usePireMessages,
103
106
  useToast: () => useToast
104
107
  });
@@ -909,7 +912,11 @@ var enMessages = {
909
912
  paginationPrevious: "Previous page",
910
913
  paginationNext: "Next page",
911
914
  paginationRowsPerPage: "Rows per page",
912
- sideNavLabel: "Main navigation"
915
+ sideNavLabel: "Main navigation",
916
+ fileUploadChoose: "Choose files",
917
+ fileUploadRemoveNamed: "Remove {name}",
918
+ fileUploadUploading: "Uploading",
919
+ fileDropZonePrompt: "Drag files here, or choose them"
913
920
  };
914
921
  var esMessages = {
915
922
  filterBarLabel: "Filtros",
@@ -941,7 +948,11 @@ var esMessages = {
941
948
  paginationPrevious: "P\xE1gina anterior",
942
949
  paginationNext: "P\xE1gina siguiente",
943
950
  paginationRowsPerPage: "Filas por p\xE1gina",
944
- sideNavLabel: "Navegaci\xF3n principal"
951
+ sideNavLabel: "Navegaci\xF3n principal",
952
+ fileUploadChoose: "Elegir archivos",
953
+ fileUploadRemoveNamed: "Quitar {name}",
954
+ fileUploadUploading: "Subiendo",
955
+ fileDropZonePrompt: "Arrastr\xE1 archivos ac\xE1, o elegilos"
945
956
  };
946
957
 
947
958
  // src/i18n/PireIntlProvider.tsx
@@ -1629,8 +1640,165 @@ function ValueHelpField({
1629
1640
  ] });
1630
1641
  }
1631
1642
 
1632
- // src/components/navigation/ShellBar.tsx
1643
+ // src/components/forms/FileUpload.tsx
1644
+ var React10 = __toESM(require("react"), 1);
1645
+ var import_react_aria_components22 = require("react-aria-components");
1646
+
1647
+ // src/components/feedback/ProgressBar.tsx
1648
+ var import_react_aria_components21 = require("react-aria-components");
1633
1649
  var import_jsx_runtime31 = require("react/jsx-runtime");
1650
+ function ProgressBar({
1651
+ value = 0,
1652
+ minValue = 0,
1653
+ maxValue = 100,
1654
+ label,
1655
+ showValue = true,
1656
+ isIndeterminate,
1657
+ status = "informative",
1658
+ size = "md",
1659
+ className,
1660
+ style
1661
+ }) {
1662
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1663
+ import_react_aria_components21.ProgressBar,
1664
+ {
1665
+ className: cx("pire-progress", className),
1666
+ "data-status": status,
1667
+ "data-size": size,
1668
+ value,
1669
+ minValue,
1670
+ maxValue,
1671
+ isIndeterminate,
1672
+ style,
1673
+ children: ({ percentage, valueText }) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
1674
+ label || showValue ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "pire-progress-head", children: [
1675
+ label ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_aria_components21.Label, { children: label }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", {}),
1676
+ showValue && !isIndeterminate ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "pire-numeric", children: valueText }) : null
1677
+ ] }) : null,
1678
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "pire-progress-track", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "pire-progress-fill", style: { width: `${isIndeterminate ? 40 : percentage}%` } }) })
1679
+ ] })
1680
+ }
1681
+ );
1682
+ }
1683
+
1684
+ // src/components/forms/FileUpload.tsx
1685
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1686
+ var isImage = (file) => file.type.startsWith("image/");
1687
+ function formatFileSize(bytes) {
1688
+ if (bytes < 1024) return `${bytes} B`;
1689
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024).toLocaleString()} KB`;
1690
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1691
+ }
1692
+ function screenFiles(files, { maxSize, acceptedFileTypes }) {
1693
+ const accepted = [];
1694
+ const rejected = [];
1695
+ for (const file of files) {
1696
+ if (maxSize != null && file.size > maxSize) {
1697
+ rejected.push({ file, reason: "size" });
1698
+ continue;
1699
+ }
1700
+ if (acceptedFileTypes?.length) {
1701
+ const ok = acceptedFileTypes.some((t) => t.startsWith(".") ? file.name.toLowerCase().endsWith(t.toLowerCase()) : t.endsWith("/*") ? file.type.startsWith(t.slice(0, -1)) : file.type === t);
1702
+ if (!ok) {
1703
+ rejected.push({ file, reason: "type" });
1704
+ continue;
1705
+ }
1706
+ }
1707
+ accepted.push(file);
1708
+ }
1709
+ return { accepted, rejected };
1710
+ }
1711
+ function FileUpload({
1712
+ label,
1713
+ value,
1714
+ defaultValue,
1715
+ onChange,
1716
+ acceptedFileTypes,
1717
+ allowsMultiple,
1718
+ maxSize,
1719
+ onError,
1720
+ showPreview = true,
1721
+ uploadProgress,
1722
+ chooseLabel,
1723
+ description,
1724
+ errorMessage,
1725
+ isInvalid,
1726
+ isDisabled,
1727
+ isReadOnly,
1728
+ isRequired,
1729
+ fullWidth = true,
1730
+ className,
1731
+ style
1732
+ }) {
1733
+ const msg = usePireMessages();
1734
+ const [uncontrolled, setUncontrolled] = React10.useState(defaultValue ?? []);
1735
+ const files = value ?? uncontrolled;
1736
+ const created = React10.useRef([]);
1737
+ React10.useEffect(() => () => {
1738
+ for (const url of created.current) URL.revokeObjectURL(url);
1739
+ }, []);
1740
+ const commit = (next) => {
1741
+ if (value === void 0) setUncontrolled(next);
1742
+ onChange?.(next);
1743
+ };
1744
+ const accept = (picked) => {
1745
+ if (!picked || isDisabled || isReadOnly) return;
1746
+ const { accepted, rejected } = screenFiles([...picked], { maxSize, acceptedFileTypes });
1747
+ if (rejected.length) onError?.(rejected);
1748
+ if (!accepted.length) return;
1749
+ const wrapped = accepted.map((file) => {
1750
+ const previewUrl = showPreview && isImage(file) ? URL.createObjectURL(file) : void 0;
1751
+ if (previewUrl) created.current.push(previewUrl);
1752
+ return { file, previewUrl };
1753
+ });
1754
+ commit(allowsMultiple ? [...files, ...wrapped] : wrapped.slice(0, 1));
1755
+ };
1756
+ const remove = (target) => commit(files.filter((f) => f.file !== target));
1757
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1758
+ "div",
1759
+ {
1760
+ className: cx("pire-field", "pire-fileupload", className),
1761
+ style,
1762
+ "data-full-width": String(fullWidth),
1763
+ "data-invalid": isInvalid ? "true" : void 0,
1764
+ children: [
1765
+ label ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "pire-field-label", children: [
1766
+ label,
1767
+ isRequired ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1768
+ ] }) : null,
1769
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1770
+ import_react_aria_components22.FileTrigger,
1771
+ {
1772
+ acceptedFileTypes,
1773
+ allowsMultiple,
1774
+ onSelect: accept,
1775
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Button, { icon: "paperclip", isDisabled: isDisabled || isReadOnly, children: chooseLabel ?? msg.fileUploadChoose })
1776
+ }
1777
+ ),
1778
+ files.length ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("li", { className: "pire-fileupload-item", children: [
1779
+ previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
1780
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-fileupload-name", children: file.name }),
1781
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
1782
+ isDisabled || isReadOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1783
+ IconButton,
1784
+ {
1785
+ icon: "x",
1786
+ size: "sm",
1787
+ label: msg.fileUploadRemoveNamed.replace("{name}", file.name),
1788
+ onPress: () => remove(file)
1789
+ }
1790
+ )
1791
+ ] }, `${file.name}-${file.size}-${file.lastModified}`)) }) : null,
1792
+ uploadProgress != null ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
1793
+ description ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_aria_components22.Text, { slot: "description", className: "pire-field-hint", children: description }) : null,
1794
+ isInvalid && errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-field-error", children: errorMessage }) : null
1795
+ ]
1796
+ }
1797
+ );
1798
+ }
1799
+
1800
+ // src/components/navigation/ShellBar.tsx
1801
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1634
1802
  var initials2 = (name) => name.trim().split(/\s+/).slice(0, 2).map((p) => p[0]).join("").toUpperCase();
1635
1803
  function ShellBar({
1636
1804
  product,
@@ -1645,22 +1813,75 @@ function ShellBar({
1645
1813
  className,
1646
1814
  ...rest
1647
1815
  }) {
1648
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("header", { className: cx("pire-shellbar", className), ...rest, children: [
1649
- onMenu ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(IconButton, { icon: "menu", label: menuLabel, variant: "inverse", size: "sm", onPress: onMenu }) : null,
1650
- monogram ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "pire-shellbar-mono", "aria-hidden": "true", children: monogram }) : null,
1651
- product ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "pire-shellbar-product", children: product }) : null,
1652
- title ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "pire-shellbar-title", children: title }) : null,
1653
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "pire-shellbar-spacer" }),
1654
- onSearch ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(IconButton, { icon: "search", label: searchLabel, variant: "inverse", size: "sm", onPress: onSearch }) : null,
1816
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("header", { className: cx("pire-shellbar", className), ...rest, children: [
1817
+ onMenu ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IconButton, { icon: "menu", label: menuLabel, variant: "inverse", size: "sm", onPress: onMenu }) : null,
1818
+ monogram ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "pire-shellbar-mono", "aria-hidden": "true", children: monogram }) : null,
1819
+ product ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "pire-shellbar-product", children: product }) : null,
1820
+ title ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "pire-shellbar-title", children: title }) : null,
1821
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "pire-shellbar-spacer" }),
1822
+ onSearch ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IconButton, { icon: "search", label: searchLabel, variant: "inverse", size: "sm", onPress: onSearch }) : null,
1655
1823
  actions,
1656
- user ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "pire-avatar", title: user, "aria-label": user, role: "img", children: initials2(user) }) : null
1824
+ user ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "pire-avatar", title: user, "aria-label": user, role: "img", children: initials2(user) }) : null
1657
1825
  ] });
1658
1826
  }
1659
1827
 
1660
1828
  // src/components/navigation/SideNav.tsx
1661
- var React10 = __toESM(require("react"), 1);
1662
- var import_react_aria_components21 = require("react-aria-components");
1663
- var import_jsx_runtime32 = require("react/jsx-runtime");
1829
+ var React11 = __toESM(require("react"), 1);
1830
+ var import_react_aria_components24 = require("react-aria-components");
1831
+
1832
+ // src/components/navigation/Menu.tsx
1833
+ var import_react_aria_components23 = require("react-aria-components");
1834
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1835
+ function Menu({ minWidth, className, style, ...rest }) {
1836
+ const width = typeof minWidth === "number" ? `${minWidth}px` : minWidth;
1837
+ const menuStyle = width == null ? style : { ["--pire-menu-min-w"]: width, ...style };
1838
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1839
+ import_react_aria_components23.Menu,
1840
+ {
1841
+ className: cx("pire-menu", className),
1842
+ style: menuStyle,
1843
+ ...rest
1844
+ }
1845
+ );
1846
+ }
1847
+ function MenuItem({
1848
+ children,
1849
+ icon,
1850
+ description,
1851
+ shortcut,
1852
+ tone = "default",
1853
+ className,
1854
+ ...rest
1855
+ }) {
1856
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1857
+ import_react_aria_components23.MenuItem,
1858
+ {
1859
+ className: cx("pire-menu-item", className),
1860
+ "data-tone": tone === "danger" ? "danger" : void 0,
1861
+ ...rest,
1862
+ children: [
1863
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Icon, { name: icon, size: 16, className: "pire-menu-item-icon" }) : null,
1864
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "pire-menu-item-body", children: [
1865
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "pire-menu-item-label", children }),
1866
+ description ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "pire-menu-item-desc", children: description }) : null
1867
+ ] }),
1868
+ shortcut ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("kbd", { className: "pire-menu-item-shortcut", children: shortcut }) : null
1869
+ ]
1870
+ }
1871
+ );
1872
+ }
1873
+ function MenuSection({ title, children, className, ...rest }) {
1874
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_aria_components23.MenuSection, { className: cx("pire-menu-section", className), ...rest, children: [
1875
+ title ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_aria_components23.Header, { className: "pire-menu-section-title", children: title }) : null,
1876
+ children
1877
+ ] });
1878
+ }
1879
+ function MenuSeparator({ className }) {
1880
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_aria_components23.Separator, { className: cx("pire-menu-separator", className) });
1881
+ }
1882
+
1883
+ // src/components/navigation/SideNav.tsx
1884
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1664
1885
  function findActiveParent(groups, value) {
1665
1886
  if (value == null) return void 0;
1666
1887
  for (const group of groups) {
@@ -1678,6 +1899,7 @@ function SideNav({
1678
1899
  defaultExpandedIds,
1679
1900
  onExpandedChange,
1680
1901
  collapsed,
1902
+ railFlyout = true,
1681
1903
  footer,
1682
1904
  className,
1683
1905
  ...rest
@@ -1685,10 +1907,10 @@ function SideNav({
1685
1907
  const msg = usePireMessages();
1686
1908
  const activeParent = findActiveParent(groups, value);
1687
1909
  const isControlled = expandedIds != null;
1688
- const [ownExpanded, setOwnExpanded] = React10.useState(
1910
+ const [ownExpanded, setOwnExpanded] = React11.useState(
1689
1911
  () => new Set(defaultExpandedIds ?? (activeParent ? [activeParent] : []))
1690
1912
  );
1691
- const [lastValue, setLastValue] = React10.useState(value);
1913
+ const [lastValue, setLastValue] = React11.useState(value);
1692
1914
  if (value !== lastValue) {
1693
1915
  setLastValue(value);
1694
1916
  if (!isControlled && activeParent && !ownExpanded.has(activeParent)) {
@@ -1708,8 +1930,8 @@ function SideNav({
1708
1930
  };
1709
1931
  const renderRow = (item, onPress, isGroup) => {
1710
1932
  const selected = !isGroup && item.id === value;
1711
- const button = /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1712
- import_react_aria_components21.Button,
1933
+ const button = /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1934
+ import_react_aria_components24.Button,
1713
1935
  {
1714
1936
  className: "pire-sidenav-item",
1715
1937
  "data-selected": selected ? "true" : void 0,
@@ -1718,50 +1940,70 @@ function SideNav({
1718
1940
  "aria-label": collapsed ? item.label : void 0,
1719
1941
  onPress,
1720
1942
  children: [
1721
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { name: item.icon, size: 16 }) : null,
1722
- collapsed ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: item.label }),
1723
- item.count != null && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-sidenav-count", children: item.count }) : null
1943
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Icon, { name: item.icon, size: 16 }) : null,
1944
+ collapsed ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: item.label }),
1945
+ item.count != null && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-sidenav-count", children: item.count }) : null
1724
1946
  ]
1725
1947
  },
1726
1948
  item.id
1727
1949
  );
1728
- return collapsed ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Tooltip, { label: item.label, placement: "right", children: button }, item.id) : button;
1950
+ return collapsed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Tooltip, { label: item.label, placement: "right", children: button }, item.id) : button;
1729
1951
  };
1730
- const renderSection = (item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_aria_components21.Disclosure, { id: item.id, className: "pire-sidenav-section", children: [
1731
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1732
- import_react_aria_components21.Button,
1952
+ const renderRailFlyout = (item) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_aria_components24.MenuTrigger, { children: [
1953
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1954
+ import_react_aria_components24.Button,
1955
+ {
1956
+ className: "pire-sidenav-item",
1957
+ "aria-label": item.label,
1958
+ "data-active-child": item.id === activeParent ? "true" : void 0,
1959
+ children: item.icon ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Icon, { name: item.icon, size: 16 }) : null
1960
+ }
1961
+ ),
1962
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_aria_components24.Popover, { className: "pire-popover", placement: "right top", offset: 4, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1963
+ Menu,
1964
+ {
1965
+ "aria-label": item.label,
1966
+ className: "pire-sidenav-flyout",
1967
+ onAction: (key) => onChange?.(String(key)),
1968
+ children: (item.items ?? []).map((child) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MenuItem, { id: child.id, children: child.label }, child.id))
1969
+ }
1970
+ ) })
1971
+ ] }, item.id);
1972
+ const renderSection = (item) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_react_aria_components24.Disclosure, { id: item.id, className: "pire-sidenav-section", children: [
1973
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1974
+ import_react_aria_components24.Button,
1733
1975
  {
1734
1976
  slot: "trigger",
1735
1977
  className: "pire-sidenav-item",
1736
1978
  "data-kind": "group",
1737
1979
  "data-active-child": item.id === activeParent ? "true" : void 0,
1738
1980
  children: [
1739
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { name: item.icon, size: 16 }) : null,
1740
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: item.label }),
1741
- item.count != null ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-sidenav-count", children: item.count }) : null,
1742
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Icon, { name: "chevron-down", size: 16, className: "pire-sidenav-chevron" })
1981
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Icon, { name: item.icon, size: 16 }) : null,
1982
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: item.label }),
1983
+ item.count != null ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-sidenav-count", children: item.count }) : null,
1984
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Icon, { name: "chevron-down", size: 16, className: "pire-sidenav-chevron" })
1743
1985
  ]
1744
1986
  }
1745
1987
  ),
1746
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_aria_components21.DisclosurePanel, { className: "pire-sidenav-subnav", children: item.items?.map((child) => {
1988
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_aria_components24.DisclosurePanel, { className: "pire-sidenav-subnav", children: item.items?.map((child) => {
1747
1989
  const selected = child.id === value;
1748
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1749
- import_react_aria_components21.Button,
1990
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1991
+ import_react_aria_components24.Button,
1750
1992
  {
1751
1993
  className: "pire-sidenav-item pire-sidenav-subitem",
1752
1994
  "data-selected": selected ? "true" : void 0,
1753
1995
  "aria-current": selected ? "page" : void 0,
1754
1996
  onPress: () => onChange?.(child.id),
1755
1997
  children: [
1756
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: child.label }),
1757
- child.count != null ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "pire-sidenav-count", children: child.count }) : null
1998
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: child.label }),
1999
+ child.count != null ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-sidenav-count", children: child.count }) : null
1758
2000
  ]
1759
2001
  },
1760
2002
  child.id
1761
2003
  );
1762
2004
  }) })
1763
2005
  ] }, item.id);
1764
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2006
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1765
2007
  "nav",
1766
2008
  {
1767
2009
  className: cx("pire-sidenav", className),
@@ -1774,12 +2016,13 @@ function SideNav({
1774
2016
  const rows = group.items.map((item) => {
1775
2017
  const isGroup = Boolean(item.items?.length);
1776
2018
  if (isGroup && !collapsed) return renderSection(item);
2019
+ if (isGroup && collapsed && railFlyout) return renderRailFlyout(item);
1777
2020
  return renderRow(item, () => isGroup ? toggleExpanded(item.id) : onChange?.(item.id), isGroup);
1778
2021
  });
1779
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "pire-sidenav-group", children: [
1780
- group.label && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "pire-sidenav-label", children: group.label }) : null,
1781
- hasSections ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1782
- import_react_aria_components21.DisclosureGroup,
2022
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "pire-sidenav-group", children: [
2023
+ group.label && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "pire-sidenav-label", children: group.label }) : null,
2024
+ hasSections ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2025
+ import_react_aria_components24.DisclosureGroup,
1783
2026
  {
1784
2027
  className: "pire-sidenav-tree",
1785
2028
  allowsMultipleExpanded: true,
@@ -1790,18 +2033,18 @@ function SideNav({
1790
2033
  ) : rows
1791
2034
  ] }, group.label ?? gi);
1792
2035
  }),
1793
- footer ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "pire-sidenav-footer", children: footer }) : null
2036
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "pire-sidenav-footer", children: footer }) : null
1794
2037
  ]
1795
2038
  }
1796
2039
  );
1797
2040
  }
1798
2041
 
1799
2042
  // src/components/navigation/Tabs.tsx
1800
- var import_react_aria_components22 = require("react-aria-components");
1801
- var import_jsx_runtime33 = require("react/jsx-runtime");
2043
+ var import_react_aria_components25 = require("react-aria-components");
2044
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1802
2045
  function Tabs({ items, value, defaultValue, onChange, panels, className, style, ...rest }) {
1803
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
1804
- import_react_aria_components22.Tabs,
2046
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2047
+ import_react_aria_components25.Tabs,
1805
2048
  {
1806
2049
  className,
1807
2050
  style,
@@ -1809,23 +2052,23 @@ function Tabs({ items, value, defaultValue, onChange, panels, className, style,
1809
2052
  defaultSelectedKey: defaultValue,
1810
2053
  onSelectionChange: (k) => onChange?.(String(k)),
1811
2054
  children: [
1812
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_aria_components22.TabList, { className: "pire-tablist", items, "aria-label": rest["aria-label"] ?? "Views", children: (item) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react_aria_components22.Tab, { className: cx("pire-tab"), id: item.id, isDisabled: item.isDisabled, children: [
1813
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { name: item.icon, size: 16 }) : null,
2055
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_aria_components25.TabList, { className: "pire-tablist", items, "aria-label": rest["aria-label"] ?? "Views", children: (item) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_aria_components25.Tab, { className: cx("pire-tab"), id: item.id, isDisabled: item.isDisabled, children: [
2056
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Icon, { name: item.icon, size: 16 }) : null,
1814
2057
  item.label,
1815
- item.count != null ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "pire-tab-count", children: item.count }) : null
2058
+ item.count != null ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "pire-tab-count", children: item.count }) : null
1816
2059
  ] }) }),
1817
- items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_aria_components22.TabPanel, { id: item.id, className: panels ? "pire-tabpanel" : void 0, children: panels?.[item.id] }, item.id))
2060
+ items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_aria_components25.TabPanel, { id: item.id, className: panels ? "pire-tabpanel" : void 0, children: panels?.[item.id] }, item.id))
1818
2061
  ]
1819
2062
  }
1820
2063
  );
1821
2064
  }
1822
2065
 
1823
2066
  // src/components/navigation/Breadcrumb.tsx
1824
- var import_react_aria_components23 = require("react-aria-components");
1825
- var import_jsx_runtime34 = require("react/jsx-runtime");
2067
+ var import_react_aria_components26 = require("react-aria-components");
2068
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1826
2069
  function Breadcrumb({ items, onNavigate, className, style }) {
1827
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1828
- import_react_aria_components23.Breadcrumbs,
2070
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2071
+ import_react_aria_components26.Breadcrumbs,
1829
2072
  {
1830
2073
  className: cx("pire-breadcrumbs", className),
1831
2074
  style,
@@ -1833,9 +2076,9 @@ function Breadcrumb({ items, onNavigate, className, style }) {
1833
2076
  onAction: (key) => onNavigate?.(String(key)),
1834
2077
  children: (item) => {
1835
2078
  const last = items[items.length - 1] === item;
1836
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_aria_components23.Breadcrumb, { className: "pire-breadcrumb", id: item.id ?? item.label, children: [
1837
- last ? item.label : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_aria_components23.Link, { href: item.href, children: item.label }),
1838
- last ? null : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Icon, { name: "chevron-right", size: 12, style: { color: "var(--text-tertiary)" } })
2079
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react_aria_components26.Breadcrumb, { className: "pire-breadcrumb", id: item.id ?? item.label, children: [
2080
+ last ? item.label : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_aria_components26.Link, { href: item.href, children: item.label }),
2081
+ last ? null : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: "chevron-right", size: 12, style: { color: "var(--text-tertiary)" } })
1839
2082
  ] });
1840
2083
  }
1841
2084
  }
@@ -1843,7 +2086,7 @@ function Breadcrumb({ items, onNavigate, className, style }) {
1843
2086
  }
1844
2087
 
1845
2088
  // src/components/navigation/Pagination.tsx
1846
- var import_jsx_runtime35 = require("react/jsx-runtime");
2089
+ var import_jsx_runtime38 = require("react/jsx-runtime");
1847
2090
  function Pagination({
1848
2091
  page = 1,
1849
2092
  pageSize = 25,
@@ -1858,9 +2101,9 @@ function Pagination({
1858
2101
  const pages = Math.max(1, Math.ceil(total / pageSize));
1859
2102
  const from = total === 0 ? 0 : (page - 1) * pageSize + 1;
1860
2103
  const to = Math.min(total, page * pageSize);
1861
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("nav", { className: cx("pire-pagination", className), style, "aria-label": msg.paginationLabel, children: [
1862
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-pagination-count", children: msg.paginationRange.replace("{from}", from.toLocaleString()).replace("{to}", to.toLocaleString()).replace("{total}", total.toLocaleString()) }),
1863
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2104
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("nav", { className: cx("pire-pagination", className), style, "aria-label": msg.paginationLabel, children: [
2105
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "pire-pagination-count", children: msg.paginationRange.replace("{from}", from.toLocaleString()).replace("{to}", to.toLocaleString()).replace("{total}", total.toLocaleString()) }),
2106
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1864
2107
  IconButton,
1865
2108
  {
1866
2109
  icon: "chevron-left",
@@ -1871,8 +2114,8 @@ function Pagination({
1871
2114
  onPress: () => onPageChange?.(page - 1)
1872
2115
  }
1873
2116
  ),
1874
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-pagination-count", "aria-live": "polite", children: msg.paginationPageOf.replace("{page}", String(page)).replace("{pages}", String(pages)) }),
1875
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2117
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "pire-pagination-count", "aria-live": "polite", children: msg.paginationPageOf.replace("{page}", String(page)).replace("{pages}", String(pages)) }),
2118
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1876
2119
  IconButton,
1877
2120
  {
1878
2121
  icon: "chevron-right",
@@ -1883,7 +2126,7 @@ function Pagination({
1883
2126
  onPress: () => onPageChange?.(page + 1)
1884
2127
  }
1885
2128
  ),
1886
- onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2129
+ onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1887
2130
  Select,
1888
2131
  {
1889
2132
  "aria-label": msg.paginationRowsPerPage,
@@ -1898,59 +2141,8 @@ function Pagination({
1898
2141
  ] });
1899
2142
  }
1900
2143
 
1901
- // src/components/navigation/Menu.tsx
1902
- var import_react_aria_components24 = require("react-aria-components");
1903
- var import_jsx_runtime36 = require("react/jsx-runtime");
1904
- function Menu({ minWidth, className, style, ...rest }) {
1905
- const width = typeof minWidth === "number" ? `${minWidth}px` : minWidth;
1906
- const menuStyle = width == null ? style : { ["--pire-menu-min-w"]: width, ...style };
1907
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1908
- import_react_aria_components24.Menu,
1909
- {
1910
- className: cx("pire-menu", className),
1911
- style: menuStyle,
1912
- ...rest
1913
- }
1914
- );
1915
- }
1916
- function MenuItem({
1917
- children,
1918
- icon,
1919
- description,
1920
- shortcut,
1921
- tone = "default",
1922
- className,
1923
- ...rest
1924
- }) {
1925
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
1926
- import_react_aria_components24.MenuItem,
1927
- {
1928
- className: cx("pire-menu-item", className),
1929
- "data-tone": tone === "danger" ? "danger" : void 0,
1930
- ...rest,
1931
- children: [
1932
- icon ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Icon, { name: icon, size: 16, className: "pire-menu-item-icon" }) : null,
1933
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "pire-menu-item-body", children: [
1934
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "pire-menu-item-label", children }),
1935
- description ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "pire-menu-item-desc", children: description }) : null
1936
- ] }),
1937
- shortcut ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("kbd", { className: "pire-menu-item-shortcut", children: shortcut }) : null
1938
- ]
1939
- }
1940
- );
1941
- }
1942
- function MenuSection({ title, children, className, ...rest }) {
1943
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_aria_components24.MenuSection, { className: cx("pire-menu-section", className), ...rest, children: [
1944
- title ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_aria_components24.Header, { className: "pire-menu-section-title", children: title }) : null,
1945
- children
1946
- ] });
1947
- }
1948
- function MenuSeparator({ className }) {
1949
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_aria_components24.Separator, { className: cx("pire-menu-separator", className) });
1950
- }
1951
-
1952
2144
  // src/components/feedback/InlineMessage.tsx
1953
- var import_jsx_runtime37 = require("react/jsx-runtime");
2145
+ var import_jsx_runtime39 = require("react/jsx-runtime");
1954
2146
  var KIND_ICON = {
1955
2147
  info: "info",
1956
2148
  success: "check-circle-2",
@@ -1960,7 +2152,7 @@ var KIND_ICON = {
1960
2152
  function InlineMessage({ kind = "info", title, action, onClose, children, className, ...rest }) {
1961
2153
  const msg = usePireMessages();
1962
2154
  const assertive = kind === "error" || kind === "warning";
1963
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
2155
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
1964
2156
  "div",
1965
2157
  {
1966
2158
  className: cx("pire-msg", className),
@@ -1969,58 +2161,21 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
1969
2161
  "aria-live": assertive ? "assertive" : "polite",
1970
2162
  ...rest,
1971
2163
  children: [
1972
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Icon, { name: KIND_ICON[kind], size: 16, style: { marginTop: 2 } }),
1973
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "var(--sp-1)" }, children: [
1974
- title ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "pire-msg-title", children: title }) : null,
1975
- children ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "pire-msg-body", children }) : null,
2164
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: KIND_ICON[kind], size: 16, style: { marginTop: 2 } }),
2165
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "var(--sp-1)" }, children: [
2166
+ title ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "pire-msg-title", children: title }) : null,
2167
+ children ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "pire-msg-body", children }) : null,
1976
2168
  action
1977
2169
  ] }),
1978
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(IconButton, { icon: "x", label: msg.inlineMessageDismiss, size: "sm", onPress: onClose }) : null
2170
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IconButton, { icon: "x", label: msg.inlineMessageDismiss, size: "sm", onPress: onClose }) : null
1979
2171
  ]
1980
2172
  }
1981
2173
  );
1982
2174
  }
1983
2175
 
1984
- // src/components/feedback/ProgressBar.tsx
1985
- var import_react_aria_components25 = require("react-aria-components");
1986
- var import_jsx_runtime38 = require("react/jsx-runtime");
1987
- function ProgressBar({
1988
- value = 0,
1989
- minValue = 0,
1990
- maxValue = 100,
1991
- label,
1992
- showValue = true,
1993
- isIndeterminate,
1994
- status = "informative",
1995
- size = "md",
1996
- className,
1997
- style
1998
- }) {
1999
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2000
- import_react_aria_components25.ProgressBar,
2001
- {
2002
- className: cx("pire-progress", className),
2003
- "data-status": status,
2004
- "data-size": size,
2005
- value,
2006
- minValue,
2007
- maxValue,
2008
- isIndeterminate,
2009
- style,
2010
- children: ({ percentage, valueText }) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
2011
- label || showValue ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "pire-progress-head", children: [
2012
- label ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_aria_components25.Label, { children: label }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", {}),
2013
- showValue && !isIndeterminate ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "pire-numeric", children: valueText }) : null
2014
- ] }) : null,
2015
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "pire-progress-track", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "pire-progress-fill", style: { width: `${isIndeterminate ? 40 : percentage}%` } }) })
2016
- ] })
2017
- }
2018
- );
2019
- }
2020
-
2021
2176
  // src/components/feedback/Toast.tsx
2022
- var React11 = __toESM(require("react"), 1);
2023
- var import_jsx_runtime39 = require("react/jsx-runtime");
2177
+ var React12 = __toESM(require("react"), 1);
2178
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2024
2179
  var KIND_ICON2 = {
2025
2180
  info: "info",
2026
2181
  success: "check-circle-2",
@@ -2029,7 +2184,7 @@ var KIND_ICON2 = {
2029
2184
  };
2030
2185
  function Toast({ kind = "success", onClose, position = "bottom-center", children, className, ...rest }) {
2031
2186
  const msg = usePireMessages();
2032
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2187
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
2033
2188
  "div",
2034
2189
  {
2035
2190
  className: cx("pire-toast", className),
@@ -2038,40 +2193,40 @@ function Toast({ kind = "success", onClose, position = "bottom-center", children
2038
2193
  "aria-live": kind === "error" ? "assertive" : "polite",
2039
2194
  ...rest,
2040
2195
  children: [
2041
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: KIND_ICON2[kind], size: 16 }),
2042
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { style: { flex: 1 }, children }),
2043
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IconButton, { icon: "x", label: msg.toastDismiss, size: "sm", variant: "inverse", onPress: onClose }) : null
2196
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: KIND_ICON2[kind], size: 16 }),
2197
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { style: { flex: 1 }, children }),
2198
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(IconButton, { icon: "x", label: msg.toastDismiss, size: "sm", variant: "inverse", onPress: onClose }) : null
2044
2199
  ]
2045
2200
  }
2046
2201
  );
2047
2202
  }
2048
- var ToastContext = React11.createContext(null);
2203
+ var ToastContext = React12.createContext(null);
2049
2204
  function ToastProvider({ children, timeout = 6e3 }) {
2050
2205
  const msg = usePireMessages();
2051
- const [toasts, setToasts] = React11.useState([]);
2052
- const close = React11.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2053
- const add = React11.useCallback((toast) => {
2206
+ const [toasts, setToasts] = React12.useState([]);
2207
+ const close = React12.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
2208
+ const add = React12.useCallback((toast) => {
2054
2209
  const id = Math.random().toString(36).slice(2);
2055
2210
  setToasts((t) => [...t, { ...toast, id }]);
2056
2211
  const ms = toast.timeout ?? timeout;
2057
2212
  if (ms > 0) setTimeout(() => close(id), ms);
2058
2213
  return id;
2059
2214
  }, [close, timeout]);
2060
- const value = React11.useMemo(() => ({ add, close }), [add, close]);
2061
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(ToastContext.Provider, { value, children: [
2215
+ const value = React12.useMemo(() => ({ add, close }), [add, close]);
2216
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(ToastContext.Provider, { value, children: [
2062
2217
  children,
2063
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2218
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2064
2219
  ] });
2065
2220
  }
2066
2221
  function useToast() {
2067
- const ctx = React11.useContext(ToastContext);
2222
+ const ctx = React12.useContext(ToastContext);
2068
2223
  if (!ctx) throw new Error("useToast must be used inside <ToastProvider>");
2069
2224
  return ctx;
2070
2225
  }
2071
2226
 
2072
2227
  // src/components/data/KpiTile.tsx
2073
- var import_react_aria_components26 = require("react-aria-components");
2074
- var import_jsx_runtime40 = require("react/jsx-runtime");
2228
+ var import_react_aria_components27 = require("react-aria-components");
2229
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2075
2230
  function KpiTile({
2076
2231
  label,
2077
2232
  value,
@@ -2087,50 +2242,50 @@ function KpiTile({
2087
2242
  style
2088
2243
  }) {
2089
2244
  const tone = deltaTone ?? (deltaDirection === "down" ? "negative" : "positive");
2090
- const body = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
2091
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "pire-kpi-label", children: [
2092
- icon ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: icon, size: 16 }) : null,
2245
+ const body = /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
2246
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "pire-kpi-label", children: [
2247
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Icon, { name: icon, size: 16 }) : null,
2093
2248
  label
2094
2249
  ] }),
2095
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "pire-kpi-value", children: [
2250
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "pire-kpi-value", children: [
2096
2251
  value,
2097
- unit ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "pire-kpi-unit", children: unit }) : null
2252
+ unit ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-kpi-unit", children: unit }) : null
2098
2253
  ] }),
2099
- delta ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "pire-kpi-delta", "data-tone": tone, children: [
2100
- deltaDirection ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: deltaDirection === "up" ? "trending-up" : "trending-down", size: 12 }) : null,
2254
+ delta ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "pire-kpi-delta", "data-tone": tone, children: [
2255
+ deltaDirection ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Icon, { name: deltaDirection === "up" ? "trending-up" : "trending-down", size: 12 }) : null,
2101
2256
  delta
2102
2257
  ] }) : null,
2103
- footnote ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "pire-kpi-foot", children: footnote }) : null
2258
+ footnote ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-kpi-foot", children: footnote }) : null
2104
2259
  ] });
2105
2260
  const props = { className: cx("pire-kpi", className), "data-status": status, style };
2106
- return onPress ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_aria_components26.Button, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { ...props, children: body });
2261
+ return onPress ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_aria_components27.Button, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { ...props, children: body });
2107
2262
  }
2108
2263
 
2109
2264
  // src/components/data/ObjectHeader.tsx
2110
- var import_jsx_runtime41 = require("react/jsx-runtime");
2265
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2111
2266
  function ObjectHeader({ title, subtitle, id, breadcrumb, badge, facts, actions, className, ...rest }) {
2112
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("header", { className: cx("pire-objheader", className), ...rest, children: [
2267
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("header", { className: cx("pire-objheader", className), ...rest, children: [
2113
2268
  breadcrumb,
2114
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "pire-objheader-row", children: [
2115
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { style: { minWidth: 0 }, children: [
2116
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h1", { className: "pire-objheader-title", children: title }),
2117
- subtitle || id ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "pire-objheader-sub", children: [
2269
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "pire-objheader-row", children: [
2270
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { style: { minWidth: 0 }, children: [
2271
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("h1", { className: "pire-objheader-title", children: title }),
2272
+ subtitle || id ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "pire-objheader-sub", children: [
2118
2273
  subtitle,
2119
- id ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-objheader-id", children: id }) : null
2274
+ id ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "pire-objheader-id", children: id }) : null
2120
2275
  ] }) : null
2121
2276
  ] }),
2122
2277
  badge,
2123
- actions ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "pire-objheader-actions", children: actions }) : null
2278
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "pire-objheader-actions", children: actions }) : null
2124
2279
  ] }),
2125
- facts?.length ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("dl", { className: "pire-facts", style: { margin: 0 }, children: facts.map((fact) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
2126
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("dt", { className: "pire-fact-label", children: fact.label }),
2127
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("dd", { className: "pire-fact-value", "data-numeric": fact.numeric ? "true" : void 0, style: { margin: 0 }, children: fact.value })
2280
+ facts?.length ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("dl", { className: "pire-facts", style: { margin: 0 }, children: facts.map((fact) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
2281
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("dt", { className: "pire-fact-label", children: fact.label }),
2282
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("dd", { className: "pire-fact-value", "data-numeric": fact.numeric ? "true" : void 0, style: { margin: 0 }, children: fact.value })
2128
2283
  ] }, fact.label)) }) : null
2129
2284
  ] });
2130
2285
  }
2131
2286
 
2132
2287
  // src/components/data/FilterBar.tsx
2133
- var import_jsx_runtime42 = require("react/jsx-runtime");
2288
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2134
2289
  function FilterBar({
2135
2290
  children,
2136
2291
  activeFilters = [],
@@ -2147,66 +2302,66 @@ function FilterBar({
2147
2302
  const label = useMessage("filterBarLabel", rest["aria-label"]);
2148
2303
  const go = useMessage("filterBarGo", goLabel);
2149
2304
  const clearAll = useMessage("filterBarClearAll", clearAllLabel);
2150
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("section", { className: cx("pire-filterbar", className), ...rest, "aria-label": label, children: [
2151
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "pire-filterbar-controls", children: [
2305
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("section", { className: cx("pire-filterbar", className), ...rest, "aria-label": label, children: [
2306
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "pire-filterbar-controls", children: [
2152
2307
  children,
2153
- onGo ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Button, { variant: "primary", onPress: onGo, children: go }) : null
2308
+ onGo ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, { variant: "primary", onPress: onGo, children: go }) : null
2154
2309
  ] }),
2155
- activeFilters.length || resultLabel || actions ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "pire-filterbar-foot", children: [
2156
- activeFilters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Tag, { onRemove: onRemoveFilter ? () => onRemoveFilter(filter.id) : void 0, children: filter.label }, filter.id)),
2157
- activeFilters.length && onClear ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Button, { variant: "tertiary", size: "sm", onPress: onClear, children: clearAll }) : null,
2158
- resultLabel ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "pire-filterbar-result", "aria-live": "polite", children: resultLabel }) : null,
2159
- actions ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "pire-filterbar-actions", children: actions }) : null
2310
+ activeFilters.length || resultLabel || actions ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "pire-filterbar-foot", children: [
2311
+ activeFilters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Tag, { onRemove: onRemoveFilter ? () => onRemoveFilter(filter.id) : void 0, children: filter.label }, filter.id)),
2312
+ activeFilters.length && onClear ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, { variant: "tertiary", size: "sm", onPress: onClear, children: clearAll }) : null,
2313
+ resultLabel ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "pire-filterbar-result", "aria-live": "polite", children: resultLabel }) : null,
2314
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "pire-filterbar-actions", children: actions }) : null
2160
2315
  ] }) : null
2161
2316
  ] });
2162
2317
  }
2163
2318
 
2164
2319
  // src/components/data/DescriptionList.tsx
2165
- var import_jsx_runtime43 = require("react/jsx-runtime");
2320
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2166
2321
  function DescriptionList({ items, layout = "rows", columns = 3, className, style, ...rest }) {
2167
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2322
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2168
2323
  "dl",
2169
2324
  {
2170
2325
  className: cx("pire-dl", className),
2171
2326
  "data-layout": layout,
2172
2327
  style: { ...layout === "grid" ? { "--pire-dl-cols": columns } : null, ...style },
2173
2328
  ...rest,
2174
- children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "pire-dl-row", "data-emphasis": item.emphasis ? "true" : void 0, children: [
2175
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("dt", { className: "pire-dl-term", children: [
2329
+ children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "pire-dl-row", "data-emphasis": item.emphasis ? "true" : void 0, children: [
2330
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("dt", { className: "pire-dl-term", children: [
2176
2331
  item.label,
2177
2332
  item.hint
2178
2333
  ] }),
2179
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("dd", { className: "pire-dl-value", "data-numeric": item.numeric ? "true" : void 0, children: item.value })
2334
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dd", { className: "pire-dl-value", "data-numeric": item.numeric ? "true" : void 0, children: item.value })
2180
2335
  ] }, i))
2181
2336
  }
2182
2337
  );
2183
2338
  }
2184
2339
 
2185
2340
  // src/components/data/Timeline.tsx
2186
- var import_jsx_runtime44 = require("react/jsx-runtime");
2341
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2187
2342
  function Timeline({ entries, reverse = false, className, ...rest }) {
2188
2343
  const list = reverse ? [...entries].reverse() : entries;
2189
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("ol", { className: cx("pire-timeline", className), ...rest, children: list.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("li", { className: "pire-timeline-item", children: [
2190
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "pire-timeline-time", children: entry.time }),
2191
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "pire-timeline-text", children: entry.event }),
2192
- entry.actor ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "pire-timeline-actor", children: entry.actor }) : null
2344
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("ol", { className: cx("pire-timeline", className), ...rest, children: list.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("li", { className: "pire-timeline-item", children: [
2345
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-timeline-time", children: entry.time }),
2346
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-timeline-text", children: entry.event }),
2347
+ entry.actor ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-timeline-actor", children: entry.actor }) : null
2193
2348
  ] }, entry.id ?? i)) });
2194
2349
  }
2195
2350
 
2196
2351
  // src/components/data/LinkList.tsx
2197
- var import_react_aria_components27 = require("react-aria-components");
2198
- var import_jsx_runtime45 = require("react/jsx-runtime");
2352
+ var import_react_aria_components28 = require("react-aria-components");
2353
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2199
2354
  function LinkList({ items, onSelect, className, ...rest }) {
2200
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cx("pire-linklist", className), role: "list", ...rest, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react_aria_components27.Button, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
2201
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
2202
- item.key ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-linklist-key", children: item.key }) : null,
2203
- item.text ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-linklist-text", children: item.text }) : null,
2355
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cx("pire-linklist", className), role: "list", ...rest, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_aria_components28.Button, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
2356
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
2357
+ item.key ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "pire-linklist-key", children: item.key }) : null,
2358
+ item.text ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "pire-linklist-text", children: item.text }) : null,
2204
2359
  item.trailing
2205
2360
  ] }, item.id)) });
2206
2361
  }
2207
2362
 
2208
2363
  // src/components/layout/PageBand.tsx
2209
- var import_jsx_runtime46 = require("react/jsx-runtime");
2364
+ var import_jsx_runtime47 = require("react/jsx-runtime");
2210
2365
  function PageBand({
2211
2366
  surface = "card",
2212
2367
  hasBorder = true,
@@ -2214,7 +2369,7 @@ function PageBand({
2214
2369
  className,
2215
2370
  ...rest
2216
2371
  }) {
2217
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
2372
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2218
2373
  "div",
2219
2374
  {
2220
2375
  className: cx("pire-pageband", className),
@@ -2227,56 +2382,56 @@ function PageBand({
2227
2382
  }
2228
2383
 
2229
2384
  // src/components/layout/PageHeader.tsx
2230
- var import_jsx_runtime47 = require("react/jsx-runtime");
2385
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2231
2386
  function PageHeader({ title, subtitle, actions, className, ...rest }) {
2232
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("header", { className: cx("pire-pageheader", className), ...rest, children: [
2233
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { style: { minWidth: 0 }, children: [
2234
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h1", { className: "pire-pageheader-title", children: title }),
2235
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "pire-pageheader-sub", children: subtitle }) : null
2387
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("header", { className: cx("pire-pageheader", className), ...rest, children: [
2388
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { style: { minWidth: 0 }, children: [
2389
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("h1", { className: "pire-pageheader-title", children: title }),
2390
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "pire-pageheader-sub", children: subtitle }) : null
2236
2391
  ] }),
2237
- actions ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "pire-pageheader-actions", children: actions }) : null
2392
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "pire-pageheader-actions", children: actions }) : null
2238
2393
  ] });
2239
2394
  }
2240
2395
 
2241
2396
  // src/components/layout/SectionHeader.tsx
2242
- var import_jsx_runtime48 = require("react/jsx-runtime");
2397
+ var import_jsx_runtime49 = require("react/jsx-runtime");
2243
2398
  function SectionHeader({ title, meta, actions, className, ...rest }) {
2244
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cx("pire-sectionhead", className), ...rest, children: [
2245
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-eyebrow", children: title }),
2246
- meta ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { style: { font: "var(--type-caption)", color: "var(--text-tertiary)" }, children: meta }) : null,
2247
- actions ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "pire-sectionhead-actions", children: actions }) : null
2399
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cx("pire-sectionhead", className), ...rest, children: [
2400
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-eyebrow", children: title }),
2401
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { style: { font: "var(--type-caption)", color: "var(--text-tertiary)" }, children: meta }) : null,
2402
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "pire-sectionhead-actions", children: actions }) : null
2248
2403
  ] });
2249
2404
  }
2250
2405
 
2251
2406
  // src/components/layout/SelectionBar.tsx
2252
- var import_jsx_runtime49 = require("react/jsx-runtime");
2407
+ var import_jsx_runtime50 = require("react/jsx-runtime");
2253
2408
  function SelectionBar({ count, noun = "record", children, actions, className, ...rest }) {
2254
2409
  if (!count) return null;
2255
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cx("pire-selectionbar", className), role: "status", "aria-live": "polite", ...rest, children: [
2256
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "pire-selectionbar-count", children: [
2410
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cx("pire-selectionbar", className), role: "status", "aria-live": "polite", ...rest, children: [
2411
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "pire-selectionbar-count", children: [
2257
2412
  count.toLocaleString(),
2258
2413
  " ",
2259
2414
  noun,
2260
2415
  count === 1 ? "" : "s",
2261
2416
  " selected"
2262
2417
  ] }),
2263
- children ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { style: { color: "var(--text-secondary)", font: "var(--type-caption)" }, children }) : null,
2264
- actions ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "pire-selectionbar-actions", children: actions }) : null
2418
+ children ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { style: { color: "var(--text-secondary)", font: "var(--type-caption)" }, children }) : null,
2419
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pire-selectionbar-actions", children: actions }) : null
2265
2420
  ] });
2266
2421
  }
2267
2422
 
2268
2423
  // src/components/layout/FooterBar.tsx
2269
- var import_jsx_runtime50 = require("react/jsx-runtime");
2424
+ var import_jsx_runtime51 = require("react/jsx-runtime");
2270
2425
  function FooterBar({ note, actions, children, className, ...rest }) {
2271
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("footer", { className: cx("pire-footerbar", className), ...rest, children: [
2272
- note ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "pire-footerbar-note", children: note }) : null,
2426
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("footer", { className: cx("pire-footerbar", className), ...rest, children: [
2427
+ note ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "pire-footerbar-note", children: note }) : null,
2273
2428
  children,
2274
- actions ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pire-footerbar-actions", children: actions }) : null
2429
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "pire-footerbar-actions", children: actions }) : null
2275
2430
  ] });
2276
2431
  }
2277
2432
 
2278
2433
  // src/components/patterns/ConfirmDialog.tsx
2279
- var import_jsx_runtime51 = require("react/jsx-runtime");
2434
+ var import_jsx_runtime52 = require("react/jsx-runtime");
2280
2435
  function ConfirmDialog({
2281
2436
  isOpen,
2282
2437
  title,
@@ -2290,7 +2445,7 @@ function ConfirmDialog({
2290
2445
  onConfirm,
2291
2446
  onCancel
2292
2447
  }) {
2293
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
2448
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
2294
2449
  Dialog,
2295
2450
  {
2296
2451
  isOpen,
@@ -2300,12 +2455,12 @@ function ConfirmDialog({
2300
2455
  onClose: onCancel,
2301
2456
  isDismissable: !isBusy,
2302
2457
  showClose: false,
2303
- footer: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
2304
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
2305
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
2458
+ footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
2459
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
2460
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
2306
2461
  ] }),
2307
2462
  children: [
2308
- consequence ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
2463
+ consequence ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
2309
2464
  children
2310
2465
  ]
2311
2466
  }
@@ -2313,12 +2468,12 @@ function ConfirmDialog({
2313
2468
  }
2314
2469
 
2315
2470
  // src/components/patterns/SidePanel.tsx
2316
- var import_react_aria_components28 = require("react-aria-components");
2317
- var import_jsx_runtime52 = require("react/jsx-runtime");
2471
+ var import_react_aria_components29 = require("react-aria-components");
2472
+ var import_jsx_runtime53 = require("react/jsx-runtime");
2318
2473
  function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onClose, className }) {
2319
2474
  const msg = usePireMessages();
2320
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
2321
- import_react_aria_components28.ModalOverlay,
2475
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
2476
+ import_react_aria_components29.ModalOverlay,
2322
2477
  {
2323
2478
  className: "pire-sidepanel-overlay",
2324
2479
  isOpen,
@@ -2326,34 +2481,138 @@ function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onC
2326
2481
  onOpenChange: (o) => {
2327
2482
  if (!o) onClose?.();
2328
2483
  },
2329
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_react_aria_components28.Modal, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_aria_components28.Dialog, { className: "pire-dialog", style: { height: "100%" }, children: [
2330
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("header", { className: "pire-dialog-head", children: [
2331
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
2332
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_react_aria_components28.Heading, { slot: "title", className: "pire-dialog-title", children: title }),
2333
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
2484
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_aria_components29.Modal, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_aria_components29.Dialog, { className: "pire-dialog", style: { height: "100%" }, children: [
2485
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("header", { className: "pire-dialog-head", children: [
2486
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
2487
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_aria_components29.Heading, { slot: "title", className: "pire-dialog-title", children: title }),
2488
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
2334
2489
  ] }),
2335
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
2490
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
2336
2491
  ] }),
2337
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
2338
- footer ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null
2492
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
2493
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null
2339
2494
  ] }) })
2340
2495
  }
2341
2496
  );
2342
2497
  }
2343
2498
 
2344
2499
  // src/components/patterns/EmptyState.tsx
2345
- var import_jsx_runtime53 = require("react/jsx-runtime");
2500
+ var import_jsx_runtime54 = require("react/jsx-runtime");
2346
2501
  function EmptyState({ icon = "file-text", title, action, compact, children, className, ...rest }) {
2347
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
2348
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
2349
- title ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
2350
- children ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
2502
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
2503
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
2504
+ title ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
2505
+ children ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
2351
2506
  action
2352
2507
  ] });
2353
2508
  }
2354
2509
 
2510
+ // src/components/patterns/FileDropZone.tsx
2511
+ var React13 = __toESM(require("react"), 1);
2512
+ var import_react_aria_components30 = require("react-aria-components");
2513
+ var import_jsx_runtime55 = require("react/jsx-runtime");
2514
+ var isImage2 = (file) => file.type.startsWith("image/");
2515
+ function FileDropZone({
2516
+ label,
2517
+ value,
2518
+ defaultValue,
2519
+ onChange,
2520
+ acceptedFileTypes,
2521
+ allowsMultiple,
2522
+ maxSize,
2523
+ onError,
2524
+ showPreview = true,
2525
+ uploadProgress,
2526
+ promptLabel,
2527
+ height = "regular",
2528
+ description,
2529
+ errorMessage,
2530
+ isInvalid,
2531
+ isDisabled,
2532
+ isReadOnly,
2533
+ isRequired,
2534
+ fullWidth = true,
2535
+ className,
2536
+ style
2537
+ }) {
2538
+ const msg = usePireMessages();
2539
+ const [uncontrolled, setUncontrolled] = React13.useState(defaultValue ?? []);
2540
+ const files = value ?? uncontrolled;
2541
+ const created = React13.useRef([]);
2542
+ React13.useEffect(() => () => {
2543
+ for (const url of created.current) URL.revokeObjectURL(url);
2544
+ }, []);
2545
+ const commit = (next) => {
2546
+ if (value === void 0) setUncontrolled(next);
2547
+ onChange?.(next);
2548
+ };
2549
+ const accept = (picked) => {
2550
+ if (isDisabled || isReadOnly || !picked.length) return;
2551
+ const { accepted, rejected } = screenFiles(picked, { maxSize, acceptedFileTypes });
2552
+ if (rejected.length) onError?.(rejected);
2553
+ if (!accepted.length) return;
2554
+ const wrapped = accepted.map((file) => {
2555
+ const previewUrl = showPreview && isImage2(file) ? URL.createObjectURL(file) : void 0;
2556
+ if (previewUrl) created.current.push(previewUrl);
2557
+ return { file, previewUrl };
2558
+ });
2559
+ commit(allowsMultiple ? [...files, ...wrapped] : wrapped.slice(0, 1));
2560
+ };
2561
+ const remove = (target) => commit(files.filter((f) => f.file !== target));
2562
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: cx("pire-field", className), style, "data-full-width": String(fullWidth), children: [
2563
+ label ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "pire-field-label", children: [
2564
+ label,
2565
+ isRequired ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
2566
+ ] }) : null,
2567
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
2568
+ import_react_aria_components30.DropZone,
2569
+ {
2570
+ className: "pire-dropzone",
2571
+ "data-height": height,
2572
+ isDisabled: isDisabled || isReadOnly,
2573
+ onDrop: async (e) => {
2574
+ const dropped = await Promise.all(
2575
+ e.items.filter(import_react_aria_components30.isFileDropItem).map((item) => item.getFile())
2576
+ );
2577
+ accept(dropped);
2578
+ },
2579
+ children: [
2580
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Icon, { name: "download", size: 24, className: "pire-dropzone-icon" }),
2581
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-dropzone-prompt", children: promptLabel ?? msg.fileDropZonePrompt }),
2582
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
2583
+ import_react_aria_components30.FileTrigger,
2584
+ {
2585
+ acceptedFileTypes,
2586
+ allowsMultiple,
2587
+ onSelect: (list) => accept(list ? [...list] : []),
2588
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Button, { variant: "secondary", isDisabled: isDisabled || isReadOnly, children: msg.fileUploadChoose })
2589
+ }
2590
+ )
2591
+ ]
2592
+ }
2593
+ ),
2594
+ files.length ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("li", { className: "pire-fileupload-item", children: [
2595
+ previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
2596
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-fileupload-name", children: file.name }),
2597
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
2598
+ isDisabled || isReadOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
2599
+ IconButton,
2600
+ {
2601
+ icon: "x",
2602
+ size: "sm",
2603
+ label: msg.fileUploadRemoveNamed.replace("{name}", file.name),
2604
+ onPress: () => remove(file)
2605
+ }
2606
+ )
2607
+ ] }, `${file.name}-${file.size}-${file.lastModified}`)) }) : null,
2608
+ uploadProgress != null ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
2609
+ description ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-field-hint", children: description }) : null,
2610
+ isInvalid && errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-field-error", children: errorMessage }) : null
2611
+ ] });
2612
+ }
2613
+
2355
2614
  // src/index.ts
2356
- var import_react_aria_components29 = require("react-aria-components");
2615
+ var import_react_aria_components31 = require("react-aria-components");
2357
2616
  // Annotate the CommonJS export names for ESM import in node:
2358
2617
  0 && (module.exports = {
2359
2618
  Avatar,
@@ -2370,6 +2629,8 @@ var import_react_aria_components29 = require("react-aria-components");
2370
2629
  Dialog,
2371
2630
  DialogTrigger,
2372
2631
  EmptyState,
2632
+ FileDropZone,
2633
+ FileUpload,
2373
2634
  FilterBar,
2374
2635
  FooterBar,
2375
2636
  FormField,
@@ -2425,6 +2686,7 @@ var import_react_aria_components29 = require("react-aria-components");
2425
2686
  configureIcons,
2426
2687
  enMessages,
2427
2688
  esMessages,
2689
+ formatFileSize,
2428
2690
  usePireMessages,
2429
2691
  useToast
2430
2692
  });