@orianatech/pire 1.1.0 → 1.3.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
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ AppLauncher: () => AppLauncher,
33
34
  Avatar: () => Avatar,
34
35
  Badge: () => Badge,
35
36
  BarChart: () => BarChart,
@@ -49,17 +50,17 @@ __export(src_exports, {
49
50
  DialogBody: () => DialogBody,
50
51
  DialogDescription: () => DialogDescription,
51
52
  DialogTitle: () => DialogTitle,
52
- DialogTrigger: () => import_react_aria_components34.DialogTrigger,
53
+ DialogTrigger: () => import_react_aria_components36.DialogTrigger,
53
54
  DonutChart: () => DonutChart,
54
55
  EmptyState: () => EmptyState,
55
56
  FileDropZone: () => FileDropZone,
56
57
  FileUpload: () => FileUpload,
57
58
  FilterBar: () => FilterBar,
58
- Focusable: () => import_react_aria_components35.Focusable,
59
+ Focusable: () => import_react_aria_components37.Focusable,
59
60
  FooterBar: () => FooterBar,
60
61
  FormField: () => FormField,
61
62
  Heading: () => Heading,
62
- I18nProvider: () => import_react_aria_components34.I18nProvider,
63
+ I18nProvider: () => import_react_aria_components36.I18nProvider,
63
64
  ICON_NAMES: () => ICON_NAMES,
64
65
  Icon: () => Icon,
65
66
  IconButton: () => IconButton,
@@ -74,32 +75,34 @@ __export(src_exports, {
74
75
  MenuItem: () => MenuItem,
75
76
  MenuSection: () => MenuSection,
76
77
  MenuSeparator: () => MenuSeparator,
77
- MenuTrigger: () => import_react_aria_components34.MenuTrigger,
78
+ MenuTrigger: () => import_react_aria_components36.MenuTrigger,
78
79
  MultiComboBox: () => MultiComboBox,
80
+ NumPad: () => NumPad,
79
81
  NumberField: () => NumberField,
80
82
  ObjectHeader: () => ObjectHeader,
81
83
  PageBand: () => PageBand,
82
84
  PageHeader: () => PageHeader,
83
85
  Pagination: () => Pagination,
84
86
  PireIntlProvider: () => PireIntlProvider,
85
- Popover: () => import_react_aria_components34.Popover,
87
+ Popover: () => import_react_aria_components36.Popover,
86
88
  ProgressBar: () => ProgressBar,
87
89
  Radio: () => Radio,
88
90
  RadioGroup: () => RadioGroup,
89
- RouterProvider: () => import_react_aria_components34.RouterProvider,
91
+ RouterProvider: () => import_react_aria_components36.RouterProvider,
90
92
  SectionHeader: () => SectionHeader,
91
93
  SegmentedControl: () => SegmentedControl,
92
94
  Select: () => Select,
93
95
  SelectionBar: () => SelectionBar,
94
96
  Separator: () => Separator,
95
97
  ShellBar: () => ShellBar,
98
+ ShellRail: () => ShellRail,
96
99
  SideNav: () => SideNav,
97
100
  SidePanel: () => SidePanel,
98
101
  Skeleton: () => Skeleton,
99
102
  SkeletonTableRow: () => SkeletonTableRow,
100
103
  SplitPane: () => SplitPane,
101
104
  Strong: () => Strong,
102
- SubmenuTrigger: () => import_react_aria_components34.SubmenuTrigger,
105
+ SubmenuTrigger: () => import_react_aria_components36.SubmenuTrigger,
103
106
  Switch: () => Switch,
104
107
  Tabs: () => Tabs,
105
108
  Tag: () => Tag,
@@ -245,6 +248,7 @@ var ICON_MARKUP = {
245
248
  "sort--descending": '<path d="M18 22 19.414 20.586 23 24.172 23 4 25 4 25 24.172 28.586 20.586 30 22 24 28 18 22z"/><path d="M2 6H16V8H2z"/><path d="M6 12H16V14H6z"/><path d="M10 18H16V20H10z"/>',
246
249
  "star": '<path d="M16,6.52l2.76,5.58.46,1,1,.15,6.16.89L22,18.44l-.75.73.18,1,1.05,6.13-5.51-2.89L16,23l-.93.49L9.56,26.34l1-6.13.18-1L10,18.44,5.58,14.09l6.16-.89,1-.15.46-1L16,6.52M16,2l-4.55,9.22L1.28,12.69l7.36,7.18L6.9,30,16,25.22,25.1,30,23.36,19.87l7.36-7.17L20.55,11.22Z"/>',
247
250
  "star--filled": '<path d="M16,2l-4.55,9.22L1.28,12.69l7.36,7.18L6.9,30,16,25.22,25.1,30,23.36,19.87l7.36-7.17L20.55,11.22Z"/>',
251
+ "store": '<path d="M30,10.68l-2-6A1,1,0,0,0,27,4H5a1,1,0,0,0-1,.68l-2,6A1.19,1.19,0,0,0,2,11v6a1,1,0,0,0,1,1H4V28H6V18h6V28H28V18h1a1,1,0,0,0,1-1V11A1.19,1.19,0,0,0,30,10.68ZM26,26H14V18H26Zm2-10H24V12H22v4H17V12H15v4H10V12H8v4H4V11.16L5.72,6H26.28L28,11.16Z"/>',
248
252
  "subtract": '<path d="M8 15H24V17H8z"/>',
249
253
  "table--split": '<path d="M27,3H5A2,2,0,0,0,3,5V27a2,2,0,0,0,2,2H27a2,2,0,0,0,2-2V5A2,2,0,0,0,27,3Zm0,2V9H5V5ZM17,11H27v7H17Zm-2,7H5V11H15ZM5,20H15v7H5Zm12,7V20H27v7Z"/>',
250
254
  "tag": '<path d="M10,14a4,4,0,1,1,4-4A4.0045,4.0045,0,0,1,10,14Zm0-6a2,2,0,1,0,1.998,2.0044A2.002,2.002,0,0,0,10,8Z"/><path d="M16.6436,29.4145,2.5858,15.3555A2,2,0,0,1,2,13.9414V4A2,2,0,0,1,4,2h9.9413a2,2,0,0,1,1.4142.5858L29.4144,16.6436a2.0005,2.0005,0,0,1,0,2.8285l-9.9424,9.9425a2.0008,2.0008,0,0,1-2.8285,0ZM4,4v9.9417L18.0578,28,28,18.0579,13.9416,4Z"/>',
@@ -272,6 +276,9 @@ var CARBON_MAP = {
272
276
  "bell": "notification",
273
277
  "help-circle": "help",
274
278
  "grid-3x3": "grid",
279
+ /* The app launcher's trigger. Carbon has no 2x2 grid, and `apps` is the glyph it uses for
280
+ exactly this affordance, so the Lucide name maps onto it rather than onto plain `grid`. */
281
+ "grid-2x2": "apps",
275
282
  "home": "home",
276
283
  "file-text": "document",
277
284
  "clipboard-list": "list--checked",
@@ -316,6 +323,7 @@ var CARBON_MAP = {
316
323
  "trending-up": "arrow--up",
317
324
  "trending-down": "arrow--down",
318
325
  "shopping-cart": "shopping--cart",
326
+ "store": "store",
319
327
  "user": "user",
320
328
  "shapes": "apps",
321
329
  "type": "text--font",
@@ -883,6 +891,12 @@ var enMessages = {
883
891
  paginationNext: "Next page",
884
892
  paginationRowsPerPage: "Rows per page",
885
893
  sideNavLabel: "Main navigation",
894
+ shellRailLabel: "Applications",
895
+ appLauncherLabel: "All applications",
896
+ appLauncherTitle: "All applications",
897
+ appLauncherSearch: "Search for an application",
898
+ appLauncherEmpty: "No application matches that search.",
899
+ appLauncherLoading: "Loading applications\u2026",
886
900
  splitPaneList: "List",
887
901
  splitPaneDetail: "Detail",
888
902
  splitPaneBack: "Back to list",
@@ -901,7 +915,9 @@ var enMessages = {
901
915
  commandPaletteHintClose: "close",
902
916
  chartCategoryHeader: "Category",
903
917
  chartNoValue: "No data",
904
- chartEmpty: "No data for this period"
918
+ chartEmpty: "No data for this period",
919
+ numPadClear: "Clear",
920
+ numPadBackspace: "Remove last digit"
905
921
  };
906
922
  var esMessages = {
907
923
  filterBarLabel: "Filtros",
@@ -943,6 +959,12 @@ var esMessages = {
943
959
  paginationNext: "P\xE1gina siguiente",
944
960
  paginationRowsPerPage: "Filas por p\xE1gina",
945
961
  sideNavLabel: "Navegaci\xF3n principal",
962
+ shellRailLabel: "Aplicaciones",
963
+ appLauncherLabel: "Todas las aplicaciones",
964
+ appLauncherTitle: "Todas las aplicaciones",
965
+ appLauncherSearch: "Busc\xE1 una aplicaci\xF3n",
966
+ appLauncherEmpty: "Ninguna aplicaci\xF3n coincide con esa b\xFAsqueda.",
967
+ appLauncherLoading: "Cargando aplicaciones\u2026",
946
968
  splitPaneList: "Lista",
947
969
  splitPaneDetail: "Detalle",
948
970
  splitPaneBack: "Volver a la lista",
@@ -961,7 +983,9 @@ var esMessages = {
961
983
  commandPaletteHintClose: "cerrar",
962
984
  chartCategoryHeader: "Categor\xEDa",
963
985
  chartNoValue: "Sin datos",
964
- chartEmpty: "Sin datos para este per\xEDodo"
986
+ chartEmpty: "Sin datos para este per\xEDodo",
987
+ numPadClear: "Limpiar",
988
+ numPadBackspace: "Borrar \xFAltimo d\xEDgito"
965
989
  };
966
990
 
967
991
  // src/i18n/PireIntlProvider.tsx
@@ -2594,6 +2618,7 @@ var import_react_aria_components24 = require("react-aria-components");
2594
2618
  var import_jsx_runtime35 = require("react/jsx-runtime");
2595
2619
  var initials2 = (name) => name.trim().split(/\s+/).slice(0, 2).map((p) => p[0]).join("").toUpperCase();
2596
2620
  function ShellBar({
2621
+ launcher,
2597
2622
  product,
2598
2623
  monogram,
2599
2624
  title,
@@ -2610,6 +2635,7 @@ function ShellBar({
2610
2635
  }) {
2611
2636
  const msg = usePireMessages();
2612
2637
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("header", { className: cx("pire-shellbar", className), ...rest, children: [
2638
+ launcher,
2613
2639
  onMenu ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(IconButton, { icon: "menu", label: menuLabel, variant: "inverse", size: "sm", onPress: onMenu }) : null,
2614
2640
  monogram ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-shellbar-mono", "aria-hidden": "true", children: monogram }) : null,
2615
2641
  product ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "pire-shellbar-product", children: product }) : null,
@@ -2856,12 +2882,38 @@ function SideNav({
2856
2882
  );
2857
2883
  }
2858
2884
 
2859
- // src/components/navigation/Tabs.tsx
2885
+ // src/components/navigation/ShellRail.tsx
2886
+ var React22 = __toESM(require("react"), 1);
2860
2887
  var import_react_aria_components27 = require("react-aria-components");
2861
- var import_jsx_runtime38 = require("react/jsx-runtime");
2888
+ var import_jsx_runtime38 = (
2889
+ // The divider is a sibling of the groups rather than a pseudo-element on one, because the
2890
+ // scrolling zone would carry its own rule out of view on the first wheel event.
2891
+ require("react/jsx-runtime")
2892
+ );
2893
+ function ShellRail({ groups, value, onChange, className, ...rest }) {
2894
+ const msg = usePireMessages();
2895
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("nav", { className: cx("pire-shellrail", className), "aria-label": msg.shellRailLabel, ...rest, children: groups.map((group, gi) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(React22.Fragment, { children: [
2896
+ gi > 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "pire-shellrail-divider" }) : null,
2897
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "pire-shellrail-group", "data-scroll": group.isScrollable ? "true" : void 0, children: group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Tooltip, { label: item.label, placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2898
+ import_react_aria_components27.Button,
2899
+ {
2900
+ className: "pire-shellrail-item",
2901
+ "aria-label": item.label,
2902
+ "data-selected": item.id === value ? "true" : void 0,
2903
+ "aria-current": item.id === value ? "true" : void 0,
2904
+ onPress: () => onChange?.(item.id),
2905
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "pire-shellrail-tile", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: item.icon, size: 20 }) })
2906
+ }
2907
+ ) }, item.id)) })
2908
+ ] }, group.items[0]?.id ?? gi)) });
2909
+ }
2910
+
2911
+ // src/components/navigation/Tabs.tsx
2912
+ var import_react_aria_components28 = require("react-aria-components");
2913
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2862
2914
  function Tabs({ items, value, defaultValue, onChange, panels, className, style, ...rest }) {
2863
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2864
- import_react_aria_components27.Tabs,
2915
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2916
+ import_react_aria_components28.Tabs,
2865
2917
  {
2866
2918
  className,
2867
2919
  style,
@@ -2869,23 +2921,23 @@ function Tabs({ items, value, defaultValue, onChange, panels, className, style,
2869
2921
  defaultSelectedKey: defaultValue,
2870
2922
  onSelectionChange: (k) => onChange?.(String(k)),
2871
2923
  children: [
2872
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_aria_components27.TabList, { className: "pire-tablist", items, "aria-label": rest["aria-label"] ?? "Views", children: (item) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_aria_components27.Tab, { className: cx("pire-tab"), id: item.id, isDisabled: item.isDisabled, children: [
2873
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: item.icon, size: 16 }) : null,
2924
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_aria_components28.TabList, { className: "pire-tablist", items, "aria-label": rest["aria-label"] ?? "Views", children: (item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react_aria_components28.Tab, { className: cx("pire-tab"), id: item.id, isDisabled: item.isDisabled, children: [
2925
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: item.icon, size: 16 }) : null,
2874
2926
  item.label,
2875
- item.count != null ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "pire-tab-count", children: item.count }) : null
2927
+ item.count != null ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "pire-tab-count", children: item.count }) : null
2876
2928
  ] }) }),
2877
- items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_aria_components27.TabPanel, { id: item.id, className: panels ? "pire-tabpanel" : void 0, children: panels?.[item.id] }, item.id))
2929
+ items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_aria_components28.TabPanel, { id: item.id, className: panels ? "pire-tabpanel" : void 0, children: panels?.[item.id] }, item.id))
2878
2930
  ]
