@orianatech/pire 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/components/data/BarChart.d.cts +32 -0
  2. package/dist/components/data/BarChart.d.ts +33 -0
  3. package/dist/components/data/BarChart.d.ts.map +1 -0
  4. package/dist/components/data/ChartFrame.d.cts +62 -0
  5. package/dist/components/data/ChartFrame.d.ts +63 -0
  6. package/dist/components/data/ChartFrame.d.ts.map +1 -0
  7. package/dist/components/data/DonutChart.d.cts +26 -0
  8. package/dist/components/data/DonutChart.d.ts +27 -0
  9. package/dist/components/data/DonutChart.d.ts.map +1 -0
  10. package/dist/components/data/LineChart.d.cts +29 -0
  11. package/dist/components/data/LineChart.d.ts +30 -0
  12. package/dist/components/data/LineChart.d.ts.map +1 -0
  13. package/dist/components/data/chartGeometry.d.cts +67 -0
  14. package/dist/components/data/chartGeometry.d.ts +68 -0
  15. package/dist/components/data/chartGeometry.d.ts.map +1 -0
  16. package/dist/components/forms/DateRangePicker.d.cts +55 -0
  17. package/dist/components/forms/DateRangePicker.d.ts +56 -0
  18. package/dist/components/forms/DateRangePicker.d.ts.map +1 -0
  19. package/dist/components/forms/Input.d.cts +5 -0
  20. package/dist/components/forms/Input.d.ts +5 -0
  21. package/dist/components/forms/Input.d.ts.map +1 -1
  22. package/dist/components.css +108 -0
  23. package/dist/i18n/messages.d.cts +8 -0
  24. package/dist/i18n/messages.d.ts +8 -0
  25. package/dist/i18n/messages.d.ts.map +1 -1
  26. package/dist/index.cjs +913 -290
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +6 -0
  29. package/dist/index.d.ts +6 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +901 -266
  32. package/dist/index.js.map +1 -1
  33. package/dist/tokens/colors.css +36 -3
  34. package/dist/tokens/themes.css +6 -0
  35. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -817,6 +817,7 @@ var enMessages = {
817
817
  datePickerOpenCalendar: "Open calendar",
818
818
  datePickerPreviousMonth: "Previous month",
819
819
  datePickerNextMonth: "Next month",
820
+ dateRangePresetsLabel: "Date range shortcuts",
820
821
  numberFieldIncrease: "Increase",
821
822
  numberFieldDecrease: "Decrease",
822
823
  valueHelpFieldClear: "Clear selection",
@@ -834,7 +835,10 @@ var enMessages = {
834
835
  fileUploadChoose: "Choose files",
835
836
  fileUploadRemoveNamed: "Remove {name}",
836
837
  fileUploadUploading: "Uploading",
837
- fileDropZonePrompt: "Drag files here, or choose them"
838
+ fileDropZonePrompt: "Drag files here, or choose them",
839
+ chartCategoryHeader: "Category",
840
+ chartNoValue: "No data",
841
+ chartEmpty: "No data for this period"
838
842
  };
839
843
  var esMessages = {
840
844
  filterBarLabel: "Filtros",
@@ -853,6 +857,7 @@ var esMessages = {
853
857
  datePickerOpenCalendar: "Abrir calendario",
854
858
  datePickerPreviousMonth: "Mes anterior",
855
859
  datePickerNextMonth: "Mes siguiente",
860
+ dateRangePresetsLabel: "Atajos de rango de fechas",
856
861
  numberFieldIncrease: "Aumentar",
857
862
  numberFieldDecrease: "Disminuir",
858
863
  valueHelpFieldClear: "Limpiar selecci\xF3n",
@@ -870,7 +875,10 @@ var esMessages = {
870
875
  fileUploadChoose: "Elegir archivos",
871
876
  fileUploadRemoveNamed: "Quitar {name}",
872
877
  fileUploadUploading: "Subiendo",
873
- fileDropZonePrompt: "Arrastr\xE1 archivos ac\xE1, o elegilos"
878
+ fileDropZonePrompt: "Arrastr\xE1 archivos ac\xE1, o elegilos",
879
+ chartCategoryHeader: "Categor\xEDa",
880
+ chartNoValue: "Sin datos",
881
+ chartEmpty: "Sin datos para este per\xEDodo"
874
882
  };
875
883
 
876
884
  // src/i18n/PireIntlProvider.tsx
@@ -1251,6 +1259,138 @@ function DatePicker({
1251
1259
  ] });
1252
1260
  }
1253
1261
 
1262
+ // src/components/forms/DateRangePicker.tsx
1263
+ import {
1264
+ DateRangePicker as AriaDateRangePicker,
1265
+ Label as Label9,
1266
+ Group as Group7,
1267
+ DateInput as DateInput2,
1268
+ DateSegment as DateSegment2,
1269
+ Button as AriaButton9,
1270
+ Popover as Popover5,
1271
+ Dialog as AriaDialog2,
1272
+ RangeCalendar,
1273
+ CalendarGrid as CalendarGrid2,
1274
+ CalendarGridHeader as CalendarGridHeader2,
1275
+ CalendarHeaderCell as CalendarHeaderCell2,
1276
+ CalendarGridBody as CalendarGridBody2,
1277
+ CalendarCell as CalendarCell2,
1278
+ Heading as Heading3,
1279
+ Text as Text10,
1280
+ FieldError as FieldError9
1281
+ } from "react-aria-components";
1282
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
1283
+ function rangeLengthInDays(range) {
1284
+ return range.end.toDate("UTC").getTime() / 864e5 - range.start.toDate("UTC").getTime() / 864e5 + 1;
1285
+ }
1286
+ function DateRangePicker({
1287
+ label,
1288
+ description,
1289
+ errorMessage,
1290
+ maxRangeDays,
1291
+ presets,
1292
+ size = "md",
1293
+ fullWidth = true,
1294
+ startName,
1295
+ endName,
1296
+ className,
1297
+ style,
1298
+ ...rest
1299
+ }) {
1300
+ const msg = usePireMessages();
1301
+ const current = rest.value ?? rest.defaultValue ?? null;
1302
+ const tooLong = maxRangeDays != null && current != null && rangeLengthInDays(current) > maxRangeDays;
1303
+ return /* @__PURE__ */ jsxs20(
1304
+ AriaDateRangePicker,
1305
+ {
1306
+ className: cx("pire-field", className),
1307
+ style,
1308
+ startName,
1309
+ endName,
1310
+ validationBehavior: "aria",
1311
+ ...rest,
1312
+ isInvalid: rest.isInvalid || tooLong,
1313
+ children: [
1314
+ label ? /* @__PURE__ */ jsxs20(Label9, { className: "pire-field-label", children: [
1315
+ label,
1316
+ rest.isRequired ? /* @__PURE__ */ jsx26("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1317
+ ] }) : null,
1318
+ /* @__PURE__ */ jsxs20(
1319
+ Group7,
1320
+ {
1321
+ className: "pire-control pire-daterange-control",
1322
+ "data-size": size,
1323
+ "data-full-width": String(fullWidth),
1324
+ "data-invalid": rest.isInvalid || tooLong ? "true" : void 0,
1325
+ "data-readonly": rest.isReadOnly ? "true" : void 0,
1326
+ children: [
1327
+ /* @__PURE__ */ jsx26(DateInput2, { slot: "start", className: "pire-datefield", children: (segment) => /* @__PURE__ */ jsx26(DateSegment2, { segment, className: "pire-datesegment" }) }),
1328
+ /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", className: "pire-daterange-dash", children: "\u2013" }),
1329
+ /* @__PURE__ */ jsx26(DateInput2, { slot: "end", className: "pire-datefield", children: (segment) => /* @__PURE__ */ jsx26(DateSegment2, { segment, className: "pire-datesegment" }) }),
1330
+ /* @__PURE__ */ jsx26(
1331
+ AriaButton9,
1332
+ {
1333
+ className: "pire-iconbtn",
1334
+ "data-size": "sm",
1335
+ "aria-label": msg.datePickerOpenCalendar,
1336
+ style: { width: 24, height: 24 },
1337
+ children: /* @__PURE__ */ jsx26(Icon, { name: "calendar", size: 16 })
1338
+ }
1339
+ )
1340
+ ]
1341
+ }
1342
+ ),
1343
+ description ? /* @__PURE__ */ jsx26(Text10, { slot: "description", className: "pire-field-hint", children: description }) : null,
1344
+ /* @__PURE__ */ jsx26(FieldError9, { className: "pire-field-error", children: errorMessage }),
1345
+ /* @__PURE__ */ jsx26(Popover5, { className: "pire-popover", children: /* @__PURE__ */ jsxs20(AriaDialog2, { className: "pire-daterange-dialog", children: [
1346
+ presets?.length ? (
1347
+ // Before the calendar in the DOM, so keyboard users reach the shortcut without
1348
+ // arrowing through a month first.
1349
+ /* @__PURE__ */ jsx26("div", { className: "pire-daterange-presets", role: "group", "aria-label": msg.dateRangePresetsLabel, children: presets.map((preset) => /* @__PURE__ */ jsx26(
1350
+ AriaButton9,
1351
+ {
1352
+ className: "pire-daterange-preset",
1353
+ onPress: () => rest.onChange?.(preset.range()),
1354
+ children: preset.label
1355
+ },
1356
+ preset.id
1357
+ )) })
1358
+ ) : null,
1359
+ /* @__PURE__ */ jsxs20(RangeCalendar, { className: "pire-calendar", children: [
1360
+ /* @__PURE__ */ jsxs20("header", { className: "pire-calendar-head", children: [
1361
+ /* @__PURE__ */ jsx26(
1362
+ AriaButton9,
1363
+ {
1364
+ slot: "previous",
1365
+ className: "pire-iconbtn",
1366
+ "data-size": "sm",
1367
+ "aria-label": msg.datePickerPreviousMonth,
1368
+ children: /* @__PURE__ */ jsx26(Icon, { name: "chevron-left", size: 16 })
1369
+ }
1370
+ ),
1371
+ /* @__PURE__ */ jsx26(Heading3, { className: "pire-calendar-title" }),
1372
+ /* @__PURE__ */ jsx26(
1373
+ AriaButton9,
1374
+ {
1375
+ slot: "next",
1376
+ className: "pire-iconbtn",
1377
+ "data-size": "sm",
1378
+ "aria-label": msg.datePickerNextMonth,
1379
+ children: /* @__PURE__ */ jsx26(Icon, { name: "chevron-right", size: 16 })
1380
+ }
1381
+ )
1382
+ ] }),
1383
+ /* @__PURE__ */ jsxs20(CalendarGrid2, { className: "pire-calendar-grid", children: [
1384
+ /* @__PURE__ */ jsx26(CalendarGridHeader2, { children: (day) => /* @__PURE__ */ jsx26(CalendarHeaderCell2, { children: day }) }),
1385
+ /* @__PURE__ */ jsx26(CalendarGridBody2, { children: (date) => /* @__PURE__ */ jsx26(CalendarCell2, { date, className: "pire-calendar-cell" }) })
1386
+ ] })
1387
+ ] })
1388
+ ] }) })
1389
+ ]
1390
+ }
1391
+ );
1392
+ }
1393
+
1254
1394
  // src/components/forms/ValueHelpField.tsx
1255
1395
  import * as React9 from "react";
1256
1396
 
@@ -1258,8 +1398,8 @@ import * as React9 from "react";
1258
1398
  import * as React8 from "react";
1259
1399
 
1260
1400
  // src/components/feedback/Dialog.tsx
1261
- import { ModalOverlay, Modal, Dialog as AriaDialog2, Heading as Heading3 } from "react-aria-components";
1262
- import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
1401
+ import { ModalOverlay, Modal, Dialog as AriaDialog3, Heading as Heading4 } from "react-aria-components";
1402
+ import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
1263
1403
  function Dialog({
1264
1404
  isOpen,
1265
1405
  onOpenChange,
@@ -1279,7 +1419,7 @@ function Dialog({
1279
1419
  onClose?.();
1280
1420
  onOpenChange?.(false);
1281
1421
  };
1282
- return /* @__PURE__ */ jsx26(
1422
+ return /* @__PURE__ */ jsx27(
1283
1423
  ModalOverlay,
1284
1424
  {
1285
1425
  className: "pire-modal-overlay",
@@ -1288,16 +1428,16 @@ function Dialog({
1288
1428
  onOpenChange: (o) => {
1289
1429
  if (!o) close();
1290
1430
  },
1291
- children: /* @__PURE__ */ jsx26(Modal, { className: cx("pire-modal", className), "data-size": size, style, children: /* @__PURE__ */ jsxs20(AriaDialog2, { className: "pire-dialog", children: [
1292
- title ? /* @__PURE__ */ jsxs20("header", { className: "pire-dialog-head", children: [
1293
- /* @__PURE__ */ jsxs20("div", { style: { flex: 1, minWidth: 0 }, children: [
1294
- /* @__PURE__ */ jsx26(Heading3, { slot: "title", className: "pire-dialog-title", children: title }),
1295
- subtitle ? /* @__PURE__ */ jsx26("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
1431
+ children: /* @__PURE__ */ jsx27(Modal, { className: cx("pire-modal", className), "data-size": size, style, children: /* @__PURE__ */ jsxs21(AriaDialog3, { className: "pire-dialog", children: [
1432
+ title ? /* @__PURE__ */ jsxs21("header", { className: "pire-dialog-head", children: [
1433
+ /* @__PURE__ */ jsxs21("div", { style: { flex: 1, minWidth: 0 }, children: [
1434
+ /* @__PURE__ */ jsx27(Heading4, { slot: "title", className: "pire-dialog-title", children: title }),
1435
+ subtitle ? /* @__PURE__ */ jsx27("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
1296
1436
  ] }),
1297
- showClose ? /* @__PURE__ */ jsx26(IconButton, { icon: "x", label: msg.dialogClose, size: "sm", onPress: close }) : null
1437
+ showClose ? /* @__PURE__ */ jsx27(IconButton, { icon: "x", label: msg.dialogClose, size: "sm", onPress: close }) : null
1298
1438
  ] }) : null,
1299
- /* @__PURE__ */ jsx26("div", { className: "pire-dialog-body", children }),
1300
- footer ? /* @__PURE__ */ jsx26("footer", { className: "pire-dialog-foot", children: footer }) : null
1439
+ /* @__PURE__ */ jsx27("div", { className: "pire-dialog-body", children }),
1440
+ footer ? /* @__PURE__ */ jsx27("footer", { className: "pire-dialog-foot", children: footer }) : null
1301
1441
  ] }) })
1302
1442
  }
1303
1443
  );
@@ -1314,9 +1454,9 @@ import {
1314
1454
  } from "react-aria-components";
1315
1455
 
1316
1456
  // src/components/feedback/Skeleton.tsx
1317
- import { jsx as jsx27 } from "react/jsx-runtime";
1457
+ import { jsx as jsx28 } from "react/jsx-runtime";
1318
1458
  function Skeleton({ shape = "text", width, height, className, style, ...rest }) {
1319
- return /* @__PURE__ */ jsx27(
1459
+ return /* @__PURE__ */ jsx28(
1320
1460
  "div",
1321
1461
  {
1322
1462
  className: cx("pire-skeleton", className),
@@ -1330,7 +1470,7 @@ function Skeleton({ shape = "text", width, height, className, style, ...rest })
1330
1470
  var BAR_WIDTHS = ["72%", "54%", "86%", "63%"];
1331
1471
  function SkeletonTableRow({ columns, density = "regular", className, style, ...rest }) {
1332
1472
  const cells = typeof columns === "number" ? Array.from({ length: columns }, () => ({})) : columns;
1333
- return /* @__PURE__ */ jsx27(
1473
+ return /* @__PURE__ */ jsx28(
1334
1474
  "div",
1335
1475
  {
1336
1476
  className: cx("pire-skeleton-row", className),
@@ -1342,13 +1482,13 @@ function SkeletonTableRow({ columns, density = "regular", className, style, ...r
1342
1482
  const align = c.numeric ? "right" : c.align ?? "left";
1343
1483
  return (
1344
1484
  // biome-ignore lint/suspicious/noArrayIndexKey: columns are positional and never reordered.
1345
- /* @__PURE__ */ jsx27(
1485
+ /* @__PURE__ */ jsx28(
1346
1486
  "div",
1347
1487
  {
1348
1488
  className: "pire-skeleton-cell",
1349
1489
  "data-align": align,
1350
1490
  style: { width: c.width, flex: c.width ? "0 0 auto" : void 0 },
1351
- children: /* @__PURE__ */ jsx27(Skeleton, { width: BAR_WIDTHS[i % BAR_WIDTHS.length] })
1491
+ children: /* @__PURE__ */ jsx28(Skeleton, { width: BAR_WIDTHS[i % BAR_WIDTHS.length] })
1352
1492
  },
1353
1493
  i
1354
1494
  )
@@ -1359,7 +1499,7 @@ function SkeletonTableRow({ columns, density = "regular", className, style, ...r
1359
1499
  }
1360
1500
 
1361
1501
  // src/components/data/DataTable.tsx
1362
- import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
1502
+ import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
1363
1503
  function DataTable({
1364
1504
  columns,
1365
1505
  rows,
@@ -1391,14 +1531,14 @@ function DataTable({
1391
1531
  ...columns.map((c) => ({ width: c.width, align: c.align, numeric: c.numeric }))
1392
1532
  ];
1393
1533
  const body = isLoading ? [] : rows;
1394
- return /* @__PURE__ */ jsx28(
1534
+ return /* @__PURE__ */ jsx29(
1395
1535
  "div",
1396
1536
  {
1397
1537
  className: cx("pire-table-wrap", className),
1398
1538
  style,
1399
1539
  "data-loading": isLoading ? "true" : void 0,
1400
1540
  "aria-busy": isLoading ? "true" : void 0,
1401
- children: /* @__PURE__ */ jsxs21(
1541
+ children: /* @__PURE__ */ jsxs22(
1402
1542
  Table,
1403
1543
  {
1404
1544
  className: "pire-table",
@@ -1415,9 +1555,9 @@ function DataTable({
1415
1555
  if (row) onRowAction(row);
1416
1556
  } : void 0,
1417
1557
  children: [
1418
- /* @__PURE__ */ jsxs21(TableHeader, { className: "pire-thead-row", children: [
1419
- selectable ? /* @__PURE__ */ jsx28(Column, { className: "pire-th", width: 44, children: /* @__PURE__ */ jsx28(Checkbox, { slot: "selection", "aria-label": msg.dataTableSelectAll }) }) : null,
1420
- columns.map((c, i) => /* @__PURE__ */ jsx28(
1558
+ /* @__PURE__ */ jsxs22(TableHeader, { className: "pire-thead-row", children: [
1559
+ selectable ? /* @__PURE__ */ jsx29(Column, { className: "pire-th", width: 44, children: /* @__PURE__ */ jsx29(Checkbox, { slot: "selection", "aria-label": msg.dataTableSelectAll }) }) : null,
1560
+ columns.map((c, i) => /* @__PURE__ */ jsx29(
1421
1561
  Column,
1422
1562
  {
1423
1563
  id: c.key,
@@ -1427,9 +1567,9 @@ function DataTable({
1427
1567
  width: c.width,
1428
1568
  "data-align": c.numeric || c.align === "right" ? "right" : c.align,
1429
1569
  "data-allows-sorting": c.sortable ? "true" : void 0,
1430
- children: /* @__PURE__ */ jsxs21("span", { className: "pire-th-inner", children: [
1570
+ children: /* @__PURE__ */ jsxs22("span", { className: "pire-th-inner", children: [
1431
1571
  c.label,
1432
- c.sortable ? /* @__PURE__ */ jsx28(
1572
+ c.sortable ? /* @__PURE__ */ jsx29(
1433
1573
  Icon,
1434
1574
  {
1435
1575
  size: 12,
@@ -1442,15 +1582,15 @@ function DataTable({
1442
1582
  c.key
1443
1583
  ))
1444
1584
  ] }),
1445
- /* @__PURE__ */ jsx28(TableBody, { renderEmptyState: () => isLoading ? /* @__PURE__ */ jsxs21("div", { className: "pire-table-loading", role: "status", "aria-live": "polite", children: [
1446
- /* @__PURE__ */ jsx28("span", { className: "pire-sr-only", children: loadingLabel ?? msg.dataTableLoading }),
1585
+ /* @__PURE__ */ jsx29(TableBody, { renderEmptyState: () => isLoading ? /* @__PURE__ */ jsxs22("div", { className: "pire-table-loading", role: "status", "aria-live": "polite", children: [
1586
+ /* @__PURE__ */ jsx29("span", { className: "pire-sr-only", children: loadingLabel ?? msg.dataTableLoading }),
1447
1587
  Array.from({ length: skeletonRows }, (_, i) => (
1448
1588
  // biome-ignore lint/suspicious/noArrayIndexKey: placeholder rows are positional.
1449
- /* @__PURE__ */ jsx28(SkeletonTableRow, { columns: skeletonColumns, density }, i)
1589
+ /* @__PURE__ */ jsx29(SkeletonTableRow, { columns: skeletonColumns, density }, i)
1450
1590
  ))
1451
- ] }) : /* @__PURE__ */ jsx28("div", { className: "pire-table-empty", children: emptyLabel }), children: body.map((row) => /* @__PURE__ */ jsxs21(Row, { id: row.id, className: "pire-tr", "data-pressable": onRowAction ? "true" : void 0, children: [
1452
- selectable ? /* @__PURE__ */ jsx28(Cell, { className: "pire-td", children: /* @__PURE__ */ jsx28(Checkbox, { slot: "selection", "aria-label": msg.dataTableSelectRow }) }) : null,
1453
- columns.map((c) => /* @__PURE__ */ jsx28(
1591
+ ] }) : /* @__PURE__ */ jsx29("div", { className: "pire-table-empty", children: emptyLabel }), children: body.map((row) => /* @__PURE__ */ jsxs22(Row, { id: row.id, className: "pire-tr", "data-pressable": onRowAction ? "true" : void 0, children: [
1592
+ selectable ? /* @__PURE__ */ jsx29(Cell, { className: "pire-td", children: /* @__PURE__ */ jsx29(Checkbox, { slot: "selection", "aria-label": msg.dataTableSelectRow }) }) : null,
1593
+ columns.map((c) => /* @__PURE__ */ jsx29(
1454
1594
  Cell,
1455
1595
  {
1456
1596
  className: "pire-td",
@@ -1469,7 +1609,7 @@ function DataTable({
1469
1609
  }
1470
1610
 
1471
1611
  // src/components/patterns/ValueHelpDialog.tsx
1472
- import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
1612
+ import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
1473
1613
  function ValueHelpDialog({
1474
1614
  isOpen,
1475
1615
  title = "Select a record",
@@ -1490,16 +1630,16 @@ function ValueHelpDialog({
1490
1630
  if (!q) return rows;
1491
1631
  return rows.filter((row) => Object.values(row).some((v) => String(v).toLowerCase().includes(q)));
1492
1632
  }, [rows, query]);
1493
- return /* @__PURE__ */ jsx29(
1633
+ return /* @__PURE__ */ jsx30(
1494
1634
  Dialog,
1495
1635
  {
1496
1636
  isOpen,
1497
1637
  size: "lg",
1498
1638
  title,
1499
1639
  onClose,
1500
- footer: /* @__PURE__ */ jsx29(Button, { variant: "tertiary", onPress: onClose, children: msg.valueHelpDialogCancel }),
1501
- children: /* @__PURE__ */ jsxs22("div", { style: { display: "flex", flexDirection: "column", gap: "var(--sp-3)" }, children: [
1502
- /* @__PURE__ */ jsx29(
1640
+ footer: /* @__PURE__ */ jsx30(Button, { variant: "tertiary", onPress: onClose, children: msg.valueHelpDialogCancel }),
1641
+ children: /* @__PURE__ */ jsxs23("div", { style: { display: "flex", flexDirection: "column", gap: "var(--sp-3)" }, children: [
1642
+ /* @__PURE__ */ jsx30(
1503
1643
  Input,
1504
1644
  {
1505
1645
  "aria-label": msg.valueHelpDialogSearch,
@@ -1511,7 +1651,7 @@ function ValueHelpDialog({
1511
1651
  autoFocus: true
1512
1652
  }
1513
1653
  ),
1514
- /* @__PURE__ */ jsx29(
1654
+ /* @__PURE__ */ jsx30(
1515
1655
  DataTable,
1516
1656
  {
1517
1657
  "aria-label": typeof title === "string" ? title : "Records",
@@ -1531,7 +1671,7 @@ function ValueHelpDialog({
1531
1671
  }
1532
1672
 
1533
1673
  // src/components/forms/ValueHelpField.tsx
1534
- import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
1674
+ import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
1535
1675
  var defaultFormat = (row) => [row.id, row.name ?? row.label ?? row.text].filter(Boolean).join(" \u2014 ");
1536
1676
  function ValueHelpField({
1537
1677
  label,
@@ -1553,9 +1693,9 @@ function ValueHelpField({
1553
1693
  }) {
1554
1694
  const msg = usePireMessages();
1555
1695
  const [open, setOpen] = React9.useState(false);
1556
- return /* @__PURE__ */ jsxs23("div", { className: cx(className), style, children: [
1557
- /* @__PURE__ */ jsxs23("div", { style: { display: "flex", gap: "var(--sp-2)", alignItems: "flex-end" }, children: [
1558
- /* @__PURE__ */ jsx30(
1696
+ return /* @__PURE__ */ jsxs24("div", { className: cx(className), style, children: [
1697
+ /* @__PURE__ */ jsxs24("div", { style: { display: "flex", gap: "var(--sp-2)", alignItems: "flex-end" }, children: [
1698
+ /* @__PURE__ */ jsx31(
1559
1699
  Input,
1560
1700
  {
1561
1701
  label,
@@ -1569,7 +1709,7 @@ function ValueHelpField({
1569
1709
  errorMessage
1570
1710
  }
1571
1711
  ),
1572
- allowsClear && value ? /* @__PURE__ */ jsx30(
1712
+ allowsClear && value ? /* @__PURE__ */ jsx31(
1573
1713
  IconButton,
1574
1714
  {
1575
1715
  icon: "x",
@@ -1579,7 +1719,7 @@ function ValueHelpField({
1579
1719
  onPress: () => onChange?.(null)
1580
1720
  }
1581
1721
  ) : null,
1582
- /* @__PURE__ */ jsx30(
1722
+ /* @__PURE__ */ jsx31(
1583
1723
  IconButton,
1584
1724
  {
1585
1725
  icon: "search",
@@ -1590,7 +1730,7 @@ function ValueHelpField({
1590
1730
  }
1591
1731
  )
1592
1732
  ] }),
1593
- /* @__PURE__ */ jsx30(
1733
+ /* @__PURE__ */ jsx31(
1594
1734
  ValueHelpDialog,
1595
1735
  {
1596
1736
  isOpen: open,
@@ -1606,11 +1746,11 @@ function ValueHelpField({
1606
1746
 
1607
1747
  // src/components/forms/FileUpload.tsx
1608
1748
  import * as React10 from "react";
1609
- import { FileTrigger, Text as Text10 } from "react-aria-components";
1749
+ import { FileTrigger, Text as Text11 } from "react-aria-components";
1610
1750
 
1611
1751
  // src/components/feedback/ProgressBar.tsx
1612
- import { ProgressBar as AriaProgressBar, Label as Label9 } from "react-aria-components";
1613
- import { Fragment as Fragment2, jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
1752
+ import { ProgressBar as AriaProgressBar, Label as Label10 } from "react-aria-components";
1753
+ import { Fragment as Fragment2, jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
1614
1754
  function ProgressBar({
1615
1755
  value = 0,
1616
1756
  minValue = 0,
@@ -1623,7 +1763,7 @@ function ProgressBar({
1623
1763
  className,
1624
1764
  style
1625
1765
  }) {
1626
- return /* @__PURE__ */ jsx31(
1766
+ return /* @__PURE__ */ jsx32(
1627
1767
  AriaProgressBar,
1628
1768
  {
1629
1769
  className: cx("pire-progress", className),
@@ -1634,19 +1774,19 @@ function ProgressBar({
1634
1774
  maxValue,
1635
1775
  isIndeterminate,
1636
1776
  style,
1637
- children: ({ percentage, valueText }) => /* @__PURE__ */ jsxs24(Fragment2, { children: [
1638
- label || showValue ? /* @__PURE__ */ jsxs24("div", { className: "pire-progress-head", children: [
1639
- label ? /* @__PURE__ */ jsx31(Label9, { children: label }) : /* @__PURE__ */ jsx31("span", {}),
1640
- showValue && !isIndeterminate ? /* @__PURE__ */ jsx31("span", { className: "pire-numeric", children: valueText }) : null
1777
+ children: ({ percentage, valueText }) => /* @__PURE__ */ jsxs25(Fragment2, { children: [
1778
+ label || showValue ? /* @__PURE__ */ jsxs25("div", { className: "pire-progress-head", children: [
1779
+ label ? /* @__PURE__ */ jsx32(Label10, { children: label }) : /* @__PURE__ */ jsx32("span", {}),
1780
+ showValue && !isIndeterminate ? /* @__PURE__ */ jsx32("span", { className: "pire-numeric", children: valueText }) : null
1641
1781
  ] }) : null,
1642
- /* @__PURE__ */ jsx31("div", { className: "pire-progress-track", children: /* @__PURE__ */ jsx31("div", { className: "pire-progress-fill", style: { width: `${isIndeterminate ? 40 : percentage}%` } }) })
1782
+ /* @__PURE__ */ jsx32("div", { className: "pire-progress-track", children: /* @__PURE__ */ jsx32("div", { className: "pire-progress-fill", style: { width: `${isIndeterminate ? 40 : percentage}%` } }) })
1643
1783
  ] })
1644
1784
  }
1645
1785
  );
1646
1786
  }
1647
1787
 
1648
1788
  // src/components/forms/FileUpload.tsx
1649
- import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
1789
+ import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
1650
1790
  var isImage = (file) => file.type.startsWith("image/");
1651
1791
  function formatFileSize(bytes) {
1652
1792
  if (bytes < 1024) return `${bytes} B`;
@@ -1718,7 +1858,7 @@ function FileUpload({
1718
1858
  commit(allowsMultiple ? [...files, ...wrapped] : wrapped.slice(0, 1));
1719
1859
  };
1720
1860
  const remove = (target) => commit(files.filter((f) => f.file !== target));
1721
- return /* @__PURE__ */ jsxs25(
1861
+ return /* @__PURE__ */ jsxs26(
1722
1862
  "div",
1723
1863
  {
1724
1864
  className: cx("pire-field", "pire-fileupload", className),
@@ -1726,24 +1866,24 @@ function FileUpload({
1726
1866
  "data-full-width": String(fullWidth),
1727
1867
  "data-invalid": isInvalid ? "true" : void 0,
1728
1868
  children: [
1729
- label ? /* @__PURE__ */ jsxs25("span", { className: "pire-field-label", children: [
1869
+ label ? /* @__PURE__ */ jsxs26("span", { className: "pire-field-label", children: [
1730
1870
  label,
1731
- isRequired ? /* @__PURE__ */ jsx32("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1871
+ isRequired ? /* @__PURE__ */ jsx33("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
1732
1872
  ] }) : null,
1733
- /* @__PURE__ */ jsx32(
1873
+ /* @__PURE__ */ jsx33(
1734
1874
  FileTrigger,
1735
1875
  {
1736
1876
  acceptedFileTypes,
1737
1877
  allowsMultiple,
1738
1878
  onSelect: accept,
1739
- children: /* @__PURE__ */ jsx32(Button, { icon: "paperclip", isDisabled: isDisabled || isReadOnly, children: chooseLabel ?? msg.fileUploadChoose })
1879
+ children: /* @__PURE__ */ jsx33(Button, { icon: "paperclip", isDisabled: isDisabled || isReadOnly, children: chooseLabel ?? msg.fileUploadChoose })
1740
1880
  }
1741
1881
  ),
1742
- files.length ? /* @__PURE__ */ jsx32("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ jsxs25("li", { className: "pire-fileupload-item", children: [
1743
- previewUrl ? /* @__PURE__ */ jsx32("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ jsx32(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
1744
- /* @__PURE__ */ jsx32("span", { className: "pire-fileupload-name", children: file.name }),
1745
- /* @__PURE__ */ jsx32("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
1746
- isDisabled || isReadOnly ? null : /* @__PURE__ */ jsx32(
1882
+ files.length ? /* @__PURE__ */ jsx33("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ jsxs26("li", { className: "pire-fileupload-item", children: [
1883
+ previewUrl ? /* @__PURE__ */ jsx33("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ jsx33(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
1884
+ /* @__PURE__ */ jsx33("span", { className: "pire-fileupload-name", children: file.name }),
1885
+ /* @__PURE__ */ jsx33("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
1886
+ isDisabled || isReadOnly ? null : /* @__PURE__ */ jsx33(
1747
1887
  IconButton,
1748
1888
  {
1749
1889
  icon: "x",
@@ -1753,16 +1893,16 @@ function FileUpload({
1753
1893
  }
1754
1894
  )
1755
1895
  ] }, `${file.name}-${file.size}-${file.lastModified}`)) }) : null,
1756
- uploadProgress != null ? /* @__PURE__ */ jsx32(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
1757
- description ? /* @__PURE__ */ jsx32(Text10, { slot: "description", className: "pire-field-hint", children: description }) : null,
1758
- isInvalid && errorMessage ? /* @__PURE__ */ jsx32("span", { className: "pire-field-error", children: errorMessage }) : null
1896
+ uploadProgress != null ? /* @__PURE__ */ jsx33(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
1897
+ description ? /* @__PURE__ */ jsx33(Text11, { slot: "description", className: "pire-field-hint", children: description }) : null,
1898
+ isInvalid && errorMessage ? /* @__PURE__ */ jsx33("span", { className: "pire-field-error", children: errorMessage }) : null
1759
1899
  ]
1760
1900
  }
1761
1901
  );
1762
1902
  }
1763
1903
 
1764
1904
  // src/components/navigation/ShellBar.tsx
1765
- import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
1905
+ import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
1766
1906
  var initials2 = (name) => name.trim().split(/\s+/).slice(0, 2).map((p) => p[0]).join("").toUpperCase();
1767
1907
  function ShellBar({
1768
1908
  product,
@@ -1777,27 +1917,27 @@ function ShellBar({
1777
1917
  className,
1778
1918
  ...rest
1779
1919
  }) {
1780
- return /* @__PURE__ */ jsxs26("header", { className: cx("pire-shellbar", className), ...rest, children: [
1781
- onMenu ? /* @__PURE__ */ jsx33(IconButton, { icon: "menu", label: menuLabel, variant: "inverse", size: "sm", onPress: onMenu }) : null,
1782
- monogram ? /* @__PURE__ */ jsx33("span", { className: "pire-shellbar-mono", "aria-hidden": "true", children: monogram }) : null,
1783
- product ? /* @__PURE__ */ jsx33("span", { className: "pire-shellbar-product", children: product }) : null,
1784
- title ? /* @__PURE__ */ jsx33("span", { className: "pire-shellbar-title", children: title }) : null,
1785
- /* @__PURE__ */ jsx33("span", { className: "pire-shellbar-spacer" }),
1786
- onSearch ? /* @__PURE__ */ jsx33(IconButton, { icon: "search", label: searchLabel, variant: "inverse", size: "sm", onPress: onSearch }) : null,
1920
+ return /* @__PURE__ */ jsxs27("header", { className: cx("pire-shellbar", className), ...rest, children: [
1921
+ onMenu ? /* @__PURE__ */ jsx34(IconButton, { icon: "menu", label: menuLabel, variant: "inverse", size: "sm", onPress: onMenu }) : null,
1922
+ monogram ? /* @__PURE__ */ jsx34("span", { className: "pire-shellbar-mono", "aria-hidden": "true", children: monogram }) : null,
1923
+ product ? /* @__PURE__ */ jsx34("span", { className: "pire-shellbar-product", children: product }) : null,
1924
+ title ? /* @__PURE__ */ jsx34("span", { className: "pire-shellbar-title", children: title }) : null,
1925
+ /* @__PURE__ */ jsx34("span", { className: "pire-shellbar-spacer" }),
1926
+ onSearch ? /* @__PURE__ */ jsx34(IconButton, { icon: "search", label: searchLabel, variant: "inverse", size: "sm", onPress: onSearch }) : null,
1787
1927
  actions,
1788
- user ? /* @__PURE__ */ jsx33("span", { className: "pire-avatar", title: user, "aria-label": user, role: "img", children: initials2(user) }) : null
1928
+ user ? /* @__PURE__ */ jsx34("span", { className: "pire-avatar", title: user, "aria-label": user, role: "img", children: initials2(user) }) : null
1789
1929
  ] });
1790
1930
  }
1791
1931
 
1792
1932
  // src/components/navigation/SideNav.tsx
1793
1933
  import * as React11 from "react";
1794
1934
  import {
1795
- Button as AriaButton9,
1935
+ Button as AriaButton10,
1796
1936
  Disclosure,
1797
1937
  DisclosureGroup,
1798
1938
  DisclosurePanel,
1799
1939
  MenuTrigger,
1800
- Popover as Popover5
1940
+ Popover as Popover6
1801
1941
  } from "react-aria-components";
1802
1942
 
1803
1943
  // src/components/navigation/Menu.tsx
@@ -1808,11 +1948,11 @@ import {
1808
1948
  Separator as AriaSeparator2,
1809
1949
  Header
1810
1950
  } from "react-aria-components";
1811
- import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
1951
+ import { jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
1812
1952
  function Menu({ minWidth, className, style, ...rest }) {
1813
1953
  const width = typeof minWidth === "number" ? `${minWidth}px` : minWidth;
1814
1954
  const menuStyle = width == null ? style : { ["--pire-menu-min-w"]: width, ...style };
1815
- return /* @__PURE__ */ jsx34(
1955
+ return /* @__PURE__ */ jsx35(
1816
1956
  AriaMenu,
1817
1957
  {
1818
1958
  className: cx("pire-menu", className),
@@ -1830,35 +1970,35 @@ function MenuItem({
1830
1970
  className,
1831
1971
  ...rest
1832
1972
  }) {
1833
- return /* @__PURE__ */ jsxs27(
1973
+ return /* @__PURE__ */ jsxs28(
1834
1974
  AriaMenuItem,
1835
1975
  {
1836
1976
  className: cx("pire-menu-item", className),
1837
1977
  "data-tone": tone === "danger" ? "danger" : void 0,
1838
1978
  ...rest,
1839
1979
  children: [
1840
- icon ? /* @__PURE__ */ jsx34(Icon, { name: icon, size: 16, className: "pire-menu-item-icon" }) : null,
1841
- /* @__PURE__ */ jsxs27("span", { className: "pire-menu-item-body", children: [
1842
- /* @__PURE__ */ jsx34("span", { className: "pire-menu-item-label", children }),
1843
- description ? /* @__PURE__ */ jsx34("span", { className: "pire-menu-item-desc", children: description }) : null
1980
+ icon ? /* @__PURE__ */ jsx35(Icon, { name: icon, size: 16, className: "pire-menu-item-icon" }) : null,
1981
+ /* @__PURE__ */ jsxs28("span", { className: "pire-menu-item-body", children: [
1982
+ /* @__PURE__ */ jsx35("span", { className: "pire-menu-item-label", children }),
1983
+ description ? /* @__PURE__ */ jsx35("span", { className: "pire-menu-item-desc", children: description }) : null
1844
1984
  ] }),
1845
- shortcut ? /* @__PURE__ */ jsx34("kbd", { className: "pire-menu-item-shortcut", children: shortcut }) : null
1985
+ shortcut ? /* @__PURE__ */ jsx35("kbd", { className: "pire-menu-item-shortcut", children: shortcut }) : null
1846
1986
  ]
1847
1987
  }
1848
1988
  );
1849
1989
  }
1850
1990
  function MenuSection({ title, children, className, ...rest }) {
1851
- return /* @__PURE__ */ jsxs27(AriaMenuSection, { className: cx("pire-menu-section", className), ...rest, children: [
1852
- title ? /* @__PURE__ */ jsx34(Header, { className: "pire-menu-section-title", children: title }) : null,
1991
+ return /* @__PURE__ */ jsxs28(AriaMenuSection, { className: cx("pire-menu-section", className), ...rest, children: [
1992
+ title ? /* @__PURE__ */ jsx35(Header, { className: "pire-menu-section-title", children: title }) : null,
1853
1993
  children
1854
1994
  ] });
1855
1995
  }
1856
1996
  function MenuSeparator({ className }) {
1857
- return /* @__PURE__ */ jsx34(AriaSeparator2, { className: cx("pire-menu-separator", className) });
1997
+ return /* @__PURE__ */ jsx35(AriaSeparator2, { className: cx("pire-menu-separator", className) });
1858
1998
  }
1859
1999
 
1860
2000
  // src/components/navigation/SideNav.tsx
1861
- import { jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
2001
+ import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
1862
2002
  function findActiveParent(groups, value) {
1863
2003
  if (value == null) return void 0;
1864
2004
  for (const group of groups) {
@@ -1907,8 +2047,8 @@ function SideNav({
1907
2047
  };
1908
2048
  const renderRow = (item, onPress, isGroup) => {
1909
2049
  const selected = !isGroup && item.id === value;
1910
- const button = /* @__PURE__ */ jsxs28(
1911
- AriaButton9,
2050
+ const button = /* @__PURE__ */ jsxs29(
2051
+ AriaButton10,
1912
2052
  {
1913
2053
  className: "pire-sidenav-item",
1914
2054
  "data-selected": selected ? "true" : void 0,
@@ -1917,70 +2057,70 @@ function SideNav({
1917
2057
  "aria-label": collapsed ? item.label : void 0,
1918
2058
  onPress,
1919
2059
  children: [
1920
- item.icon ? /* @__PURE__ */ jsx35(Icon, { name: item.icon, size: 16 }) : null,
1921
- collapsed ? null : /* @__PURE__ */ jsx35("span", { children: item.label }),
1922
- item.count != null && !collapsed ? /* @__PURE__ */ jsx35("span", { className: "pire-sidenav-count", children: item.count }) : null
2060
+ item.icon ? /* @__PURE__ */ jsx36(Icon, { name: item.icon, size: 16 }) : null,
2061
+ collapsed ? null : /* @__PURE__ */ jsx36("span", { children: item.label }),
2062
+ item.count != null && !collapsed ? /* @__PURE__ */ jsx36("span", { className: "pire-sidenav-count", children: item.count }) : null
1923
2063
  ]
1924
2064
  },
1925
2065
  item.id
1926
2066
  );
1927
- return collapsed ? /* @__PURE__ */ jsx35(Tooltip, { label: item.label, placement: "right", children: button }, item.id) : button;
2067
+ return collapsed ? /* @__PURE__ */ jsx36(Tooltip, { label: item.label, placement: "right", children: button }, item.id) : button;
1928
2068
  };
1929
- const renderRailFlyout = (item) => /* @__PURE__ */ jsxs28(MenuTrigger, { children: [
1930
- /* @__PURE__ */ jsx35(
1931
- AriaButton9,
2069
+ const renderRailFlyout = (item) => /* @__PURE__ */ jsxs29(MenuTrigger, { children: [
2070
+ /* @__PURE__ */ jsx36(
2071
+ AriaButton10,
1932
2072
  {
1933
2073
  className: "pire-sidenav-item",
1934
2074
  "aria-label": item.label,
1935
2075
  "data-active-child": item.id === activeParent ? "true" : void 0,
1936
- children: item.icon ? /* @__PURE__ */ jsx35(Icon, { name: item.icon, size: 16 }) : null
2076
+ children: item.icon ? /* @__PURE__ */ jsx36(Icon, { name: item.icon, size: 16 }) : null
1937
2077
  }
1938
2078
  ),
1939
- /* @__PURE__ */ jsx35(Popover5, { className: "pire-popover", placement: "right top", offset: 4, children: /* @__PURE__ */ jsx35(
2079
+ /* @__PURE__ */ jsx36(Popover6, { className: "pire-popover", placement: "right top", offset: 4, children: /* @__PURE__ */ jsx36(
1940
2080
  Menu,
1941
2081
  {
1942
2082
  "aria-label": item.label,
1943
2083
  className: "pire-sidenav-flyout",
1944
2084
  onAction: (key) => onChange?.(String(key)),
1945
- children: (item.items ?? []).map((child) => /* @__PURE__ */ jsx35(MenuItem, { id: child.id, children: child.label }, child.id))
2085
+ children: (item.items ?? []).map((child) => /* @__PURE__ */ jsx36(MenuItem, { id: child.id, children: child.label }, child.id))
1946
2086
  }
1947
2087
  ) })
1948
2088
  ] }, item.id);
1949
- const renderSection = (item) => /* @__PURE__ */ jsxs28(Disclosure, { id: item.id, className: "pire-sidenav-section", children: [
1950
- /* @__PURE__ */ jsxs28(
1951
- AriaButton9,
2089
+ const renderSection = (item) => /* @__PURE__ */ jsxs29(Disclosure, { id: item.id, className: "pire-sidenav-section", children: [
2090
+ /* @__PURE__ */ jsxs29(
2091
+ AriaButton10,
1952
2092
  {
1953
2093
  slot: "trigger",
1954
2094
  className: "pire-sidenav-item",
1955
2095
  "data-kind": "group",
1956
2096
  "data-active-child": item.id === activeParent ? "true" : void 0,
1957
2097
  children: [
1958
- item.icon ? /* @__PURE__ */ jsx35(Icon, { name: item.icon, size: 16 }) : null,
1959
- /* @__PURE__ */ jsx35("span", { children: item.label }),
1960
- item.count != null ? /* @__PURE__ */ jsx35("span", { className: "pire-sidenav-count", children: item.count }) : null,
1961
- /* @__PURE__ */ jsx35(Icon, { name: "chevron-down", size: 16, className: "pire-sidenav-chevron" })
2098
+ item.icon ? /* @__PURE__ */ jsx36(Icon, { name: item.icon, size: 16 }) : null,
2099
+ /* @__PURE__ */ jsx36("span", { children: item.label }),
2100
+ item.count != null ? /* @__PURE__ */ jsx36("span", { className: "pire-sidenav-count", children: item.count }) : null,
2101
+ /* @__PURE__ */ jsx36(Icon, { name: "chevron-down", size: 16, className: "pire-sidenav-chevron" })
1962
2102
  ]
1963
2103
  }
1964
2104
  ),
1965
- /* @__PURE__ */ jsx35(DisclosurePanel, { className: "pire-sidenav-subnav", children: item.items?.map((child) => {
2105
+ /* @__PURE__ */ jsx36(DisclosurePanel, { className: "pire-sidenav-subnav", children: item.items?.map((child) => {
1966
2106
  const selected = child.id === value;
1967
- return /* @__PURE__ */ jsxs28(
1968
- AriaButton9,
2107
+ return /* @__PURE__ */ jsxs29(
2108
+ AriaButton10,
1969
2109
  {
1970
2110
  className: "pire-sidenav-item pire-sidenav-subitem",
1971
2111
  "data-selected": selected ? "true" : void 0,
1972
2112
  "aria-current": selected ? "page" : void 0,
1973
2113
  onPress: () => onChange?.(child.id),
1974
2114
  children: [
1975
- /* @__PURE__ */ jsx35("span", { children: child.label }),
1976
- child.count != null ? /* @__PURE__ */ jsx35("span", { className: "pire-sidenav-count", children: child.count }) : null
2115
+ /* @__PURE__ */ jsx36("span", { children: child.label }),
2116
+ child.count != null ? /* @__PURE__ */ jsx36("span", { className: "pire-sidenav-count", children: child.count }) : null
1977
2117
  ]
1978
2118
  },
1979
2119
  child.id
1980
2120
  );
1981
2121
  }) })
1982
2122
  ] }, item.id);
1983
- return /* @__PURE__ */ jsxs28(
2123
+ return /* @__PURE__ */ jsxs29(
1984
2124
  "nav",
1985
2125
  {
1986
2126
  className: cx("pire-sidenav", className),
@@ -1996,9 +2136,9 @@ function SideNav({
1996
2136
  if (isGroup && collapsed && railFlyout) return renderRailFlyout(item);
1997
2137
  return renderRow(item, () => isGroup ? toggleExpanded(item.id) : onChange?.(item.id), isGroup);
1998
2138
  });
1999
- return /* @__PURE__ */ jsxs28("div", { className: "pire-sidenav-group", children: [
2000
- group.label && !collapsed ? /* @__PURE__ */ jsx35("div", { className: "pire-sidenav-label", children: group.label }) : null,
2001
- hasSections ? /* @__PURE__ */ jsx35(
2139
+ return /* @__PURE__ */ jsxs29("div", { className: "pire-sidenav-group", children: [
2140
+ group.label && !collapsed ? /* @__PURE__ */ jsx36("div", { className: "pire-sidenav-label", children: group.label }) : null,
2141
+ hasSections ? /* @__PURE__ */ jsx36(
2002
2142
  DisclosureGroup,
2003
2143
  {
2004
2144
  className: "pire-sidenav-tree",
@@ -2010,7 +2150,7 @@ function SideNav({
2010
2150
  ) : rows
2011
2151
  ] }, group.label ?? gi);
2012
2152
  }),
2013
- footer ? /* @__PURE__ */ jsx35("div", { className: "pire-sidenav-footer", children: footer }) : null
2153
+ footer ? /* @__PURE__ */ jsx36("div", { className: "pire-sidenav-footer", children: footer }) : null
2014
2154
  ]
2015
2155
  }
2016
2156
  );
@@ -2018,9 +2158,9 @@ function SideNav({
2018
2158
 
2019
2159
  // src/components/navigation/Tabs.tsx
2020
2160
  import { Tabs as AriaTabs, TabList, Tab as AriaTab, TabPanel } from "react-aria-components";
2021
- import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
2161
+ import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
2022
2162
  function Tabs({ items, value, defaultValue, onChange, panels, className, style, ...rest }) {
2023
- return /* @__PURE__ */ jsxs29(
2163
+ return /* @__PURE__ */ jsxs30(
2024
2164
  AriaTabs,
2025
2165
  {
2026
2166
  className,
@@ -2029,12 +2169,12 @@ function Tabs({ items, value, defaultValue, onChange, panels, className, style,
2029
2169
  defaultSelectedKey: defaultValue,
2030
2170
  onSelectionChange: (k) => onChange?.(String(k)),
2031
2171
  children: [
2032
- /* @__PURE__ */ jsx36(TabList, { className: "pire-tablist", items, "aria-label": rest["aria-label"] ?? "Views", children: (item) => /* @__PURE__ */ jsxs29(AriaTab, { className: cx("pire-tab"), id: item.id, isDisabled: item.isDisabled, children: [
2033
- item.icon ? /* @__PURE__ */ jsx36(Icon, { name: item.icon, size: 16 }) : null,
2172
+ /* @__PURE__ */ jsx37(TabList, { className: "pire-tablist", items, "aria-label": rest["aria-label"] ?? "Views", children: (item) => /* @__PURE__ */ jsxs30(AriaTab, { className: cx("pire-tab"), id: item.id, isDisabled: item.isDisabled, children: [
2173
+ item.icon ? /* @__PURE__ */ jsx37(Icon, { name: item.icon, size: 16 }) : null,
2034
2174
  item.label,
2035
- item.count != null ? /* @__PURE__ */ jsx36("span", { className: "pire-tab-count", children: item.count }) : null
2175
+ item.count != null ? /* @__PURE__ */ jsx37("span", { className: "pire-tab-count", children: item.count }) : null
2036
2176
  ] }) }),
2037
- items.map((item) => /* @__PURE__ */ jsx36(TabPanel, { id: item.id, className: panels ? "pire-tabpanel" : void 0, children: panels?.[item.id] }, item.id))
2177
+ items.map((item) => /* @__PURE__ */ jsx37(TabPanel, { id: item.id, className: panels ? "pire-tabpanel" : void 0, children: panels?.[item.id] }, item.id))
2038
2178
  ]
2039
2179
  }
2040
2180
  );
@@ -2042,9 +2182,9 @@ function Tabs({ items, value, defaultValue, onChange, panels, className, style,
2042
2182
 
2043
2183
  // src/components/navigation/Breadcrumb.tsx
2044
2184
  import { Breadcrumbs as AriaBreadcrumbs, Breadcrumb as AriaBreadcrumb, Link as Link2 } from "react-aria-components";
2045
- import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
2185
+ import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
2046
2186
  function Breadcrumb({ items, onNavigate, className, style }) {
2047
- return /* @__PURE__ */ jsx37(
2187
+ return /* @__PURE__ */ jsx38(
2048
2188
  AriaBreadcrumbs,
2049
2189
  {
2050
2190
  className: cx("pire-breadcrumbs", className),
@@ -2053,9 +2193,9 @@ function Breadcrumb({ items, onNavigate, className, style }) {
2053
2193
  onAction: (key) => onNavigate?.(String(key)),
2054
2194
  children: (item) => {
2055
2195
  const last = items[items.length - 1] === item;
2056
- return /* @__PURE__ */ jsxs30(AriaBreadcrumb, { className: "pire-breadcrumb", id: item.id ?? item.label, children: [
2057
- last ? item.label : /* @__PURE__ */ jsx37(Link2, { href: item.href, children: item.label }),
2058
- last ? null : /* @__PURE__ */ jsx37(Icon, { name: "chevron-right", size: 12, style: { color: "var(--text-tertiary)" } })
2196
+ return /* @__PURE__ */ jsxs31(AriaBreadcrumb, { className: "pire-breadcrumb", id: item.id ?? item.label, children: [
2197
+ last ? item.label : /* @__PURE__ */ jsx38(Link2, { href: item.href, children: item.label }),
2198
+ last ? null : /* @__PURE__ */ jsx38(Icon, { name: "chevron-right", size: 12, style: { color: "var(--text-tertiary)" } })
2059
2199
  ] });
2060
2200
  }
2061
2201
  }
@@ -2063,7 +2203,7 @@ function Breadcrumb({ items, onNavigate, className, style }) {
2063
2203
  }
2064
2204
 
2065
2205
  // src/components/navigation/Pagination.tsx
2066
- import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
2206
+ import { jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
2067
2207
  function Pagination({
2068
2208
  page = 1,
2069
2209
  pageSize = 25,
@@ -2078,9 +2218,9 @@ function Pagination({
2078
2218
  const pages = Math.max(1, Math.ceil(total / pageSize));
2079
2219
  const from = total === 0 ? 0 : (page - 1) * pageSize + 1;
2080
2220
  const to = Math.min(total, page * pageSize);
2081
- return /* @__PURE__ */ jsxs31("nav", { className: cx("pire-pagination", className), style, "aria-label": msg.paginationLabel, children: [
2082
- /* @__PURE__ */ jsx38("span", { className: "pire-pagination-count", children: msg.paginationRange.replace("{from}", from.toLocaleString()).replace("{to}", to.toLocaleString()).replace("{total}", total.toLocaleString()) }),
2083
- /* @__PURE__ */ jsx38(
2221
+ return /* @__PURE__ */ jsxs32("nav", { className: cx("pire-pagination", className), style, "aria-label": msg.paginationLabel, children: [
2222
+ /* @__PURE__ */ jsx39("span", { className: "pire-pagination-count", children: msg.paginationRange.replace("{from}", from.toLocaleString()).replace("{to}", to.toLocaleString()).replace("{total}", total.toLocaleString()) }),
2223
+ /* @__PURE__ */ jsx39(
2084
2224
  IconButton,
2085
2225
  {
2086
2226
  icon: "chevron-left",
@@ -2091,8 +2231,8 @@ function Pagination({
2091
2231
  onPress: () => onPageChange?.(page - 1)
2092
2232
  }
2093
2233
  ),
2094
- /* @__PURE__ */ jsx38("span", { className: "pire-pagination-count", "aria-live": "polite", children: msg.paginationPageOf.replace("{page}", String(page)).replace("{pages}", String(pages)) }),
2095
- /* @__PURE__ */ jsx38(
2234
+ /* @__PURE__ */ jsx39("span", { className: "pire-pagination-count", "aria-live": "polite", children: msg.paginationPageOf.replace("{page}", String(page)).replace("{pages}", String(pages)) }),
2235
+ /* @__PURE__ */ jsx39(
2096
2236
  IconButton,
2097
2237
  {
2098
2238
  icon: "chevron-right",
@@ -2103,7 +2243,7 @@ function Pagination({
2103
2243
  onPress: () => onPageChange?.(page + 1)
2104
2244
  }
2105
2245
  ),
2106
- onPageSizeChange ? /* @__PURE__ */ jsx38(
2246
+ onPageSizeChange ? /* @__PURE__ */ jsx39(
2107
2247
  Select,
2108
2248
  {
2109
2249
  "aria-label": msg.paginationRowsPerPage,
@@ -2119,7 +2259,7 @@ function Pagination({
2119
2259
  }
2120
2260
 
2121
2261
  // src/components/feedback/InlineMessage.tsx
2122
- import { jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
2262
+ import { jsx as jsx40, jsxs as jsxs33 } from "react/jsx-runtime";
2123
2263
  var KIND_ICON = {
2124
2264
  info: "info",
2125
2265
  success: "check-circle-2",
@@ -2129,7 +2269,7 @@ var KIND_ICON = {
2129
2269
  function InlineMessage({ kind = "info", title, action, onClose, children, className, ...rest }) {
2130
2270
  const msg = usePireMessages();
2131
2271
  const assertive = kind === "error" || kind === "warning";
2132
- return /* @__PURE__ */ jsxs32(
2272
+ return /* @__PURE__ */ jsxs33(
2133
2273
  "div",
2134
2274
  {
2135
2275
  className: cx("pire-msg", className),
@@ -2138,13 +2278,13 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
2138
2278
  "aria-live": assertive ? "assertive" : "polite",
2139
2279
  ...rest,
2140
2280
  children: [
2141
- /* @__PURE__ */ jsx39(Icon, { name: KIND_ICON[kind], size: 16, style: { marginTop: 2 } }),
2142
- /* @__PURE__ */ jsxs32("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "var(--sp-1)" }, children: [
2143
- title ? /* @__PURE__ */ jsx39("span", { className: "pire-msg-title", children: title }) : null,
2144
- children ? /* @__PURE__ */ jsx39("span", { className: "pire-msg-body", children }) : null,
2281
+ /* @__PURE__ */ jsx40(Icon, { name: KIND_ICON[kind], size: 16, style: { marginTop: 2 } }),
2282
+ /* @__PURE__ */ jsxs33("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "var(--sp-1)" }, children: [
2283
+ title ? /* @__PURE__ */ jsx40("span", { className: "pire-msg-title", children: title }) : null,
2284
+ children ? /* @__PURE__ */ jsx40("span", { className: "pire-msg-body", children }) : null,
2145
2285
  action
2146
2286
  ] }),
2147
- onClose ? /* @__PURE__ */ jsx39(IconButton, { icon: "x", label: msg.inlineMessageDismiss, size: "sm", onPress: onClose }) : null
2287
+ onClose ? /* @__PURE__ */ jsx40(IconButton, { icon: "x", label: msg.inlineMessageDismiss, size: "sm", onPress: onClose }) : null
2148
2288
  ]
2149
2289
  }
2150
2290
  );
@@ -2152,7 +2292,7 @@ function InlineMessage({ kind = "info", title, action, onClose, children, classN
2152
2292
 
2153
2293
  // src/components/feedback/Toast.tsx
2154
2294
  import * as React12 from "react";
2155
- import { jsx as jsx40, jsxs as jsxs33 } from "react/jsx-runtime";
2295
+ import { jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
2156
2296
  var KIND_ICON2 = {
2157
2297
  info: "info",
2158
2298
  success: "check-circle-2",
@@ -2161,7 +2301,7 @@ var KIND_ICON2 = {
2161
2301
  };
2162
2302
  function Toast({ kind = "success", onClose, position = "bottom-center", children, className, ...rest }) {
2163
2303
  const msg = usePireMessages();
2164
- return /* @__PURE__ */ jsxs33(
2304
+ return /* @__PURE__ */ jsxs34(
2165
2305
  "div",
2166
2306
  {
2167
2307
  className: cx("pire-toast", className),
@@ -2170,9 +2310,9 @@ function Toast({ kind = "success", onClose, position = "bottom-center", children
2170
2310
  "aria-live": kind === "error" ? "assertive" : "polite",
2171
2311
  ...rest,
2172
2312
  children: [
2173
- /* @__PURE__ */ jsx40(Icon, { name: KIND_ICON2[kind], size: 16 }),
2174
- /* @__PURE__ */ jsx40("span", { style: { flex: 1 }, children }),
2175
- onClose ? /* @__PURE__ */ jsx40(IconButton, { icon: "x", label: msg.toastDismiss, size: "sm", variant: "inverse", onPress: onClose }) : null
2313
+ /* @__PURE__ */ jsx41(Icon, { name: KIND_ICON2[kind], size: 16 }),
2314
+ /* @__PURE__ */ jsx41("span", { style: { flex: 1 }, children }),
2315
+ onClose ? /* @__PURE__ */ jsx41(IconButton, { icon: "x", label: msg.toastDismiss, size: "sm", variant: "inverse", onPress: onClose }) : null
2176
2316
  ]
2177
2317
  }
2178
2318
  );
@@ -2190,9 +2330,9 @@ function ToastProvider({ children, timeout = 6e3 }) {
2190
2330
  return id;
2191
2331
  }, [close, timeout]);
2192
2332
  const value = React12.useMemo(() => ({ add, close }), [add, close]);
2193
- return /* @__PURE__ */ jsxs33(ToastContext.Provider, { value, children: [
2333
+ return /* @__PURE__ */ jsxs34(ToastContext.Provider, { value, children: [
2194
2334
  children,
2195
- /* @__PURE__ */ jsx40("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ jsx40(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2335
+ /* @__PURE__ */ jsx41("div", { className: "pire-toast-region", role: "region", "aria-label": msg.toastRegionLabel, children: toasts.map((t) => /* @__PURE__ */ jsx41(Toast, { kind: t.kind, onClose: () => close(t.id), style: { position: "static", transform: "none" }, children: t.message }, t.id)) })
2196
2336
  ] });
2197
2337
  }
2198
2338
  function useToast() {
@@ -2202,8 +2342,8 @@ function useToast() {
2202
2342
  }
2203
2343
 
2204
2344
  // src/components/data/KpiTile.tsx
2205
- import { Button as AriaButton10 } from "react-aria-components";
2206
- import { Fragment as Fragment3, jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
2345
+ import { Button as AriaButton11 } from "react-aria-components";
2346
+ import { Fragment as Fragment3, jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
2207
2347
  function KpiTile({
2208
2348
  label,
2209
2349
  value,
@@ -2219,50 +2359,50 @@ function KpiTile({
2219
2359
  style
2220
2360
  }) {
2221
2361
  const tone = deltaTone ?? (deltaDirection === "down" ? "negative" : "positive");
2222
- const body = /* @__PURE__ */ jsxs34(Fragment3, { children: [
2223
- /* @__PURE__ */ jsxs34("span", { className: "pire-kpi-label", children: [
2224
- icon ? /* @__PURE__ */ jsx41(Icon, { name: icon, size: 16 }) : null,
2362
+ const body = /* @__PURE__ */ jsxs35(Fragment3, { children: [
2363
+ /* @__PURE__ */ jsxs35("span", { className: "pire-kpi-label", children: [
2364
+ icon ? /* @__PURE__ */ jsx42(Icon, { name: icon, size: 16 }) : null,
2225
2365
  label
2226
2366
  ] }),
2227
- /* @__PURE__ */ jsxs34("span", { className: "pire-kpi-value", children: [
2367
+ /* @__PURE__ */ jsxs35("span", { className: "pire-kpi-value", children: [
2228
2368
  value,
2229
- unit ? /* @__PURE__ */ jsx41("span", { className: "pire-kpi-unit", children: unit }) : null
2369
+ unit ? /* @__PURE__ */ jsx42("span", { className: "pire-kpi-unit", children: unit }) : null
2230
2370
  ] }),
2231
- delta ? /* @__PURE__ */ jsxs34("span", { className: "pire-kpi-delta", "data-tone": tone, children: [
2232
- deltaDirection ? /* @__PURE__ */ jsx41(Icon, { name: deltaDirection === "up" ? "trending-up" : "trending-down", size: 12 }) : null,
2371
+ delta ? /* @__PURE__ */ jsxs35("span", { className: "pire-kpi-delta", "data-tone": tone, children: [
2372
+ deltaDirection ? /* @__PURE__ */ jsx42(Icon, { name: deltaDirection === "up" ? "trending-up" : "trending-down", size: 12 }) : null,
2233
2373
  delta
2234
2374
  ] }) : null,
2235
- footnote ? /* @__PURE__ */ jsx41("span", { className: "pire-kpi-foot", children: footnote }) : null
2375
+ footnote ? /* @__PURE__ */ jsx42("span", { className: "pire-kpi-foot", children: footnote }) : null
2236
2376
  ] });
2237
2377
  const props = { className: cx("pire-kpi", className), "data-status": status, style };
2238
- return onPress ? /* @__PURE__ */ jsx41(AriaButton10, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ jsx41("div", { ...props, children: body });
2378
+ return onPress ? /* @__PURE__ */ jsx42(AriaButton11, { ...props, "data-pressable": "true", onPress, children: body }) : /* @__PURE__ */ jsx42("div", { ...props, children: body });
2239
2379
  }
2240
2380
 
2241
2381
  // src/components/data/ObjectHeader.tsx
2242
- import { jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
2382
+ import { jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
2243
2383
  function ObjectHeader({ title, subtitle, id, breadcrumb, badge, facts, actions, className, ...rest }) {
2244
- return /* @__PURE__ */ jsxs35("header", { className: cx("pire-objheader", className), ...rest, children: [
2384
+ return /* @__PURE__ */ jsxs36("header", { className: cx("pire-objheader", className), ...rest, children: [
2245
2385
  breadcrumb,
2246
- /* @__PURE__ */ jsxs35("div", { className: "pire-objheader-row", children: [
2247
- /* @__PURE__ */ jsxs35("div", { style: { minWidth: 0 }, children: [
2248
- /* @__PURE__ */ jsx42("h1", { className: "pire-objheader-title", children: title }),
2249
- subtitle || id ? /* @__PURE__ */ jsxs35("div", { className: "pire-objheader-sub", children: [
2386
+ /* @__PURE__ */ jsxs36("div", { className: "pire-objheader-row", children: [
2387
+ /* @__PURE__ */ jsxs36("div", { style: { minWidth: 0 }, children: [
2388
+ /* @__PURE__ */ jsx43("h1", { className: "pire-objheader-title", children: title }),
2389
+ subtitle || id ? /* @__PURE__ */ jsxs36("div", { className: "pire-objheader-sub", children: [
2250
2390
  subtitle,
2251
- id ? /* @__PURE__ */ jsx42("span", { className: "pire-objheader-id", children: id }) : null
2391
+ id ? /* @__PURE__ */ jsx43("span", { className: "pire-objheader-id", children: id }) : null
2252
2392
  ] }) : null
2253
2393
  ] }),
2254
2394
  badge,
2255
- actions ? /* @__PURE__ */ jsx42("div", { className: "pire-objheader-actions", children: actions }) : null
2395
+ actions ? /* @__PURE__ */ jsx43("div", { className: "pire-objheader-actions", children: actions }) : null
2256
2396
  ] }),
2257
- facts?.length ? /* @__PURE__ */ jsx42("dl", { className: "pire-facts", style: { margin: 0 }, children: facts.map((fact) => /* @__PURE__ */ jsxs35("div", { children: [
2258
- /* @__PURE__ */ jsx42("dt", { className: "pire-fact-label", children: fact.label }),
2259
- /* @__PURE__ */ jsx42("dd", { className: "pire-fact-value", "data-numeric": fact.numeric ? "true" : void 0, style: { margin: 0 }, children: fact.value })
2397
+ facts?.length ? /* @__PURE__ */ jsx43("dl", { className: "pire-facts", style: { margin: 0 }, children: facts.map((fact) => /* @__PURE__ */ jsxs36("div", { children: [
2398
+ /* @__PURE__ */ jsx43("dt", { className: "pire-fact-label", children: fact.label }),
2399
+ /* @__PURE__ */ jsx43("dd", { className: "pire-fact-value", "data-numeric": fact.numeric ? "true" : void 0, style: { margin: 0 }, children: fact.value })
2260
2400
  ] }, fact.label)) }) : null
2261
2401
  ] });
2262
2402
  }
2263
2403
 
2264
2404
  // src/components/data/FilterBar.tsx
2265
- import { jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
2405
+ import { jsx as jsx44, jsxs as jsxs37 } from "react/jsx-runtime";
2266
2406
  function FilterBar({
2267
2407
  children,
2268
2408
  activeFilters = [],
@@ -2279,66 +2419,555 @@ function FilterBar({
2279
2419
  const label = useMessage("filterBarLabel", rest["aria-label"]);
2280
2420
  const go = useMessage("filterBarGo", goLabel);
2281
2421
  const clearAll = useMessage("filterBarClearAll", clearAllLabel);
2282
- return /* @__PURE__ */ jsxs36("section", { className: cx("pire-filterbar", className), ...rest, "aria-label": label, children: [
2283
- /* @__PURE__ */ jsxs36("div", { className: "pire-filterbar-controls", children: [
2422
+ return /* @__PURE__ */ jsxs37("section", { className: cx("pire-filterbar", className), ...rest, "aria-label": label, children: [
2423
+ /* @__PURE__ */ jsxs37("div", { className: "pire-filterbar-controls", children: [
2284
2424
  children,
2285
- onGo ? /* @__PURE__ */ jsx43(Button, { variant: "primary", onPress: onGo, children: go }) : null
2425
+ onGo ? /* @__PURE__ */ jsx44(Button, { variant: "primary", onPress: onGo, children: go }) : null
2286
2426
  ] }),
2287
- activeFilters.length || resultLabel || actions ? /* @__PURE__ */ jsxs36("div", { className: "pire-filterbar-foot", children: [
2288
- activeFilters.map((filter) => /* @__PURE__ */ jsx43(Tag, { onRemove: onRemoveFilter ? () => onRemoveFilter(filter.id) : void 0, children: filter.label }, filter.id)),
2289
- activeFilters.length && onClear ? /* @__PURE__ */ jsx43(Button, { variant: "tertiary", size: "sm", onPress: onClear, children: clearAll }) : null,
2290
- resultLabel ? /* @__PURE__ */ jsx43("span", { className: "pire-filterbar-result", "aria-live": "polite", children: resultLabel }) : null,
2291
- actions ? /* @__PURE__ */ jsx43("div", { className: "pire-filterbar-actions", children: actions }) : null
2427
+ activeFilters.length || resultLabel || actions ? /* @__PURE__ */ jsxs37("div", { className: "pire-filterbar-foot", children: [
2428
+ activeFilters.map((filter) => /* @__PURE__ */ jsx44(Tag, { onRemove: onRemoveFilter ? () => onRemoveFilter(filter.id) : void 0, children: filter.label }, filter.id)),
2429
+ activeFilters.length && onClear ? /* @__PURE__ */ jsx44(Button, { variant: "tertiary", size: "sm", onPress: onClear, children: clearAll }) : null,
2430
+ resultLabel ? /* @__PURE__ */ jsx44("span", { className: "pire-filterbar-result", "aria-live": "polite", children: resultLabel }) : null,
2431
+ actions ? /* @__PURE__ */ jsx44("div", { className: "pire-filterbar-actions", children: actions }) : null
2292
2432
  ] }) : null
2293
2433
  ] });
2294
2434
  }
2295
2435
 
2296
2436
  // src/components/data/DescriptionList.tsx
2297
- import { jsx as jsx44, jsxs as jsxs37 } from "react/jsx-runtime";
2437
+ import { jsx as jsx45, jsxs as jsxs38 } from "react/jsx-runtime";
2298
2438
  function DescriptionList({ items, layout = "rows", columns = 3, className, style, ...rest }) {
2299
- return /* @__PURE__ */ jsx44(
2439
+ return /* @__PURE__ */ jsx45(
2300
2440
  "dl",
2301
2441
  {
2302
2442
  className: cx("pire-dl", className),
2303
2443
  "data-layout": layout,
2304
2444
  style: { ...layout === "grid" ? { "--pire-dl-cols": columns } : null, ...style },
2305
2445
  ...rest,
2306
- children: items.map((item, i) => /* @__PURE__ */ jsxs37("div", { className: "pire-dl-row", "data-emphasis": item.emphasis ? "true" : void 0, children: [
2307
- /* @__PURE__ */ jsxs37("dt", { className: "pire-dl-term", children: [
2446
+ children: items.map((item, i) => /* @__PURE__ */ jsxs38("div", { className: "pire-dl-row", "data-emphasis": item.emphasis ? "true" : void 0, children: [
2447
+ /* @__PURE__ */ jsxs38("dt", { className: "pire-dl-term", children: [
2308
2448
  item.label,
2309
2449
  item.hint
2310
2450
  ] }),
2311
- /* @__PURE__ */ jsx44("dd", { className: "pire-dl-value", "data-numeric": item.numeric ? "true" : void 0, children: item.value })
2451
+ /* @__PURE__ */ jsx45("dd", { className: "pire-dl-value", "data-numeric": item.numeric ? "true" : void 0, children: item.value })
2312
2452
  ] }, i))
2313
2453
  }
2314
2454
  );
2315
2455
  }
2316
2456
 
2317
2457
  // src/components/data/Timeline.tsx
2318
- import { jsx as jsx45, jsxs as jsxs38 } from "react/jsx-runtime";
2458
+ import { jsx as jsx46, jsxs as jsxs39 } from "react/jsx-runtime";
2319
2459
  function Timeline({ entries, reverse = false, className, ...rest }) {
2320
2460
  const list = reverse ? [...entries].reverse() : entries;
2321
- return /* @__PURE__ */ jsx45("ol", { className: cx("pire-timeline", className), ...rest, children: list.map((entry, i) => /* @__PURE__ */ jsxs38("li", { className: "pire-timeline-item", children: [
2322
- /* @__PURE__ */ jsx45("span", { className: "pire-timeline-time", children: entry.time }),
2323
- /* @__PURE__ */ jsx45("span", { className: "pire-timeline-text", children: entry.event }),
2324
- entry.actor ? /* @__PURE__ */ jsx45("span", { className: "pire-timeline-actor", children: entry.actor }) : null
2461
+ return /* @__PURE__ */ jsx46("ol", { className: cx("pire-timeline", className), ...rest, children: list.map((entry, i) => /* @__PURE__ */ jsxs39("li", { className: "pire-timeline-item", children: [
2462
+ /* @__PURE__ */ jsx46("span", { className: "pire-timeline-time", children: entry.time }),
2463
+ /* @__PURE__ */ jsx46("span", { className: "pire-timeline-text", children: entry.event }),
2464
+ entry.actor ? /* @__PURE__ */ jsx46("span", { className: "pire-timeline-actor", children: entry.actor }) : null
2325
2465
  ] }, entry.id ?? i)) });
2326
2466
  }
2327
2467
 
2468
+ // src/components/data/chartGeometry.ts
2469
+ var VIZ_SLOT_COUNT = 6;
2470
+ var NICE_STEPS = [1, 2, 2.5, 5, 10];
2471
+ function niceStep(rough) {
2472
+ if (!(rough > 0)) return 1;
2473
+ const magnitude = 10 ** Math.floor(Math.log10(rough));
2474
+ const normalized = rough / magnitude;
2475
+ return (NICE_STEPS.find((candidate) => candidate >= normalized) ?? 10) * magnitude;
2476
+ }
2477
+ function linearScale(values, tickCount = 4, startAtZero = true) {
2478
+ const present = values.filter((value) => value != null && Number.isFinite(value));
2479
+ if (present.length === 0) return { min: 0, max: 1, ticks: [0, 1] };
2480
+ let low = Math.min(...present);
2481
+ let high = Math.max(...present);
2482
+ if (startAtZero) {
2483
+ low = Math.min(0, low);
2484
+ high = Math.max(0, high);
2485
+ }
2486
+ if (low === high) {
2487
+ high = low === 0 ? 1 : low + Math.abs(low);
2488
+ }
2489
+ const step = niceStep((high - low) / Math.max(1, tickCount));
2490
+ const EDGE_TOLERANCE = 1e-9;
2491
+ const decimals = Math.max(0, 1 - Math.floor(Math.log10(step)));
2492
+ const toStepPrecision = (value) => Number(value.toFixed(decimals));
2493
+ const min = toStepPrecision(Math.floor(low / step + EDGE_TOLERANCE) * step);
2494
+ const max = toStepPrecision(Math.ceil(high / step - EDGE_TOLERANCE) * step);
2495
+ const stepCount = Math.round((max - min) / step);
2496
+ const ticks = Array.from(
2497
+ { length: stepCount + 1 },
2498
+ (_, index) => toStepPrecision(min + index * step)
2499
+ );
2500
+ return { min, max, ticks };
2501
+ }
2502
+ function scalePosition(value, scale) {
2503
+ const span = scale.max - scale.min;
2504
+ return span === 0 ? 0 : (value - scale.min) / span;
2505
+ }
2506
+ function seriesColor(series, index) {
2507
+ const slot = series.colorIndex ?? index + 1;
2508
+ return slot >= 1 && slot <= VIZ_SLOT_COUNT ? `var(--viz-${slot})` : "var(--viz-other)";
2509
+ }
2510
+ var IS_DEV2 = process.env.NODE_ENV !== "production";
2511
+ var warnedCharts = /* @__PURE__ */ new Set();
2512
+ function warnOnSlotOverflow(series, chartLabel) {
2513
+ if (!IS_DEV2 || warnedCharts.has(chartLabel)) return;
2514
+ if (series.length <= VIZ_SLOT_COUNT) return;
2515
+ warnedCharts.add(chartLabel);
2516
+ console.warn(
2517
+ `[pire] "${chartLabel}" has ${series.length} series but the palette defines ${VIZ_SLOT_COUNT} distinguishable colours. The extras render in one shared neutral. Group the tail into an "Other" series, or split the chart into small multiples.`
2518
+ );
2519
+ }
2520
+ function warnOnDonutShape(series, categoryCount, chartLabel) {
2521
+ if (!IS_DEV2 || warnedCharts.has(`donut:${chartLabel}`)) return;
2522
+ const complaints = [];
2523
+ if (series.length > 1) {
2524
+ complaints.push(`it has ${series.length} series but a donut draws one \u2014 the rest are ignored`);
2525
+ }
2526
+ if (categoryCount > VIZ_SLOT_COUNT) {
2527
+ complaints.push(`it has ${categoryCount} segments and the palette defines ${VIZ_SLOT_COUNT}; past about four, slices stop being readable at all \u2014 group the tail into "Other"`);
2528
+ }
2529
+ if (series[0]?.values.some((value) => value != null && value < 0)) {
2530
+ complaints.push("it contains negative values, which have no part-to-whole meaning \u2014 a signed measure belongs in a bar chart");
2531
+ }
2532
+ if (complaints.length === 0) return;
2533
+ warnedCharts.add(`donut:${chartLabel}`);
2534
+ console.warn(`[pire] DonutChart "${chartLabel}": ${complaints.join("; ")}.`);
2535
+ }
2536
+ function stackTotal(series, categoryIndex) {
2537
+ return series.reduce((total, one) => total + (one.values[categoryIndex] ?? 0), 0);
2538
+ }
2539
+ function flatValues(series) {
2540
+ return series.flatMap((one) => one.values);
2541
+ }
2542
+ function alignToCategories(series, categoryCount) {
2543
+ return series.map((one) => one.values.length <= categoryCount ? one : { ...one, values: one.values.slice(0, categoryCount) });
2544
+ }
2545
+
2546
+ // src/components/data/ChartFrame.tsx
2547
+ import { jsx as jsx47, jsxs as jsxs40 } from "react/jsx-runtime";
2548
+ function seriesLegend(series) {
2549
+ return series.map((one, index) => ({
2550
+ key: one.id,
2551
+ label: one.label,
2552
+ color: seriesColor(one, index)
2553
+ }));
2554
+ }
2555
+ var defaultFormatValue = (value) => value.toLocaleString();
2556
+ function ChartFrame({
2557
+ label,
2558
+ title,
2559
+ description,
2560
+ categories,
2561
+ series,
2562
+ formatValue,
2563
+ legend,
2564
+ showDataTable,
2565
+ className,
2566
+ style,
2567
+ children
2568
+ }) {
2569
+ const msg = usePireMessages();
2570
+ return /* @__PURE__ */ jsxs40("figure", { className: cx("pire-chart", className), style, children: [
2571
+ title || description ? /* @__PURE__ */ jsxs40("figcaption", { className: "pire-chart-head", children: [
2572
+ title ? /* @__PURE__ */ jsx47("span", { className: "pire-chart-title", children: title }) : null,
2573
+ description ? /* @__PURE__ */ jsx47("span", { className: "pire-chart-desc", children: description }) : null
2574
+ ] }) : null,
2575
+ legend && legend.length > 1 ? /* @__PURE__ */ jsx47("ul", { className: "pire-chart-legend", children: legend.map((item) => /* @__PURE__ */ jsxs40("li", { className: "pire-chart-legend-item", children: [
2576
+ /* @__PURE__ */ jsx47("span", { className: "pire-chart-swatch", style: { background: item.color } }),
2577
+ item.label
2578
+ ] }, item.key)) }) : null,
2579
+ /* @__PURE__ */ jsx47("div", { className: "pire-chart-plot", "aria-hidden": "true", children }),
2580
+ /* @__PURE__ */ jsx47("div", { className: showDataTable ? "pire-chart-table" : "pire-sr-only", children: /* @__PURE__ */ jsxs40("table", { children: [
2581
+ /* @__PURE__ */ jsx47("caption", { children: label }),
2582
+ /* @__PURE__ */ jsx47("thead", { children: /* @__PURE__ */ jsxs40("tr", { children: [
2583
+ /* @__PURE__ */ jsx47("th", { scope: "col", children: msg.chartCategoryHeader }),
2584
+ series.map((one) => /* @__PURE__ */ jsx47("th", { scope: "col", children: one.label }, one.id))
2585
+ ] }) }),
2586
+ /* @__PURE__ */ jsx47("tbody", { children: categories.map((category, categoryIndex) => (
2587
+ // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
2588
+ /* @__PURE__ */ jsxs40("tr", { children: [
2589
+ /* @__PURE__ */ jsx47("th", { scope: "row", children: category }),
2590
+ series.map((one) => {
2591
+ const value = one.values[categoryIndex];
2592
+ return /* @__PURE__ */ jsx47("td", { children: value == null ? msg.chartNoValue : formatValue(value) }, one.id);
2593
+ })
2594
+ ] }, categoryIndex)
2595
+ )) })
2596
+ ] }) })
2597
+ ] });
2598
+ }
2599
+
2600
+ // src/components/data/BarChart.tsx
2601
+ import { jsx as jsx48, jsxs as jsxs41 } from "react/jsx-runtime";
2602
+ function BarChart({
2603
+ categories,
2604
+ series: rawSeries,
2605
+ title,
2606
+ description,
2607
+ formatValue = defaultFormatValue,
2608
+ height = 260,
2609
+ emptyState,
2610
+ showDataTable,
2611
+ orientation = "horizontal",
2612
+ stacked = false,
2613
+ showValues,
2614
+ className,
2615
+ style,
2616
+ ...rest
2617
+ }) {
2618
+ const label = rest["aria-label"];
2619
+ const msg = usePireMessages();
2620
+ warnOnSlotOverflow(rawSeries, label);
2621
+ const series = alignToCategories(rawSeries, categories.length);
2622
+ const hasData = categories.length > 0 && series.length > 0;
2623
+ const withValues = showValues ?? series.length === 1;
2624
+ const scale = linearScale(
2625
+ stacked ? categories.map((_, index) => stackTotal(series, index)) : flatValues(series)
2626
+ );
2627
+ const sizeOf = (value) => `${scalePosition(value, scale) * 100}%`;
2628
+ const horizontalLabelFor = (categoryIndex) => {
2629
+ if (stacked) return formatValue(stackTotal(series, categoryIndex));
2630
+ const value = series[0].values[categoryIndex];
2631
+ return value == null ? msg.chartNoValue : formatValue(value);
2632
+ };
2633
+ return /* @__PURE__ */ jsx48(
2634
+ ChartFrame,
2635
+ {
2636
+ label,
2637
+ title,
2638
+ description,
2639
+ categories,
2640
+ series,
2641
+ formatValue,
2642
+ legend: seriesLegend(series),
2643
+ showDataTable,
2644
+ className,
2645
+ style,
2646
+ children: !hasData ? /* @__PURE__ */ jsx48("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ jsx48(
2647
+ "div",
2648
+ {
2649
+ className: "pire-chart-bars",
2650
+ "data-orientation": orientation,
2651
+ "data-stacked": String(stacked),
2652
+ style: { "--pire-chart-height": `${height}px` },
2653
+ children: categories.map((category, categoryIndex) => (
2654
+ // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
2655
+ /* @__PURE__ */ jsxs41("div", { className: "pire-chart-group", children: [
2656
+ /* @__PURE__ */ jsx48("span", { className: "pire-chart-cat", children: category }),
2657
+ /* @__PURE__ */ jsx48("div", { className: "pire-chart-track", children: series.map((one, seriesIndex) => {
2658
+ const value = one.values[categoryIndex];
2659
+ if (value == null) return null;
2660
+ return /* @__PURE__ */ jsxs41(
2661
+ "div",
2662
+ {
2663
+ className: "pire-chart-bar",
2664
+ style: {
2665
+ "--pire-bar-size": sizeOf(value),
2666
+ "--pire-bar-color": seriesColor(one, seriesIndex)
2667
+ },
2668
+ children: [
2669
+ withValues && orientation === "vertical" ? /* @__PURE__ */ jsx48("span", { className: "pire-chart-barval", children: formatValue(value) }) : null,
2670
+ /* @__PURE__ */ jsxs41("span", { className: "pire-chart-tip", role: "presentation", children: [
2671
+ series.length > 1 ? `${one.label}: ` : "",
2672
+ formatValue(value)
2673
+ ] })
2674
+ ]
2675
+ },
2676
+ one.id
2677
+ );
2678
+ }) }),
2679
+ withValues && orientation === "horizontal" ? /* @__PURE__ */ jsx48("span", { className: "pire-chart-val", children: horizontalLabelFor(categoryIndex) }) : null
2680
+ ] }, categoryIndex)
2681
+ ))
2682
+ }
2683
+ )
2684
+ }
2685
+ );
2686
+ }
2687
+
2688
+ // src/components/data/LineChart.tsx
2689
+ import * as React13 from "react";
2690
+ import { jsx as jsx49, jsxs as jsxs42 } from "react/jsx-runtime";
2691
+ var PLOT_INSET = { top: 10, right: 14, bottom: 24, left: 58 };
2692
+ var MARKER_LIMIT = 20;
2693
+ var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? React13.useEffect : React13.useLayoutEffect;
2694
+ function useMeasuredWidth() {
2695
+ const ref = React13.useRef(null);
2696
+ const [width, setWidth] = React13.useState(0);
2697
+ useIsomorphicLayoutEffect2(() => {
2698
+ const element = ref.current;
2699
+ if (!element) return;
2700
+ setWidth(element.getBoundingClientRect().width);
2701
+ const observer = new ResizeObserver(([entry]) => setWidth(entry.contentRect.width));
2702
+ observer.observe(element);
2703
+ return () => observer.disconnect();
2704
+ }, []);
2705
+ return [ref, width];
2706
+ }
2707
+ function LineChart({
2708
+ categories,
2709
+ series: rawSeries,
2710
+ title,
2711
+ description,
2712
+ formatValue = defaultFormatValue,
2713
+ height = 260,
2714
+ emptyState,
2715
+ showDataTable,
2716
+ showArea = false,
2717
+ showMarkers,
2718
+ zoomToData = false,
2719
+ className,
2720
+ style,
2721
+ ...rest
2722
+ }) {
2723
+ const label = rest["aria-label"];
2724
+ const msg = usePireMessages();
2725
+ warnOnSlotOverflow(rawSeries, label);
2726
+ const [plotRef, width] = useMeasuredWidth();
2727
+ const series = alignToCategories(rawSeries, categories.length);
2728
+ const hasData = categories.length > 0 && series.length > 0;
2729
+ const withMarkers = showMarkers ?? categories.length <= MARKER_LIMIT;
2730
+ const scale = linearScale(flatValues(series), 4, !zoomToData);
2731
+ const innerWidth = Math.max(0, width - PLOT_INSET.left - PLOT_INSET.right);
2732
+ const innerHeight = Math.max(0, height - PLOT_INSET.top - PLOT_INSET.bottom);
2733
+ const xAt = (index) => PLOT_INSET.left + (categories.length <= 1 ? innerWidth / 2 : index / (categories.length - 1) * innerWidth);
2734
+ const yAt = (value) => PLOT_INSET.top + innerHeight - scalePosition(value, scale) * innerHeight;
2735
+ const pathFor = (values) => {
2736
+ let path = "";
2737
+ let penIsDown = false;
2738
+ values.forEach((value, index) => {
2739
+ if (value == null) {
2740
+ penIsDown = false;
2741
+ return;
2742
+ }
2743
+ path += `${penIsDown ? "L" : "M"}${xAt(index)} ${yAt(value)} `;
2744
+ penIsDown = true;
2745
+ });
2746
+ return path.trim();
2747
+ };
2748
+ const areaFor = (values) => {
2749
+ const present = values.map((value, index) => ({ value, index })).filter((point) => point.value != null);
2750
+ if (present.length < 2) return "";
2751
+ const baseline = PLOT_INSET.top + innerHeight;
2752
+ const line = present.map((point) => `${xAt(point.index)} ${yAt(point.value)}`).join(" L");
2753
+ const last = present[present.length - 1];
2754
+ return `M${xAt(present[0].index)} ${baseline} L${line} L${xAt(last.index)} ${baseline} Z`;
2755
+ };
2756
+ const labelEvery = Math.max(1, Math.ceil(categories.length / Math.max(2, Math.floor(innerWidth / 64))));
2757
+ return /* @__PURE__ */ jsx49(
2758
+ ChartFrame,
2759
+ {
2760
+ label,
2761
+ title,
2762
+ description,
2763
+ categories,
2764
+ series,
2765
+ formatValue,
2766
+ legend: seriesLegend(series),
2767
+ showDataTable,
2768
+ className,
2769
+ style,
2770
+ children: !hasData ? /* @__PURE__ */ jsx49("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ jsxs42("div", { className: "pire-chart-lines", ref: plotRef, style: { height }, children: [
2771
+ width > 0 ? /* @__PURE__ */ jsxs42(
2772
+ "svg",
2773
+ {
2774
+ width,
2775
+ height,
2776
+ className: "pire-chart-svg",
2777
+ "aria-hidden": "true",
2778
+ focusable: "false",
2779
+ children: [
2780
+ /* @__PURE__ */ jsx49("g", { className: "pire-chart-grid", children: scale.ticks.map((tick) => /* @__PURE__ */ jsx49(
2781
+ "line",
2782
+ {
2783
+ x1: PLOT_INSET.left,
2784
+ x2: width - PLOT_INSET.right,
2785
+ y1: yAt(tick),
2786
+ y2: yAt(tick)
2787
+ },
2788
+ tick
2789
+ )) }),
2790
+ /* @__PURE__ */ jsxs42("g", { className: "pire-chart-tick", children: [
2791
+ scale.ticks.map((tick) => /* @__PURE__ */ jsx49(
2792
+ "text",
2793
+ {
2794
+ x: PLOT_INSET.left - 8,
2795
+ y: yAt(tick),
2796
+ textAnchor: "end",
2797
+ dominantBaseline: "middle",
2798
+ children: formatValue(tick)
2799
+ },
2800
+ tick
2801
+ )),
2802
+ categories.map((category, index) => index % labelEvery === 0 ? (
2803
+ // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
2804
+ /* @__PURE__ */ jsx49("text", { x: xAt(index), y: height - 6, textAnchor: "middle", children: category }, index)
2805
+ ) : null)
2806
+ ] }),
2807
+ showArea && series[0] ? /* @__PURE__ */ jsx49(
2808
+ "path",
2809
+ {
2810
+ d: areaFor(series[0].values),
2811
+ className: "pire-chart-area",
2812
+ style: { fill: seriesColor(series[0], 0) }
2813
+ }
2814
+ ) : null,
2815
+ /* @__PURE__ */ jsx49("g", { className: "pire-chart-line", fill: "none", children: series.map((one, index) => /* @__PURE__ */ jsx49("path", { d: pathFor(one.values), stroke: seriesColor(one, index) }, one.id)) }),
2816
+ withMarkers ? /* @__PURE__ */ jsx49("g", { className: "pire-chart-marker", children: series.map((one, seriesIndex) => one.values.map((value, index) => value == null ? null : (
2817
+ // biome-ignore lint/suspicious/noArrayIndexKey: a series is positional — the index is the point's identity, and category labels repeat.
2818
+ /* @__PURE__ */ jsx49(
2819
+ "circle",
2820
+ {
2821
+ cx: xAt(index),
2822
+ cy: yAt(value),
2823
+ r: 4,
2824
+ fill: seriesColor(one, seriesIndex)
2825
+ },
2826
+ `${one.id}-${index}`
2827
+ )
2828
+ ))) }) : null
2829
+ ]
2830
+ }
2831
+ ) : null,
2832
+ /* @__PURE__ */ jsx49(
2833
+ "div",
2834
+ {
2835
+ className: "pire-chart-hover",
2836
+ style: { inset: `${PLOT_INSET.top}px ${PLOT_INSET.right}px ${PLOT_INSET.bottom}px ${PLOT_INSET.left}px` },
2837
+ children: categories.map((category, categoryIndex) => (
2838
+ // biome-ignore lint/suspicious/noArrayIndexKey: categories are positional and repeat legitimately (two quarters both labelled "Q1").
2839
+ /* @__PURE__ */ jsx49("div", { className: "pire-chart-band", children: /* @__PURE__ */ jsxs42("span", { className: "pire-chart-tip", role: "presentation", children: [
2840
+ /* @__PURE__ */ jsx49("strong", { children: category }),
2841
+ series.map((one) => {
2842
+ const value = one.values[categoryIndex];
2843
+ return /* @__PURE__ */ jsxs42("span", { className: "pire-chart-tip-row", children: [
2844
+ one.label,
2845
+ ": ",
2846
+ value == null ? "No data" : formatValue(value)
2847
+ ] }, one.id);
2848
+ })
2849
+ ] }) }, categoryIndex)
2850
+ ))
2851
+ }
2852
+ )
2853
+ ] })
2854
+ }
2855
+ );
2856
+ }
2857
+
2858
+ // src/components/data/DonutChart.tsx
2859
+ import * as React14 from "react";
2860
+ import { jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
2861
+ var SEGMENT_GAP_DEGREES = 1.5;
2862
+ function DonutChart({
2863
+ categories,
2864
+ series,
2865
+ title,
2866
+ description,
2867
+ formatValue = defaultFormatValue,
2868
+ height = 220,
2869
+ emptyState,
2870
+ showDataTable,
2871
+ centerLabel,
2872
+ centerCaption,
2873
+ thickness = 28,
2874
+ className,
2875
+ style,
2876
+ ...rest
2877
+ }) {
2878
+ const label = rest["aria-label"];
2879
+ const msg = usePireMessages();
2880
+ const [hoveredIndex, setHoveredIndex] = React14.useState(null);
2881
+ warnOnDonutShape(series, categories.length, label);
2882
+ const values = (series[0]?.values ?? []).slice(0, categories.length);
2883
+ const segments = categories.map((category, index) => ({ category, index, value: values[index] ?? 0 })).filter((segment) => segment.value > 0);
2884
+ const total = segments.reduce((sum, segment) => sum + segment.value, 0);
2885
+ const hasData = segments.length > 0 && total > 0;
2886
+ const size = height;
2887
+ const radius = (size - thickness) / 2;
2888
+ const circumference = 2 * Math.PI * radius;
2889
+ const gapLength = SEGMENT_GAP_DEGREES / 360 * circumference;
2890
+ const legend = segments.map((segment) => ({
2891
+ key: segment.category,
2892
+ label: segment.category,
2893
+ color: colorForSegment(segment.index)
2894
+ }));
2895
+ const hovered = hoveredIndex == null ? null : segments.find((segment) => segment.index === hoveredIndex) ?? null;
2896
+ let arcStart = 0;
2897
+ return /* @__PURE__ */ jsx50(
2898
+ ChartFrame,
2899
+ {
2900
+ label,
2901
+ title,
2902
+ description,
2903
+ categories,
2904
+ series,
2905
+ formatValue,
2906
+ legend,
2907
+ showDataTable,
2908
+ className,
2909
+ style,
2910
+ children: !hasData ? /* @__PURE__ */ jsx50("div", { className: "pire-chart-empty", children: emptyState ?? msg.chartEmpty }) : /* @__PURE__ */ jsxs43("div", { className: "pire-chart-donut", style: { height: size }, children: [
2911
+ /* @__PURE__ */ jsx50(
2912
+ "svg",
2913
+ {
2914
+ width: size,
2915
+ height: size,
2916
+ "aria-hidden": "true",
2917
+ focusable: "false",
2918
+ onMouseLeave: () => setHoveredIndex(null),
2919
+ children: /* @__PURE__ */ jsx50("g", { transform: `rotate(-90 ${size / 2} ${size / 2})`, children: segments.map((segment) => {
2920
+ const arcLength = segment.value / total * circumference;
2921
+ const offset = arcStart;
2922
+ arcStart += arcLength;
2923
+ return (
2924
+ // 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.
2925
+ /* @__PURE__ */ jsx50(
2926
+ "circle",
2927
+ {
2928
+ className: "pire-chart-arc",
2929
+ cx: size / 2,
2930
+ cy: size / 2,
2931
+ r: radius,
2932
+ stroke: colorForSegment(segment.index),
2933
+ strokeWidth: thickness,
2934
+ strokeDasharray: `${Math.max(0, arcLength - gapLength)} ${circumference}`,
2935
+ strokeDashoffset: -offset,
2936
+ "data-hovered": hoveredIndex === segment.index ? "true" : void 0,
2937
+ onMouseEnter: () => setHoveredIndex(segment.index)
2938
+ },
2939
+ segment.category
2940
+ )
2941
+ );
2942
+ }) })
2943
+ }
2944
+ ),
2945
+ /* @__PURE__ */ jsxs43("div", { className: "pire-chart-donut-center", style: { width: size - thickness * 2 - 8 }, children: [
2946
+ /* @__PURE__ */ jsx50("span", { className: "pire-chart-donut-value", children: hovered ? formatValue(hovered.value) : centerLabel ?? formatValue(total) }),
2947
+ /* @__PURE__ */ jsx50("span", { className: "pire-chart-donut-caption", children: hovered ? hovered.category : centerCaption })
2948
+ ] })
2949
+ ] })
2950
+ }
2951
+ );
2952
+ }
2953
+ function colorForSegment(index) {
2954
+ return index < VIZ_SLOT_COUNT ? `var(--viz-${index + 1})` : "var(--viz-other)";
2955
+ }
2956
+
2328
2957
  // src/components/data/LinkList.tsx
2329
- import { Button as AriaButton11 } from "react-aria-components";
2330
- import { jsx as jsx46, jsxs as jsxs39 } from "react/jsx-runtime";
2958
+ import { Button as AriaButton12 } from "react-aria-components";
2959
+ import { jsx as jsx51, jsxs as jsxs44 } from "react/jsx-runtime";
2331
2960
  function LinkList({ items, onSelect, className, ...rest }) {
2332
- return /* @__PURE__ */ jsx46("div", { className: cx("pire-linklist", className), role: "list", ...rest, children: items.map((item) => /* @__PURE__ */ jsxs39(AriaButton11, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
2333
- item.icon ? /* @__PURE__ */ jsx46(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
2334
- item.key ? /* @__PURE__ */ jsx46("span", { className: "pire-linklist-key", children: item.key }) : null,
2335
- item.text ? /* @__PURE__ */ jsx46("span", { className: "pire-linklist-text", children: item.text }) : null,
2961
+ return /* @__PURE__ */ jsx51("div", { className: cx("pire-linklist", className), role: "list", ...rest, children: items.map((item) => /* @__PURE__ */ jsxs44(AriaButton12, { className: "pire-linklist-item", onPress: () => onSelect?.(item.id), children: [
2962
+ item.icon ? /* @__PURE__ */ jsx51(Icon, { name: item.icon, size: 16, style: { color: "var(--text-secondary)" } }) : null,
2963
+ item.key ? /* @__PURE__ */ jsx51("span", { className: "pire-linklist-key", children: item.key }) : null,
2964
+ item.text ? /* @__PURE__ */ jsx51("span", { className: "pire-linklist-text", children: item.text }) : null,
2336
2965
  item.trailing
2337
2966
  ] }, item.id)) });
2338
2967
  }
2339
2968
 
2340
2969
  // src/components/layout/PageBand.tsx
2341
- import { jsx as jsx47 } from "react/jsx-runtime";
2970
+ import { jsx as jsx52 } from "react/jsx-runtime";
2342
2971
  function PageBand({
2343
2972
  surface = "card",
2344
2973
  hasBorder = true,
@@ -2346,7 +2975,7 @@ function PageBand({
2346
2975
  className,
2347
2976
  ...rest
2348
2977
  }) {
2349
- return /* @__PURE__ */ jsx47(
2978
+ return /* @__PURE__ */ jsx52(
2350
2979
  "div",
2351
2980
  {
2352
2981
  className: cx("pire-pageband", className),
@@ -2359,56 +2988,56 @@ function PageBand({
2359
2988
  }
2360
2989
 
2361
2990
  // src/components/layout/PageHeader.tsx
2362
- import { jsx as jsx48, jsxs as jsxs40 } from "react/jsx-runtime";
2991
+ import { jsx as jsx53, jsxs as jsxs45 } from "react/jsx-runtime";
2363
2992
  function PageHeader({ title, subtitle, actions, className, ...rest }) {
2364
- return /* @__PURE__ */ jsxs40("header", { className: cx("pire-pageheader", className), ...rest, children: [
2365
- /* @__PURE__ */ jsxs40("div", { style: { minWidth: 0 }, children: [
2366
- /* @__PURE__ */ jsx48("h1", { className: "pire-pageheader-title", children: title }),
2367
- subtitle ? /* @__PURE__ */ jsx48("p", { className: "pire-pageheader-sub", children: subtitle }) : null
2993
+ return /* @__PURE__ */ jsxs45("header", { className: cx("pire-pageheader", className), ...rest, children: [
2994
+ /* @__PURE__ */ jsxs45("div", { style: { minWidth: 0 }, children: [
2995
+ /* @__PURE__ */ jsx53("h1", { className: "pire-pageheader-title", children: title }),
2996
+ subtitle ? /* @__PURE__ */ jsx53("p", { className: "pire-pageheader-sub", children: subtitle }) : null
2368
2997
  ] }),
2369
- actions ? /* @__PURE__ */ jsx48("div", { className: "pire-pageheader-actions", children: actions }) : null
2998
+ actions ? /* @__PURE__ */ jsx53("div", { className: "pire-pageheader-actions", children: actions }) : null
2370
2999
  ] });
2371
3000
  }
2372
3001
 
2373
3002
  // src/components/layout/SectionHeader.tsx
2374
- import { jsx as jsx49, jsxs as jsxs41 } from "react/jsx-runtime";
3003
+ import { jsx as jsx54, jsxs as jsxs46 } from "react/jsx-runtime";
2375
3004
  function SectionHeader({ title, meta, actions, className, ...rest }) {
2376
- return /* @__PURE__ */ jsxs41("div", { className: cx("pire-sectionhead", className), ...rest, children: [
2377
- /* @__PURE__ */ jsx49("span", { className: "pire-eyebrow", children: title }),
2378
- meta ? /* @__PURE__ */ jsx49("span", { style: { font: "var(--type-caption)", color: "var(--text-tertiary)" }, children: meta }) : null,
2379
- actions ? /* @__PURE__ */ jsx49("div", { className: "pire-sectionhead-actions", children: actions }) : null
3005
+ return /* @__PURE__ */ jsxs46("div", { className: cx("pire-sectionhead", className), ...rest, children: [
3006
+ /* @__PURE__ */ jsx54("span", { className: "pire-eyebrow", children: title }),
3007
+ meta ? /* @__PURE__ */ jsx54("span", { style: { font: "var(--type-caption)", color: "var(--text-tertiary)" }, children: meta }) : null,
3008
+ actions ? /* @__PURE__ */ jsx54("div", { className: "pire-sectionhead-actions", children: actions }) : null
2380
3009
  ] });
2381
3010
  }
2382
3011
 
2383
3012
  // src/components/layout/SelectionBar.tsx
2384
- import { jsx as jsx50, jsxs as jsxs42 } from "react/jsx-runtime";
3013
+ import { jsx as jsx55, jsxs as jsxs47 } from "react/jsx-runtime";
2385
3014
  function SelectionBar({ count, noun = "record", children, actions, className, ...rest }) {
2386
3015
  if (!count) return null;
2387
- return /* @__PURE__ */ jsxs42("div", { className: cx("pire-selectionbar", className), role: "status", "aria-live": "polite", ...rest, children: [
2388
- /* @__PURE__ */ jsxs42("span", { className: "pire-selectionbar-count", children: [
3016
+ return /* @__PURE__ */ jsxs47("div", { className: cx("pire-selectionbar", className), role: "status", "aria-live": "polite", ...rest, children: [
3017
+ /* @__PURE__ */ jsxs47("span", { className: "pire-selectionbar-count", children: [
2389
3018
  count.toLocaleString(),
2390
3019
  " ",
2391
3020
  noun,
2392
3021
  count === 1 ? "" : "s",
2393
3022
  " selected"
2394
3023
  ] }),
2395
- children ? /* @__PURE__ */ jsx50("span", { style: { color: "var(--text-secondary)", font: "var(--type-caption)" }, children }) : null,
2396
- actions ? /* @__PURE__ */ jsx50("div", { className: "pire-selectionbar-actions", children: actions }) : null
3024
+ children ? /* @__PURE__ */ jsx55("span", { style: { color: "var(--text-secondary)", font: "var(--type-caption)" }, children }) : null,
3025
+ actions ? /* @__PURE__ */ jsx55("div", { className: "pire-selectionbar-actions", children: actions }) : null
2397
3026
  ] });
2398
3027
  }
2399
3028
 
2400
3029
  // src/components/layout/FooterBar.tsx
2401
- import { jsx as jsx51, jsxs as jsxs43 } from "react/jsx-runtime";
3030
+ import { jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
2402
3031
  function FooterBar({ note, actions, children, className, ...rest }) {
2403
- return /* @__PURE__ */ jsxs43("footer", { className: cx("pire-footerbar", className), ...rest, children: [
2404
- note ? /* @__PURE__ */ jsx51("span", { className: "pire-footerbar-note", children: note }) : null,
3032
+ return /* @__PURE__ */ jsxs48("footer", { className: cx("pire-footerbar", className), ...rest, children: [
3033
+ note ? /* @__PURE__ */ jsx56("span", { className: "pire-footerbar-note", children: note }) : null,
2405
3034
  children,
2406
- actions ? /* @__PURE__ */ jsx51("div", { className: "pire-footerbar-actions", children: actions }) : null
3035
+ actions ? /* @__PURE__ */ jsx56("div", { className: "pire-footerbar-actions", children: actions }) : null
2407
3036
  ] });
2408
3037
  }
2409
3038
 
2410
3039
  // src/components/patterns/ConfirmDialog.tsx
2411
- import { Fragment as Fragment4, jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
3040
+ import { Fragment as Fragment4, jsx as jsx57, jsxs as jsxs49 } from "react/jsx-runtime";
2412
3041
  function ConfirmDialog({
2413
3042
  isOpen,
2414
3043
  title,
@@ -2422,7 +3051,7 @@ function ConfirmDialog({
2422
3051
  onConfirm,
2423
3052
  onCancel
2424
3053
  }) {
2425
- return /* @__PURE__ */ jsxs44(
3054
+ return /* @__PURE__ */ jsxs49(
2426
3055
  Dialog,
2427
3056
  {
2428
3057
  isOpen,
@@ -2432,12 +3061,12 @@ function ConfirmDialog({
2432
3061
  onClose: onCancel,
2433
3062
  isDismissable: !isBusy,
2434
3063
  showClose: false,
2435
- footer: /* @__PURE__ */ jsxs44(Fragment4, { children: [
2436
- /* @__PURE__ */ jsx52(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
2437
- /* @__PURE__ */ jsx52(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
3064
+ footer: /* @__PURE__ */ jsxs49(Fragment4, { children: [
3065
+ /* @__PURE__ */ jsx57(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
3066
+ /* @__PURE__ */ jsx57(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
2438
3067
  ] }),
2439
3068
  children: [
2440
- consequence ? /* @__PURE__ */ jsx52(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
3069
+ consequence ? /* @__PURE__ */ jsx57(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
2441
3070
  children
2442
3071
  ]
2443
3072
  }
@@ -2445,11 +3074,11 @@ function ConfirmDialog({
2445
3074
  }
2446
3075
 
2447
3076
  // src/components/patterns/SidePanel.tsx
2448
- import { ModalOverlay as ModalOverlay2, Modal as Modal2, Dialog as AriaDialog3, Heading as Heading4 } from "react-aria-components";
2449
- import { jsx as jsx53, jsxs as jsxs45 } from "react/jsx-runtime";
3077
+ import { ModalOverlay as ModalOverlay2, Modal as Modal2, Dialog as AriaDialog4, Heading as Heading5 } from "react-aria-components";
3078
+ import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
2450
3079
  function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onClose, className }) {
2451
3080
  const msg = usePireMessages();
2452
- return /* @__PURE__ */ jsx53(
3081
+ return /* @__PURE__ */ jsx58(
2453
3082
  ModalOverlay2,
2454
3083
  {
2455
3084
  className: "pire-sidepanel-overlay",
@@ -2458,36 +3087,36 @@ function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onC
2458
3087
  onOpenChange: (o) => {
2459
3088
  if (!o) onClose?.();
2460
3089
  },
2461
- children: /* @__PURE__ */ jsx53(Modal2, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ jsxs45(AriaDialog3, { className: "pire-dialog", style: { height: "100%" }, children: [
2462
- /* @__PURE__ */ jsxs45("header", { className: "pire-dialog-head", children: [
2463
- /* @__PURE__ */ jsxs45("div", { style: { flex: 1, minWidth: 0 }, children: [
2464
- /* @__PURE__ */ jsx53(Heading4, { slot: "title", className: "pire-dialog-title", children: title }),
2465
- subtitle ? /* @__PURE__ */ jsx53("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
3090
+ children: /* @__PURE__ */ jsx58(Modal2, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ jsxs50(AriaDialog4, { className: "pire-dialog", style: { height: "100%" }, children: [
3091
+ /* @__PURE__ */ jsxs50("header", { className: "pire-dialog-head", children: [
3092
+ /* @__PURE__ */ jsxs50("div", { style: { flex: 1, minWidth: 0 }, children: [
3093
+ /* @__PURE__ */ jsx58(Heading5, { slot: "title", className: "pire-dialog-title", children: title }),
3094
+ subtitle ? /* @__PURE__ */ jsx58("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
2466
3095
  ] }),
2467
- /* @__PURE__ */ jsx53(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
3096
+ /* @__PURE__ */ jsx58(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
2468
3097
  ] }),
2469
- /* @__PURE__ */ jsx53("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
2470
- footer ? /* @__PURE__ */ jsx53("footer", { className: "pire-dialog-foot", children: footer }) : null
3098
+ /* @__PURE__ */ jsx58("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
3099
+ footer ? /* @__PURE__ */ jsx58("footer", { className: "pire-dialog-foot", children: footer }) : null
2471
3100
  ] }) })
2472
3101
  }
2473
3102
  );
2474
3103
  }
2475
3104
 
2476
3105
  // src/components/patterns/EmptyState.tsx
2477
- import { jsx as jsx54, jsxs as jsxs46 } from "react/jsx-runtime";
3106
+ import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
2478
3107
  function EmptyState({ icon = "file-text", title, action, compact, children, className, ...rest }) {
2479
- return /* @__PURE__ */ jsxs46("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
2480
- /* @__PURE__ */ jsx54(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
2481
- title ? /* @__PURE__ */ jsx54("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
2482
- children ? /* @__PURE__ */ jsx54("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
3108
+ return /* @__PURE__ */ jsxs51("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
3109
+ /* @__PURE__ */ jsx59(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
3110
+ title ? /* @__PURE__ */ jsx59("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
3111
+ children ? /* @__PURE__ */ jsx59("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
2483
3112
  action
2484
3113
  ] });
2485
3114
  }
2486
3115
 
2487
3116
  // src/components/patterns/FileDropZone.tsx
2488
- import * as React13 from "react";
3117
+ import * as React15 from "react";
2489
3118
  import { DropZone, FileTrigger as FileTrigger2, isFileDropItem } from "react-aria-components";
2490
- import { jsx as jsx55, jsxs as jsxs47 } from "react/jsx-runtime";
3119
+ import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
2491
3120
  var isImage2 = (file) => file.type.startsWith("image/");
2492
3121
  function FileDropZone({
2493
3122
  label,
@@ -2513,10 +3142,10 @@ function FileDropZone({
2513
3142
  style
2514
3143
  }) {
2515
3144
  const msg = usePireMessages();
2516
- const [uncontrolled, setUncontrolled] = React13.useState(defaultValue ?? []);
3145
+ const [uncontrolled, setUncontrolled] = React15.useState(defaultValue ?? []);
2517
3146
  const files = value ?? uncontrolled;
2518
- const created = React13.useRef([]);
2519
- React13.useEffect(() => () => {
3147
+ const created = React15.useRef([]);
3148
+ React15.useEffect(() => () => {
2520
3149
  for (const url of created.current) URL.revokeObjectURL(url);
2521
3150
  }, []);
2522
3151
  const commit = (next) => {
@@ -2536,12 +3165,12 @@ function FileDropZone({
2536
3165
  commit(allowsMultiple ? [...files, ...wrapped] : wrapped.slice(0, 1));
2537
3166
  };
2538
3167
  const remove = (target) => commit(files.filter((f) => f.file !== target));
2539
- return /* @__PURE__ */ jsxs47("div", { className: cx("pire-field", className), style, "data-full-width": String(fullWidth), children: [
2540
- label ? /* @__PURE__ */ jsxs47("span", { className: "pire-field-label", children: [
3168
+ return /* @__PURE__ */ jsxs52("div", { className: cx("pire-field", className), style, "data-full-width": String(fullWidth), children: [
3169
+ label ? /* @__PURE__ */ jsxs52("span", { className: "pire-field-label", children: [
2541
3170
  label,
2542
- isRequired ? /* @__PURE__ */ jsx55("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
3171
+ isRequired ? /* @__PURE__ */ jsx60("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
2543
3172
  ] }) : null,
2544
- /* @__PURE__ */ jsxs47(
3173
+ /* @__PURE__ */ jsxs52(
2545
3174
  DropZone,
2546
3175
  {
2547
3176
  className: "pire-dropzone",
@@ -2554,25 +3183,25 @@ function FileDropZone({
2554
3183
  accept(dropped);
2555
3184
  },
2556
3185
  children: [
2557
- /* @__PURE__ */ jsx55(Icon, { name: "download", size: 24, className: "pire-dropzone-icon" }),
2558
- /* @__PURE__ */ jsx55("span", { className: "pire-dropzone-prompt", children: promptLabel ?? msg.fileDropZonePrompt }),
2559
- /* @__PURE__ */ jsx55(
3186
+ /* @__PURE__ */ jsx60(Icon, { name: "download", size: 24, className: "pire-dropzone-icon" }),
3187
+ /* @__PURE__ */ jsx60("span", { className: "pire-dropzone-prompt", children: promptLabel ?? msg.fileDropZonePrompt }),
3188
+ /* @__PURE__ */ jsx60(
2560
3189
  FileTrigger2,
2561
3190
  {
2562
3191
  acceptedFileTypes,
2563
3192
  allowsMultiple,
2564
3193
  onSelect: (list) => accept(list ? [...list] : []),
2565
- children: /* @__PURE__ */ jsx55(Button, { variant: "secondary", isDisabled: isDisabled || isReadOnly, children: msg.fileUploadChoose })
3194
+ children: /* @__PURE__ */ jsx60(Button, { variant: "secondary", isDisabled: isDisabled || isReadOnly, children: msg.fileUploadChoose })
2566
3195
  }
2567
3196
  )
2568
3197
  ]
2569
3198
  }
2570
3199
  ),
2571
- files.length ? /* @__PURE__ */ jsx55("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ jsxs47("li", { className: "pire-fileupload-item", children: [
2572
- previewUrl ? /* @__PURE__ */ jsx55("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ jsx55(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
2573
- /* @__PURE__ */ jsx55("span", { className: "pire-fileupload-name", children: file.name }),
2574
- /* @__PURE__ */ jsx55("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
2575
- isDisabled || isReadOnly ? null : /* @__PURE__ */ jsx55(
3200
+ files.length ? /* @__PURE__ */ jsx60("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ jsxs52("li", { className: "pire-fileupload-item", children: [
3201
+ previewUrl ? /* @__PURE__ */ jsx60("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ jsx60(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
3202
+ /* @__PURE__ */ jsx60("span", { className: "pire-fileupload-name", children: file.name }),
3203
+ /* @__PURE__ */ jsx60("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
3204
+ isDisabled || isReadOnly ? null : /* @__PURE__ */ jsx60(
2576
3205
  IconButton,
2577
3206
  {
2578
3207
  icon: "x",
@@ -2582,17 +3211,18 @@ function FileDropZone({
2582
3211
  }
2583
3212
  )
2584
3213
  ] }, `${file.name}-${file.size}-${file.lastModified}`)) }) : null,
2585
- uploadProgress != null ? /* @__PURE__ */ jsx55(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
2586
- description ? /* @__PURE__ */ jsx55("span", { className: "pire-field-hint", children: description }) : null,
2587
- isInvalid && errorMessage ? /* @__PURE__ */ jsx55("span", { className: "pire-field-error", children: errorMessage }) : null
3214
+ uploadProgress != null ? /* @__PURE__ */ jsx60(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
3215
+ description ? /* @__PURE__ */ jsx60("span", { className: "pire-field-hint", children: description }) : null,
3216
+ isInvalid && errorMessage ? /* @__PURE__ */ jsx60("span", { className: "pire-field-error", children: errorMessage }) : null
2588
3217
  ] });
2589
3218
  }
2590
3219
 
2591
3220
  // src/index.ts
2592
- import { DialogTrigger, MenuTrigger as MenuTrigger2, SubmenuTrigger, Popover as Popover6, RouterProvider, I18nProvider } from "react-aria-components";
3221
+ import { DialogTrigger, MenuTrigger as MenuTrigger2, SubmenuTrigger, Popover as Popover7, RouterProvider, I18nProvider } from "react-aria-components";
2593
3222
  export {
2594
3223
  Avatar,
2595
3224
  Badge,
3225
+ BarChart,
2596
3226
  Breadcrumb,
2597
3227
  Button,
2598
3228
  Card,
@@ -2601,9 +3231,11 @@ export {
2601
3231
  ConfirmDialog,
2602
3232
  DataTable,
2603
3233
  DatePicker,
3234
+ DateRangePicker,
2604
3235
  DescriptionList,
2605
3236
  Dialog,
2606
3237
  DialogTrigger,
3238
+ DonutChart,
2607
3239
  EmptyState,
2608
3240
  FileDropZone,
2609
3241
  FileUpload,
@@ -2617,6 +3249,7 @@ export {
2617
3249
  InlineMessage,
2618
3250
  Input,
2619
3251
  KpiTile,
3252
+ LineChart,
2620
3253
  Link,
2621
3254
  LinkList,
2622
3255
  Menu,
@@ -2631,7 +3264,7 @@ export {
2631
3264
  PageHeader,
2632
3265
  Pagination,
2633
3266
  PireIntlProvider,
2634
- Popover6 as Popover,
3267
+ Popover7 as Popover,
2635
3268
  ProgressBar,
2636
3269
  Radio,
2637
3270
  RadioGroup,
@@ -2657,12 +3290,14 @@ export {
2657
3290
  Toast,
2658
3291
  ToastProvider,
2659
3292
  Tooltip,
3293
+ VIZ_SLOT_COUNT,
2660
3294
  ValueHelpDialog,
2661
3295
  ValueHelpField,
2662
3296
  configureIcons,
2663
3297
  enMessages,
2664
3298
  esMessages,
2665
3299
  formatFileSize,
3300
+ rangeLengthInDays,
2666
3301
  usePireMessages,
2667
3302
  useToast
2668
3303
  };