2879
2931
  }
2880
2932
  );
2881
2933
  }
2882
2934
 
2883
2935
  // src/components/navigation/Breadcrumb.tsx
2884
- var import_react_aria_components28 = require("react-aria-components");
2885
- var import_jsx_runtime39 = require("react/jsx-runtime");
2936
+ var import_react_aria_components29 = require("react-aria-components");
2937
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2886
2938
  function Breadcrumb({ items, onNavigate, className, style }) {
2887
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2888
- import_react_aria_components28.Breadcrumbs,
2939
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2940
+ import_react_aria_components29.Breadcrumbs,
2889
2941
  {
2890
2942
  className: cx("pire-breadcrumbs", className),
2891
2943
  style,
@@ -2893,9 +2945,9 @@ function Breadcrumb({ items, onNavigate, className, style }) {
2893
2945
  onAction: (key) => onNavigate?.(String(key)),
2894
2946
  children: (item) => {
2895
2947
  const last = items[items.length - 1] === item;
2896
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_react_aria_components28.Breadcrumb, { className: "pire-breadcrumb", id: item.id ?? item.label, children: [
2897
- last ? item.label : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_aria_components28.Link, { href: item.href, children: item.label }),
2898
- last ? null : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "chevron-right", size: 12, style: { color: "var(--text-tertiary)" } })
2948
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_aria_components29.Breadcrumb, { className: "pire-breadcrumb", id: item.id ?? item.label, children: [
2949
+ last ? item.label : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_aria_components29.Link, { href: item.href, children: item.label }),
2950
+ last ? null : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Icon, { name: "chevron-right", size: 12, style: { color: "var(--text-tertiary)" } })
2899
2951
  ] });
2900
2952
  }
2901
2953
  }
@@ -2903,7 +2955,7 @@ function Breadcrumb({ items, onNavigate, className, style }) {
2903
2955
  }
2904
2956
 
2905
2957
  // src/components/navigation/Pagination.tsx
2906
- var import_jsx_runtime40 = require("react/jsx-runtime");
2958
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2907
2959
  function Pagination({
2908
2960
  page = 1,
2909
2961
  pageSize = 25,
@@ -2918,9 +2970,9 @@ function Pagination({
2918
2970
  const pages = Math.max(1, Math.ceil(total / pageSize));
2919
2971
  const from = total === 0 ? 0 : (page - 1) * pageSize + 1;
2920
2972
  const to = Math.min(total, page * pageSize);
2921
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("nav", { className: cx("pire-pagination", className), style, "aria-label": msg.paginationLabel, children: [
2922
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "pire-pagination-count", children: msg.paginationRange.replace("{from}", from.toLocaleString()).replace("{to}", to.toLocaleString()).replace("{total}", total.toLocaleString()) }),
2923
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2973
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("nav", { className: cx("pire-pagination", className), style, "aria-label": msg.paginationLabel, children: [
2974
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-pagination-count", children: msg.paginationRange.replace("{from}", from.toLocaleString()).replace("{to}", to.toLocaleString()).replace("{total}", total.toLocaleString()) }),
2975
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2924
2976
  IconButton,
2925
2977
  {
2926
2978
  icon: "chevron-left",
@@ -2931,8 +2983,8 @@ function Pagination({
2931
2983
  onPress: () => onPageChange?.(page - 1)
2932
2984
  }
2933
2985
  ),
2934
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "pire-pagination-count", "aria-live": "polite", children: msg.paginationPageOf.replace("{page}", String(page)).replace("{pages}", String(pages)) }),
2935
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2986
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-pagination-count", "aria-live": "polite", children: msg.paginationPageOf.replace("{page}", String(page)).replace("{pages}", String(pages)) }),
2987
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2936
2988
  IconButton,
2937
2989
  {
2938
2990
  icon: "chevron-right",
@@ -2943,7 +2995,7 @@ function Pagination({
2943
2995
  onPress: () => onPageChange?.(page + 1)
2944
2996
  }
2945
2997
  ),
2946
- onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2998
+ onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2947
2999
  Select,
2948
3000
  {
2949
3001
  "aria-label": msg.paginationRowsPerPage,
@@ -2959,7 +3011,7 @@ function Pagination({
2959
3011
  }
2960
3012
 
2961
3013
  // src/components/feedback/InlineMessage.tsx
2962
- var import_jsx_runtime41 = require("react/jsx-runtime");
3014
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2963
3015
  var KIND_ICON = {
2964
3016
  info: "info",
2965
3017
  success: "check-circle-2",
@@ -2969,7 +3021,7 @@ var KIND_ICON = {
2969
3021
  function InlineMessage({ kind = "info", title, action, onClose, children, className, ...rest }) {
2970
3022
  const msg = usePireMessages();
2971
3023
  const assertive = kind === "error" || kind === "warning";
2972
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3024
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2973
3025
  "div",
2974
3026
  {
2975
3027
  className: cx("pire-msg", className),
@@ -2978,21 +3030,21 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
2978
3030
  "aria-live": assertive ? "assertive" : "polite",
2979
3031
  ...rest,
2980
3032
  children: [
2981
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Icon, { name: KIND_ICON[kind], size: 16, style: { marginTop: 2 } }),
2982
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "var(--sp-1)" }, children: [
2983
- title ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-msg-title", children: title }) : null,
2984
- children ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "pire-msg-body", children }) : null,
3033
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon, { name: KIND_ICON[kind], size: 16, style: { marginTop: 2 } }),
3034
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "var(--sp-1)" }, children: [
3035
+ title ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "pire-msg-title", children: title }) : null,
3036
+ children ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "pire-msg-body", children }) : null,
2985
3037
  action
2986
3038
  ] }),
2987
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(IconButton, { icon: "x", label: msg.inlineMessageDismiss, size: "sm", onPress: onClose }) : null
3039
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(IconButton, { icon: "x", label: msg.inlineMessageDismiss, size: "sm", onPress: onClose }) : null
2988
3040
  ]
2989
3041
  }
2990
3042
  );
2991
3043
  }
2992
3044
 
2993
3045
  // src/components/feedback/Toast.tsx
2994
- var React22 = __toESM(require("react"), 1);
2995
- var import_jsx_runtime42 = require("react/jsx-runtime");
3046
+ var React23 = __toESM(require("react"), 1);
3047
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2996
3048
  var KIND_ICON2 = {
2997
3049
  info: "info",
2998
3050
  success: "check-circle-2",
@@ -3001,7 +3053,7 @@ var KIND_ICON2 = {
3001
3053
  };
3002
3054
  function Toast({ kind = "success", onClose, position = "bottom-center", children, className, ...rest }) {
3003
3055
  const msg = usePireMessages();
3004
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3056
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
3005
3057
  "div",
3006
3058
  {
3007
3059
  className: cx("pire-toast", className),
@@ -3010,40 +3062,40 @@ function Toast({ kind = "success", onClose, position = "bottom-center", children
3010
3062
  "aria-live": kind === "error" ? "assertive" : "polite",
3011
3063
  ...rest,
3012
3064
  children: [
3013
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon, { name: KIND_ICON2[kind], size: 16 }),
3014
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { style: { flex: 1 }, children }),
3015
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(IconButton, { icon: "x", label: msg.toastDismiss, size: "sm", variant: "inverse", onPress: onClose }) : null
3065
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Icon, { name: KIND_ICON2[kind], size: 16 }),
3066
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { style: { flex: 1 }, children }),
3067
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(IconButton, { icon: "x", label: msg.toastDismiss, size: "sm", variant: "inverse", onPress: onClose }) : null
3016
3068
  ]
3017
3069
  }
3018
3070
  );
3019
3071
  }
3020
- var ToastContext = React22.createContext(null);
3072
+ var ToastContext = React23.createContext(null);
3021
3073
  function ToastProvider({ children, timeout = 6e3 }) {
3022
3074
  const msg = usePireMessages();
3023
- const [toasts, setToasts] = React22.useState([]);
3024
- const close = React22.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
3025
- const add = React22.useCallback((toast) => {
3075
+ const [toasts, setToasts] = React23.useState([]);
3076
+ const close = React23.useCallback((id) => setToasts((t) => t.filter((x) => x.id !== id)), []);
3077
+ const add = React23.useCallback((toast) => {
3026
3078
  const id = Math.random().toString(36).slice(2);
3027
3079
  setToasts((t) => [...t, { ...toast, id }]);
3028
3080
  const ms = toast.timeout ?? timeout;
3029
3081
  if (ms > 0) setTimeout(() => close(id), ms);
3030
3082
  return id;
3031
3083
  }, [close, timeout]);
3032
- const value = React22.useMemo(() => ({ add, close }), [add, close]);
3033
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(ToastContext.Provider, { value, children: [
3084
+ const value = React23.useMemo(() => ({ add, close }), [add, close]);
3085
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(ToastContext.Provider, { value, children: [
3034
3086
  children,
3035
- /* @__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)) })
3087
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
3036
3088
  ] });
3037
3089
  }
3038
3090
  function useToast() {
3039
- const ctx = React22.useContext(ToastContext);
3091
+ const ctx = React23.useContext(ToastContext);
3040
3092
  if (!ctx) throw new Error("useToast must be used inside <ToastProvider>");
3041
3093
  return ctx;
3042
3094
  }
3043
3095
 
3044
3096
  // src/components/data/KpiTile.tsx
3045
- var import_react_aria_components29 = require("react-aria-components");
3046
- var import_jsx_runtime43 = require("react/jsx-runtime");
3097
+ var import_react_aria_components30 = require("react-aria-components");
3098
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3047
3099
  function KpiTile({
3048
3100
  label,
3049
3101
  value,
@@ -3059,50 +3111,50 @@ function KpiTile({
3059
3111
  style
3060
3112
  }) {
3061
3113
  const tone = deltaTone ?? (deltaDirection === "down" ? "negative" : "positive");
3062
- const body = /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
3063
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "pire-kpi-label", children: [
3064
- icon ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Icon, { name: icon, size: 16 }) : null,
3114
+ const body = /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
3115
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "pire-kpi-label", children: [
3116
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: icon, size: 16 }) : null,
3065
3117
  label
3066
3118
  ] }),
3067
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "pire-kpi-value", children: [
3119
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "pire-kpi-value", children: [
3068
3120
  value,
3069
- unit ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "pire-kpi-unit", children: unit }) : null
3121
+ unit ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "pire-kpi-unit", children: unit }) : null
3070
3122
  ] }),
3071
- delta ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "pire-kpi-delta", "data-tone": tone, children: [
3072
- deltaDirection ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Icon, { name: deltaDirection === "up" ? "trending-up" : "trending-down", size: 12 }) : null,
3123
+ delta ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "pire-kpi-delta", "data-tone": tone, children: [
3124
+ deltaDirection ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Icon, { name: deltaDirection === "up" ? "trending-up" : "trending-down", size: 12 }) : null,
3073
3125
  delta
3074
3126
  ] }) : null,
3075
- footnote ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "pire-kpi-foot", children: footnote }) : null
3127
+ footnote ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "pire-kpi-foot", children: footnote }) : null
3076
3128
  ] });
3077
3129
  const props = { className: cx("pire-kpi", className), "data-status": status, style };
3078
- return onPress ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_aria_components29.Button, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { ...props, children: body });
3130
+ return onPress ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_aria_components30.Button, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { ...props, children: body });
3079
3131
  }
3080
3132
 
3081
3133
  // src/components/data/ObjectHeader.tsx
3082
- var import_jsx_runtime44 = require("react/jsx-runtime");
3134
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3083
3135
  function ObjectHeader({ title, subtitle, id, breadcrumb, badge, facts, actions, className, ...rest }) {
3084
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("header", { className: cx("pire-objheader", className), ...rest, children: [
3136
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("header", { className: cx("pire-objheader", className), ...rest, children: [
3085
3137
  breadcrumb,
3086
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "pire-objheader-row", children: [
3087
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { style: { minWidth: 0 }, children: [
3088
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h1", { className: "pire-objheader-title", children: title }),
3089
- subtitle || id ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "pire-objheader-sub", children: [
3138
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "pire-objheader-row", children: [
3139
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { style: { minWidth: 0 }, children: [
3140
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h1", { className: "pire-objheader-title", children: title }),
3141
+ subtitle || id ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "pire-objheader-sub", children: [
3090
3142
  subtitle,
3091
- id ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "pire-objheader-id", children: id }) : null
3143
+ id ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-objheader-id", children: id }) : null
3092
3144
  ] }) : null
3093
3145
  ] }),
3094
3146
  badge,
3095
- actions ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "pire-objheader-actions", children: actions }) : null
3147
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "pire-objheader-actions", children: actions }) : null
3096
3148
  ] }),
3097
- facts?.length ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dl", { className: "pire-facts", style: { margin: 0 }, children: facts.map((fact) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { children: [
3098
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dt", { className: "pire-fact-label", children: fact.label }),
3099
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("dd", { className: "pire-fact-value", "data-numeric": fact.numeric ? "true" : void 0, style: { margin: 0 }, children: fact.value })
3149
+ facts?.length ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("dl", { className: "pire-facts", style: { margin: 0 }, children: facts.map((fact) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
3150
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("dt", { className: "pire-fact-label", children: fact.label }),
3151
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("dd", { className: "pire-fact-value", "data-numeric": fact.numeric ? "true" : void 0, style: { margin: 0 }, children: fact.value })
3100
3152
  ] }, fact.label)) }) : null
3101
3153
  ] });
3102
3154
  }
3103
3155
 
3104
3156
  // src/components/data/FilterBar.tsx
3105
- var import_jsx_runtime45 = require("react/jsx-runtime");
3157
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3106
3158
  function FilterBar({
3107
3159
  children,
3108
3160
  activeFilters = [],
@@ -3119,49 +3171,49 @@ function FilterBar({
3119
3171
  const label = useMessage("filterBarLabel", rest["aria-label"]);
3120
3172
  const go = useMessage("filterBarGo", goLabel);
3121
3173
  const clearAll = useMessage("filterBarClearAll", clearAllLabel);
3122
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("section", { className: cx("pire-filterbar", className), ...rest, "aria-label": label, children: [
3123
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "pire-filterbar-controls", children: [
3174
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("section", { className: cx("pire-filterbar", className), ...rest, "aria-label": label, children: [
3175
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "pire-filterbar-controls", children: [
3124
3176
  children,
3125
- onGo ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { variant: "primary", onPress: onGo, children: go }) : null
3177
+ onGo ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Button, { variant: "primary", onPress: onGo, children: go }) : null
3126
3178
  ] }),
3127
- activeFilters.length || resultLabel || actions ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "pire-filterbar-foot", children: [
3128
- activeFilters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Tag, { onRemove: onRemoveFilter ? () => onRemoveFilter(filter.id) : void 0, children: filter.label }, filter.id)),
3129
- activeFilters.length && onClear ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { variant: "tertiary", size: "sm", onPress: onClear, children: clearAll }) : null,
3130
- resultLabel ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pire-filterbar-result", "aria-live": "polite", children: resultLabel }) : null,
3131
- actions ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "pire-filterbar-actions", children: actions }) : null
3179
+ activeFilters.length || resultLabel || actions ? /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "pire-filterbar-foot", children: [
3180
+ activeFilters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Tag, { onRemove: onRemoveFilter ? () => onRemoveFilter(filter.id) : void 0, children: filter.label }, filter.id)),
3181
+ activeFilters.length && onClear ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Button, { variant: "tertiary", size: "sm", onPress: onClear, children: clearAll }) : null,
3182
+ resultLabel ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "pire-filterbar-result", "aria-live": "polite", children: resultLabel }) : null,
3183
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "pire-filterbar-actions", children: actions }) : null
3132
3184
  ] }) : null
3133
3185
  ] });
3134
3186
  }
3135
3187
 
3136
3188
  // src/components/data/DescriptionList.tsx
3137
- var import_jsx_runtime46 = require("react/jsx-runtime");
3189
+ var import_jsx_runtime47 = require("react/jsx-runtime");
3138
3190
  function DescriptionList({ items, layout = "rows", columns = 3, className, style, ...rest }) {
3139
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3191
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3140
3192
  "dl",
3141
3193
  {
3142
3194
  className: cx("pire-dl", className),
3143
3195
  "data-layout": layout,
3144
3196
  style: { ...layout === "grid" ? { "--pire-dl-cols": columns } : null, ...style },
3145
3197
  ...rest,
3146
- children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "pire-dl-row", "data-emphasis": item.emphasis ? "true" : void 0, children: [
3147
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("dt", { className: "pire-dl-term", children: [
3198
+ children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "pire-dl-row", "data-emphasis": item.emphasis ? "true" : void 0, children: [
3199
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("dt", { className: "pire-dl-term", children: [
3148
3200
  item.label,
3149
3201
  item.hint
3150
3202
  ] }),
3151
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("dd", { className: "pire-dl-value", "data-numeric": item.numeric ? "true" : void 0, children: item.value })
3203
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("dd", { className: "pire-dl-value", "data-numeric": item.numeric ? "true" : void 0, children: item.value })
3152
3204
  ] }, i))
3153
3205
  }
3154
3206
  );
3155
3207
  }
3156
3208
 
3157
3209
  // src/components/data/Timeline.tsx
3158
- var import_jsx_runtime47 = require("react/jsx-runtime");
3210
+ var import_jsx_runtime48 = require("react/jsx-runtime");
3159
3211
  function Timeline({ entries, reverse = false, className, ...rest }) {
3160
3212
  const list = reverse ? [...entries].reverse() : entries;
3161
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("ol", { className: cx("pire-timeline", className), ...rest, children: list.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("li", { className: "pire-timeline-item", children: [
3162
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "pire-timeline-time", children: entry.time }),
3163
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "pire-timeline-text", children: entry.event }),
3164
- entry.actor ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "pire-timeline-actor", children: entry.actor }) : null
3213
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("ol", { className: cx("pire-timeline", className), ...rest, children: list.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("li", { className: "pire-timeline-item", children: [
3214
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-timeline-time", children: entry.time }),
3215
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-timeline-text", children: entry.event }),
3216
+ entry.actor ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-timeline-actor", children: entry.actor }) : null
3165
3217
  ] }, entry.id ?? i)) });
3166
3218
  }
3167
3219
 
@@ -3244,7 +3296,7 @@ function alignToCategories(series, categoryCount) {
3244
3296
  }
3245
3297
 
3246
3298
  // src/components/data/ChartFrame.tsx
3247
- var import_jsx_runtime48 = require("react/jsx-runtime");
3299
+ var import_jsx_runtime49 = require("react/jsx-runtime");
3248
3300
  function seriesLegend(series) {
3249
3301
  return series.map((one, index) => ({
3250
3302
  key: one.id,
@@ -3267,29 +3319,29 @@ function ChartFrame({
3267
3319
  children
3268
3320
  }) {
3269
3321
  const msg = usePireMessages();
3270
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("figure", { className: cx("pire-chart", className), style, children: [
3271
- title || description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("figcaption", { className: "pire-chart-head", children: [
3272
- title ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-chart-title", children: title }) : null,
3273
- description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-chart-desc", children: description }) : null
3322
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("figure", { className: cx("pire-chart", className), style, children: [
3323
+ title || description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("figcaption", { className: "pire-chart-head", children: [
3324
+ title ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-chart-title", children: title }) : null,
3325
+ description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-chart-desc", children: description }) : null
3274
3326
  ] }) : null,
3275
- legend && legend.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("ul", { className: "pire-chart-legend", children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("li", { className: "pire-chart-legend-item", children: [
3276
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "pire-chart-swatch", style: { background: item.color } }),
3327
+ legend && legend.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("ul", { className: "pire-chart-legend", children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("li", { className: "pire-chart-legend-item", children: [
3328
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-chart-swatch", style: { background: item.color } }),
3277
3329
  item.label
3278
3330
  ] }, item.key)) }) : null,
3279
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "pire-chart-plot", "aria-hidden": "true", children }),
3280
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: showDataTable ? "pire-chart-table" : "pire-sr-only", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("table", { children: [
3281
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("caption", { children: label }),
3282
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("tr", { children: [
3283
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { scope: "col", children: msg.chartCategoryHeader }),
3284
- series.map((one) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { scope: "col", children: one.label }, one.id))
3331
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "pire-chart-plot", "aria-hidden": "true", children }),
3332
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: showDataTable ? "pire-chart-table" : "pire-sr-only", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("table", { children: [
3333
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("caption", { children: label }),
3334
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("tr", { children: [
3335
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("th", { scope: "col", children: msg.chartCategoryHeader }),
3336
+ series.map((one) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("th", { scope: "col", children: one.label }, one.id))
3285
3337
  ] }) }),
3286
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tbody", { children: categories.map((category, categoryIndex) => (
3338
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("tbody", { children: categories.map((category, categoryIndex) => (
3287
3339
  // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
3288
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("tr", { children: [
3289
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { scope: "row", children: category }),
3340
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("tr", { children: [
3341
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("th", { scope: "row", children: category }),
3290
3342
  series.map((one) => {
3291
3343
  const value = one.values[categoryIndex];
3292
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("td", { children: value == null ? msg.chartNoValue : formatValue(value) }, one.id);
3344
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("td", { children: value == null ? msg.chartNoValue : formatValue(value) }, one.id);
3293
3345
  })
3294
3346
  ] }, categoryIndex)
3295
3347
  )) })
@@ -3298,7 +3350,7 @@ function ChartFrame({
3298
3350
  }
3299
3351
 
3300
3352
  // src/components/data/BarChart.tsx
3301
- var import_jsx_runtime49 = require("react/jsx-runtime");
3353
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3302
3354
  function BarChart({
3303
3355
  categories,
3304
3356
  series: rawSeries,
@@ -3330,7 +3382,7 @@ function BarChart({
3330
3382
  const value = series[0].values[categoryIndex];
3331
3383
  return value == null ? msg.chartNoValue : formatValue(value);
3332
3384
  };
3333
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3385
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3334
3386
  ChartFrame,
3335
3387
  {
3336
3388
  label,
@@ -3343,7 +3395,7 @@ function BarChart({
3343
3395
  showDataTable,
3344
3396
  className,
3345
3397
  style,
3346
- children: !hasData ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3398
+ children: !hasData ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3347
3399
  "div",
3348
3400
  {
3349
3401
  className: "pire-chart-bars",
@@ -3352,12 +3404,12 @@ function BarChart({
3352
3404
  style: { "--pire-chart-height": `${height}px` },
3353
3405
  children: categories.map((category, categoryIndex) => (
3354
3406
  // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
3355
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "pire-chart-group", children: [
3356
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-chart-cat", children: category }),
3357
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "pire-chart-track", children: series.map((one, seriesIndex) => {
3407
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "pire-chart-group", children: [
3408
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "pire-chart-cat", children: category }),
3409
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pire-chart-track", children: series.map((one, seriesIndex) => {
3358
3410
  const value = one.values[categoryIndex];
3359
3411
  if (value == null) return null;
3360
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
3412
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
3361
3413
  "div",
3362
3414
  {
3363
3415
  className: "pire-chart-bar",
@@ -3366,8 +3418,8 @@ function BarChart({
3366
3418
  "--pire-bar-color": seriesColor(one, seriesIndex)
3367
3419
  },
3368
3420
  children: [
3369
- withValues && orientation === "vertical" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-chart-barval", children: formatValue(value) }) : null,
3370
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "pire-chart-tip", role: "presentation", children: [
3421
+ withValues && orientation === "vertical" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "pire-chart-barval", children: formatValue(value) }) : null,
3422
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "pire-chart-tip", role: "presentation", children: [
3371
3423
  series.length > 1 ? `${one.label}: ` : "",
3372
3424
  formatValue(value)
3373
3425
  ] })
@@ -3376,7 +3428,7 @@ function BarChart({
3376
3428
  one.id
3377
3429
  );
3378
3430
  }) }),
3379
- withValues && orientation === "horizontal" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "pire-chart-val", children: horizontalLabelFor(categoryIndex) }) : null
3431
+ withValues && orientation === "horizontal" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "pire-chart-val", children: horizontalLabelFor(categoryIndex) }) : null
3380
3432
  ] }, categoryIndex)
3381
3433
  ))
3382
3434
  }
@@ -3386,14 +3438,14 @@ function BarChart({
3386
3438
  }
3387
3439
 
3388
3440
  // src/components/data/LineChart.tsx
3389
- var React23 = __toESM(require("react"), 1);
3390
- var import_jsx_runtime50 = require("react/jsx-runtime");
3441
+ var React24 = __toESM(require("react"), 1);
3442
+ var import_jsx_runtime51 = require("react/jsx-runtime");
3391
3443
  var PLOT_INSET = { top: 10, right: 14, bottom: 24, left: 58 };
3392
3444
  var MARKER_LIMIT = 20;
3393
- var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React23.useEffect : React23.useLayoutEffect;
3445
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React24.useEffect : React24.useLayoutEffect;
3394
3446
  function useMeasuredWidth() {
3395
- const ref = React23.useRef(null);
3396
- const [width, setWidth] = React23.useState(0);
3447
+ const ref = React24.useRef(null);
3448
+ const [width, setWidth] = React24.useState(0);
3397
3449
  useIsomorphicLayoutEffect2(() => {
3398
3450
  const element = ref.current;
3399
3451
  if (!element) return;
@@ -3454,7 +3506,7 @@ function LineChart({
3454
3506
  return `M${xAt(present[0].index)} ${baseline} L${line} L${xAt(last.index)} ${baseline} Z`;
3455
3507
  };
3456
3508
  const labelEvery = Math.max(1, Math.ceil(categories.length / Math.max(2, Math.floor(innerWidth / 64))));
3457
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3509
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3458
3510
  ChartFrame,
3459
3511
  {
3460
3512
  label,
@@ -3467,8 +3519,8 @@ function LineChart({
3467
3519
  showDataTable,
3468
3520
  className,
3469
3521
  style,
3470
- children: !hasData ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "pire-chart-lines", ref: plotRef, style: { height }, children: [
3471
- width > 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
3522
+ children: !hasData ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "pire-chart-lines", ref: plotRef, style: { height }, children: [
3523
+ width > 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
3472
3524
  "svg",
3473
3525
  {
3474
3526
  width,
@@ -3477,7 +3529,7 @@ function LineChart({
3477
3529
  "aria-hidden": "true",
3478
3530
  focusable: "false",
3479
3531
  children: [
3480
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("g", { className: "pire-chart-grid", children: scale.ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3532
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { className: "pire-chart-grid", children: scale.ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3481
3533
  "line",
3482
3534
  {
3483
3535
  x1: PLOT_INSET.left,
@@ -3487,8 +3539,8 @@ function LineChart({
3487
3539
  },
3488
3540
  tick
3489
3541
  )) }),
3490
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("g", { className: "pire-chart-tick", children: [
3491
- scale.ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3542
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("g", { className: "pire-chart-tick", children: [
3543
+ scale.ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3492
3544
  "text",
3493
3545
  {
3494
3546
  x: PLOT_INSET.left - 8,
@@ -3501,10 +3553,10 @@ function LineChart({
3501
3553
  )),
3502
3554
  categories.map((category, index) => index % labelEvery === 0 ? (
3503
3555
  // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
3504
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("text", { x: xAt(index), y: height - 6, textAnchor: "middle", children: category }, index)
3556
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("text", { x: xAt(index), y: height - 6, textAnchor: "middle", children: category }, index)
3505
3557
  ) : null)
3506
3558
  ] }),
3507
- showArea && series[0] ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3559
+ showArea && series[0] ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3508
3560
  "path",
3509
3561
  {
3510
3562
  d: areaFor(series[0].values),
@@ -3512,10 +3564,10 @@ function LineChart({
3512
3564
  style: { fill: seriesColor(series[0], 0) }
3513
3565
  }
3514
3566
  ) : null,
3515
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("g", { className: "pire-chart-line", fill: "none", children: series.map((one, index) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { d: pathFor(one.values), stroke: seriesColor(one, index) }, one.id)) }),
3516
- withMarkers ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("g", { className: "pire-chart-marker", children: series.map((one, seriesIndex) => one.values.map((value, index) => value == null ? null : (
3567
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { className: "pire-chart-line", fill: "none", children: series.map((one, index) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: pathFor(one.values), stroke: seriesColor(one, index) }, one.id)) }),
3568
+ withMarkers ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { className: "pire-chart-marker", children: series.map((one, seriesIndex) => one.values.map((value, index) => value == null ? null : (
3517
3569
  // biome-ignore lint/suspicious/noArrayIndexKey: a series is positional — the index is the point's identity, and category labels repeat.
3518
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3570
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3519
3571
  "circle",
3520
3572
  {
3521
3573
  cx: xAt(index),
@@ -3529,18 +3581,18 @@ function LineChart({
3529
3581
  ]
3530
3582
  }
3531
3583
  ) : null,
3532
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3584
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3533
3585
  "div",
3534
3586
  {
3535
3587
  className: "pire-chart-hover",
3536
3588
  style: { inset: `${PLOT_INSET.top}px ${PLOT_INSET.right}px ${PLOT_INSET.bottom}px ${PLOT_INSET.left}px` },
3537
3589
  children: categories.map((category, categoryIndex) => (
3538
3590
  // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
3539
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pire-chart-band", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "pire-chart-tip", role: "presentation", children: [
3540
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("strong", { children: category }),
3591
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "pire-chart-band", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "pire-chart-tip", role: "presentation", children: [
3592
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: category }),
3541
3593
  series.map((one) => {
3542
3594
  const value = one.values[categoryIndex];
3543
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "pire-chart-tip-row", children: [
3595
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "pire-chart-tip-row", children: [
3544
3596
  one.label,
3545
3597
  ": ",
3546
3598
  value == null ? "No data" : formatValue(value)
@@ -3556,8 +3608,8 @@ function LineChart({
3556
3608
  }
3557
3609
 
3558
3610
  // src/components/data/DonutChart.tsx
3559
- var React24 = __toESM(require("react"), 1);
3560
- var import_jsx_runtime51 = require("react/jsx-runtime");
3611
+ var React25 = __toESM(require("react"), 1);
3612
+ var import_jsx_runtime52 = require("react/jsx-runtime");
3561
3613
  var SEGMENT_GAP_DEGREES = 1.5;
3562
3614
  function DonutChart({
3563
3615
  categories,
@@ -3577,7 +3629,7 @@ function DonutChart({
3577
3629
  }) {
3578
3630
  const label = rest["aria-label"];
3579
3631
  const msg = usePireMessages();
3580
- const [hoveredIndex, setHoveredIndex] = React24.useState(null);
3632
+ const [hoveredIndex, setHoveredIndex] = React25.useState(null);
3581
3633
  warnOnDonutShape(series, categories.length, label);
3582
3634
  const values = (series[0]?.values ?? []).slice(0, categories.length);
3583
3635
  const segments = categories.map((category, index) => ({ category, index, value: values[index] ?? 0 })).filter((segment) => segment.value > 0);
@@ -3594,7 +3646,7 @@ function DonutChart({
3594
3646
  }));
3595
3647
  const hovered = hoveredIndex == null ? null : segments.find((segment) => segment.index === hoveredIndex) ?? null;
3596
3648
  let arcStart = 0;
3597
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3649
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3598
3650
  ChartFrame,
3599
3651
  {
3600
3652
  label,
@@ -3607,8 +3659,8 @@ function DonutChart({
3607
3659
  showDataTable,
3608
3660
  className,
3609
3661
  style,
3610
- children: !hasData ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "pire-chart-donut", style: { height: size }, children: [
3611
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3662
+ children: !hasData ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "pire-chart-donut", style: { height: size }, children: [
3663
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3612
3664
  "svg",
3613
3665
  {
3614
3666
  width: size,
@@ -3616,13 +3668,13 @@ function DonutChart({
3616
3668
  "aria-hidden": "true",
3617
3669
  focusable: "false",
3618
3670
  onMouseLeave: () => setHoveredIndex(null),
3619
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { transform: `rotate(-90 ${size / 2} ${size / 2})`, children: segments.map((segment) => {
3671
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("g", { transform: `rotate(-90 ${size / 2} ${size / 2})`, children: segments.map((segment) => {
3620
3672
  const arcLength = segment.value / total * circumference;
3621
3673
  const offset = arcStart;
3622
3674
  arcStart += arcLength;
3623
3675
  return (
3624
3676
  // biome-ignore lint/a11y/noStaticElementInteractions: pointer-only enhancement inside an aria-hidden plot — the arcs carry nothing the data table does not, so there is nothing here for a keyboard to reach.
3625
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3677
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3626
3678
  "circle",
3627
3679
  {
3628
3680
  className: "pire-chart-arc",
@@ -3642,9 +3694,9 @@ function DonutChart({
3642
3694
  }) })
3643
3695
  }
3644
3696
  ),
3645
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "pire-chart-donut-center", style: { width: size - thickness * 2 - 8 }, children: [
3646
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "pire-chart-donut-value", children: hovered ? formatValue(hovered.value) : centerLabel ?? formatValue(total) }),
3647
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "pire-chart-donut-caption", children: hovered ? hovered.category : centerCaption })
3697
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "pire-chart-donut-center", style: { width: size - thickness * 2 - 8 }, children: [
3698
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "pire-chart-donut-value", children: hovered ? formatValue(hovered.value) : centerLabel ?? formatValue(total) }),
3699
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "pire-chart-donut-caption", children: hovered ? hovered.category : centerCaption })
3648
3700
  ] })
3649
3701
  ] })
3650
3702
  }
@@ -3655,15 +3707,15 @@ function colorForSegment(index) {
3655
3707
  }
3656
3708
 
3657
3709
  // src/components/data/LinkList.tsx
3658
- var import_react_aria_components30 = require("react-aria-components");
3659
- var import_jsx_runtime52 = require("react/jsx-runtime");
3710
+ var import_react_aria_components31 = require("react-aria-components");
3711
+ var import_jsx_runtime53 = require("react/jsx-runtime");
3660
3712
  function LinkList({ items, onSelect, emphasis = "key", className, ...rest }) {
3661
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: cx("pire-linklist", className), role: "list", "data-emphasis": emphasis, ...rest, children: items.map((item) => {
3662
- const keySlot = item.key ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "pire-linklist-key", children: item.key }) : null;
3663
- const textSlot = item.text ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "pire-linklist-text", children: item.text }) : null;
3713
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: cx("pire-linklist", className), role: "list", "data-emphasis": emphasis, ...rest, children: items.map((item) => {
3714
+ const keySlot = item.key ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "pire-linklist-key", children: item.key }) : null;
3715
+ const textSlot = item.text ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "pire-linklist-text", children: item.text }) : null;
3664
3716
  const [first, second] = emphasis === "text" ? [textSlot, keySlot] : [keySlot, textSlot];
3665
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { role: "listitem", className: "pire-linklist-row", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_aria_components30.Button, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
3666
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
3717
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { role: "listitem", className: "pire-linklist-row", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_aria_components31.Button, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
3718
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
3667
3719
  first,
3668
3720
  second,
3669
3721
  item.trailing
@@ -3672,7 +3724,7 @@ function LinkList({ items, onSelect, emphasis = "key", className, ...rest }) {
3672
3724
  }
3673
3725
 
3674
3726
  // src/components/layout/PageBand.tsx
3675
- var import_jsx_runtime53 = require("react/jsx-runtime");
3727
+ var import_jsx_runtime54 = require("react/jsx-runtime");
3676
3728
  function PageBand({
3677
3729
  surface = "card",
3678
3730
  hasBorder = true,
@@ -3680,7 +3732,7 @@ function PageBand({
3680
3732
  className,
3681
3733
  ...rest
3682
3734
  }) {
3683
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
3735
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3684
3736
  "div",
3685
3737
  {
3686
3738
  className: cx("pire-pageband", className),
@@ -3693,56 +3745,56 @@ function PageBand({
3693
3745
  }
3694
3746
 
3695
3747
  // src/components/layout/PageHeader.tsx
3696
- var import_jsx_runtime54 = require("react/jsx-runtime");
3748
+ var import_jsx_runtime55 = require("react/jsx-runtime");
3697
3749
  function PageHeader({ title, subtitle, actions, className, ...rest }) {
3698
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("header", { className: cx("pire-pageheader", className), ...rest, children: [
3699
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: { minWidth: 0 }, children: [
3700
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("h1", { className: "pire-pageheader-title", children: title }),
3701
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "pire-pageheader-sub", children: subtitle }) : null
3750
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("header", { className: cx("pire-pageheader", className), ...rest, children: [
3751
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { minWidth: 0 }, children: [
3752
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h1", { className: "pire-pageheader-title", children: title }),
3753
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "pire-pageheader-sub", children: subtitle }) : null
3702
3754
  ] }),
3703
- actions ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "pire-pageheader-actions", children: actions }) : null
3755
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "pire-pageheader-actions", children: actions }) : null
3704
3756
  ] });
3705
3757
  }
3706
3758
 
3707
3759
  // src/components/layout/SectionHeader.tsx
3708
- var import_jsx_runtime55 = require("react/jsx-runtime");
3760
+ var import_jsx_runtime56 = require("react/jsx-runtime");
3709
3761
  function SectionHeader({ title, meta, actions, className, ...rest }) {
3710
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: cx("pire-sectionhead", className), ...rest, children: [
3711
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "pire-eyebrow", children: title }),
3712
- meta ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { style: { font: "var(--type-caption)", color: "var(--text-tertiary)" }, children: meta }) : null,
3713
- actions ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "pire-sectionhead-actions", children: actions }) : null
3762
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cx("pire-sectionhead", className), ...rest, children: [
3763
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "pire-eyebrow", children: title }),
3764
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { style: { font: "var(--type-caption)", color: "var(--text-tertiary)" }, children: meta }) : null,
3765
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "pire-sectionhead-actions", children: actions }) : null
3714
3766
  ] });
3715
3767
  }
3716
3768
 
3717
3769
  // src/components/layout/SelectionBar.tsx
3718
- var import_jsx_runtime56 = require("react/jsx-runtime");
3770
+ var import_jsx_runtime57 = require("react/jsx-runtime");
3719
3771
  function SelectionBar({ count, noun = "record", children, actions, className, ...rest }) {
3720
3772
  if (!count) return null;
3721
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cx("pire-selectionbar", className), role: "status", "aria-live": "polite", ...rest, children: [
3722
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "pire-selectionbar-count", children: [
3773
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cx("pire-selectionbar", className), role: "status", "aria-live": "polite", ...rest, children: [
3774
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "pire-selectionbar-count", children: [
3723
3775
  count.toLocaleString(),
3724
3776
  " ",
3725
3777
  noun,
3726
3778
  count === 1 ? "" : "s",
3727
3779
  " selected"
3728
3780
  ] }),
3729
- children ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { style: { color: "var(--text-secondary)", font: "var(--type-caption)" }, children }) : null,
3730
- actions ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "pire-selectionbar-actions", children: actions }) : null
3781
+ children ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { style: { color: "var(--text-secondary)", font: "var(--type-caption)" }, children }) : null,
3782
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "pire-selectionbar-actions", children: actions }) : null
3731
3783
  ] });
3732
3784
  }
3733
3785
 
3734
3786
  // src/components/layout/FooterBar.tsx
3735
- var import_jsx_runtime57 = require("react/jsx-runtime");
3787
+ var import_jsx_runtime58 = require("react/jsx-runtime");
3736
3788
  function FooterBar({ note, actions, children, className, ...rest }) {
3737
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("footer", { className: cx("pire-footerbar", className), ...rest, children: [
3738
- note ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "pire-footerbar-note", children: note }) : null,
3789
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("footer", { className: cx("pire-footerbar", className), ...rest, children: [
3790
+ note ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "pire-footerbar-note", children: note }) : null,
3739
3791
  children,
3740
- actions ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "pire-footerbar-actions", children: actions }) : null
3792
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "pire-footerbar-actions", children: actions }) : null
3741
3793
  ] });
3742
3794
  }
3743
3795
 
3744
3796
  // src/components/layout/SplitPane.tsx
3745
- var import_jsx_runtime58 = require("react/jsx-runtime");
3797
+ var import_jsx_runtime59 = require("react/jsx-runtime");
3746
3798
  function SplitPane({
3747
3799
  list,
3748
3800
  detail,
@@ -3758,7 +3810,7 @@ function SplitPane({
3758
3810
  }) {
3759
3811
  const msg = usePireMessages();
3760
3812
  const width = typeof listWidth === "number" ? `${listWidth}px` : listWidth;
3761
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
3813
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
3762
3814
  "div",
3763
3815
  {
3764
3816
  className: cx("pire-split", className),
@@ -3766,10 +3818,10 @@ function SplitPane({
3766
3818
  style: { ["--pire-split-list-w"]: width, ...style },
3767
3819
  ...rest,
3768
3820
  children: [
3769
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("section", { className: "pire-split-list", "aria-label": listLabel ?? msg.splitPaneList, children: list }),
3770
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: "pire-split-detail", "aria-label": detailLabel ?? msg.splitPaneDetail, children: [
3771
- onBack ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "pire-split-back", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Button, { variant: "tertiary", size: "sm", icon: "arrow-left", onPress: onBack, children: backLabel ?? msg.splitPaneBack }) }) : null,
3772
- detail ?? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "pire-split-empty", children: emptyDetail })
3821
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("section", { className: "pire-split-list", "aria-label": listLabel ?? msg.splitPaneList, children: list }),
3822
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("section", { className: "pire-split-detail", "aria-label": detailLabel ?? msg.splitPaneDetail, children: [
3823
+ onBack ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "pire-split-back", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { variant: "tertiary", size: "sm", icon: "arrow-left", onPress: onBack, children: backLabel ?? msg.splitPaneBack }) }) : null,
3824
+ detail ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "pire-split-empty", children: emptyDetail })
3773
3825
  ] })
3774
3826
  ]
3775
3827
  }
@@ -3777,7 +3829,7 @@ function SplitPane({
3777
3829
  }
3778
3830
 
3779
3831
  // src/components/patterns/ConfirmDialog.tsx
3780
- var import_jsx_runtime59 = require("react/jsx-runtime");
3832
+ var import_jsx_runtime60 = require("react/jsx-runtime");
3781
3833
  function ConfirmDialog({
3782
3834
  isOpen,
3783
3835
  title,
@@ -3791,7 +3843,7 @@ function ConfirmDialog({
3791
3843
  onConfirm,
3792
3844
  onCancel
3793
3845
  }) {
3794
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
3846
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
3795
3847
  Dialog,
3796
3848
  {
3797
3849
  isOpen,
@@ -3801,12 +3853,12 @@ function ConfirmDialog({
3801
3853
  onClose: onCancel,
3802
3854
  isDismissable: !isBusy,
3803
3855
  showClose: false,
3804
- footer: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
3805
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
3806
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
3856
+ footer: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
3857
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
3858
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
3807
3859
  ] }),
3808
3860
  children: [
3809
- consequence ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
3861
+ consequence ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
3810
3862
  children
3811
3863
  ]
3812
3864
  }
@@ -3814,9 +3866,9 @@ function ConfirmDialog({
3814
3866
  }
3815
3867
 
3816
3868
  // src/components/patterns/CommandPalette.tsx
3817
- var React25 = __toESM(require("react"), 1);
3818
- var import_react_aria_components31 = require("react-aria-components");
3819
- var import_jsx_runtime60 = require("react/jsx-runtime");
3869
+ var React26 = __toESM(require("react"), 1);
3870
+ var import_react_aria_components32 = require("react-aria-components");
3871
+ var import_jsx_runtime61 = require("react/jsx-runtime");
3820
3872
  var RESULTS_SECTION_KEY = "__pire_results__";
3821
3873
  var searchableText = (item) => [item.label, item.description, item.keywords].filter(Boolean).join(" ");
3822
3874
  function CommandPalette({
@@ -3837,17 +3889,17 @@ function CommandPalette({
3837
3889
  style
3838
3890
  }) {
3839
3891
  const msg = usePireMessages();
3840
- const [query, setQuery] = React25.useState("");
3841
- const { contains } = (0, import_react_aria_components31.useFilter)({ sensitivity: "base" });
3842
- React25.useEffect(() => {
3892
+ const [query, setQuery] = React26.useState("");
3893
+ const { contains } = (0, import_react_aria_components32.useFilter)({ sensitivity: "base" });
3894
+ React26.useEffect(() => {
3843
3895
  if (isOpen) setQuery("");
3844
3896
  }, [isOpen]);
3845
- const searchableById = React25.useMemo(() => {
3897
+ const searchableById = React26.useMemo(() => {
3846
3898
  const byId = /* @__PURE__ */ new Map();
3847
3899
  for (const group of groups) for (const item of group.items) byId.set(item.id, searchableText(item));
3848
3900
  return byId;
3849
3901
  }, [groups]);
3850
- const filter = React25.useCallback((textValue, inputValue, node) => {
3902
+ const filter = React26.useCallback((textValue, inputValue, node) => {
3851
3903
  if (node.parentKey === RESULTS_SECTION_KEY) return true;
3852
3904
  return contains(searchableById.get(String(node.key)) ?? textValue, inputValue);
3853
3905
  }, [contains, searchableById]);
@@ -3857,8 +3909,8 @@ function CommandPalette({
3857
3909
  };
3858
3910
  const sections = [...groups, ...resultsGroup ? [{ ...resultsGroup, id: RESULTS_SECTION_KEY }] : []];
3859
3911
  const status = isLoading ? loadingLabel ?? msg.commandPaletteLoading : emptyLabel ?? msg.commandPaletteEmpty;
3860
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
3861
- import_react_aria_components31.ModalOverlay,
3912
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3913
+ import_react_aria_components32.ModalOverlay,
3862
3914
  {
3863
3915
  className: "pire-cp-overlay",
3864
3916
  isOpen,
@@ -3866,12 +3918,12 @@ function CommandPalette({
3866
3918
  onOpenChange: (open) => {
3867
3919
  if (!open) onOpenChange?.(false);
3868
3920
  },
3869
- children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_aria_components31.Modal, { className: cx("pire-cp-modal", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.Dialog, { className: "pire-cp-dialog", "aria-label": ariaLabel ?? msg.commandPaletteLabel, children: [
3870
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.Autocomplete, { filter, inputValue: query, onInputChange: handleInputChange, children: [
3871
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.SearchField, { className: "pire-cp-search", "aria-label": msg.commandPaletteSearchLabel, children: [
3872
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { name: "search", size: 18, className: "pire-cp-search-icon" }),
3873
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
3874
- import_react_aria_components31.Input,
3921
+ children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_aria_components32.Modal, { className: cx("pire-cp-modal", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react_aria_components32.Dialog, { className: "pire-cp-dialog", "aria-label": ariaLabel ?? msg.commandPaletteLabel, children: [
3922
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react_aria_components32.Autocomplete, { filter, inputValue: query, onInputChange: handleInputChange, children: [
3923
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react_aria_components32.SearchField, { className: "pire-cp-search", "aria-label": msg.commandPaletteSearchLabel, children: [
3924
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Icon, { name: "search", size: 18, className: "pire-cp-search-icon" }),
3925
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3926
+ import_react_aria_components32.Input,
3875
3927
  {
3876
3928
  className: "pire-cp-input",
3877
3929
  autoFocus: true,
@@ -3879,16 +3931,16 @@ function CommandPalette({
3879
3931
  }
3880
3932
  )
3881
3933
  ] }),
3882
- isLoading ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "pire-cp-loading", role: "status", "aria-live": "polite", children: loadingLabel ?? msg.commandPaletteLoading }) : null,
3883
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
3884
- import_react_aria_components31.Menu,
3934
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "pire-cp-loading", role: "status", "aria-live": "polite", children: loadingLabel ?? msg.commandPaletteLoading }) : null,
3935
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3936
+ import_react_aria_components32.Menu,
3885
3937
  {
3886
3938
  className: "pire-cp-list",
3887
3939
  onAction: (key) => onAction?.(String(key)),
3888
- renderEmptyState: () => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "pire-cp-status", children: status }),
3889
- children: sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.MenuSection, { id: section.id, className: "pire-cp-section", children: [
3890
- section.label ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_aria_components31.Header, { className: "pire-cp-section-title", children: section.label }) : null,
3891
- section.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
3940
+ renderEmptyState: () => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "pire-cp-status", children: status }),
3941
+ children: sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react_aria_components32.MenuSection, { id: section.id, className: "pire-cp-section", children: [
3942
+ section.label ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_aria_components32.Header, { className: "pire-cp-section-title", children: section.label }) : null,
3943
+ section.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3892
3944
  MenuItem,
3893
3945
  {
3894
3946
  id: item.id,
@@ -3909,18 +3961,18 @@ function CommandPalette({
3909
3961
  // aria-hidden: the glyphs are a sighted affordance for discovering the keys. A screen
3910
3962
  // reader already announces the listbox semantics that make those keys work, so reading
3911
3963
  // "up arrow down arrow navigate" out loud is noise on every open.
3912
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "pire-cp-foot", "aria-hidden": "true", children: footer ?? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
3913
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "pire-cp-hint", children: [
3914
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "\u2191" }),
3915
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "\u2193" }),
3964
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "pire-cp-foot", "aria-hidden": "true", children: footer ?? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
3965
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "pire-cp-hint", children: [
3966
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Kbd, { children: "\u2191" }),
3967
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Kbd, { children: "\u2193" }),
3916
3968
  msg.commandPaletteHintNavigate
3917
3969
  ] }),
3918
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "pire-cp-hint", children: [
3919
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "\u21B5" }),
3970
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "pire-cp-hint", children: [
3971
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Kbd, { children: "\u21B5" }),
3920
3972
  msg.commandPaletteHintSelect
3921
3973
  ] }),
3922
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "pire-cp-hint", children: [
3923
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "esc" }),
3974
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "pire-cp-hint", children: [
3975
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Kbd, { children: "esc" }),
3924
3976
  msg.commandPaletteHintClose
3925
3977
  ] })
3926
3978
  ] }) })
@@ -3930,9 +3982,9 @@ function CommandPalette({
3930
3982
  );
3931
3983
  }
3932
3984
  function useCommandPaletteShortcut(onTrigger, { key = "k", isDisabled } = {}) {
3933
- const handler = React25.useRef(onTrigger);
3985
+ const handler = React26.useRef(onTrigger);
3934
3986
  handler.current = onTrigger;
3935
- React25.useEffect(() => {
3987
+ React26.useEffect(() => {
3936
3988
  if (isDisabled) return;
3937
3989
  const onKeyDown = (event) => {
3938
3990
  if (!(event.metaKey || event.ctrlKey) || event.altKey) return;
@@ -3945,13 +3997,120 @@ function useCommandPaletteShortcut(onTrigger, { key = "k", isDisabled } = {}) {
3945
3997
  }, [key, isDisabled]);
3946
3998
  }
3947
3999
 
4000
+ // src/components/patterns/AppLauncher.tsx
4001
+ var React27 = __toESM(require("react"), 1);
4002
+ var import_react_aria_components33 = require("react-aria-components");
4003
+ var import_jsx_runtime62 = require("react/jsx-runtime");
4004
+ var searchableText2 = (item) => [item.label, item.description, item.keywords].filter(Boolean).join(" ");
4005
+ function AppLauncher({
4006
+ sections,
4007
+ onAction,
4008
+ value,
4009
+ title,
4010
+ meta,
4011
+ isSearchable = true,
4012
+ onSearchChange,
4013
+ isFilteredExternally,
4014
+ isLoading,
4015
+ emptyLabel,
4016
+ searchPlaceholder,
4017
+ "aria-label": ariaLabel,
4018
+ icon = "grid-2x2",
4019
+ className
4020
+ }) {
4021
+ const msg = usePireMessages();
4022
+ const [query, setQuery] = React27.useState("");
4023
+ const { contains } = (0, import_react_aria_components33.useFilter)({ sensitivity: "base" });
4024
+ const handleSearch = (next) => {
4025
+ setQuery(next);
4026
+ onSearchChange?.(next);
4027
+ };
4028
+ const visible = React27.useMemo(() => {
4029
+ if (isFilteredExternally) return sections;
4030
+ const q = query.trim();
4031
+ if (!q) return sections;
4032
+ return sections.map((section) => ({ ...section, items: section.items.filter((i) => contains(searchableText2(i), q)) })).filter((section) => section.items.length > 0);
4033
+ }, [sections, query, isFilteredExternally, contains]);
4034
+ const isEmpty = !isLoading && visible.length === 0;
4035
+ const label = ariaLabel ?? msg.appLauncherLabel;
4036
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_react_aria_components33.DialogTrigger, { children: [
4037
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_react_aria_components33.Button, { className: "pire-launcher-trigger", "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { name: icon, size: 20 }) }),
4038
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
4039
+ import_react_aria_components33.Popover,
4040
+ {
4041
+ className: cx("pire-launcher-popover", className),
4042
+ placement: "bottom start",
4043
+ offset: 0,
4044
+ crossOffset: 0,
4045
+ containerPadding: 0,
4046
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_react_aria_components33.Dialog, { className: "pire-launcher", "aria-label": label, children: ({ close }) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
4047
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "pire-launcher-head", children: [
4048
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "pire-launcher-title", children: title ?? msg.appLauncherTitle }),
4049
+ meta ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "pire-launcher-meta", children: meta }) : null
4050
+ ] }),
4051
+ isSearchable ? (
4052
+ // autoFocus is right here specifically: the panel exists to be searched, and the
4053
+ // user just chose to open it, so taking the caret is what they asked for.
4054
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
4055
+ Input,
4056
+ {
4057
+ "aria-label": msg.appLauncherSearch,
4058
+ icon: "search",
4059
+ type: "search",
4060
+ autoFocus: true,
4061
+ isClearable: true,
4062
+ value: query,
4063
+ onChange: handleSearch,
4064
+ placeholder: searchPlaceholder ?? msg.appLauncherSearch
4065
+ }
4066
+ )
4067
+ ) : null,
4068
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "pire-launcher-empty", role: "status", "aria-live": "polite", children: msg.appLauncherLoading }) : null,
4069
+ isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "pire-launcher-empty", children: emptyLabel ?? msg.appLauncherEmpty }) : null,
4070
+ visible.map((section, si) => (
4071
+ // Sections are positional zones with no record identity, so the heading is the key
4072
+ // where there is one. Same reasoning as ShellRail's groups.
4073
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "pire-launcher-section", children: [
4074
+ section.label ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "pire-eyebrow", children: section.label }) : null,
4075
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "pire-launcher-grid", "data-variant": section.variant ?? "tile", children: section.items.map((item) => {
4076
+ const isCurrent = item.id === value;
4077
+ const showsDescription = (section.variant ?? "tile") === "tile" && Boolean(item.description);
4078
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
4079
+ import_react_aria_components33.Button,
4080
+ {
4081
+ className: "pire-launcher-item",
4082
+ "data-selected": isCurrent ? "true" : void 0,
4083
+ "aria-current": isCurrent ? "true" : void 0,
4084
+ onPress: () => {
4085
+ close();
4086
+ onAction?.(item.id);
4087
+ },
4088
+ children: [
4089
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "pire-launcher-item-icon", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { name: item.icon, size: (section.variant ?? "tile") === "tile" ? 20 : 16 }) }) : null,
4090
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "pire-launcher-item-text", children: [
4091
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "pire-launcher-item-label", children: item.label }),
4092
+ showsDescription ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "pire-launcher-item-desc", children: item.description }) : null
4093
+ ] })
4094
+ ]
4095
+ },
4096
+ item.id
4097
+ );
4098
+ }) })
4099
+ ] }, section.label ?? section.items[0]?.id ?? si)
4100
+ ))
4101
+ ] }) })
4102
+ }
4103
+ )
4104
+ ] });
4105
+ }
4106
+
3948
4107
  // src/components/patterns/SidePanel.tsx
3949
- var import_react_aria_components32 = require("react-aria-components");
3950
- var import_jsx_runtime61 = require("react/jsx-runtime");
4108
+ var import_react_aria_components34 = require("react-aria-components");
4109
+ var import_jsx_runtime63 = require("react/jsx-runtime");
3951
4110
  function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onClose, className }) {
3952
4111
  const msg = usePireMessages();
3953
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
3954
- import_react_aria_components32.ModalOverlay,
4112
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4113
+ import_react_aria_components34.ModalOverlay,
3955
4114
  {
3956
4115
  className: "pire-sidepanel-overlay",
3957
4116
  isOpen,
@@ -3959,36 +4118,151 @@ function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onC
3959
4118
  onOpenChange: (o) => {
3960
4119
  if (!o) onClose?.();
3961
4120
  },
3962
- children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_aria_components32.Modal, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react_aria_components32.Dialog, { className: "pire-dialog", style: { height: "100%" }, children: [
3963
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("header", { className: "pire-dialog-head", children: [
3964
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
3965
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_aria_components32.Heading, { slot: "title", className: "pire-dialog-title", children: title }),
3966
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
4121
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_react_aria_components34.Modal, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_react_aria_components34.Dialog, { className: "pire-dialog", style: { height: "100%" }, children: [
4122
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("header", { className: "pire-dialog-head", children: [
4123
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4124
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_react_aria_components34.Heading, { slot: "title", className: "pire-dialog-title", children: title }),
4125
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
3967
4126
  ] }),
3968
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
4127
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
3969
4128
  ] }),
3970
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
3971
- footer ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null
4129
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
4130
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null
3972
4131
  ] }) })
3973
4132
  }
3974
4133
  );
3975
4134
  }
3976
4135
 
3977
4136
  // src/components/patterns/EmptyState.tsx
3978
- var import_jsx_runtime62 = require("react/jsx-runtime");
4137
+ var import_jsx_runtime64 = require("react/jsx-runtime");
3979
4138
  function EmptyState({ icon = "file-text", title, action, compact, children, className, ...rest }) {
3980
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
3981
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
3982
- title ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
3983
- children ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
4139
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
4140
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
4141
+ title ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
4142
+ children ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
3984
4143
  action
3985
4144
  ] });
3986
4145
  }
3987
4146
 
4147
+ // src/components/patterns/NumPad.tsx
4148
+ var React28 = __toESM(require("react"), 1);
4149
+ var import_jsx_runtime65 = require("react/jsx-runtime");
4150
+ var BASE_KEYS = [
4151
+ { value: "7" },
4152
+ { value: "8" },
4153
+ { value: "9" },
4154
+ { value: "clear", label: "C" },
4155
+ { value: "4" },
4156
+ { value: "5" },
4157
+ { value: "6" },
4158
+ { value: "backspace", label: "\u232B" },
4159
+ { value: "1" },
4160
+ { value: "2" },
4161
+ { value: "3" },
4162
+ { value: "0" }
4163
+ ];
4164
+ var isInsertable = (value) => /^[0-9]+$/.test(value);
4165
+ function useNumPadKeyboard(onKey, isDisabled, containerRef) {
4166
+ const handler = React28.useRef(onKey);
4167
+ handler.current = onKey;
4168
+ React28.useEffect(() => {
4169
+ if (isDisabled) return;
4170
+ const isEditingElsewhere = () => {
4171
+ const el = document.activeElement;
4172
+ if (!el) return false;
4173
+ const tag = el.tagName;
4174
+ return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || el.hasAttribute("contenteditable");
4175
+ };
4176
+ const isBackgroundedByAnOverlay = () => containerRef.current?.closest("[inert]") != null;
4177
+ const onKeyDown = (event) => {
4178
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
4179
+ if (isEditingElsewhere() || isBackgroundedByAnOverlay()) return;
4180
+ if (event.key >= "0" && event.key <= "9") {
4181
+ handler.current(event.key);
4182
+ return;
4183
+ }
4184
+ if (event.key === "Backspace") {
4185
+ handler.current("backspace");
4186
+ return;
4187
+ }
4188
+ if (event.key === "Escape") {
4189
+ handler.current("clear");
4190
+ return;
4191
+ }
4192
+ };
4193
+ document.addEventListener("keydown", onKeyDown);
4194
+ return () => document.removeEventListener("keydown", onKeyDown);
4195
+ }, [isDisabled, containerRef]);
4196
+ }
4197
+ function NumPad({
4198
+ "aria-label": ariaLabel,
4199
+ target,
4200
+ value,
4201
+ onChange,
4202
+ extraKeys = [],
4203
+ onAction,
4204
+ isDisabled,
4205
+ size = "md",
4206
+ className,
4207
+ style
4208
+ }) {
4209
+ const msg = usePireMessages();
4210
+ const containerRef = React28.useRef(null);
4211
+ const applyKey = React28.useCallback((key) => {
4212
+ if (isDisabled) return;
4213
+ if (key.value === "backspace") {
4214
+ onChange(value.slice(0, -1));
4215
+ return;
4216
+ }
4217
+ if (key.value === "clear") {
4218
+ onChange("");
4219
+ return;
4220
+ }
4221
+ if (isInsertable(key.value)) {
4222
+ onChange(value + key.value);
4223
+ return;
4224
+ }
4225
+ onAction?.(key.value);
4226
+ }, [isDisabled, value, onChange, onAction]);
4227
+ useNumPadKeyboard((keyValue) => applyKey({ value: keyValue }), isDisabled, containerRef);
4228
+ const keys = [...BASE_KEYS, ...extraKeys];
4229
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
4230
+ "div",
4231
+ {
4232
+ ref: containerRef,
4233
+ className: cx("pire-numpad", className),
4234
+ style,
4235
+ "data-size": size,
4236
+ "data-disabled": isDisabled ? "true" : void 0,
4237
+ children: [
4238
+ target !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "pire-numpad-target", role: "status", "aria-live": "polite", children: target }) : null,
4239
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "pire-numpad-grid", role: "group", "aria-label": ariaLabel, children: keys.map((key) => {
4240
+ const accessibleLabel = key.value === "backspace" ? msg.numPadBackspace : key.value === "clear" ? msg.numPadClear : void 0;
4241
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
4242
+ Button,
4243
+ {
4244
+ variant: "secondary",
4245
+ size,
4246
+ fullWidth: true,
4247
+ className: "pire-numpad-key",
4248
+ "data-span": key.span === 2 ? "2" : void 0,
4249
+ isDisabled,
4250
+ "aria-label": accessibleLabel,
4251
+ onPress: () => applyKey(key),
4252
+ children: key.label ?? key.value
4253
+ },
4254
+ key.value
4255
+ );
4256
+ }) })
4257
+ ]
4258
+ }
4259
+ );
4260
+ }
4261
+
3988
4262
  // src/components/patterns/FileDropZone.tsx
3989
- var React26 = __toESM(require("react"), 1);
3990
- var import_react_aria_components33 = require("react-aria-components");
3991
- var import_jsx_runtime63 = require("react/jsx-runtime");
4263
+ var React29 = __toESM(require("react"), 1);
4264
+ var import_react_aria_components35 = require("react-aria-components");
4265
+ var import_jsx_runtime66 = require("react/jsx-runtime");
3992
4266
  var isImage2 = (file) => file.type.startsWith("image/");
3993
4267
  function FileDropZone({
3994
4268
  label,
@@ -4016,10 +4290,10 @@ function FileDropZone({
4016
4290
  ...rest
4017
4291
  }) {
4018
4292
  const msg = usePireMessages();
4019
- const [uncontrolled, setUncontrolled] = React26.useState(defaultValue ?? []);
4293
+ const [uncontrolled, setUncontrolled] = React29.useState(defaultValue ?? []);
4020
4294
  const files = value ?? uncontrolled;
4021
- const created = React26.useRef([]);
4022
- React26.useEffect(() => () => {
4295
+ const created = React29.useRef([]);
4296
+ React29.useEffect(() => () => {
4023
4297
  for (const url of created.current) URL.revokeObjectURL(url);
4024
4298
  }, []);
4025
4299
  const commit = (next) => {
@@ -4039,13 +4313,13 @@ function FileDropZone({
4039
4313
  commit(allowsMultiple ? [...files, ...wrapped] : wrapped.slice(0, 1));
4040
4314
  };
4041
4315
  const remove = (target) => commit(files.filter((f) => f.file !== target));
4042
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cx("pire-field", className), style, "data-full-width": String(fullWidth), ...rest, children: [
4043
- label ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "pire-field-label", children: [
4316
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: cx("pire-field", className), style, "data-full-width": String(fullWidth), ...rest, children: [
4317
+ label ? /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { className: "pire-field-label", children: [
4044
4318
  label,
4045
- isRequired ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
4319
+ isRequired ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
4046
4320
  ] }) : null,
4047
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
4048
- import_react_aria_components33.DropZone,
4321
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
4322
+ import_react_aria_components35.DropZone,
4049
4323
  {
4050
4324
  className: "pire-dropzone",
4051
4325
  "aria-label": ariaLabel,
@@ -4053,30 +4327,30 @@ function FileDropZone({
4053
4327
  isDisabled: isDisabled || isReadOnly,
4054
4328
  onDrop: async (e) => {
4055
4329
  const dropped = await Promise.all(
4056
- e.items.filter(import_react_aria_components33.isFileDropItem).map((item) => item.getFile())
4330
+ e.items.filter(import_react_aria_components35.isFileDropItem).map((item) => item.getFile())
4057
4331
  );
4058
4332
  accept(dropped);
4059
4333
  },
4060
4334
  children: [
4061
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Icon, { name: "download", size: 24, className: "pire-dropzone-icon" }),
4062
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-dropzone-prompt", children: promptLabel ?? msg.fileDropZonePrompt }),
4063
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4064
- import_react_aria_components33.FileTrigger,
4335
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Icon, { name: "download", size: 24, className: "pire-dropzone-icon" }),
4336
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "pire-dropzone-prompt", children: promptLabel ?? msg.fileDropZonePrompt }),
4337
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
4338
+ import_react_aria_components35.FileTrigger,
4065
4339
  {
4066
4340
  acceptedFileTypes,
4067
4341
  allowsMultiple,
4068
4342
  onSelect: (list) => accept(list ? [...list] : []),
4069
- children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Button, { variant: "secondary", isDisabled: isDisabled || isReadOnly, children: msg.fileUploadChoose })
4343
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Button, { variant: "secondary", isDisabled: isDisabled || isReadOnly, children: msg.fileUploadChoose })
4070
4344
  }
4071
4345
  )
4072
4346
  ]
4073
4347
  }
4074
4348
  ),
4075
- files.length ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("li", { className: "pire-fileupload-item", children: [
4076
- previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
4077
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-fileupload-name", children: file.name }),
4078
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
4079
- isDisabled || isReadOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
4349
+ files.length ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("li", { className: "pire-fileupload-item", children: [
4350
+ previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
4351
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "pire-fileupload-name", children: file.name }),
4352
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
4353
+ isDisabled || isReadOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
4080
4354
  IconButton,
4081
4355
  {
4082
4356
  icon: "x",
@@ -4086,17 +4360,18 @@ function FileDropZone({
4086
4360
  }
4087
4361
  )
4088
4362
  ] }, `${file.name}-${file.size}-${file.lastModified}`)) }) : null,
4089
- uploadProgress != null ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
4090
- description ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-field-hint", children: description }) : null,
4091
- isInvalid && errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-field-error", children: errorMessage }) : null
4363
+ uploadProgress != null ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
4364
+ description ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "pire-field-hint", children: description }) : null,
4365
+ isInvalid && errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "pire-field-error", children: errorMessage }) : null
4092
4366
  ] });
4093
4367
  }
4094
4368
 
4095
4369
  // src/index.ts
4096
- var import_react_aria_components34 = require("react-aria-components");
4097
- var import_react_aria_components35 = require("react-aria-components");
4370
+ var import_react_aria_components36 = require("react-aria-components");
4371
+ var import_react_aria_components37 = require("react-aria-components");
4098
4372
  // Annotate the CommonJS export names for ESM import in node:
4099
4373
  0 && (module.exports = {
4374
+ AppLauncher,
4100
4375
  Avatar,
4101
4376
  Badge,
4102
4377
  BarChart,
@@ -4143,6 +4418,7 @@ var import_react_aria_components35 = require("react-aria-components");
4143
4418
  MenuSeparator,
4144
4419
  MenuTrigger,
4145
4420
  MultiComboBox,
4421
+ NumPad,
4146
4422
  NumberField,
4147
4423
  ObjectHeader,
4148
4424
  PageBand,
@@ -4160,6 +4436,7 @@ var import_react_aria_components35 = require("react-aria-components");
4160
4436
  SelectionBar,
4161
4437
  Separator,
4162
4438
  ShellBar,
4439
+ ShellRail,
4163
4440
  SideNav,
4164
4441
  SidePanel,
4165
4442
  Skeleton,