@altertable/data-app 0.64.0 → 0.65.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 (47) hide show
  1. package/AGENTS.md +3 -0
  2. package/README.md +1 -1
  3. package/dist/chunks/{contract-xtxza1fy.js → contract-a061yj6r.js} +2 -2
  4. package/dist/chunks/contract-awa2d5b1.js +272 -0
  5. package/dist/chunks/contract-awa2d5b1.js.map +12 -0
  6. package/dist/chunks/{contract-zr3jd7mr.js → contract-g6hky7x6.js} +93 -72
  7. package/dist/chunks/contract-g6hky7x6.js.map +12 -0
  8. package/dist/chunks/{contract-mwe7gnmh.js → contract-sm7j7k95.js} +109 -73
  9. package/dist/chunks/contract-sm7j7k95.js.map +14 -0
  10. package/dist/client/index.js +2 -2
  11. package/dist/embed/index.js +19 -9
  12. package/dist/embed/index.js.map +3 -3
  13. package/dist/react/embed/index.js +5 -2
  14. package/dist/react/embed/index.js.map +3 -3
  15. package/dist/react/index.js +715 -443
  16. package/dist/react/index.js.map +13 -10
  17. package/dist/types/client/iframe.d.ts +2 -0
  18. package/dist/types/client/index.d.ts +1 -0
  19. package/dist/types/client/logger.d.ts +6 -0
  20. package/dist/types/core/bridge-endpoint.d.ts +21 -0
  21. package/dist/types/core/bridge.d.ts +137 -16
  22. package/dist/types/core/logger.d.ts +12 -0
  23. package/dist/types/embed/host.d.ts +6 -2
  24. package/dist/types/embed/index.d.ts +1 -0
  25. package/dist/types/embed/source.d.ts +1 -1
  26. package/dist/types/react/embed/bridge.d.ts +1 -1
  27. package/dist/types/react/index.d.ts +1 -0
  28. package/dist/types/react/ui/AppToolbar.d.ts +3 -1
  29. package/dist/types/react/ui/DataApp.d.ts +6 -1
  30. package/dist/types/react/ui/ExportControl.d.ts +4 -0
  31. package/dist/types/react/ui/Toast.d.ts +8 -0
  32. package/dist/types/react/ui/csv-export.d.ts +19 -0
  33. package/dist/types/react/ui/icons.d.ts +1 -0
  34. package/dist/worker.js +381 -79
  35. package/docs/app-authoring.md +28 -2
  36. package/docs/embed.md +1 -1
  37. package/docs/hosted-apps.md +2 -2
  38. package/docs/layout.md +31 -0
  39. package/docs/local-data-apps.md +1 -1
  40. package/docs/react.md +64 -2
  41. package/examples/starter-data-app/index.tsx +50 -32
  42. package/package.json +2 -1
  43. package/dist/chunks/contract-cxr9t12b.js +0 -18
  44. package/dist/chunks/contract-cxr9t12b.js.map +0 -10
  45. package/dist/chunks/contract-mwe7gnmh.js.map +0 -13
  46. package/dist/chunks/contract-zr3jd7mr.js.map +0 -12
  47. /package/dist/chunks/{contract-xtxza1fy.js.map → contract-a061yj6r.js.map} +0 -0
@@ -23,12 +23,12 @@ import {
23
23
  import {
24
24
  createDataClient2,
25
25
  getDataAppNavigation2
26
- } from "../chunks/contract-xtxza1fy.js";
26
+ } from "../chunks/contract-a061yj6r.js";
27
27
  import {
28
28
  DataAppError2,
29
29
  localFrameBridge,
30
30
  getDataAppTransport2
31
- } from "../chunks/contract-mwe7gnmh.js";
31
+ } from "../chunks/contract-sm7j7k95.js";
32
32
 
33
33
  // src/react/injectStyles.ts
34
34
  function injectStyles({
@@ -332,6 +332,7 @@ function injectDataAppStyles(options = {}) {
332
332
  .altertable-grid > * {
333
333
  min-width: 0;
334
334
  min-height: 0;
335
+ margin: 0;
335
336
  }
336
337
 
337
338
  .altertable-grid[data-align="stretch"] {
@@ -375,19 +376,19 @@ function injectDataAppStyles(options = {}) {
375
376
  min-height: 0;
376
377
  }
377
378
 
378
- @container altertable-grid (width >= 408px) {
379
+ @container altertable-grid (width >= 414px) {
379
380
  .altertable-grid:not([data-columns="1"])[data-min-item-width="compact"] > .altertable-grid-item[data-span="2"] {
380
381
  grid-column: span 2;
381
382
  }
382
383
  }
383
384
 
384
- @container altertable-grid (width >= 504px) {
385
+ @container altertable-grid (width >= 510px) {
385
386
  .altertable-grid:not([data-columns="1"])[data-min-item-width="regular"] > .altertable-grid-item[data-span="2"] {
386
387
  grid-column: span 2;
387
388
  }
388
389
  }
389
390
 
390
- @container altertable-grid (width >= 664px) {
391
+ @container altertable-grid (width >= 670px) {
391
392
  .altertable-grid:not([data-columns="1"])[data-min-item-width="wide"] > .altertable-grid-item[data-span="2"] {
392
393
  grid-column: span 2;
393
394
  }
@@ -2692,9 +2693,16 @@ body, #root {
2692
2693
  }
2693
2694
 
2694
2695
  .altertable-app-body {
2696
+ display: grid;
2697
+ grid-template-columns: minmax(0, 1fr);
2698
+ gap: var(--at-layout-gap, 24px);
2695
2699
  min-width: 0;
2696
2700
  }
2697
2701
 
2702
+ .altertable-app-main > *, .altertable-app-body > * {
2703
+ margin: 0;
2704
+ }
2705
+
2698
2706
  .altertable-app-footer {
2699
2707
  margin-top: auto;
2700
2708
  }
@@ -3380,6 +3388,11 @@ button {
3380
3388
  justify-content: center;
3381
3389
  }
3382
3390
 
3391
+ .altertable-data-view-toast-region[data-position="top"] {
3392
+ top: max(20px, env(safe-area-inset-top));
3393
+ bottom: auto;
3394
+ }
3395
+
3383
3396
  .altertable-data-view-toast {
3384
3397
  display: flex;
3385
3398
  overflow: auto;
@@ -3405,7 +3418,7 @@ button {
3405
3418
  flex: none;
3406
3419
  }
3407
3420
 
3408
- .altertable-data-view-toast[data-state="stale-error"] > svg {
3421
+ .altertable-data-view-toast[data-state="error"] > svg {
3409
3422
  color: var(--at-danger, #b42318);
3410
3423
  }
3411
3424
 
@@ -3769,6 +3782,10 @@ button {
3769
3782
  gap: var(--at-layout-gap, 24px);
3770
3783
  }
3771
3784
 
3785
+ .altertable-stack > * {
3786
+ margin: 0;
3787
+ }
3788
+
3772
3789
  /* src/react/ui/Inspect.css */
3773
3790
  .altertable-inspect-trigger {
3774
3791
  display: inline-grid;
@@ -4752,6 +4769,31 @@ button {
4752
4769
  height: 16px;
4753
4770
  }
4754
4771
 
4772
+ /* src/react/ui/ExportControl.css */
4773
+ .altertable-export-popover {
4774
+ z-index: 1000;
4775
+ max-height: min(320px, var(--available-height));
4776
+ overflow: auto;
4777
+ border: 1px solid var(--at-border, #e3e6e8);
4778
+ border-radius: var(--at-radius-surface, 12px);
4779
+ background: var(--at-surface, #fff);
4780
+ color: var(--at-text, #202124);
4781
+ max-width: min(320px, 100vw - 32px);
4782
+ padding: 4px;
4783
+ box-shadow: 0 10px 32px #0000001f;
4784
+ }
4785
+
4786
+ .altertable-export-popover [role="menuitem"] {
4787
+ outline: none;
4788
+ border-radius: 6px;
4789
+ padding: 10px 12px;
4790
+ font-size: 13px;
4791
+ }
4792
+
4793
+ .altertable-export-popover [role="menuitem"][data-focused] {
4794
+ background: var(--at-border, #e3e6e8);
4795
+ }
4796
+
4755
4797
  /* src/react/styles.css */
4756
4798
 
4757
4799
  `,
@@ -4806,6 +4848,7 @@ function injectDataAppShellStyles(options = {}) {
4806
4848
  .altertable-grid > * {
4807
4849
  min-width: 0;
4808
4850
  min-height: 0;
4851
+ margin: 0;
4809
4852
  }
4810
4853
 
4811
4854
  .altertable-grid[data-align="stretch"] {
@@ -4849,19 +4892,19 @@ function injectDataAppShellStyles(options = {}) {
4849
4892
  min-height: 0;
4850
4893
  }
4851
4894
 
4852
- @container altertable-grid (width >= 408px) {
4895
+ @container altertable-grid (width >= 414px) {
4853
4896
  .altertable-grid:not([data-columns="1"])[data-min-item-width="compact"] > .altertable-grid-item[data-span="2"] {
4854
4897
  grid-column: span 2;
4855
4898
  }
4856
4899
  }
4857
4900
 
4858
- @container altertable-grid (width >= 504px) {
4901
+ @container altertable-grid (width >= 510px) {
4859
4902
  .altertable-grid:not([data-columns="1"])[data-min-item-width="regular"] > .altertable-grid-item[data-span="2"] {
4860
4903
  grid-column: span 2;
4861
4904
  }
4862
4905
  }
4863
4906
 
4864
- @container altertable-grid (width >= 664px) {
4907
+ @container altertable-grid (width >= 670px) {
4865
4908
  .altertable-grid:not([data-columns="1"])[data-min-item-width="wide"] > .altertable-grid-item[data-span="2"] {
4866
4909
  grid-column: span 2;
4867
4910
  }
@@ -5236,7 +5279,12 @@ function mountDataApp({
5236
5279
  document.documentElement.lang = navigator.language;
5237
5280
  document.title = dataAppTitle2(config);
5238
5281
  getDataAppNavigation2();
5239
- createRoot(root).render(/* @__PURE__ */ jsx(DataAppProvider, {
5282
+ createRoot(root, {
5283
+ onUncaughtError(error) {
5284
+ console.error(error);
5285
+ getDataAppTransport2()?.fail();
5286
+ }
5287
+ }).render(/* @__PURE__ */ jsx(DataAppProvider, {
5240
5288
  children: /* @__PURE__ */ jsx(Component, {})
5241
5289
  }));
5242
5290
  }
@@ -5323,6 +5371,7 @@ import {
5323
5371
  Clock3,
5324
5372
  Copy,
5325
5373
  FileCode2,
5374
+ Download,
5326
5375
  Info,
5327
5376
  LoaderCircle,
5328
5377
  Minus,
@@ -5349,6 +5398,7 @@ var brandedIcons = {
5349
5398
  info: Info,
5350
5399
  openDetails: ChevronRight,
5351
5400
  present: Presentation,
5401
+ export: Download,
5352
5402
  error: CircleAlert,
5353
5403
  close: X,
5354
5404
  previous: ArrowLeft,
@@ -8462,15 +8512,81 @@ function AppScope({
8462
8512
  });
8463
8513
  }
8464
8514
 
8465
- // src/react/ui/LiveControl.tsx
8466
- import {
8467
- Button as AriaButton2,
8468
- ListBox as ListBox3,
8469
- ListBoxItem as ListBoxItem3,
8470
- Popover as Popover3,
8471
- Select as Select2,
8472
- SelectValue as SelectValue2
8473
- } from "react-aria-components";
8515
+ // src/react/ui/ExportControl.tsx
8516
+ import { useState as useState12 } from "react";
8517
+
8518
+ // src/react/ui/csv-export.ts
8519
+ import { strToU8, zipSync } from "fflate";
8520
+ function formatCsv({
8521
+ columns,
8522
+ rows
8523
+ }) {
8524
+ if (!columns.length)
8525
+ throw new Error("CSV export needs at least one column.");
8526
+ if (rows.some((row) => row.length !== columns.length))
8527
+ throw new Error("CSV rows must match the export columns.");
8528
+ function cell(value) {
8529
+ if (value === null || value === undefined)
8530
+ return "";
8531
+ let text = String(value);
8532
+ if (typeof value === "string" && /^[\s]*[=+\-@]|^[\t\r\n]/.test(text))
8533
+ text = `'${text}`;
8534
+ return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
8535
+ }
8536
+ return [columns, ...rows].map((row) => row.map(cell).join(",")).join(`\r
8537
+ `) + `\r
8538
+ `;
8539
+ }
8540
+ function filenameWithExtension(name, extension) {
8541
+ const filename = name.toLowerCase().endsWith(`.${extension}`) ? name : `${name.replace(/\.(?:csv|zip)$/i, "")}.${extension}`;
8542
+ if (!name.trim() || filename.length > 255 || /[\p{Cc}\\/]/u.test(filename))
8543
+ throw new Error("Export filenames must be nonempty names without paths.");
8544
+ return filename;
8545
+ }
8546
+ function createCsvDownload(data, selectedTable) {
8547
+ if (!data.tables.length)
8548
+ throw new Error("CSV export needs at least one dataset.");
8549
+ const names = data.tables.map((table) => filenameWithExtension(table.name, "csv"));
8550
+ if (new Set(names.map((name) => name.toLowerCase())).size !== names.length)
8551
+ throw new Error("CSV dataset names must be unique.");
8552
+ const table = selectedTable ?? (data.tables.length === 1 ? data.tables[0] : undefined);
8553
+ if (table)
8554
+ return {
8555
+ filename: filenameWithExtension(selectedTable ? table.name : data.filename, "csv"),
8556
+ blob: new Blob(["\uFEFF" + formatCsv(table)], {
8557
+ type: "text/csv;charset=utf-8"
8558
+ }),
8559
+ route: "export:csv"
8560
+ };
8561
+ const files = Object.fromEntries(data.tables.map((dataset, index) => [
8562
+ names[index],
8563
+ strToU8("\uFEFF" + formatCsv(dataset))
8564
+ ]));
8565
+ return {
8566
+ filename: filenameWithExtension(data.filename, "zip"),
8567
+ blob: new Blob([zipSync(files, { level: 1 })], { type: "application/zip" }),
8568
+ route: "export:zip"
8569
+ };
8570
+ }
8571
+ async function exportCsv(data, table) {
8572
+ const { filename, blob, route } = createCsvDownload(data, table);
8573
+ const transport = getDataAppTransport2();
8574
+ if (transport) {
8575
+ await transport.request({ route, payload: { filename, blob } });
8576
+ return;
8577
+ }
8578
+ const url = URL.createObjectURL(blob);
8579
+ const link = document.createElement("a");
8580
+ link.href = url;
8581
+ link.download = filename;
8582
+ document.body.append(link);
8583
+ try {
8584
+ link.click();
8585
+ } finally {
8586
+ link.remove();
8587
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
8588
+ }
8589
+ }
8474
8590
 
8475
8591
  // src/react/ui/IconButton.tsx
8476
8592
  import { jsx as jsx27, jsxs as jsxs18, Fragment as Fragment6 } from "react/jsx-runtime";
@@ -8522,8 +8638,129 @@ function IconButton({
8522
8638
  });
8523
8639
  }
8524
8640
 
8525
- // src/react/ui/LiveControl.tsx
8641
+ // src/react/ui/ExportControl.tsx
8642
+ import { Menu, MenuItem, MenuTrigger, Popover as Popover3 } from "react-aria-components";
8643
+
8644
+ // src/react/ui/Toast.tsx
8526
8645
  import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
8646
+ function Toast({
8647
+ state,
8648
+ children,
8649
+ onRetry,
8650
+ position = "bottom"
8651
+ }) {
8652
+ const failed = state === "error";
8653
+ const updating = state === "updating";
8654
+ return /* @__PURE__ */ jsx28("div", {
8655
+ className: "altertable-data-view-toast-region",
8656
+ "data-position": position,
8657
+ children: /* @__PURE__ */ jsxs19("div", {
8658
+ className: "altertable-data-view-toast",
8659
+ "data-state": state,
8660
+ role: failed ? "alert" : "status",
8661
+ children: [
8662
+ /* @__PURE__ */ jsx28(AppIcon, {
8663
+ name: failed ? "error" : updating ? "loading" : "live",
8664
+ size: 16,
8665
+ className: updating ? "altertable-data-view-toast-spinner" : undefined
8666
+ }),
8667
+ /* @__PURE__ */ jsx28("span", {
8668
+ children
8669
+ }),
8670
+ failed && onRetry && /* @__PURE__ */ jsx28(Button, {
8671
+ onClick: onRetry,
8672
+ children: "Try again"
8673
+ })
8674
+ ]
8675
+ })
8676
+ });
8677
+ }
8678
+
8679
+ // src/react/ui/ExportControl.tsx
8680
+ import { jsx as jsx29, jsxs as jsxs20, Fragment as Fragment7 } from "react/jsx-runtime";
8681
+ function ExportControl({ csv }) {
8682
+ const [open, setOpen] = useState12(false);
8683
+ const [status, setStatus] = useState12("idle");
8684
+ const [retryTableName, setRetryTableName] = useState12();
8685
+ async function download(table) {
8686
+ setOpen(false);
8687
+ setRetryTableName(table?.name);
8688
+ setStatus("pending");
8689
+ try {
8690
+ await exportCsv(csv, table);
8691
+ setStatus("idle");
8692
+ } catch {
8693
+ setStatus("error");
8694
+ }
8695
+ }
8696
+ return /* @__PURE__ */ jsxs20(Fragment7, {
8697
+ children: [
8698
+ status === "error" && /* @__PURE__ */ jsx29(Toast, {
8699
+ state: "error",
8700
+ position: "top",
8701
+ onRetry: () => void download(csv.tables.find((table) => table.name === retryTableName)),
8702
+ children: "Couldn’t export data."
8703
+ }),
8704
+ csv.tables.length === 1 ? /* @__PURE__ */ jsx29(IconButton, {
8705
+ icon: "export",
8706
+ variant: "elevated",
8707
+ label: "Export CSV",
8708
+ disabled: status === "pending",
8709
+ "aria-busy": status === "pending",
8710
+ onClick: () => void download()
8711
+ }) : /* @__PURE__ */ jsxs20(MenuTrigger, {
8712
+ isOpen: open,
8713
+ onOpenChange: setOpen,
8714
+ children: [
8715
+ /* @__PURE__ */ jsx29(PressButton, {
8716
+ variant: "elevated",
8717
+ size: "icon",
8718
+ "aria-label": "Export",
8719
+ isDisabled: status === "pending",
8720
+ "aria-busy": status === "pending",
8721
+ children: /* @__PURE__ */ jsx29(AppIcon, {
8722
+ name: "export"
8723
+ })
8724
+ }),
8725
+ /* @__PURE__ */ jsx29(Popover3, {
8726
+ placement: "bottom end",
8727
+ className: "altertable-export-popover",
8728
+ children: /* @__PURE__ */ jsxs20(Menu, {
8729
+ "aria-label": "Export data",
8730
+ children: [
8731
+ csv.tables.map((table, index) => /* @__PURE__ */ jsxs20(MenuItem, {
8732
+ id: index,
8733
+ onAction: () => void download(table),
8734
+ children: [
8735
+ "Export ",
8736
+ table.name,
8737
+ " (CSV)"
8738
+ ]
8739
+ }, index)),
8740
+ /* @__PURE__ */ jsx29(MenuItem, {
8741
+ id: "all",
8742
+ onAction: () => void download(),
8743
+ children: "Export all (ZIP)"
8744
+ })
8745
+ ]
8746
+ })
8747
+ })
8748
+ ]
8749
+ })
8750
+ ]
8751
+ });
8752
+ }
8753
+
8754
+ // src/react/ui/LiveControl.tsx
8755
+ import {
8756
+ Button as AriaButton2,
8757
+ ListBox as ListBox3,
8758
+ ListBoxItem as ListBoxItem3,
8759
+ Popover as Popover4,
8760
+ Select as Select2,
8761
+ SelectValue as SelectValue2
8762
+ } from "react-aria-components";
8763
+ import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
8527
8764
  var intervals = [
8528
8765
  { seconds: 30, label: "Every 30 seconds", description: "every 30 seconds" },
8529
8766
  { seconds: 60, label: "Every minute", description: "every minute" },
@@ -8539,11 +8776,11 @@ function LiveControl({
8539
8776
  }) {
8540
8777
  const frequency = intervals.find((interval) => interval.seconds === intervalSeconds)?.description;
8541
8778
  invariant(frequency, "LiveControl requires a supported update interval.");
8542
- return /* @__PURE__ */ jsxs19("div", {
8779
+ return /* @__PURE__ */ jsxs21("div", {
8543
8780
  className: classNames("altertable-live-control", className),
8544
8781
  "data-active": enabled,
8545
8782
  children: [
8546
- /* @__PURE__ */ jsx28(IconButton, {
8783
+ /* @__PURE__ */ jsx30(IconButton, {
8547
8784
  ...props,
8548
8785
  icon: "live",
8549
8786
  variant: "ghost",
@@ -8551,7 +8788,7 @@ function LiveControl({
8551
8788
  "aria-pressed": enabled,
8552
8789
  onClick: () => onChange(!enabled)
8553
8790
  }),
8554
- /* @__PURE__ */ jsxs19(Select2, {
8791
+ /* @__PURE__ */ jsxs21(Select2, {
8555
8792
  "aria-label": `Live update frequency: ${frequency}`,
8556
8793
  selectedKey: String(intervalSeconds),
8557
8794
  onSelectionChange: (key) => {
@@ -8561,29 +8798,29 @@ function LiveControl({
8561
8798
  },
8562
8799
  className: "altertable-live-frequency",
8563
8800
  children: [
8564
- /* @__PURE__ */ jsxs19(AriaButton2, {
8801
+ /* @__PURE__ */ jsxs21(AriaButton2, {
8565
8802
  "aria-label": `Live update frequency: ${frequency}`,
8566
8803
  children: [
8567
- /* @__PURE__ */ jsx28(SelectValue2, {
8804
+ /* @__PURE__ */ jsx30(SelectValue2, {
8568
8805
  className: "altertable-visually-hidden"
8569
8806
  }),
8570
- /* @__PURE__ */ jsx28(AppIcon, {
8807
+ /* @__PURE__ */ jsx30(AppIcon, {
8571
8808
  name: "disclosure",
8572
8809
  size: 14
8573
8810
  })
8574
8811
  ]
8575
8812
  }),
8576
- /* @__PURE__ */ jsx28(Popover3, {
8813
+ /* @__PURE__ */ jsx30(Popover4, {
8577
8814
  placement: "bottom end",
8578
8815
  className: "altertable-live-frequency-popover",
8579
- children: /* @__PURE__ */ jsx28(ListBox3, {
8816
+ children: /* @__PURE__ */ jsx30(ListBox3, {
8580
8817
  "aria-label": "Live update frequency",
8581
- children: intervals.map((interval) => /* @__PURE__ */ jsxs19(ListBoxItem3, {
8818
+ children: intervals.map((interval) => /* @__PURE__ */ jsxs21(ListBoxItem3, {
8582
8819
  id: String(interval.seconds),
8583
8820
  textValue: interval.label,
8584
8821
  children: [
8585
8822
  interval.label,
8586
- /* @__PURE__ */ jsx28(AppIcon, {
8823
+ /* @__PURE__ */ jsx30(AppIcon, {
8587
8824
  name: "check",
8588
8825
  size: 15
8589
8826
  })
@@ -8603,7 +8840,7 @@ import {
8603
8840
  useEffectEvent as useEffectEvent2,
8604
8841
  useId as useId7,
8605
8842
  useRef as useRef5,
8606
- useState as useState12
8843
+ useState as useState13
8607
8844
  } from "react";
8608
8845
  import { useMergeRefs as useMergeRefs5 } from "@floating-ui/react";
8609
8846
 
@@ -8613,7 +8850,7 @@ import {
8613
8850
  useId as useId6,
8614
8851
  useSyncExternalStore as useSyncExternalStore3
8615
8852
  } from "react";
8616
- import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
8853
+ import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
8617
8854
  var themes = [
8618
8855
  { value: "light", label: "Light", icon: "lightTheme" },
8619
8856
  { value: "dark", label: "Dark", icon: "darkTheme" }
@@ -8642,19 +8879,19 @@ function ThemeSelector({
8642
8879
  }) {
8643
8880
  const selected = useResolvedTheme(theme);
8644
8881
  const name = useId6();
8645
- return /* @__PURE__ */ jsxs20("fieldset", {
8882
+ return /* @__PURE__ */ jsxs22("fieldset", {
8646
8883
  ...props,
8647
8884
  className: classNames("altertable-theme-selector", className),
8648
8885
  children: [
8649
- /* @__PURE__ */ jsx29("legend", {
8886
+ /* @__PURE__ */ jsx31("legend", {
8650
8887
  className: "altertable-theme-legend",
8651
8888
  children: "Color theme"
8652
8889
  }),
8653
- themes.map(({ value, label, icon }) => /* @__PURE__ */ jsx29(Tooltip, {
8890
+ themes.map(({ value, label, icon }) => /* @__PURE__ */ jsx31(Tooltip, {
8654
8891
  content: `${label} theme`,
8655
- children: /* @__PURE__ */ jsxs20("label", {
8892
+ children: /* @__PURE__ */ jsxs22("label", {
8656
8893
  children: [
8657
- /* @__PURE__ */ jsx29("input", {
8894
+ /* @__PURE__ */ jsx31("input", {
8658
8895
  type: "radio",
8659
8896
  name,
8660
8897
  value,
@@ -8662,7 +8899,7 @@ function ThemeSelector({
8662
8899
  "aria-label": `${label} theme`,
8663
8900
  onChange: () => theme.setTheme(value)
8664
8901
  }),
8665
- /* @__PURE__ */ jsx29(AppIcon, {
8902
+ /* @__PURE__ */ jsx31(AppIcon, {
8666
8903
  name: icon,
8667
8904
  size: 16
8668
8905
  })
@@ -8680,7 +8917,7 @@ function ThemeToggle({
8680
8917
  const selected = useResolvedTheme(theme);
8681
8918
  const next = selected === "dark" ? "light" : "dark";
8682
8919
  const icon = next === "dark" ? "darkTheme" : "lightTheme";
8683
- return /* @__PURE__ */ jsx29(IconButton, {
8920
+ return /* @__PURE__ */ jsx31(IconButton, {
8684
8921
  icon,
8685
8922
  variant: "ghost",
8686
8923
  label: `Switch to ${next} theme`,
@@ -8717,7 +8954,7 @@ function storySteps(findings, context) {
8717
8954
  }
8718
8955
 
8719
8956
  // src/react/ui/PresentStory.tsx
8720
- import { jsx as jsx30, jsxs as jsxs21, Fragment as Fragment7 } from "react/jsx-runtime";
8957
+ import { jsx as jsx32, jsxs as jsxs23, Fragment as Fragment8 } from "react/jsx-runtime";
8721
8958
  var stepKeys = {
8722
8959
  ArrowRight(index) {
8723
8960
  return index + 1;
@@ -8760,9 +8997,11 @@ function PresentStory({
8760
8997
  const dialog = useRef5(null);
8761
8998
  const trigger = useRef5(null);
8762
8999
  const headline = useRef5(null);
9000
+ const ownedFullscreenElement = useRef5(null);
9001
+ const isOpening = useRef5(false);
8763
9002
  const headlineId = useId7();
8764
9003
  const contextId = useId7();
8765
- const [stepId, setStepId] = useState12(steps[0]?.id);
9004
+ const [stepId, setStepId] = useState13(steps[0]?.id);
8766
9005
  const triggerRef = useMergeRefs5([trigger, ref]);
8767
9006
  const dialogRef = useMergeRefs5([dialog, dialogProps?.ref]);
8768
9007
  const index = Math.max(0, steps.findIndex((step) => step.id === stepId));
@@ -8790,18 +9029,62 @@ function PresentStory({
8790
9029
  if (dialog.current?.open)
8791
9030
  headline.current?.focus({ preventScroll: true });
8792
9031
  }, [stepId]);
9032
+ useEffect11(() => {
9033
+ const presentationDialog = dialog.current;
9034
+ if (!presentationDialog)
9035
+ return;
9036
+ const ownerDocument = presentationDialog.ownerDocument;
9037
+ function handleFullscreenChange() {
9038
+ const fullscreenElement = ownedFullscreenElement.current;
9039
+ if (!fullscreenElement || ownerDocument.fullscreenElement === fullscreenElement)
9040
+ return;
9041
+ ownedFullscreenElement.current = null;
9042
+ dialog.current?.close();
9043
+ }
9044
+ ownerDocument.addEventListener("fullscreenchange", handleFullscreenChange);
9045
+ return () => {
9046
+ ownerDocument.removeEventListener("fullscreenchange", handleFullscreenChange);
9047
+ exitPresentationFullscreen();
9048
+ };
9049
+ }, []);
9050
+ function exitPresentationFullscreen() {
9051
+ const fullscreenElement = ownedFullscreenElement.current;
9052
+ ownedFullscreenElement.current = null;
9053
+ if (!fullscreenElement)
9054
+ return;
9055
+ const ownerDocument = fullscreenElement.ownerDocument;
9056
+ if (ownerDocument.fullscreenElement === fullscreenElement)
9057
+ ownerDocument.exitFullscreen().catch(() => {});
9058
+ }
8793
9059
  function writePresentation(id, mode = "replace") {
8794
9060
  writeSearch({ present: id ? "1" : null, step: id ?? null }, mode);
8795
9061
  }
8796
- function open() {
8797
- if (unavailable)
9062
+ async function openPresentation() {
9063
+ const presentationDialog = dialog.current;
9064
+ const firstStep = steps[0];
9065
+ if (unavailable || isOpening.current || !presentationDialog || !firstStep)
9066
+ return;
9067
+ const ownerDocument = presentationDialog.ownerDocument;
9068
+ const fullscreenElement = ownerDocument.documentElement;
9069
+ isOpening.current = true;
9070
+ try {
9071
+ if (!ownerDocument.fullscreenElement && ownerDocument.fullscreenEnabled) {
9072
+ await fullscreenElement.requestFullscreen();
9073
+ ownedFullscreenElement.current = fullscreenElement;
9074
+ }
9075
+ } catch {} finally {
9076
+ isOpening.current = false;
9077
+ }
9078
+ if (!presentationDialog.isConnected) {
9079
+ exitPresentationFullscreen();
8798
9080
  return;
8799
- setStepId(steps[0].id);
8800
- dialog.current?.showModal();
9081
+ }
9082
+ setStepId(firstStep.id);
9083
+ presentationDialog.showModal();
8801
9084
  headline.current?.focus({ preventScroll: true });
8802
- writePresentation(steps[0].id, "push");
9085
+ writePresentation(firstStep.id, "push");
8803
9086
  }
8804
- useShortcut(shortcuts.playStory, open, !unavailable);
9087
+ useShortcut(shortcuts.playStory, openPresentation, !unavailable);
8805
9088
  function goTo(nextIndex) {
8806
9089
  const next = steps[nextIndex];
8807
9090
  if (!next)
@@ -8818,12 +9101,12 @@ function PresentStory({
8818
9101
  event.preventDefault();
8819
9102
  goTo(move(index, steps.length - 1));
8820
9103
  }
8821
- return /* @__PURE__ */ jsxs21(Fragment7, {
9104
+ return /* @__PURE__ */ jsxs23(Fragment8, {
8822
9105
  children: [
8823
- /* @__PURE__ */ jsx30("span", {
9106
+ /* @__PURE__ */ jsx32("span", {
8824
9107
  ...launcherProps,
8825
9108
  className: classNames("altertable-present-launch", launcherProps?.className),
8826
- children: /* @__PURE__ */ jsx30(IconButton, {
9109
+ children: /* @__PURE__ */ jsx32(IconButton, {
8827
9110
  ...props,
8828
9111
  ref: triggerRef,
8829
9112
  icon: "present",
@@ -8836,12 +9119,12 @@ function PresentStory({
8836
9119
  onClick: (event) => {
8837
9120
  onClick?.(event);
8838
9121
  if (!event.defaultPrevented)
8839
- open();
9122
+ openPresentation();
8840
9123
  },
8841
9124
  children
8842
9125
  })
8843
9126
  }),
8844
- /* @__PURE__ */ jsx30("dialog", {
9127
+ /* @__PURE__ */ jsx32("dialog", {
8845
9128
  ...dialogProps,
8846
9129
  ref: dialogRef,
8847
9130
  className: classNames("altertable-present-dialog", dialogProps?.className),
@@ -8850,6 +9133,7 @@ function PresentStory({
8850
9133
  onClose: (event) => {
8851
9134
  if (event.target !== event.currentTarget)
8852
9135
  return;
9136
+ exitPresentationFullscreen();
8853
9137
  if (searchParams().get("present") === "1")
8854
9138
  writePresentation();
8855
9139
  trigger.current?.focus({ preventScroll: true });
@@ -8860,21 +9144,21 @@ function PresentStory({
8860
9144
  if (!event.defaultPrevented)
8861
9145
  handleKeyDown(event);
8862
9146
  },
8863
- children: step && /* @__PURE__ */ jsxs21("div", {
9147
+ children: step && /* @__PURE__ */ jsxs23("div", {
8864
9148
  className: "altertable-present-shell",
8865
9149
  children: [
8866
- /* @__PURE__ */ jsxs21("header", {
9150
+ /* @__PURE__ */ jsxs23("header", {
8867
9151
  className: "altertable-present-header",
8868
9152
  children: [
8869
- /* @__PURE__ */ jsxs21("div", {
9153
+ /* @__PURE__ */ jsxs23("div", {
8870
9154
  className: "altertable-present-title",
8871
9155
  children: [
8872
- /* @__PURE__ */ jsx30("strong", {
9156
+ /* @__PURE__ */ jsx32("strong", {
8873
9157
  children: title
8874
9158
  }),
8875
- scope && /* @__PURE__ */ jsxs21(Fragment7, {
9159
+ scope && /* @__PURE__ */ jsxs23(Fragment8, {
8876
9160
  children: [
8877
- /* @__PURE__ */ jsx30("span", {
9161
+ /* @__PURE__ */ jsx32("span", {
8878
9162
  className: "altertable-present-connector",
8879
9163
  "aria-hidden": "true",
8880
9164
  children: "/"
@@ -8884,10 +9168,10 @@ function PresentStory({
8884
9168
  })
8885
9169
  ]
8886
9170
  }),
8887
- /* @__PURE__ */ jsxs21("div", {
9171
+ /* @__PURE__ */ jsxs23("div", {
8888
9172
  className: "altertable-present-actions",
8889
9173
  children: [
8890
- /* @__PURE__ */ jsxs21("span", {
9174
+ /* @__PURE__ */ jsxs23("span", {
8891
9175
  className: "altertable-present-count",
8892
9176
  "aria-label": `Finding ${index + 1} of ${steps.length}`,
8893
9177
  children: [
@@ -8896,15 +9180,15 @@ function PresentStory({
8896
9180
  steps.length
8897
9181
  ]
8898
9182
  }),
8899
- theme && /* @__PURE__ */ jsx30("span", {
9183
+ theme && /* @__PURE__ */ jsx32("span", {
8900
9184
  className: "altertable-present-theme",
8901
- children: /* @__PURE__ */ jsx30(ThemeToggle, {
9185
+ children: /* @__PURE__ */ jsx32(ThemeToggle, {
8902
9186
  theme,
8903
9187
  portalRoot: dialog
8904
9188
  })
8905
9189
  }),
8906
9190
  headerActions,
8907
- /* @__PURE__ */ jsx30(IconButton, {
9191
+ /* @__PURE__ */ jsx32(IconButton, {
8908
9192
  icon: "close",
8909
9193
  variant: "ghost",
8910
9194
  label: "Exit presentation",
@@ -8917,25 +9201,25 @@ function PresentStory({
8917
9201
  })
8918
9202
  ]
8919
9203
  }),
8920
- /* @__PURE__ */ jsxs21(GradientScroll, {
9204
+ /* @__PURE__ */ jsxs23(GradientScroll, {
8921
9205
  className: "altertable-present-main",
8922
9206
  children: [
8923
- /* @__PURE__ */ jsxs21("div", {
9207
+ /* @__PURE__ */ jsxs23("div", {
8924
9208
  className: "altertable-present-copy",
8925
9209
  children: [
8926
- /* @__PURE__ */ jsx30("h2", {
9210
+ /* @__PURE__ */ jsx32("h2", {
8927
9211
  id: headlineId,
8928
9212
  ref: headline,
8929
9213
  tabIndex: -1,
8930
9214
  children: step.headline
8931
9215
  }),
8932
- step.context && /* @__PURE__ */ jsx30("p", {
9216
+ step.context && /* @__PURE__ */ jsx32("p", {
8933
9217
  id: contextId,
8934
9218
  children: step.context
8935
9219
  }),
8936
- /* @__PURE__ */ jsx30("div", {
9220
+ /* @__PURE__ */ jsx32("div", {
8937
9221
  className: "altertable-present-explore",
8938
- children: /* @__PURE__ */ jsxs21(AboutData, {
9222
+ children: /* @__PURE__ */ jsxs23(AboutData, {
8939
9223
  shortcut: false,
8940
9224
  id: step.id,
8941
9225
  empty: step.empty ?? empty,
@@ -8954,7 +9238,7 @@ function PresentStory({
8954
9238
  variant: "outline",
8955
9239
  portalRoot: dialog,
8956
9240
  children: [
8957
- /* @__PURE__ */ jsx30(AppIcon, {
9241
+ /* @__PURE__ */ jsx32(AppIcon, {
8958
9242
  name: "explore"
8959
9243
  }),
8960
9244
  " Explore sources"
@@ -8963,18 +9247,18 @@ function PresentStory({
8963
9247
  })
8964
9248
  ]
8965
9249
  }),
8966
- /* @__PURE__ */ jsx30("div", {
9250
+ /* @__PURE__ */ jsx32("div", {
8967
9251
  className: "altertable-present-visual",
8968
9252
  "data-kind": step.visualKind,
8969
9253
  children: step.visual
8970
9254
  })
8971
9255
  ]
8972
9256
  }, step.id),
8973
- /* @__PURE__ */ jsxs21("nav", {
9257
+ /* @__PURE__ */ jsxs23("nav", {
8974
9258
  className: "altertable-present-nav",
8975
9259
  "aria-label": "Story findings",
8976
9260
  children: [
8977
- /* @__PURE__ */ jsx30(IconButton, {
9261
+ /* @__PURE__ */ jsx32(IconButton, {
8978
9262
  icon: "previous",
8979
9263
  variant: "ghost",
8980
9264
  label: "Previous step",
@@ -8985,13 +9269,13 @@ function PresentStory({
8985
9269
  onClick: () => goTo(index - 1),
8986
9270
  disabled: index === 0
8987
9271
  }),
8988
- /* @__PURE__ */ jsx30("div", {
9272
+ /* @__PURE__ */ jsx32("div", {
8989
9273
  className: "altertable-present-dots",
8990
- children: steps.map((item, itemIndex) => /* @__PURE__ */ jsx30(Tooltip, {
9274
+ children: steps.map((item, itemIndex) => /* @__PURE__ */ jsx32(Tooltip, {
8991
9275
  content: item.headline,
8992
9276
  placement: "top",
8993
9277
  portalRoot: dialog,
8994
- children: /* @__PURE__ */ jsx30("button", {
9278
+ children: /* @__PURE__ */ jsx32("button", {
8995
9279
  type: "button",
8996
9280
  "aria-label": `Finding ${itemIndex + 1}: ${item.headline}`,
8997
9281
  "aria-current": itemIndex === index ? "step" : undefined,
@@ -8999,7 +9283,7 @@ function PresentStory({
8999
9283
  })
9000
9284
  }, item.id))
9001
9285
  }),
9002
- /* @__PURE__ */ jsx30(IconButton, {
9286
+ /* @__PURE__ */ jsx32(IconButton, {
9003
9287
  icon: "next",
9004
9288
  variant: "ghost",
9005
9289
  label: "Next step",
@@ -9023,9 +9307,9 @@ function PresentStory({
9023
9307
  // src/react/ui/RefreshControl.tsx
9024
9308
  import {
9025
9309
  useEffect as useEffect12,
9026
- useState as useState13
9310
+ useState as useState14
9027
9311
  } from "react";
9028
- import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
9312
+ import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
9029
9313
  function RefreshControl({
9030
9314
  refreshing,
9031
9315
  children,
@@ -9035,7 +9319,7 @@ function RefreshControl({
9035
9319
  className,
9036
9320
  ...props
9037
9321
  }) {
9038
- const [refreshDelay, setRefreshDelay] = useState13({
9322
+ const [refreshDelay, setRefreshDelay] = useState14({
9039
9323
  refreshing,
9040
9324
  elapsed: false
9041
9325
  });
@@ -9048,12 +9332,12 @@ function RefreshControl({
9048
9332
  return () => window.clearTimeout(timer);
9049
9333
  }, [refreshing]);
9050
9334
  const showProgress = refreshing && refreshDelay.refreshing && refreshDelay.elapsed;
9051
- return /* @__PURE__ */ jsxs22("div", {
9335
+ return /* @__PURE__ */ jsxs24("div", {
9052
9336
  ...props,
9053
9337
  className: classNames("altertable-refresh-control", className),
9054
9338
  "data-refreshing": showProgress ? "" : undefined,
9055
9339
  children: [
9056
- /* @__PURE__ */ jsx31("div", {
9340
+ /* @__PURE__ */ jsx33("div", {
9057
9341
  ...statusProps,
9058
9342
  className: classNames("altertable-refresh-status", statusProps?.className),
9059
9343
  "aria-live": "polite",
@@ -9066,7 +9350,7 @@ function RefreshControl({
9066
9350
  }
9067
9351
 
9068
9352
  // src/react/ui/AppToolbar.tsx
9069
- import { jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
9353
+ import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
9070
9354
  function AppToolbar({
9071
9355
  children,
9072
9356
  updatedAt,
@@ -9076,6 +9360,7 @@ function AppToolbar({
9076
9360
  live,
9077
9361
  aboutData,
9078
9362
  story,
9363
+ csvExport,
9079
9364
  end,
9080
9365
  controlsProps,
9081
9366
  className,
@@ -9097,27 +9382,27 @@ function AppToolbar({
9097
9382
  refresh.onRefresh();
9098
9383
  }
9099
9384
  useShortcut(shortcuts.refresh, runRefresh, !!refresh);
9100
- return /* @__PURE__ */ jsx32("div", {
9385
+ return /* @__PURE__ */ jsx34("div", {
9101
9386
  ...props,
9102
9387
  className: classNames("altertable-app-toolbar", className),
9103
9388
  role,
9104
9389
  "aria-label": ariaLabel,
9105
- children: /* @__PURE__ */ jsxs23("div", {
9390
+ children: /* @__PURE__ */ jsxs25("div", {
9106
9391
  ...controlsProps,
9107
9392
  className: classNames("altertable-app-toolbar-actions", controlsProps?.className),
9108
9393
  children: [
9109
9394
  children,
9110
- (initialLoading || updatedAt) && /* @__PURE__ */ jsx32("span", {
9395
+ (initialLoading || updatedAt) && /* @__PURE__ */ jsx34("span", {
9111
9396
  className: "altertable-app-toolbar-updated",
9112
- children: initialLoading ? /* @__PURE__ */ jsx32("output", {
9397
+ children: initialLoading ? /* @__PURE__ */ jsx34("output", {
9113
9398
  children: "Loading data"
9114
9399
  }) : updatedAt
9115
9400
  }),
9116
- refresh && /* @__PURE__ */ jsx32(RefreshControl, {
9401
+ refresh && /* @__PURE__ */ jsx34(RefreshControl, {
9117
9402
  refreshing: refresh.refreshing,
9118
9403
  label: requestState === "loading" ? "Loading data" : requestState === "updating" ? "Updating data" : refresh.label,
9119
9404
  statusProps: refresh.statusProps,
9120
- children: /* @__PURE__ */ jsxs23(IconButton, {
9405
+ children: /* @__PURE__ */ jsxs25(IconButton, {
9121
9406
  ...refresh.buttonProps,
9122
9407
  icon: "refresh",
9123
9408
  variant: "elevated",
@@ -9126,17 +9411,17 @@ function AppToolbar({
9126
9411
  tooltip: refresh.refreshing && refresh.onCancel ? "Cancel refresh" : refresh.tooltip,
9127
9412
  onClick: activateRefresh,
9128
9413
  children: [
9129
- /* @__PURE__ */ jsx32(AppIcon, {
9414
+ /* @__PURE__ */ jsx34(AppIcon, {
9130
9415
  name: "refresh",
9131
9416
  className: "altertable-refresh-idle",
9132
9417
  size: 17
9133
9418
  }),
9134
- /* @__PURE__ */ jsx32(AppIcon, {
9419
+ /* @__PURE__ */ jsx34(AppIcon, {
9135
9420
  name: "loading",
9136
9421
  className: "altertable-refresh-loading",
9137
9422
  size: 17
9138
9423
  }),
9139
- refresh.onCancel && /* @__PURE__ */ jsx32(AppIcon, {
9424
+ refresh.onCancel && /* @__PURE__ */ jsx34(AppIcon, {
9140
9425
  name: "stop",
9141
9426
  className: "altertable-refresh-cancel",
9142
9427
  size: 17,
@@ -9146,11 +9431,14 @@ function AppToolbar({
9146
9431
  ]
9147
9432
  })
9148
9433
  }),
9149
- live && /* @__PURE__ */ jsx32(LiveControl, {
9434
+ live && /* @__PURE__ */ jsx34(LiveControl, {
9150
9435
  ...live
9151
9436
  }),
9152
9437
  aboutData,
9153
- story && /* @__PURE__ */ jsx32(PresentStory, {
9438
+ !!csvExport?.tables.length && /* @__PURE__ */ jsx34(ExportControl, {
9439
+ csv: csvExport
9440
+ }),
9441
+ story && /* @__PURE__ */ jsx34(PresentStory, {
9154
9442
  ...story
9155
9443
  }),
9156
9444
  end
@@ -9160,7 +9448,7 @@ function AppToolbar({
9160
9448
  }
9161
9449
 
9162
9450
  // src/react/ui/VariableBar.tsx
9163
- import { jsx as jsx33 } from "react/jsx-runtime";
9451
+ import { jsx as jsx35 } from "react/jsx-runtime";
9164
9452
  function VariableBar({
9165
9453
  children,
9166
9454
  className,
@@ -9168,7 +9456,7 @@ function VariableBar({
9168
9456
  "aria-label": ariaLabel = "View variables",
9169
9457
  ...props
9170
9458
  }) {
9171
- return /* @__PURE__ */ jsx33("div", {
9459
+ return /* @__PURE__ */ jsx35("div", {
9172
9460
  ...props,
9173
9461
  className: classNames("altertable-variable-bar", className),
9174
9462
  role,
@@ -9178,15 +9466,15 @@ function VariableBar({
9178
9466
  }
9179
9467
 
9180
9468
  // src/react/ui/DataViewToast.tsx
9181
- import { useEffect as useEffect13, useState as useState14 } from "react";
9182
- import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
9469
+ import { useEffect as useEffect13, useState as useState15 } from "react";
9470
+ import { jsx as jsx36 } from "react/jsx-runtime";
9183
9471
  function DataViewToast({
9184
9472
  view,
9185
9473
  message,
9186
9474
  notice,
9187
9475
  onRetry
9188
9476
  }) {
9189
- const [delay, setDelay] = useState14({ kind: view.kind, elapsed: false });
9477
+ const [delay, setDelay] = useState15({ kind: view.kind, elapsed: false });
9190
9478
  if (delay.kind !== view.kind)
9191
9479
  setDelay({ kind: view.kind, elapsed: false });
9192
9480
  useEffect13(() => {
@@ -9203,34 +9491,16 @@ function DataViewToast({
9203
9491
  const failed = showStaleError;
9204
9492
  const showingUpdate = view.kind === "updating" && showUpdating;
9205
9493
  const detail = view.kind === "stale-error" || view.kind === "updating" ? view.message : undefined;
9206
- const icon = failed ? "error" : showingUpdate ? "loading" : "live";
9207
- const state = failed ? "stale-error" : showingUpdate ? "updating" : "notice";
9208
- return /* @__PURE__ */ jsx34("div", {
9209
- className: "altertable-data-view-toast-region",
9210
- children: /* @__PURE__ */ jsxs24("div", {
9211
- className: "altertable-data-view-toast",
9212
- "data-state": state,
9213
- role: failed ? "alert" : "status",
9214
- children: [
9215
- /* @__PURE__ */ jsx34(AppIcon, {
9216
- name: icon,
9217
- size: 16,
9218
- className: showingUpdate ? "altertable-data-view-toast-spinner" : undefined
9219
- }),
9220
- /* @__PURE__ */ jsx34("span", {
9221
- children: failed ? message ?? detail : showingUpdate ? message ?? detail : notice
9222
- }),
9223
- failed && onRetry && /* @__PURE__ */ jsx34(Button, {
9224
- onClick: onRetry,
9225
- children: "Try again"
9226
- })
9227
- ]
9228
- })
9494
+ const state = failed ? "error" : showingUpdate ? "updating" : "notice";
9495
+ return /* @__PURE__ */ jsx36(Toast, {
9496
+ state,
9497
+ onRetry,
9498
+ children: failed || showingUpdate ? message ?? detail : notice
9229
9499
  });
9230
9500
  }
9231
9501
 
9232
9502
  // src/react/ui/ContentSkeleton.tsx
9233
- import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
9503
+ import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
9234
9504
  function ContentSkeleton({
9235
9505
  variant,
9236
9506
  rows = 4,
@@ -9238,29 +9508,29 @@ function ContentSkeleton({
9238
9508
  ...props
9239
9509
  }) {
9240
9510
  invariant(Number.isInteger(rows) && rows >= 0 && rows <= 100, "Skeleton rows must be between 0 and 100.");
9241
- return /* @__PURE__ */ jsxs25("div", {
9511
+ return /* @__PURE__ */ jsxs26("div", {
9242
9512
  ...props,
9243
9513
  "aria-hidden": "true",
9244
9514
  className: classNames(`altertable-${variant === "metric" ? "metric-widget" : "data-widget"}`, "altertable-content-skeleton", className),
9245
9515
  children: [
9246
- /* @__PURE__ */ jsx35(Skeleton, {
9516
+ /* @__PURE__ */ jsx37(Skeleton, {
9247
9517
  className: "altertable-content-skeleton-label"
9248
9518
  }),
9249
- /* @__PURE__ */ jsx35(Skeleton, {
9519
+ /* @__PURE__ */ jsx37(Skeleton, {
9250
9520
  className: variant === "metric" ? "altertable-content-skeleton-value" : variant === "ranking" ? "altertable-content-skeleton-subtitle" : "altertable-content-skeleton-chart"
9251
9521
  }),
9252
- variant === "panel" && /* @__PURE__ */ jsx35(Skeleton, {
9522
+ variant === "panel" && /* @__PURE__ */ jsx37(Skeleton, {
9253
9523
  className: "altertable-content-skeleton-foot"
9254
9524
  }),
9255
- variant === "ranking" && /* @__PURE__ */ jsx35("div", {
9525
+ variant === "ranking" && /* @__PURE__ */ jsx37("div", {
9256
9526
  className: "altertable-content-skeleton-rows",
9257
- children: Array.from({ length: rows }, (_, index) => index).map((row) => /* @__PURE__ */ jsxs25("div", {
9527
+ children: Array.from({ length: rows }, (_, index) => index).map((row) => /* @__PURE__ */ jsxs26("div", {
9258
9528
  className: "altertable-content-skeleton-row",
9259
9529
  children: [
9260
- /* @__PURE__ */ jsx35(Skeleton, {
9530
+ /* @__PURE__ */ jsx37(Skeleton, {
9261
9531
  className: "altertable-content-skeleton-row-label"
9262
9532
  }),
9263
- /* @__PURE__ */ jsx35(Skeleton, {
9533
+ /* @__PURE__ */ jsx37(Skeleton, {
9264
9534
  className: "altertable-content-skeleton-row-track"
9265
9535
  })
9266
9536
  ]
@@ -9271,7 +9541,7 @@ function ContentSkeleton({
9271
9541
  }
9272
9542
 
9273
9543
  // src/react/ui/DataBoundary.tsx
9274
- import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
9544
+ import { jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
9275
9545
  function DataBoundary({
9276
9546
  view,
9277
9547
  loading,
@@ -9285,41 +9555,41 @@ function DataBoundary({
9285
9555
  ...props
9286
9556
  }) {
9287
9557
  if (view.kind === "loading" || view.kind === "empty" || view.kind === "error")
9288
- return /* @__PURE__ */ jsx36("div", {
9558
+ return /* @__PURE__ */ jsx38("div", {
9289
9559
  ...props,
9290
9560
  className: classNames("altertable-data-boundary", className),
9291
9561
  children: view.kind === "loading" ? loading : view.kind === "empty" ? empty : error(view.error)
9292
9562
  });
9293
9563
  const updating = view.kind === "updating";
9294
9564
  const hasStaleError = view.kind === "stale-error";
9295
- return /* @__PURE__ */ jsxs26("div", {
9565
+ return /* @__PURE__ */ jsxs27("div", {
9296
9566
  ...props,
9297
9567
  className: classNames("altertable-data-boundary", className),
9298
9568
  children: [
9299
- notice === "inline" && (updating || hasStaleError) && /* @__PURE__ */ jsxs26("div", {
9569
+ notice === "inline" && (updating || hasStaleError) && /* @__PURE__ */ jsxs27("div", {
9300
9570
  className: "altertable-data-boundary-notice",
9301
9571
  "data-state": view.kind,
9302
9572
  role: hasStaleError ? "alert" : "status",
9303
9573
  children: [
9304
- updating ? /* @__PURE__ */ jsx36(AppIcon, {
9574
+ updating ? /* @__PURE__ */ jsx38(AppIcon, {
9305
9575
  name: "loading",
9306
9576
  size: 16,
9307
9577
  className: "altertable-data-boundary-spinner"
9308
- }) : /* @__PURE__ */ jsx36(AppIcon, {
9578
+ }) : /* @__PURE__ */ jsx38(AppIcon, {
9309
9579
  name: "error",
9310
9580
  size: 16
9311
9581
  }),
9312
- /* @__PURE__ */ jsx36("span", {
9582
+ /* @__PURE__ */ jsx38("span", {
9313
9583
  className: "altertable-data-boundary-message",
9314
9584
  children: view.message
9315
9585
  }),
9316
- staleError && view.kind === "stale-error" && /* @__PURE__ */ jsx36("span", {
9586
+ staleError && view.kind === "stale-error" && /* @__PURE__ */ jsx38("span", {
9317
9587
  className: "altertable-data-boundary-action",
9318
9588
  children: staleError(view.error)
9319
9589
  })
9320
9590
  ]
9321
9591
  }),
9322
- /* @__PURE__ */ jsx36("div", {
9592
+ /* @__PURE__ */ jsx38("div", {
9323
9593
  className: "altertable-data-boundary-content",
9324
9594
  "data-updating": updating && dimOnUpdate || undefined,
9325
9595
  children: children(view.data, view.kind === "ready" ? view.input : view.displayedInput)
@@ -9329,7 +9599,7 @@ function DataBoundary({
9329
9599
  }
9330
9600
 
9331
9601
  // src/react/ui/StatusPanel.tsx
9332
- import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
9602
+ import { jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
9333
9603
  function StatusPanel({
9334
9604
  status,
9335
9605
  title,
@@ -9341,32 +9611,32 @@ function StatusPanel({
9341
9611
  role,
9342
9612
  ...props
9343
9613
  }) {
9344
- return /* @__PURE__ */ jsxs27("div", {
9614
+ return /* @__PURE__ */ jsxs28("div", {
9345
9615
  ...props,
9346
9616
  className: classNames("altertable-status-panel", className),
9347
9617
  "data-status": status,
9348
9618
  role: role ?? (status === "error" ? "alert" : "status"),
9349
9619
  children: [
9350
- status === "error" && /* @__PURE__ */ jsx37(AppIcon, {
9620
+ status === "error" && /* @__PURE__ */ jsx39(AppIcon, {
9351
9621
  name: "error",
9352
9622
  size: 18
9353
9623
  }),
9354
- /* @__PURE__ */ jsxs27("div", {
9624
+ /* @__PURE__ */ jsxs28("div", {
9355
9625
  className: "altertable-status-copy",
9356
9626
  children: [
9357
- /* @__PURE__ */ jsx37("strong", {
9627
+ /* @__PURE__ */ jsx39("strong", {
9358
9628
  children: title
9359
9629
  }),
9360
- description && /* @__PURE__ */ jsx37("p", {
9630
+ description && /* @__PURE__ */ jsx39("p", {
9361
9631
  children: description
9362
9632
  }),
9363
- details && /* @__PURE__ */ jsx37("small", {
9633
+ details && /* @__PURE__ */ jsx39("small", {
9364
9634
  children: details
9365
9635
  }),
9366
9636
  children
9367
9637
  ]
9368
9638
  }),
9369
- action && /* @__PURE__ */ jsx37("div", {
9639
+ action && /* @__PURE__ */ jsx39("div", {
9370
9640
  className: "altertable-status-action",
9371
9641
  children: action
9372
9642
  })
@@ -9375,7 +9645,7 @@ function StatusPanel({
9375
9645
  }
9376
9646
 
9377
9647
  // src/react/ui/DataSection.tsx
9378
- import { jsx as jsx38 } from "react/jsx-runtime";
9648
+ import { jsx as jsx40 } from "react/jsx-runtime";
9379
9649
  function errorPresentation(cause) {
9380
9650
  const code = cause instanceof DataAppError2 ? cause.code : "request_failed";
9381
9651
  switch (code) {
@@ -9434,33 +9704,33 @@ function DataSection({
9434
9704
  dimOnUpdate = false,
9435
9705
  ...props
9436
9706
  }) {
9437
- return /* @__PURE__ */ jsx38(DataBoundary, {
9707
+ return /* @__PURE__ */ jsx40(DataBoundary, {
9438
9708
  ...props,
9439
9709
  view: result.view,
9440
9710
  role: label ? "region" : undefined,
9441
9711
  "aria-label": label,
9442
9712
  notice,
9443
9713
  dimOnUpdate,
9444
- loading: loading ?? /* @__PURE__ */ jsx38(ContentSkeleton, {
9714
+ loading: loading ?? /* @__PURE__ */ jsx40(ContentSkeleton, {
9445
9715
  variant: "panel"
9446
9716
  }),
9447
- empty: /* @__PURE__ */ jsx38(EmptyState, {
9717
+ empty: /* @__PURE__ */ jsx40(EmptyState, {
9448
9718
  ...empty
9449
9719
  }),
9450
9720
  error: (cause) => {
9451
9721
  const presentation = errorPresentation(cause);
9452
9722
  const retryAction = error?.onRetry ?? (presentation.retryable ? () => void result.refetch() : undefined);
9453
- return /* @__PURE__ */ jsx38(StatusPanel, {
9723
+ return /* @__PURE__ */ jsx40(StatusPanel, {
9454
9724
  status: "error",
9455
9725
  title: error?.title ?? presentation.title,
9456
9726
  description: error?.description ?? presentation.description,
9457
- action: retryAction && /* @__PURE__ */ jsx38(Button, {
9727
+ action: retryAction && /* @__PURE__ */ jsx40(Button, {
9458
9728
  onClick: retryAction,
9459
9729
  children: "Retry"
9460
9730
  })
9461
9731
  });
9462
9732
  },
9463
- staleError: () => /* @__PURE__ */ jsx38(Button, {
9733
+ staleError: () => /* @__PURE__ */ jsx40(Button, {
9464
9734
  onClick: error?.onRetry ?? (() => void result.refetch()),
9465
9735
  children: "Retry"
9466
9736
  }),
@@ -9469,7 +9739,7 @@ function DataSection({
9469
9739
  }
9470
9740
 
9471
9741
  // src/react/ui/DataApp.tsx
9472
- import { jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
9742
+ import { jsx as jsx41, jsxs as jsxs29 } from "react/jsx-runtime";
9473
9743
  function DataApp(props) {
9474
9744
  const {
9475
9745
  config,
@@ -9493,12 +9763,14 @@ function DataApp(props) {
9493
9763
  console.warn("DataApp owns the page title. Use section headings (h2) in its body.");
9494
9764
  });
9495
9765
  const snapshot = request && displayedSnapshot(request.view);
9496
- const story = request && props.story && snapshot ? { findings: props.story(snapshot) } : undefined;
9497
- const scope = /* @__PURE__ */ jsx39(AppScope, {
9766
+ const findings = request && snapshot ? props.story(snapshot) : undefined;
9767
+ const story = findings?.length ? { findings } : undefined;
9768
+ const scope = /* @__PURE__ */ jsx41(AppScope, {
9498
9769
  organization: scopeLabels?.organization ?? config.scope.organization,
9499
9770
  environment: scopeLabels?.environment ?? config.scope.environment
9500
9771
  });
9501
- const toolbar = /* @__PURE__ */ jsx39(AppToolbar, {
9772
+ const toolbar = /* @__PURE__ */ jsx41(AppToolbar, {
9773
+ csvExport: request ? snapshot ? props.csvExport(snapshot) : undefined : props.csvExport,
9502
9774
  requestState: request?.view.kind,
9503
9775
  refresh: refresh ?? request?.refresh,
9504
9776
  story: story && {
@@ -9509,7 +9781,7 @@ function DataApp(props) {
9509
9781
  empty: aboutEmpty,
9510
9782
  theme: themeController
9511
9783
  },
9512
- aboutData: /* @__PURE__ */ jsx39(AboutData, {
9784
+ aboutData: /* @__PURE__ */ jsx41(AboutData, {
9513
9785
  id: "data",
9514
9786
  shortcut: true,
9515
9787
  dataContext,
@@ -9520,32 +9792,32 @@ function DataApp(props) {
9520
9792
  }),
9521
9793
  children: toolbarActions
9522
9794
  });
9523
- return /* @__PURE__ */ jsx39(InspectionContext, {
9795
+ return /* @__PURE__ */ jsx41(InspectionContext, {
9524
9796
  value: {
9525
9797
  dataContext,
9526
9798
  empty: aboutEmpty,
9527
9799
  queries: queries ?? request?.queries
9528
9800
  },
9529
- children: /* @__PURE__ */ jsxs28(AppLayout, {
9801
+ children: /* @__PURE__ */ jsxs29(AppLayout, {
9530
9802
  ...layoutProps,
9531
9803
  footer: isEmbedded ? null : layoutProps?.footer,
9532
- footerActions: footerActions ?? (themeController && /* @__PURE__ */ jsx39(ThemeToggle, {
9804
+ footerActions: footerActions ?? (themeController && /* @__PURE__ */ jsx41(ThemeToggle, {
9533
9805
  theme: themeController
9534
9806
  })),
9535
9807
  children: [
9536
- isEmbedded ? toolbar : /* @__PURE__ */ jsx39(AppHeader, {
9808
+ isEmbedded ? toolbar : /* @__PURE__ */ jsx41(AppHeader, {
9537
9809
  scope,
9538
9810
  title: config.title,
9539
9811
  description,
9540
9812
  toolbar
9541
9813
  }),
9542
- (request?.controls ?? props.variables) && /* @__PURE__ */ jsx39(VariableBar, {
9814
+ (request?.controls ?? props.variables) && /* @__PURE__ */ jsx41(VariableBar, {
9543
9815
  children: request?.controls ?? props.variables
9544
9816
  }),
9545
- /* @__PURE__ */ jsx39("div", {
9817
+ /* @__PURE__ */ jsx41("div", {
9546
9818
  ref: bodyRef,
9547
9819
  className: "altertable-app-body",
9548
- children: request ? /* @__PURE__ */ jsx39(DataSection, {
9820
+ children: request ? /* @__PURE__ */ jsx41(DataSection, {
9549
9821
  result: request,
9550
9822
  notice: "none",
9551
9823
  dimOnUpdate: false,
@@ -9555,7 +9827,7 @@ function DataApp(props) {
9555
9827
  children: (data, displayedInput) => props.children(data, displayedInput)
9556
9828
  }) : props.children
9557
9829
  }),
9558
- request && /* @__PURE__ */ jsx39(DataViewToast, {
9830
+ request && /* @__PURE__ */ jsx41(DataViewToast, {
9559
9831
  view: request.view,
9560
9832
  onRetry: () => void request.refetch()
9561
9833
  })
@@ -9564,7 +9836,7 @@ function DataApp(props) {
9564
9836
  });
9565
9837
  }
9566
9838
  // src/react/ui/GettingStarted.tsx
9567
- import { jsx as jsx40, jsxs as jsxs29 } from "react/jsx-runtime";
9839
+ import { jsx as jsx42, jsxs as jsxs30 } from "react/jsx-runtime";
9568
9840
  var client = /* @__PURE__ */ createDataClient2();
9569
9841
  var { useDataQuery } = /* @__PURE__ */ createDataHooks(client);
9570
9842
  function GettingStarted({
@@ -9573,7 +9845,7 @@ function GettingStarted({
9573
9845
  }) {
9574
9846
  const connection = useDataQuery("connection", {});
9575
9847
  const state = connection.error ? "error" : connection.isFetching || !connection.data ? "checking" : "connected";
9576
- return /* @__PURE__ */ jsxs29(DataApp, {
9848
+ return /* @__PURE__ */ jsxs30(DataApp, {
9577
9849
  config,
9578
9850
  dataContext,
9579
9851
  description: "Check your lakehouse connection, then build a view around a real question.",
@@ -9587,98 +9859,98 @@ function GettingStarted({
9587
9859
  buttonProps: { "aria-label": "Check connection" }
9588
9860
  },
9589
9861
  children: [
9590
- /* @__PURE__ */ jsxs29("section", {
9862
+ /* @__PURE__ */ jsxs30("section", {
9591
9863
  className: "starter-connection",
9592
9864
  "data-state": state,
9593
9865
  role: state === "error" ? "alert" : "status",
9594
9866
  children: [
9595
- /* @__PURE__ */ jsx40("div", {
9867
+ /* @__PURE__ */ jsx42("div", {
9596
9868
  className: "starter-connection-icon",
9597
- children: /* @__PURE__ */ jsx40(AppIcon, {
9869
+ children: /* @__PURE__ */ jsx42(AppIcon, {
9598
9870
  name: state === "connected" ? "check" : state === "error" ? "error" : "loading",
9599
9871
  size: 24
9600
9872
  })
9601
9873
  }),
9602
- /* @__PURE__ */ jsxs29("div", {
9874
+ /* @__PURE__ */ jsxs30("div", {
9603
9875
  className: "starter-connection-copy",
9604
9876
  children: [
9605
- /* @__PURE__ */ jsx40("span", {
9877
+ /* @__PURE__ */ jsx42("span", {
9606
9878
  className: "starter-eyebrow",
9607
9879
  children: "Lakehouse connection"
9608
9880
  }),
9609
- /* @__PURE__ */ jsx40("h2", {
9881
+ /* @__PURE__ */ jsx42("h2", {
9610
9882
  children: state === "connected" ? "Connected" : state === "error" ? "Connection not verified" : "Checking connection…"
9611
9883
  }),
9612
- /* @__PURE__ */ jsx40("p", {
9884
+ /* @__PURE__ */ jsx42("p", {
9613
9885
  children: state === "connected" ? "A query completed successfully using this app’s current profile. You’re ready to build your first view." : state === "error" ? connection.data ? "An earlier query succeeded, but the latest check failed. Check the profile and try again." : "The query could not complete. Check the profile and lakehouse access, then try again." : "Running a lightweight query with this app’s current profile."
9614
9886
  }),
9615
- state === "connected" && /* @__PURE__ */ jsx40("small", {
9887
+ state === "connected" && /* @__PURE__ */ jsx42("small", {
9616
9888
  children: "This check does not verify access to every dataset."
9617
9889
  })
9618
9890
  ]
9619
9891
  }),
9620
- state === "error" && /* @__PURE__ */ jsx40(Button, {
9892
+ state === "error" && /* @__PURE__ */ jsx42(Button, {
9621
9893
  onClick: () => void connection.refetch(),
9622
9894
  children: "Try again"
9623
9895
  })
9624
9896
  ]
9625
9897
  }),
9626
- /* @__PURE__ */ jsxs29("section", {
9898
+ /* @__PURE__ */ jsxs30("section", {
9627
9899
  className: "starter-next",
9628
9900
  "aria-labelledby": "starter-next-title",
9629
9901
  children: [
9630
- /* @__PURE__ */ jsxs29("div", {
9902
+ /* @__PURE__ */ jsxs30("div", {
9631
9903
  className: "starter-next-heading",
9632
9904
  children: [
9633
- /* @__PURE__ */ jsx40("span", {
9905
+ /* @__PURE__ */ jsx42("span", {
9634
9906
  className: "starter-eyebrow",
9635
9907
  children: "Next steps"
9636
9908
  }),
9637
- /* @__PURE__ */ jsx40("h2", {
9909
+ /* @__PURE__ */ jsx42("h2", {
9638
9910
  id: "starter-next-title",
9639
9911
  children: "Turn this starter into a useful app"
9640
9912
  }),
9641
- /* @__PURE__ */ jsx40("p", {
9913
+ /* @__PURE__ */ jsx42("p", {
9642
9914
  children: "Start with one question your readers need answered."
9643
9915
  })
9644
9916
  ]
9645
9917
  }),
9646
- /* @__PURE__ */ jsxs29("ol", {
9918
+ /* @__PURE__ */ jsxs30("ol", {
9647
9919
  className: "starter-steps",
9648
9920
  children: [
9649
- /* @__PURE__ */ jsxs29("li", {
9921
+ /* @__PURE__ */ jsxs30("li", {
9650
9922
  children: [
9651
- /* @__PURE__ */ jsx40("strong", {
9923
+ /* @__PURE__ */ jsx42("strong", {
9652
9924
  children: "Choose a question"
9653
9925
  }),
9654
- /* @__PURE__ */ jsx40("p", {
9926
+ /* @__PURE__ */ jsx42("p", {
9655
9927
  children: "Decide what someone should learn or do after opening this app."
9656
9928
  })
9657
9929
  ]
9658
9930
  }),
9659
- /* @__PURE__ */ jsxs29("li", {
9931
+ /* @__PURE__ */ jsxs30("li", {
9660
9932
  children: [
9661
- /* @__PURE__ */ jsx40("strong", {
9933
+ /* @__PURE__ */ jsx42("strong", {
9662
9934
  children: "Find the right data"
9663
9935
  }),
9664
- /* @__PURE__ */ jsx40("p", {
9936
+ /* @__PURE__ */ jsx42("p", {
9665
9937
  children: "Inspect the relevant catalogs, tables, and columns before writing the query."
9666
9938
  })
9667
9939
  ]
9668
9940
  }),
9669
- /* @__PURE__ */ jsxs29("li", {
9941
+ /* @__PURE__ */ jsxs30("li", {
9670
9942
  children: [
9671
- /* @__PURE__ */ jsx40("strong", {
9943
+ /* @__PURE__ */ jsx42("strong", {
9672
9944
  children: "Build the first view"
9673
9945
  }),
9674
- /* @__PURE__ */ jsxs29("p", {
9946
+ /* @__PURE__ */ jsxs30("p", {
9675
9947
  children: [
9676
9948
  "Replace the connection check in ",
9677
- /* @__PURE__ */ jsx40("code", {
9949
+ /* @__PURE__ */ jsx42("code", {
9678
9950
  children: "src/operations.ts"
9679
9951
  }),
9680
9952
  ", then render its result in ",
9681
- /* @__PURE__ */ jsx40("code", {
9953
+ /* @__PURE__ */ jsx42("code", {
9682
9954
  children: "src/App.tsx"
9683
9955
  }),
9684
9956
  "."
@@ -9694,14 +9966,14 @@ function GettingStarted({
9694
9966
  });
9695
9967
  }
9696
9968
  // src/react/ui/Stack.tsx
9697
- import { jsx as jsx41 } from "react/jsx-runtime";
9969
+ import { jsx as jsx43 } from "react/jsx-runtime";
9698
9970
  function Stack({
9699
9971
  children,
9700
9972
  gap = "lg",
9701
9973
  className,
9702
9974
  ...props
9703
9975
  }) {
9704
- return /* @__PURE__ */ jsx41("div", {
9976
+ return /* @__PURE__ */ jsx43("div", {
9705
9977
  ...props,
9706
9978
  className: classNames("altertable-stack", className),
9707
9979
  "data-gap": gap,
@@ -9709,7 +9981,7 @@ function Stack({
9709
9981
  });
9710
9982
  }
9711
9983
  // src/react/ui/Grid.tsx
9712
- import { jsx as jsx42 } from "react/jsx-runtime";
9984
+ import { jsx as jsx44 } from "react/jsx-runtime";
9713
9985
  function Grid({
9714
9986
  children,
9715
9987
  columns = 1,
@@ -9719,7 +9991,7 @@ function Grid({
9719
9991
  className,
9720
9992
  ...props
9721
9993
  }) {
9722
- return /* @__PURE__ */ jsx42("div", {
9994
+ return /* @__PURE__ */ jsx44("div", {
9723
9995
  ...props,
9724
9996
  className: classNames("altertable-grid", className),
9725
9997
  "data-columns": columns,
@@ -9730,14 +10002,14 @@ function Grid({
9730
10002
  });
9731
10003
  }
9732
10004
  // src/react/ui/GridItem.tsx
9733
- import { jsx as jsx43 } from "react/jsx-runtime";
10005
+ import { jsx as jsx45 } from "react/jsx-runtime";
9734
10006
  function GridItem({
9735
10007
  children,
9736
10008
  span = 1,
9737
10009
  className,
9738
10010
  ...props
9739
10011
  }) {
9740
- return /* @__PURE__ */ jsx43("div", {
10012
+ return /* @__PURE__ */ jsx45("div", {
9741
10013
  ...props,
9742
10014
  className: classNames("altertable-grid-item", className),
9743
10015
  "data-span": span,
@@ -9746,24 +10018,24 @@ function GridItem({
9746
10018
  }
9747
10019
  // src/react/ui/DataWidget.tsx
9748
10020
  import { useId as useId8 } from "react";
9749
- import { jsx as jsx44, jsxs as jsxs30, Fragment as Fragment8 } from "react/jsx-runtime";
10021
+ import { jsx as jsx46, jsxs as jsxs31, Fragment as Fragment9 } from "react/jsx-runtime";
9750
10022
  function DataWidget(props) {
9751
10023
  if (props.reading) {
9752
10024
  const { reading, isEmpty, empty, skeleton, children, ...shell } = props;
9753
10025
  if (reading.loading)
9754
- return /* @__PURE__ */ jsx44(ContentSkeleton, {
10026
+ return /* @__PURE__ */ jsx46(ContentSkeleton, {
9755
10027
  variant: "panel",
9756
10028
  ...skeleton,
9757
10029
  className: shell.className
9758
10030
  });
9759
10031
  const noData = isEmpty(reading.value);
9760
- return /* @__PURE__ */ jsx44(DataWidgetContent, {
10032
+ return /* @__PURE__ */ jsx46(DataWidgetContent, {
9761
10033
  ...shell,
9762
10034
  empty: noData ? empty : undefined,
9763
10035
  children: noData ? null : children(reading.value)
9764
10036
  });
9765
10037
  }
9766
- return /* @__PURE__ */ jsx44(DataWidgetContent, {
10038
+ return /* @__PURE__ */ jsx46(DataWidgetContent, {
9767
10039
  ...props
9768
10040
  });
9769
10041
  }
@@ -9782,16 +10054,16 @@ function DataWidgetContent({
9782
10054
  ...props
9783
10055
  }) {
9784
10056
  const titleId = useId8();
9785
- const content = empty ? /* @__PURE__ */ jsx44(EmptyState, {
10057
+ const content = empty ? /* @__PURE__ */ jsx46(EmptyState, {
9786
10058
  ...empty
9787
10059
  }) : children;
9788
- const visual = /* @__PURE__ */ jsx44(WidgetContent, {
10060
+ const visual = /* @__PURE__ */ jsx46(WidgetContent, {
9789
10061
  bodyPadding: empty ? "flush" : bodyPadding,
9790
10062
  footer: empty ? undefined : footer,
9791
10063
  status,
9792
10064
  children: content
9793
10065
  });
9794
- const help = evidence && /* @__PURE__ */ jsxs30(AboutData, {
10066
+ const help = evidence && /* @__PURE__ */ jsxs31(AboutData, {
9795
10067
  id: evidence.id,
9796
10068
  references: {
9797
10069
  kind: "ids",
@@ -9804,7 +10076,7 @@ function DataWidgetContent({
9804
10076
  tooltip: "Explore this widget",
9805
10077
  shortcut: false,
9806
10078
  title,
9807
- headerActions: /* @__PURE__ */ jsx44(WidgetStatusControl, {
10079
+ headerActions: /* @__PURE__ */ jsx46(WidgetStatusControl, {
9808
10080
  status
9809
10081
  }),
9810
10082
  description,
@@ -9812,41 +10084,41 @@ function DataWidgetContent({
9812
10084
  visualKind: "widget",
9813
10085
  children: [
9814
10086
  title,
9815
- /* @__PURE__ */ jsx44(AppIcon, {
10087
+ /* @__PURE__ */ jsx46(AppIcon, {
9816
10088
  name: "openDetails"
9817
10089
  })
9818
10090
  ]
9819
10091
  });
9820
- return /* @__PURE__ */ jsxs30("section", {
10092
+ return /* @__PURE__ */ jsxs31("section", {
9821
10093
  ...props,
9822
10094
  className: classNames("altertable-data-widget", className),
9823
10095
  "aria-labelledby": props["aria-labelledby"] ?? titleId,
9824
10096
  children: [
9825
- /* @__PURE__ */ jsxs30("header", {
10097
+ /* @__PURE__ */ jsxs31("header", {
9826
10098
  className: "altertable-data-widget-header",
9827
10099
  children: [
9828
- /* @__PURE__ */ jsxs30("div", {
10100
+ /* @__PURE__ */ jsxs31("div", {
9829
10101
  children: [
9830
- /* @__PURE__ */ jsxs30("h2", {
10102
+ /* @__PURE__ */ jsxs31("h2", {
9831
10103
  id: titleId,
9832
10104
  "aria-label": typeof title === "string" ? title : undefined,
9833
10105
  children: [
9834
10106
  help ?? title,
9835
- count !== undefined && /* @__PURE__ */ jsx44("span", {
10107
+ count !== undefined && /* @__PURE__ */ jsx46("span", {
9836
10108
  className: "altertable-data-widget-count",
9837
10109
  children: formatCount2(count)
9838
10110
  })
9839
10111
  ]
9840
10112
  }),
9841
- description && /* @__PURE__ */ jsx44("p", {
10113
+ description && /* @__PURE__ */ jsx46("p", {
9842
10114
  children: description
9843
10115
  })
9844
10116
  ]
9845
10117
  }),
9846
- /* @__PURE__ */ jsxs30("div", {
10118
+ /* @__PURE__ */ jsxs31("div", {
9847
10119
  className: "altertable-data-widget-help",
9848
10120
  children: [
9849
- /* @__PURE__ */ jsx44(WidgetStatusControl, {
10121
+ /* @__PURE__ */ jsx46(WidgetStatusControl, {
9850
10122
  status
9851
10123
  }),
9852
10124
  action
@@ -9864,15 +10136,15 @@ function WidgetContent({
9864
10136
  status,
9865
10137
  children
9866
10138
  }) {
9867
- return /* @__PURE__ */ jsxs30(Fragment8, {
10139
+ return /* @__PURE__ */ jsxs31(Fragment9, {
9868
10140
  children: [
9869
- /* @__PURE__ */ jsx44("div", {
10141
+ /* @__PURE__ */ jsx46("div", {
9870
10142
  className: "altertable-data-widget-body",
9871
10143
  "data-padding": bodyPadding,
9872
10144
  "aria-busy": status?.kind === "updating" || undefined,
9873
10145
  children
9874
10146
  }),
9875
- footer && /* @__PURE__ */ jsx44("footer", {
10147
+ footer && /* @__PURE__ */ jsx46("footer", {
9876
10148
  className: "altertable-data-widget-footer",
9877
10149
  children: footer
9878
10150
  })
@@ -9880,39 +10152,39 @@ function WidgetContent({
9880
10152
  });
9881
10153
  }
9882
10154
  // src/react/ui/TextContent.tsx
9883
- import { jsx as jsx45 } from "react/jsx-runtime";
10155
+ import { jsx as jsx47 } from "react/jsx-runtime";
9884
10156
  function TextContent({ className, ...props }) {
9885
- return /* @__PURE__ */ jsx45("div", {
10157
+ return /* @__PURE__ */ jsx47("div", {
9886
10158
  ...props,
9887
10159
  className: classNames("altertable-text-content", className)
9888
10160
  });
9889
10161
  }
9890
10162
  // src/react/ui/TextWidget.tsx
9891
- import { jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
10163
+ import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
9892
10164
  function TextWidget(props) {
9893
10165
  const content = props.reading ? props.reading.loading ? null : props.children(props.reading.value) : props.children;
9894
10166
  const { reading, children: _, className, ...shell } = props;
9895
10167
  const loading = reading?.loading === true;
9896
- return /* @__PURE__ */ jsx46(DataWidget, {
10168
+ return /* @__PURE__ */ jsx48(DataWidget, {
9897
10169
  ...shell,
9898
10170
  className: classNames("altertable-text-widget", className),
9899
10171
  evidence: loading ? undefined : shell.evidence,
9900
10172
  "aria-busy": loading || shell["aria-busy"],
9901
- children: /* @__PURE__ */ jsx46(TextContent, {
9902
- children: loading ? /* @__PURE__ */ jsxs31("div", {
10173
+ children: /* @__PURE__ */ jsx48(TextContent, {
10174
+ children: loading ? /* @__PURE__ */ jsxs32("div", {
9903
10175
  className: "altertable-text-widget-skeleton",
9904
10176
  "aria-hidden": "true",
9905
10177
  children: [
9906
- /* @__PURE__ */ jsx46(Skeleton, {}),
9907
- /* @__PURE__ */ jsx46(Skeleton, {}),
9908
- /* @__PURE__ */ jsx46(Skeleton, {})
10178
+ /* @__PURE__ */ jsx48(Skeleton, {}),
10179
+ /* @__PURE__ */ jsx48(Skeleton, {}),
10180
+ /* @__PURE__ */ jsx48(Skeleton, {})
9909
10181
  ]
9910
10182
  }) : content
9911
10183
  })
9912
10184
  });
9913
10185
  }
9914
10186
  // src/react/ui/VisualizationWidget.tsx
9915
- import { useState as useState15 } from "react";
10187
+ import { useState as useState16 } from "react";
9916
10188
 
9917
10189
  // src/react/ui/widget-views.ts
9918
10190
  function validateWidgetViews(views, selected) {
@@ -9922,7 +10194,7 @@ function validateWidgetViews(views, selected) {
9922
10194
  }
9923
10195
 
9924
10196
  // src/react/ui/WidgetViewTabs.tsx
9925
- import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
10197
+ import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
9926
10198
  function WidgetViewTabs({
9927
10199
  label,
9928
10200
  views,
@@ -9932,24 +10204,24 @@ function WidgetViewTabs({
9932
10204
  ...props
9933
10205
  }) {
9934
10206
  validateWidgetViews(views, selectedKey);
9935
- return /* @__PURE__ */ jsx47("div", {
10207
+ return /* @__PURE__ */ jsx49("div", {
9936
10208
  ...props,
9937
10209
  className: classNames("altertable-widget-view-tabs", className),
9938
- children: /* @__PURE__ */ jsxs32(Tabs, {
10210
+ children: /* @__PURE__ */ jsxs33(Tabs, {
9939
10211
  selectedKey,
9940
10212
  onSelectionChange: (key) => onSelectionChange(String(key)),
9941
10213
  children: [
9942
- /* @__PURE__ */ jsx47(TabList, {
10214
+ /* @__PURE__ */ jsx49(TabList, {
9943
10215
  "aria-label": label,
9944
- children: views.map((view) => /* @__PURE__ */ jsx47(Tab, {
10216
+ children: views.map((view) => /* @__PURE__ */ jsx49(Tab, {
9945
10217
  id: view.id,
9946
10218
  children: view.label
9947
10219
  }, view.id))
9948
10220
  }),
9949
- /* @__PURE__ */ jsx47(TabPanels, {
9950
- children: views.map((view) => /* @__PURE__ */ jsx47(TabPanel, {
10221
+ /* @__PURE__ */ jsx49(TabPanels, {
10222
+ children: views.map((view) => /* @__PURE__ */ jsx49(TabPanel, {
9951
10223
  id: view.id,
9952
- children: view.isEmpty ? /* @__PURE__ */ jsx47(EmptyState, {
10224
+ children: view.isEmpty ? /* @__PURE__ */ jsx49(EmptyState, {
9953
10225
  ...view.empty
9954
10226
  }) : view.content
9955
10227
  }, view.id))
@@ -9960,22 +10232,22 @@ function WidgetViewTabs({
9960
10232
  }
9961
10233
 
9962
10234
  // src/react/ui/VisualizationWidget.tsx
9963
- import { jsx as jsx48 } from "react/jsx-runtime";
10235
+ import { jsx as jsx50 } from "react/jsx-runtime";
9964
10236
  function VisualizationWidget(props) {
9965
10237
  if ("views" in props && props.views)
9966
- return /* @__PURE__ */ jsx48(VisualizationWidgetWithViews, {
10238
+ return /* @__PURE__ */ jsx50(VisualizationWidgetWithViews, {
9967
10239
  ...props
9968
10240
  });
9969
10241
  if ("reading" in props) {
9970
10242
  const { reading, children, isEmpty, empty, skeleton, insight, ...shell } = props;
9971
- return /* @__PURE__ */ jsx48(DataWidget, {
10243
+ return /* @__PURE__ */ jsx50(DataWidget, {
9972
10244
  ...shell,
9973
10245
  reading,
9974
10246
  isEmpty,
9975
10247
  empty,
9976
10248
  skeleton,
9977
10249
  footer: insight,
9978
- children: (data) => /* @__PURE__ */ jsx48("div", {
10250
+ children: (data) => /* @__PURE__ */ jsx50("div", {
9979
10251
  className: "altertable-visualization-widget-content",
9980
10252
  children: children(data)
9981
10253
  })
@@ -9983,14 +10255,14 @@ function VisualizationWidget(props) {
9983
10255
  }
9984
10256
  const { visual, loading = false, insight, ...shell } = props;
9985
10257
  if (loading)
9986
- return /* @__PURE__ */ jsx48(ContentSkeleton, {
10258
+ return /* @__PURE__ */ jsx50(ContentSkeleton, {
9987
10259
  variant: "panel",
9988
10260
  className: shell.className
9989
10261
  });
9990
- return /* @__PURE__ */ jsx48(DataWidget, {
10262
+ return /* @__PURE__ */ jsx50(DataWidget, {
9991
10263
  ...shell,
9992
10264
  footer: insight,
9993
- children: /* @__PURE__ */ jsx48("div", {
10265
+ children: /* @__PURE__ */ jsx50("div", {
9994
10266
  className: "altertable-visualization-widget-content",
9995
10267
  children: visual
9996
10268
  })
@@ -10007,18 +10279,18 @@ function VisualizationWidgetWithViews({
10007
10279
  insight,
10008
10280
  ...shell
10009
10281
  }) {
10010
- const [selected, setSelected] = useState15(initialView ?? views[0]?.id ?? "");
10282
+ const [selected, setSelected] = useState16(initialView ?? views[0]?.id ?? "");
10011
10283
  validateWidgetViews(views, selected);
10012
- return /* @__PURE__ */ jsx48(DataWidget, {
10284
+ return /* @__PURE__ */ jsx50(DataWidget, {
10013
10285
  ...shell,
10014
10286
  reading,
10015
10287
  isEmpty,
10016
10288
  empty,
10017
10289
  skeleton,
10018
10290
  footer: insight,
10019
- children: (data) => /* @__PURE__ */ jsx48("div", {
10291
+ children: (data) => /* @__PURE__ */ jsx50("div", {
10020
10292
  className: "altertable-visualization-widget-content",
10021
- children: /* @__PURE__ */ jsx48(WidgetViewTabs, {
10293
+ children: /* @__PURE__ */ jsx50(WidgetViewTabs, {
10022
10294
  label: viewLabel,
10023
10295
  views: views.map((view) => ({
10024
10296
  id: view.id,
@@ -10034,14 +10306,14 @@ function VisualizationWidgetWithViews({
10034
10306
  });
10035
10307
  }
10036
10308
  // src/react/ui/TableWidget.tsx
10037
- import { useState as useState18 } from "react";
10309
+ import { useState as useState19 } from "react";
10038
10310
 
10039
10311
  // src/react/ui/DateTimeTooltip.tsx
10040
- import { useEffect as useEffect15, useState as useState17 } from "react";
10312
+ import { useEffect as useEffect15, useState as useState18 } from "react";
10041
10313
 
10042
10314
  // src/react/ui/HelpPopover.tsx
10043
10315
  import {
10044
- useState as useState16
10316
+ useState as useState17
10045
10317
  } from "react";
10046
10318
  import {
10047
10319
  autoUpdate as autoUpdate2,
@@ -10059,7 +10331,7 @@ import {
10059
10331
  useMergeRefs as useMergeRefs6,
10060
10332
  useRole
10061
10333
  } from "@floating-ui/react";
10062
- import { jsx as jsx49, jsxs as jsxs33, Fragment as Fragment9 } from "react/jsx-runtime";
10334
+ import { jsx as jsx51, jsxs as jsxs34, Fragment as Fragment10 } from "react/jsx-runtime";
10063
10335
  function HelpPopover({
10064
10336
  trigger,
10065
10337
  triggerLabel,
@@ -10074,8 +10346,8 @@ function HelpPopover({
10074
10346
  open: openProp,
10075
10347
  onOpenChange
10076
10348
  }) {
10077
- const [uncontrolledOpen, setUncontrolledOpen] = useState16(false);
10078
- const [dialogRoot, setDialogRoot] = useState16(null);
10349
+ const [uncontrolledOpen, setUncontrolledOpen] = useState17(false);
10350
+ const [dialogRoot, setDialogRoot] = useState17(null);
10079
10351
  const open = openProp ?? uncontrolledOpen;
10080
10352
  function setOpen(next) {
10081
10353
  onOpenChange?.(next);
@@ -10106,9 +10378,9 @@ function HelpPopover({
10106
10378
  (element) => setDialogRoot(element?.closest("dialog") ?? null)
10107
10379
  ]);
10108
10380
  const mergedPanelRef = useMergeRefs6([refs.setFloating, panelProps?.ref]);
10109
- return /* @__PURE__ */ jsxs33(Fragment9, {
10381
+ return /* @__PURE__ */ jsxs34(Fragment10, {
10110
10382
  children: [
10111
- /* @__PURE__ */ jsx49("button", {
10383
+ /* @__PURE__ */ jsx51("button", {
10112
10384
  ...getReferenceProps({
10113
10385
  ...triggerProps,
10114
10386
  "aria-label": triggerProps?.["aria-label"] ?? triggerLabel
@@ -10121,13 +10393,13 @@ function HelpPopover({
10121
10393
  "data-open": open,
10122
10394
  children: trigger
10123
10395
  }),
10124
- open && /* @__PURE__ */ jsx49(FloatingPortal2, {
10396
+ open && /* @__PURE__ */ jsx51(FloatingPortal2, {
10125
10397
  root: portalRoot ?? dialogRoot ?? undefined,
10126
- children: /* @__PURE__ */ jsx49(FloatingFocusManager, {
10398
+ children: /* @__PURE__ */ jsx51(FloatingFocusManager, {
10127
10399
  context,
10128
10400
  modal: false,
10129
10401
  initialFocus: -1,
10130
- children: /* @__PURE__ */ jsx49("section", {
10402
+ children: /* @__PURE__ */ jsx51("section", {
10131
10403
  ...getFloatingProps(panelProps ?? {}),
10132
10404
  ref: mergedPanelRef,
10133
10405
  className: classNames("altertable-help-popover", panelClassName, panelProps?.className),
@@ -10142,7 +10414,7 @@ function HelpPopover({
10142
10414
  }
10143
10415
 
10144
10416
  // src/react/ui/DateTimeTooltip.tsx
10145
- import { jsx as jsx50, jsxs as jsxs34 } from "react/jsx-runtime";
10417
+ import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
10146
10418
  function formattedDate(date, timeZone) {
10147
10419
  return new Intl.DateTimeFormat(undefined, {
10148
10420
  timeZone,
@@ -10164,7 +10436,7 @@ function DateTimeTooltip({
10164
10436
  panelClassName,
10165
10437
  ...props
10166
10438
  }) {
10167
- const [now, setNow] = useState17(Date.now);
10439
+ const [now, setNow] = useState18(Date.now);
10168
10440
  useEffect15(() => {
10169
10441
  const interval = window.setInterval(() => setNow(Date.now()), 30000);
10170
10442
  return () => window.clearInterval(interval);
@@ -10180,54 +10452,54 @@ function DateTimeTooltip({
10180
10452
  ...timeZone && timeZone !== browserTimeZone ? [{ label: `Browser · ${browserTimeZone}`, zone: browserTimeZone }] : []
10181
10453
  ];
10182
10454
  const timestamp = date.toISOString();
10183
- return /* @__PURE__ */ jsx50(HelpPopover, {
10455
+ return /* @__PURE__ */ jsx52(HelpPopover, {
10184
10456
  ...props,
10185
10457
  placement: props.placement ?? "bottom",
10186
10458
  triggerClassName,
10187
10459
  panelClassName: ["altertable-date-time-tooltip", panelClassName].filter(Boolean).join(" "),
10188
10460
  triggerLabel: "Show exact date and time",
10189
10461
  label: "Date and time details",
10190
- trigger: children ?? /* @__PURE__ */ jsx50("time", {
10462
+ trigger: children ?? /* @__PURE__ */ jsx52("time", {
10191
10463
  dateTime: timestamp,
10192
10464
  children: formattedDate(date, timeZone ?? browserTimeZone)
10193
10465
  }),
10194
- children: /* @__PURE__ */ jsxs34("div", {
10466
+ children: /* @__PURE__ */ jsxs35("div", {
10195
10467
  className: "altertable-date-time-rows",
10196
10468
  children: [
10197
- rows.map(({ label, zone }) => /* @__PURE__ */ jsxs34("span", {
10469
+ rows.map(({ label, zone }) => /* @__PURE__ */ jsxs35("span", {
10198
10470
  className: "altertable-date-time-row",
10199
10471
  children: [
10200
- /* @__PURE__ */ jsx50("span", {
10472
+ /* @__PURE__ */ jsx52("span", {
10201
10473
  className: "altertable-date-time-label",
10202
10474
  children: label
10203
10475
  }),
10204
- /* @__PURE__ */ jsx50("time", {
10476
+ /* @__PURE__ */ jsx52("time", {
10205
10477
  dateTime: timestamp,
10206
10478
  children: formattedDate(date, zone)
10207
10479
  })
10208
10480
  ]
10209
10481
  }, label)),
10210
- /* @__PURE__ */ jsxs34("span", {
10482
+ /* @__PURE__ */ jsxs35("span", {
10211
10483
  className: "altertable-date-time-row",
10212
10484
  children: [
10213
- /* @__PURE__ */ jsx50("span", {
10485
+ /* @__PURE__ */ jsx52("span", {
10214
10486
  className: "altertable-date-time-label",
10215
10487
  children: "Relative"
10216
10488
  }),
10217
- /* @__PURE__ */ jsx50("time", {
10489
+ /* @__PURE__ */ jsx52("time", {
10218
10490
  dateTime: timestamp,
10219
10491
  children: relativeDate(date, now)
10220
10492
  })
10221
10493
  ]
10222
10494
  }),
10223
- /* @__PURE__ */ jsxs34("span", {
10495
+ /* @__PURE__ */ jsxs35("span", {
10224
10496
  className: "altertable-date-time-row",
10225
10497
  children: [
10226
- /* @__PURE__ */ jsx50("span", {
10498
+ /* @__PURE__ */ jsx52("span", {
10227
10499
  className: "altertable-date-time-label",
10228
10500
  children: "Timestamp"
10229
10501
  }),
10230
- /* @__PURE__ */ jsx50("time", {
10502
+ /* @__PURE__ */ jsx52("time", {
10231
10503
  dateTime: timestamp,
10232
10504
  children: date.getTime()
10233
10505
  })
@@ -10239,16 +10511,16 @@ function DateTimeTooltip({
10239
10511
  }
10240
10512
 
10241
10513
  // src/react/ui/DataTable.tsx
10242
- import { jsx as jsx51, jsxs as jsxs35, Fragment as Fragment10 } from "react/jsx-runtime";
10514
+ import { jsx as jsx53, jsxs as jsxs36, Fragment as Fragment11 } from "react/jsx-runtime";
10243
10515
  function DataTable({
10244
10516
  className,
10245
10517
  ref,
10246
10518
  searchable,
10247
10519
  ...props
10248
10520
  }) {
10249
- return /* @__PURE__ */ jsxs35(Fragment10, {
10521
+ return /* @__PURE__ */ jsxs36(Fragment11, {
10250
10522
  children: [
10251
- searchable && (searchable.itemCount > 5 || searchable.value !== (searchable.resetValue ?? "")) && /* @__PURE__ */ jsx51(SearchField, {
10523
+ searchable && (searchable.itemCount > 5 || searchable.value !== (searchable.resetValue ?? "")) && /* @__PURE__ */ jsx53(SearchField, {
10252
10524
  label: searchable.label,
10253
10525
  placeholder: searchable.placeholder,
10254
10526
  value: searchable.value,
@@ -10257,9 +10529,9 @@ function DataTable({
10257
10529
  size: "compact",
10258
10530
  className: "altertable-data-table-search"
10259
10531
  }),
10260
- /* @__PURE__ */ jsx51("div", {
10532
+ /* @__PURE__ */ jsx53("div", {
10261
10533
  className: "altertable-data-table-scroll",
10262
- children: /* @__PURE__ */ jsx51("table", {
10534
+ children: /* @__PURE__ */ jsx53("table", {
10263
10535
  ...props,
10264
10536
  ref,
10265
10537
  className: classNames("altertable-data-table", className)
@@ -10275,7 +10547,7 @@ function DataTableShare({ value }) {
10275
10547
  minimumFractionDigits: 1,
10276
10548
  maximumFractionDigits: 1
10277
10549
  }).format(ratio);
10278
- return /* @__PURE__ */ jsx51("span", {
10550
+ return /* @__PURE__ */ jsx53("span", {
10279
10551
  className: "altertable-data-table-share",
10280
10552
  children: label
10281
10553
  });
@@ -10285,11 +10557,11 @@ function DataTableEmptyRow({
10285
10557
  title,
10286
10558
  description
10287
10559
  }) {
10288
- return /* @__PURE__ */ jsx51("tr", {
10560
+ return /* @__PURE__ */ jsx53("tr", {
10289
10561
  className: "altertable-data-table-empty-row",
10290
- children: /* @__PURE__ */ jsx51("td", {
10562
+ children: /* @__PURE__ */ jsx53("td", {
10291
10563
  colSpan,
10292
- children: /* @__PURE__ */ jsx51(EmptyState, {
10564
+ children: /* @__PURE__ */ jsx53(EmptyState, {
10293
10565
  title,
10294
10566
  description,
10295
10567
  variant: "table"
@@ -10304,15 +10576,15 @@ function DataTableTimestamp({
10304
10576
  }) {
10305
10577
  const date = value instanceof Date ? value : new Date(value);
10306
10578
  if (Number.isNaN(date.getTime()))
10307
- return /* @__PURE__ */ jsx51(Fragment10, {
10579
+ return /* @__PURE__ */ jsx53(Fragment11, {
10308
10580
  children: children ?? value.toString()
10309
10581
  });
10310
10582
  const timestamp = date.toISOString();
10311
- return /* @__PURE__ */ jsx51(DateTimeTooltip, {
10583
+ return /* @__PURE__ */ jsx53(DateTimeTooltip, {
10312
10584
  date,
10313
10585
  timeZone,
10314
10586
  triggerClassName: "altertable-data-table-timestamp",
10315
- children: /* @__PURE__ */ jsx51("time", {
10587
+ children: /* @__PURE__ */ jsx53("time", {
10316
10588
  dateTime: timestamp,
10317
10589
  children: children ?? timestamp
10318
10590
  })
@@ -10320,7 +10592,7 @@ function DataTableTimestamp({
10320
10592
  }
10321
10593
 
10322
10594
  // src/react/ui/TableWidget.tsx
10323
- import { jsx as jsx52, jsxs as jsxs36, Fragment as Fragment11 } from "react/jsx-runtime";
10595
+ import { jsx as jsx54, jsxs as jsxs37, Fragment as Fragment12 } from "react/jsx-runtime";
10324
10596
  function TableWidget(props) {
10325
10597
  const { pagination, limit, columns } = props;
10326
10598
  invariant(!pagination || Number.isSafeInteger(pagination.pageSize) && pagination.pageSize >= 1, "TableWidget pagination.pageSize must be a positive integer.");
@@ -10330,17 +10602,17 @@ function TableWidget(props) {
10330
10602
  if (props.reading) {
10331
10603
  const { reading, skeletonRows = 5, ...rest } = props;
10332
10604
  if (reading.loading)
10333
- return /* @__PURE__ */ jsx52(ContentSkeleton, {
10605
+ return /* @__PURE__ */ jsx54(ContentSkeleton, {
10334
10606
  variant: "ranking",
10335
10607
  rows: skeletonRows,
10336
10608
  className: rest.className
10337
10609
  });
10338
- return /* @__PURE__ */ jsx52(TableWidgetContent, {
10610
+ return /* @__PURE__ */ jsx54(TableWidgetContent, {
10339
10611
  ...rest,
10340
10612
  rows: reading.value
10341
10613
  });
10342
10614
  }
10343
- return /* @__PURE__ */ jsx52(TableWidgetContent, {
10615
+ return /* @__PURE__ */ jsx54(TableWidgetContent, {
10344
10616
  ...props
10345
10617
  });
10346
10618
  }
@@ -10364,7 +10636,7 @@ function TableWidgetContent({
10364
10636
  invariant(keys.every((key) => typeof key === "string" ? !!key.trim() : Number.isFinite(key)) && new Set(keys.map(String)).size === keys.length, "TableWidget row keys must be nonempty and unique.");
10365
10637
  const rowKeys = JSON.stringify(keys);
10366
10638
  const pageSize = pagination === false || limit !== undefined ? null : pagination?.pageSize ?? 10;
10367
- const [pageState, setPageState] = useState18({
10639
+ const [pageState, setPageState] = useState19({
10368
10640
  page: 0,
10369
10641
  rowKeys,
10370
10642
  searchValue: search?.value,
@@ -10390,29 +10662,29 @@ function TableWidgetContent({
10390
10662
  resetValue: search.resetValue,
10391
10663
  itemCount: rows.length
10392
10664
  };
10393
- const table = /* @__PURE__ */ jsx52(Fragment11, {
10394
- children: /* @__PURE__ */ jsxs36(DataTable, {
10665
+ const table = /* @__PURE__ */ jsx54(Fragment12, {
10666
+ children: /* @__PURE__ */ jsxs37(DataTable, {
10395
10667
  searchable,
10396
10668
  children: [
10397
- /* @__PURE__ */ jsx52("thead", {
10398
- children: /* @__PURE__ */ jsx52("tr", {
10399
- children: columns.map((column) => /* @__PURE__ */ jsx52("th", {
10669
+ /* @__PURE__ */ jsx54("thead", {
10670
+ children: /* @__PURE__ */ jsx54("tr", {
10671
+ children: columns.map((column) => /* @__PURE__ */ jsx54("th", {
10400
10672
  scope: "col",
10401
10673
  "data-type": column.type,
10402
10674
  children: column.header
10403
10675
  }, column.id))
10404
10676
  })
10405
10677
  }),
10406
- /* @__PURE__ */ jsx52("tbody", {
10407
- children: visible.length === 0 ? /* @__PURE__ */ jsx52(DataTableEmptyRow, {
10678
+ /* @__PURE__ */ jsx54("tbody", {
10679
+ children: visible.length === 0 ? /* @__PURE__ */ jsx54(DataTableEmptyRow, {
10408
10680
  colSpan: columns.length,
10409
10681
  ...empty
10410
- }) : visible.map((hit) => /* @__PURE__ */ jsx52("tr", {
10411
- children: columns.map((column, index) => index === 0 ? /* @__PURE__ */ jsx52("th", {
10682
+ }) : visible.map((hit) => /* @__PURE__ */ jsx54("tr", {
10683
+ children: columns.map((column, index) => index === 0 ? /* @__PURE__ */ jsx54("th", {
10412
10684
  scope: "row",
10413
10685
  "data-type": column.type,
10414
10686
  children: column.cell(hit.item, hit)
10415
- }, column.id) : /* @__PURE__ */ jsx52("td", {
10687
+ }, column.id) : /* @__PURE__ */ jsx54("td", {
10416
10688
  "data-type": column.type,
10417
10689
  children: column.cell(hit.item, hit)
10418
10690
  }, column.id))
@@ -10421,11 +10693,11 @@ function TableWidgetContent({
10421
10693
  ]
10422
10694
  })
10423
10695
  });
10424
- const pager = pageSize && pageCount > 1 && /* @__PURE__ */ jsxs36("nav", {
10696
+ const pager = pageSize && pageCount > 1 && /* @__PURE__ */ jsxs37("nav", {
10425
10697
  className: "altertable-table-pagination",
10426
10698
  "aria-label": "Table pages",
10427
10699
  children: [
10428
- /* @__PURE__ */ jsxs36("span", {
10700
+ /* @__PURE__ */ jsxs37("span", {
10429
10701
  className: "altertable-table-pagination-range",
10430
10702
  children: [
10431
10703
  formatCount2(start + 1),
@@ -10438,10 +10710,10 @@ function TableWidgetContent({
10438
10710
  pluralize2(hits.length, "result")
10439
10711
  ]
10440
10712
  }),
10441
- /* @__PURE__ */ jsxs36("span", {
10713
+ /* @__PURE__ */ jsxs37("span", {
10442
10714
  className: "altertable-table-pagination-controls",
10443
10715
  children: [
10444
- /* @__PURE__ */ jsxs36("span", {
10716
+ /* @__PURE__ */ jsxs37("span", {
10445
10717
  children: [
10446
10718
  "Page ",
10447
10719
  page + 1,
@@ -10449,9 +10721,9 @@ function TableWidgetContent({
10449
10721
  pageCount
10450
10722
  ]
10451
10723
  }),
10452
- /* @__PURE__ */ jsx52(Tooltip, {
10724
+ /* @__PURE__ */ jsx54(Tooltip, {
10453
10725
  content: "Previous page",
10454
- children: /* @__PURE__ */ jsx52(Button, {
10726
+ children: /* @__PURE__ */ jsx54(Button, {
10455
10727
  size: "icon-compact",
10456
10728
  "aria-label": "Previous page",
10457
10729
  disabled: page === 0,
@@ -10461,15 +10733,15 @@ function TableWidgetContent({
10461
10733
  searchValue: search?.value,
10462
10734
  pageSize
10463
10735
  }),
10464
- children: /* @__PURE__ */ jsx52(AppIcon, {
10736
+ children: /* @__PURE__ */ jsx54(AppIcon, {
10465
10737
  name: "previousMonth",
10466
10738
  size: 16
10467
10739
  })
10468
10740
  })
10469
10741
  }),
10470
- /* @__PURE__ */ jsx52(Tooltip, {
10742
+ /* @__PURE__ */ jsx54(Tooltip, {
10471
10743
  content: "Next page",
10472
- children: /* @__PURE__ */ jsx52(Button, {
10744
+ children: /* @__PURE__ */ jsx54(Button, {
10473
10745
  size: "icon-compact",
10474
10746
  "aria-label": "Next page",
10475
10747
  disabled: page >= pageCount - 1,
@@ -10479,7 +10751,7 @@ function TableWidgetContent({
10479
10751
  searchValue: search?.value,
10480
10752
  pageSize
10481
10753
  }),
10482
- children: /* @__PURE__ */ jsx52(AppIcon, {
10754
+ children: /* @__PURE__ */ jsx54(AppIcon, {
10483
10755
  name: "nextMonth",
10484
10756
  size: 16
10485
10757
  })
@@ -10489,20 +10761,20 @@ function TableWidgetContent({
10489
10761
  })
10490
10762
  ]
10491
10763
  });
10492
- return /* @__PURE__ */ jsx52(DataWidget, {
10764
+ return /* @__PURE__ */ jsx54(DataWidget, {
10493
10765
  ...props,
10494
10766
  title,
10495
10767
  count,
10496
10768
  description,
10497
10769
  action,
10498
10770
  evidence,
10499
- footer: (pager || insight) && /* @__PURE__ */ jsxs36(Fragment11, {
10771
+ footer: (pager || insight) && /* @__PURE__ */ jsxs37(Fragment12, {
10500
10772
  children: [
10501
10773
  pager,
10502
10774
  insight
10503
10775
  ]
10504
10776
  }),
10505
- children: /* @__PURE__ */ jsx52("div", {
10777
+ children: /* @__PURE__ */ jsx54("div", {
10506
10778
  className: "altertable-table-widget-content",
10507
10779
  children: table
10508
10780
  })
@@ -10516,7 +10788,7 @@ function chartColor(id) {
10516
10788
  return `var(--at-chart-${(hash >>> 0) % 8 + 1}, var(--at-accent, #4779dc))`;
10517
10789
  }
10518
10790
  // src/react/ui/Breakdown.tsx
10519
- import { jsx as jsx53, jsxs as jsxs37 } from "react/jsx-runtime";
10791
+ import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
10520
10792
  function Breakdown({
10521
10793
  total,
10522
10794
  items,
@@ -10526,18 +10798,18 @@ function Breakdown({
10526
10798
  }) {
10527
10799
  invariant(Number.isFinite(total) && total >= 0 && items.every((item) => Number.isFinite(item.value) && item.value >= 0) && items.reduce((sum, item) => sum + item.value, 0) <= total, "Breakdown items must be nonnegative parts of the observed total.");
10528
10800
  const dominant = total > 0 && items.some((item) => item.value / total >= 0.85);
10529
- return /* @__PURE__ */ jsxs37("div", {
10801
+ return /* @__PURE__ */ jsxs38("div", {
10530
10802
  ...props,
10531
10803
  className: classNames("altertable-breakdown", className),
10532
10804
  "data-dominant": dominant || undefined,
10533
10805
  children: [
10534
- /* @__PURE__ */ jsxs37("div", {
10806
+ /* @__PURE__ */ jsxs38("div", {
10535
10807
  className: "altertable-breakdown-summary",
10536
10808
  children: [
10537
- /* @__PURE__ */ jsx53("span", {
10809
+ /* @__PURE__ */ jsx55("span", {
10538
10810
  children: "Share of total"
10539
10811
  }),
10540
- /* @__PURE__ */ jsxs37("strong", {
10812
+ /* @__PURE__ */ jsxs38("strong", {
10541
10813
  children: [
10542
10814
  formatValue(total),
10543
10815
  " total"
@@ -10545,42 +10817,42 @@ function Breakdown({
10545
10817
  })
10546
10818
  ]
10547
10819
  }),
10548
- /* @__PURE__ */ jsx53("div", {
10820
+ /* @__PURE__ */ jsx55("div", {
10549
10821
  className: "altertable-breakdown-bar",
10550
10822
  "aria-hidden": "true",
10551
- children: items.map((item) => /* @__PURE__ */ jsx53("span", {
10823
+ children: items.map((item) => /* @__PURE__ */ jsx55("span", {
10552
10824
  style: {
10553
10825
  width: `${total ? item.value / total * 100 : 0}%`,
10554
10826
  backgroundColor: chartColor(item.id)
10555
10827
  }
10556
10828
  }, item.id))
10557
10829
  }),
10558
- /* @__PURE__ */ jsx53("dl", {
10830
+ /* @__PURE__ */ jsx55("dl", {
10559
10831
  className: "altertable-breakdown-list",
10560
10832
  children: items.map((item) => {
10561
10833
  const share = total ? item.value / total : 0;
10562
10834
  const color = {
10563
10835
  "--altertable-breakdown-color": chartColor(item.id)
10564
10836
  };
10565
- return /* @__PURE__ */ jsxs37("div", {
10837
+ return /* @__PURE__ */ jsxs38("div", {
10566
10838
  className: "altertable-breakdown-row",
10567
10839
  "data-empty": item.value === 0 || undefined,
10568
10840
  style: color,
10569
10841
  children: [
10570
- /* @__PURE__ */ jsxs37("dt", {
10842
+ /* @__PURE__ */ jsxs38("dt", {
10571
10843
  children: [
10572
- /* @__PURE__ */ jsx53("span", {
10844
+ /* @__PURE__ */ jsx55("span", {
10573
10845
  className: "altertable-breakdown-swatch",
10574
10846
  "aria-hidden": "true"
10575
10847
  }),
10576
10848
  item.label
10577
10849
  ]
10578
10850
  }),
10579
- /* @__PURE__ */ jsx53("dd", {
10851
+ /* @__PURE__ */ jsx55("dd", {
10580
10852
  className: "altertable-breakdown-value",
10581
10853
  children: formatValue(item.value)
10582
10854
  }),
10583
- /* @__PURE__ */ jsx53("dd", {
10855
+ /* @__PURE__ */ jsx55("dd", {
10584
10856
  className: "altertable-breakdown-share",
10585
10857
  children: formatPercent2(share)
10586
10858
  })
@@ -10592,7 +10864,7 @@ function Breakdown({
10592
10864
  });
10593
10865
  }
10594
10866
  // src/react/ui/Ranking.tsx
10595
- import { jsx as jsx54, jsxs as jsxs38 } from "react/jsx-runtime";
10867
+ import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
10596
10868
  function Ranking({
10597
10869
  items,
10598
10870
  formatValue = formatCount2,
@@ -10601,30 +10873,30 @@ function Ranking({
10601
10873
  }) {
10602
10874
  invariant(items.every((item) => Number.isFinite(item.value) && item.value >= 0), "Ranking values must be finite and nonnegative.");
10603
10875
  const max = Math.max(0, ...items.map((item) => item.value));
10604
- return /* @__PURE__ */ jsx54("ol", {
10876
+ return /* @__PURE__ */ jsx56("ol", {
10605
10877
  ...props,
10606
10878
  className: classNames("altertable-ranking", className),
10607
- children: items.map((item) => /* @__PURE__ */ jsxs38("li", {
10879
+ children: items.map((item) => /* @__PURE__ */ jsxs39("li", {
10608
10880
  children: [
10609
- /* @__PURE__ */ jsxs38("div", {
10881
+ /* @__PURE__ */ jsxs39("div", {
10610
10882
  className: "altertable-ranking-reading",
10611
10883
  children: [
10612
- /* @__PURE__ */ jsx54("span", {
10884
+ /* @__PURE__ */ jsx56("span", {
10613
10885
  children: item.label
10614
10886
  }),
10615
- /* @__PURE__ */ jsx54("strong", {
10887
+ /* @__PURE__ */ jsx56("strong", {
10616
10888
  children: formatValue(item.value)
10617
10889
  })
10618
10890
  ]
10619
10891
  }),
10620
- /* @__PURE__ */ jsx54("div", {
10892
+ /* @__PURE__ */ jsx56("div", {
10621
10893
  className: "altertable-ranking-track",
10622
10894
  "aria-hidden": "true",
10623
- children: /* @__PURE__ */ jsx54("span", {
10895
+ children: /* @__PURE__ */ jsx56("span", {
10624
10896
  style: { width: `${max ? item.value / max * 100 : 0}%` }
10625
10897
  })
10626
10898
  }),
10627
- item.detail != null && /* @__PURE__ */ jsx54("div", {
10899
+ item.detail != null && /* @__PURE__ */ jsx56("div", {
10628
10900
  className: "altertable-ranking-detail",
10629
10901
  children: item.detail
10630
10902
  })
@@ -10633,27 +10905,27 @@ function Ranking({
10633
10905
  });
10634
10906
  }
10635
10907
  // src/react/ui/WidgetDisclosure.tsx
10636
- import { jsx as jsx55, jsxs as jsxs39 } from "react/jsx-runtime";
10908
+ import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
10637
10909
  function WidgetDisclosure({
10638
10910
  label,
10639
10911
  children,
10640
10912
  className,
10641
10913
  ...props
10642
10914
  }) {
10643
- return /* @__PURE__ */ jsxs39("details", {
10915
+ return /* @__PURE__ */ jsxs40("details", {
10644
10916
  ...props,
10645
10917
  className: classNames("altertable-widget-disclosure", className),
10646
10918
  children: [
10647
- /* @__PURE__ */ jsxs39("summary", {
10919
+ /* @__PURE__ */ jsxs40("summary", {
10648
10920
  children: [
10649
10921
  label,
10650
- /* @__PURE__ */ jsx55(AppIcon, {
10922
+ /* @__PURE__ */ jsx57(AppIcon, {
10651
10923
  name: "disclosure",
10652
10924
  size: 16
10653
10925
  })
10654
10926
  ]
10655
10927
  }),
10656
- /* @__PURE__ */ jsx55("div", {
10928
+ /* @__PURE__ */ jsx57("div", {
10657
10929
  className: "altertable-widget-disclosure-content",
10658
10930
  children
10659
10931
  })
@@ -10703,23 +10975,23 @@ function metricComparison(metric, reading) {
10703
10975
  }
10704
10976
 
10705
10977
  // src/react/ui/ComparisonVisual.tsx
10706
- import { jsx as jsx56, jsxs as jsxs40, Fragment as Fragment12 } from "react/jsx-runtime";
10978
+ import { jsx as jsx58, jsxs as jsxs41, Fragment as Fragment13 } from "react/jsx-runtime";
10707
10979
  function ComparisonVisual(props) {
10708
10980
  if ("metric" in props) {
10709
10981
  if (props.reading.loading)
10710
- return /* @__PURE__ */ jsx56(ContentSkeleton, {
10982
+ return /* @__PURE__ */ jsx58(ContentSkeleton, {
10711
10983
  variant: "panel"
10712
10984
  });
10713
10985
  const comparison = metricComparison(props.metric, props.reading);
10714
10986
  if (!comparison)
10715
10987
  return null;
10716
- return /* @__PURE__ */ jsx56(ComparisonContent, {
10988
+ return /* @__PURE__ */ jsx58(ComparisonContent, {
10717
10989
  ...comparison,
10718
10990
  label: props.metric.label,
10719
10991
  emphasis: props.emphasis
10720
10992
  });
10721
10993
  }
10722
- return /* @__PURE__ */ jsx56(ComparisonContent, {
10994
+ return /* @__PURE__ */ jsx58(ComparisonContent, {
10723
10995
  ...props
10724
10996
  });
10725
10997
  }
@@ -10736,64 +11008,64 @@ function ComparisonContent({
10736
11008
  previous,
10737
11009
  favorableDirection
10738
11010
  });
10739
- return /* @__PURE__ */ jsxs40("figure", {
11011
+ return /* @__PURE__ */ jsxs41("figure", {
10740
11012
  className: "altertable-comparison-visual",
10741
11013
  "data-emphasis": emphasis,
10742
11014
  "aria-label": `${label} comparison`,
10743
11015
  children: [
10744
- /* @__PURE__ */ jsx56("figcaption", {
11016
+ /* @__PURE__ */ jsx58("figcaption", {
10745
11017
  children: label
10746
11018
  }),
10747
- /* @__PURE__ */ jsxs40("div", {
11019
+ /* @__PURE__ */ jsxs41("div", {
10748
11020
  className: "altertable-comparison-row",
10749
11021
  "data-period": "current",
10750
11022
  children: [
10751
- /* @__PURE__ */ jsxs40("div", {
11023
+ /* @__PURE__ */ jsxs41("div", {
10752
11024
  children: [
10753
- /* @__PURE__ */ jsx56("span", {
11025
+ /* @__PURE__ */ jsx58("span", {
10754
11026
  children: current.periodLabel ?? "Current period"
10755
11027
  }),
10756
- /* @__PURE__ */ jsx56("strong", {
11028
+ /* @__PURE__ */ jsx58("strong", {
10757
11029
  children: current.formattedValue
10758
11030
  })
10759
11031
  ]
10760
11032
  }),
10761
- /* @__PURE__ */ jsx56("span", {
11033
+ /* @__PURE__ */ jsx58("span", {
10762
11034
  className: "altertable-comparison-track",
10763
- children: /* @__PURE__ */ jsx56("span", {
11035
+ children: /* @__PURE__ */ jsx58("span", {
10764
11036
  style: { width: `${current.value / max * 100}%` }
10765
11037
  })
10766
11038
  })
10767
11039
  ]
10768
11040
  }),
10769
- previous && /* @__PURE__ */ jsxs40("div", {
11041
+ previous && /* @__PURE__ */ jsxs41("div", {
10770
11042
  className: "altertable-comparison-row",
10771
11043
  "data-period": "previous",
10772
11044
  children: [
10773
- /* @__PURE__ */ jsxs40("div", {
11045
+ /* @__PURE__ */ jsxs41("div", {
10774
11046
  children: [
10775
- /* @__PURE__ */ jsx56("span", {
11047
+ /* @__PURE__ */ jsx58("span", {
10776
11048
  children: previous.periodLabel ?? "Previous period"
10777
11049
  }),
10778
- /* @__PURE__ */ jsx56("strong", {
11050
+ /* @__PURE__ */ jsx58("strong", {
10779
11051
  children: previous.formattedValue
10780
11052
  })
10781
11053
  ]
10782
11054
  }),
10783
- /* @__PURE__ */ jsx56("span", {
11055
+ /* @__PURE__ */ jsx58("span", {
10784
11056
  className: "altertable-comparison-track",
10785
- children: /* @__PURE__ */ jsx56("span", {
11057
+ children: /* @__PURE__ */ jsx58("span", {
10786
11058
  style: { width: `${(previous.value ?? 0) / max * 100}%` }
10787
11059
  })
10788
11060
  })
10789
11061
  ]
10790
11062
  }),
10791
- /* @__PURE__ */ jsx56("p", {
11063
+ /* @__PURE__ */ jsx58("p", {
10792
11064
  className: "altertable-comparison-change",
10793
11065
  "data-tone": tone,
10794
- children: percent === null ? "No comparable previous value" : /* @__PURE__ */ jsxs40(Fragment12, {
11066
+ children: percent === null ? "No comparable previous value" : /* @__PURE__ */ jsxs41(Fragment13, {
10795
11067
  children: [
10796
- /* @__PURE__ */ jsx56(AppIcon, {
11068
+ /* @__PURE__ */ jsx58(AppIcon, {
10797
11069
  name: icon,
10798
11070
  size: 17
10799
11071
  }),
@@ -10808,17 +11080,17 @@ function ComparisonContent({
10808
11080
  });
10809
11081
  }
10810
11082
  // src/react/ui/MetricWidget.tsx
10811
- import { jsx as jsx57, jsxs as jsxs41 } from "react/jsx-runtime";
11083
+ import { jsx as jsx59, jsxs as jsxs42 } from "react/jsx-runtime";
10812
11084
  function MetricWidget(props) {
10813
11085
  if ("metric" in props) {
10814
11086
  const { metric, reading, ...rest } = props;
10815
11087
  if (reading.loading)
10816
- return /* @__PURE__ */ jsx57(MetricWidgetContent, {
11088
+ return /* @__PURE__ */ jsx59(MetricWidgetContent, {
10817
11089
  ...rest,
10818
11090
  label: metric.label,
10819
11091
  loading: true
10820
11092
  });
10821
- return /* @__PURE__ */ jsx57(MetricWidgetContent, {
11093
+ return /* @__PURE__ */ jsx59(MetricWidgetContent, {
10822
11094
  ...rest,
10823
11095
  label: metric.label,
10824
11096
  value: reading.value.current,
@@ -10827,7 +11099,7 @@ function MetricWidget(props) {
10827
11099
  comparison: metricComparison(metric, reading)
10828
11100
  });
10829
11101
  }
10830
- return /* @__PURE__ */ jsx57(MetricWidgetContent, {
11102
+ return /* @__PURE__ */ jsx59(MetricWidgetContent, {
10831
11103
  ...props
10832
11104
  });
10833
11105
  }
@@ -10848,17 +11120,17 @@ function MetricWidgetContent({
10848
11120
  ...props
10849
11121
  }) {
10850
11122
  if (loading)
10851
- return /* @__PURE__ */ jsx57(ContentSkeleton, {
11123
+ return /* @__PURE__ */ jsx59(ContentSkeleton, {
10852
11124
  variant: "metric",
10853
11125
  className
10854
11126
  });
10855
11127
  const shownValue = format ? formatMetric2(value, format) : content;
10856
11128
  const change = comparison ? comparisonChange(comparison) : null;
10857
- const shownTrend = change?.percent != null ? /* @__PURE__ */ jsxs41("span", {
11129
+ const shownTrend = change?.percent != null ? /* @__PURE__ */ jsxs42("span", {
10858
11130
  className: "altertable-metric-change",
10859
11131
  "data-tone": change.tone,
10860
11132
  children: [
10861
- /* @__PURE__ */ jsx57(AppIcon, {
11133
+ /* @__PURE__ */ jsx59(AppIcon, {
10862
11134
  name: change.icon,
10863
11135
  size: 14
10864
11136
  }),
@@ -10867,33 +11139,33 @@ function MetricWidgetContent({
10867
11139
  " ",
10868
11140
  comparison?.previous?.periodLabel?.toLowerCase() ?? "previous period"
10869
11141
  ]
10870
- }) : comparison?.previous?.value === null ? /* @__PURE__ */ jsx57("span", {
11142
+ }) : comparison?.previous?.value === null ? /* @__PURE__ */ jsx59("span", {
10871
11143
  className: "altertable-metric-change",
10872
11144
  "data-tone": "neutral",
10873
11145
  children: "Previous period unavailable"
10874
11146
  }) : null;
10875
- const reading = /* @__PURE__ */ jsxs41("div", {
11147
+ const reading = /* @__PURE__ */ jsxs42("div", {
10876
11148
  className: "altertable-metric-reading",
10877
11149
  children: [
10878
- /* @__PURE__ */ jsx57("strong", {
11150
+ /* @__PURE__ */ jsx59("strong", {
10879
11151
  className: "altertable-metric-value",
10880
11152
  "data-unavailable": shownValue === "—" || undefined,
10881
11153
  children: shownValue
10882
11154
  }),
10883
- shownTrend && /* @__PURE__ */ jsx57("span", {
11155
+ shownTrend && /* @__PURE__ */ jsx59("span", {
10884
11156
  className: "altertable-metric-trend",
10885
11157
  children: shownTrend
10886
11158
  })
10887
11159
  ]
10888
11160
  });
10889
- const visualization = visual && /* @__PURE__ */ jsx57("div", {
11161
+ const visualization = visual && /* @__PURE__ */ jsx59("div", {
10890
11162
  className: "altertable-metric-visual",
10891
11163
  children: visual
10892
11164
  });
10893
- const feedback = /* @__PURE__ */ jsx57(WidgetStatusControl, {
11165
+ const feedback = /* @__PURE__ */ jsx59(WidgetStatusControl, {
10894
11166
  status
10895
11167
  });
10896
- const help = evidence ? /* @__PURE__ */ jsxs41(AboutData, {
11168
+ const help = evidence ? /* @__PURE__ */ jsxs42(AboutData, {
10897
11169
  "aria-label": `Explore ${label}`,
10898
11170
  variant: "ghost",
10899
11171
  className: "altertable-widget-heading-trigger",
@@ -10908,7 +11180,7 @@ function MetricWidgetContent({
10908
11180
  title: label,
10909
11181
  headerActions: feedback,
10910
11182
  description,
10911
- visual: /* @__PURE__ */ jsxs41("div", {
11183
+ visual: /* @__PURE__ */ jsxs42("div", {
10912
11184
  className: "altertable-metric-evidence",
10913
11185
  children: [
10914
11186
  reading,
@@ -10918,22 +11190,22 @@ function MetricWidgetContent({
10918
11190
  visualKind: "metric",
10919
11191
  children: [
10920
11192
  label,
10921
- /* @__PURE__ */ jsx57(AppIcon, {
11193
+ /* @__PURE__ */ jsx59(AppIcon, {
10922
11194
  name: "openDetails"
10923
11195
  })
10924
11196
  ]
10925
11197
  }) : null;
10926
- return /* @__PURE__ */ jsxs41("div", {
11198
+ return /* @__PURE__ */ jsxs42("div", {
10927
11199
  ...props,
10928
11200
  className: classNames("altertable-metric-widget", className),
10929
11201
  children: [
10930
- /* @__PURE__ */ jsxs41("div", {
11202
+ /* @__PURE__ */ jsxs42("div", {
10931
11203
  className: "altertable-metric-label",
10932
11204
  children: [
10933
- /* @__PURE__ */ jsx57("span", {
11205
+ /* @__PURE__ */ jsx59("span", {
10934
11206
  children: help ?? label
10935
11207
  }),
10936
- /* @__PURE__ */ jsxs41("div", {
11208
+ /* @__PURE__ */ jsxs42("div", {
10937
11209
  className: "altertable-metric-help",
10938
11210
  children: [
10939
11211
  feedback,
@@ -10943,12 +11215,12 @@ function MetricWidgetContent({
10943
11215
  ]
10944
11216
  }),
10945
11217
  reading,
10946
- description && /* @__PURE__ */ jsx57("small", {
11218
+ description && /* @__PURE__ */ jsx59("small", {
10947
11219
  className: "altertable-metric-description",
10948
11220
  children: description
10949
11221
  }),
10950
11222
  visualization,
10951
- insight && /* @__PURE__ */ jsx57("div", {
11223
+ insight && /* @__PURE__ */ jsx59("div", {
10952
11224
  className: "altertable-metric-insight",
10953
11225
  children: insight
10954
11226
  })
@@ -10956,8 +11228,8 @@ function MetricWidgetContent({
10956
11228
  });
10957
11229
  }
10958
11230
  // src/react/ui/SelectableBarChart.tsx
10959
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef7, useState as useState19 } from "react";
10960
- import { jsx as jsx58, jsxs as jsxs42 } from "react/jsx-runtime";
11231
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef7, useState as useState20 } from "react";
11232
+ import { jsx as jsx60, jsxs as jsxs43 } from "react/jsx-runtime";
10961
11233
  function SelectableBarChart({
10962
11234
  items,
10963
11235
  selectedId,
@@ -10966,7 +11238,7 @@ function SelectableBarChart({
10966
11238
  ariaLabel,
10967
11239
  formatValue = (value) => new Intl.NumberFormat().format(value)
10968
11240
  }) {
10969
- const [previewId, setPreviewId] = useState19(null);
11241
+ const [previewId, setPreviewId] = useState20(null);
10970
11242
  const scrollport = useRef7(null);
10971
11243
  const buttons = useRef7([]);
10972
11244
  useLayoutEffect2(() => {
@@ -10988,20 +11260,20 @@ function SelectableBarChart({
10988
11260
  const next = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : Math.max(0, Math.min(items.length - 1, index + (event.key === "ArrowRight" ? 1 : -1)));
10989
11261
  buttons.current[next]?.focus();
10990
11262
  }
10991
- return /* @__PURE__ */ jsxs42("div", {
11263
+ return /* @__PURE__ */ jsxs43("div", {
10992
11264
  className: "altertable-selectable-bars",
10993
11265
  children: [
10994
- /* @__PURE__ */ jsxs42("div", {
11266
+ /* @__PURE__ */ jsxs43("div", {
10995
11267
  className: "altertable-selectable-bars-preview",
10996
11268
  "aria-live": "polite",
10997
11269
  children: [
10998
- preview ? /* @__PURE__ */ jsxs42("span", {
11270
+ preview ? /* @__PURE__ */ jsxs43("span", {
10999
11271
  children: [
11000
- /* @__PURE__ */ jsx58("small", {
11272
+ /* @__PURE__ */ jsx60("small", {
11001
11273
  children: previewId && previewId !== selectedId ? "Preview" : selected ? "Selected" : "Latest"
11002
11274
  }),
11003
11275
  " ",
11004
- /* @__PURE__ */ jsx58("strong", {
11276
+ /* @__PURE__ */ jsx60("strong", {
11005
11277
  children: preview.label
11006
11278
  }),
11007
11279
  " · ",
@@ -11009,21 +11281,21 @@ function SelectableBarChart({
11009
11281
  " ",
11010
11282
  unit
11011
11283
  ]
11012
- }) : /* @__PURE__ */ jsx58("span", {
11284
+ }) : /* @__PURE__ */ jsx60("span", {
11013
11285
  children: "No data"
11014
11286
  }),
11015
- selected && /* @__PURE__ */ jsx58("button", {
11287
+ selected && /* @__PURE__ */ jsx60("button", {
11016
11288
  type: "button",
11017
11289
  onClick: () => onSelectionChange(null),
11018
11290
  children: "Clear selection"
11019
11291
  })
11020
11292
  ]
11021
11293
  }),
11022
- /* @__PURE__ */ jsx58("div", {
11294
+ /* @__PURE__ */ jsx60("div", {
11023
11295
  className: "altertable-selectable-bars-scroll",
11024
11296
  ref: scrollport,
11025
11297
  "aria-label": ariaLabel,
11026
- children: items.map((item, index) => /* @__PURE__ */ jsxs42("button", {
11298
+ children: items.map((item, index) => /* @__PURE__ */ jsxs43("button", {
11027
11299
  ref: (node) => {
11028
11300
  buttons.current[index] = node;
11029
11301
  },
@@ -11038,23 +11310,23 @@ function SelectableBarChart({
11038
11310
  onBlur: () => setPreviewId(null),
11039
11311
  onKeyDown: (event) => onKeyDown(event, index),
11040
11312
  children: [
11041
- /* @__PURE__ */ jsx58("span", {
11313
+ /* @__PURE__ */ jsx60("span", {
11042
11314
  className: "altertable-selectable-bars-area",
11043
- children: /* @__PURE__ */ jsx58("span", {
11315
+ children: /* @__PURE__ */ jsx60("span", {
11044
11316
  className: "altertable-selectable-bars-bar",
11045
11317
  style: {
11046
11318
  height: `${Math.max(item.value > 0 ? 3 : 0, item.value / maximum * 100)}%`
11047
11319
  }
11048
11320
  })
11049
11321
  }),
11050
- /* @__PURE__ */ jsx58("span", {
11322
+ /* @__PURE__ */ jsx60("span", {
11051
11323
  className: "altertable-selectable-bars-label",
11052
11324
  children: item.label
11053
11325
  })
11054
11326
  ]
11055
11327
  }, item.id))
11056
11328
  }),
11057
- items.length > 0 && /* @__PURE__ */ jsx58("p", {
11329
+ items.length > 0 && /* @__PURE__ */ jsx60("p", {
11058
11330
  className: "altertable-selectable-bars-help",
11059
11331
  children: "Select a bar to inspect its day. Use arrow keys to move; press Escape to clear."
11060
11332
  })
@@ -11062,7 +11334,7 @@ function SelectableBarChart({
11062
11334
  });
11063
11335
  }
11064
11336
  // src/react/ui/DataAppSkeleton.tsx
11065
- import { jsx as jsx59, jsxs as jsxs43 } from "react/jsx-runtime";
11337
+ import { jsx as jsx61, jsxs as jsxs44 } from "react/jsx-runtime";
11066
11338
  var chartHeights = [40, 60, 50, 80, 60, 100, 80, 60];
11067
11339
  function DataAppSkeleton({
11068
11340
  header,
@@ -11070,60 +11342,60 @@ function DataAppSkeleton({
11070
11342
  className,
11071
11343
  ...props
11072
11344
  }) {
11073
- return /* @__PURE__ */ jsx59("output", {
11345
+ return /* @__PURE__ */ jsx61("output", {
11074
11346
  "aria-label": "Loading data app",
11075
11347
  ...props,
11076
11348
  "aria-busy": "true",
11077
11349
  className: classNames("altertable-data-app-skeleton", className),
11078
- children: /* @__PURE__ */ jsxs43("div", {
11350
+ children: /* @__PURE__ */ jsxs44("div", {
11079
11351
  className: "altertable-data-app-skeleton-content",
11080
11352
  children: [
11081
- header != null && header !== false && /* @__PURE__ */ jsx59("div", {
11353
+ header != null && header !== false && /* @__PURE__ */ jsx61("div", {
11082
11354
  className: "altertable-data-app-skeleton-header",
11083
11355
  children: header
11084
11356
  }),
11085
- /* @__PURE__ */ jsxs43("div", {
11357
+ /* @__PURE__ */ jsxs44("div", {
11086
11358
  className: "altertable-data-app-skeleton-body",
11087
11359
  "aria-hidden": "true",
11088
11360
  children: [
11089
- /* @__PURE__ */ jsx59(Grid, {
11361
+ /* @__PURE__ */ jsx61(Grid, {
11090
11362
  columns: 3,
11091
11363
  gap: "md",
11092
- children: [0, 1, 2].map((item) => /* @__PURE__ */ jsx59(MetricWidget, {
11364
+ children: [0, 1, 2].map((item) => /* @__PURE__ */ jsx61(MetricWidget, {
11093
11365
  label: "",
11094
11366
  loading: true
11095
11367
  }, item))
11096
11368
  }),
11097
- /* @__PURE__ */ jsx59(VisualizationWidget, {
11098
- title: /* @__PURE__ */ jsx59(Skeleton, {
11369
+ /* @__PURE__ */ jsx61(VisualizationWidget, {
11370
+ title: /* @__PURE__ */ jsx61(Skeleton, {
11099
11371
  className: "altertable-data-app-skeleton-widget-title"
11100
11372
  }),
11101
- visual: /* @__PURE__ */ jsx59("div", {
11373
+ visual: /* @__PURE__ */ jsx61("div", {
11102
11374
  className: "altertable-data-app-skeleton-chart",
11103
- children: chartHeights.map((height, index) => /* @__PURE__ */ jsx59(Skeleton, {
11375
+ children: chartHeights.map((height, index) => /* @__PURE__ */ jsx61(Skeleton, {
11104
11376
  style: { height: `${height}%` }
11105
11377
  }, index))
11106
11378
  })
11107
11379
  }),
11108
- /* @__PURE__ */ jsx59(DataWidget, {
11109
- title: /* @__PURE__ */ jsx59(Skeleton, {
11380
+ /* @__PURE__ */ jsx61(DataWidget, {
11381
+ title: /* @__PURE__ */ jsx61(Skeleton, {
11110
11382
  className: "altertable-data-app-skeleton-widget-title"
11111
11383
  }),
11112
- children: /* @__PURE__ */ jsx59("div", {
11384
+ children: /* @__PURE__ */ jsx61("div", {
11113
11385
  className: "altertable-data-app-skeleton-rows",
11114
- children: [0, 1, 2].map((row) => /* @__PURE__ */ jsxs43("div", {
11386
+ children: [0, 1, 2].map((row) => /* @__PURE__ */ jsxs44("div", {
11115
11387
  className: "altertable-data-app-skeleton-row",
11116
11388
  children: [
11117
- /* @__PURE__ */ jsx59(Skeleton, {}),
11118
- /* @__PURE__ */ jsx59(Skeleton, {}),
11119
- /* @__PURE__ */ jsx59(Skeleton, {})
11389
+ /* @__PURE__ */ jsx61(Skeleton, {}),
11390
+ /* @__PURE__ */ jsx61(Skeleton, {}),
11391
+ /* @__PURE__ */ jsx61(Skeleton, {})
11120
11392
  ]
11121
11393
  }, row))
11122
11394
  })
11123
11395
  })
11124
11396
  ]
11125
11397
  }),
11126
- footer != null && footer !== false && /* @__PURE__ */ jsx59("div", {
11398
+ footer != null && footer !== false && /* @__PURE__ */ jsx61("div", {
11127
11399
  className: "altertable-data-app-skeleton-footer",
11128
11400
  children: footer
11129
11401
  })
@@ -11132,7 +11404,7 @@ function DataAppSkeleton({
11132
11404
  });
11133
11405
  }
11134
11406
  // src/react/ui/RefreshRegion.tsx
11135
- import { jsx as jsx60 } from "react/jsx-runtime";
11407
+ import { jsx as jsx62 } from "react/jsx-runtime";
11136
11408
  function RefreshRegion({
11137
11409
  refreshing,
11138
11410
  dimOnUpdate = false,
@@ -11141,10 +11413,10 @@ function RefreshRegion({
11141
11413
  className,
11142
11414
  ...props
11143
11415
  }) {
11144
- return /* @__PURE__ */ jsx60("div", {
11416
+ return /* @__PURE__ */ jsx62("div", {
11145
11417
  ...props,
11146
11418
  className: classNames("altertable-refresh-region", className),
11147
- children: /* @__PURE__ */ jsx60("div", {
11419
+ children: /* @__PURE__ */ jsx62("div", {
11148
11420
  ...contentProps,
11149
11421
  className: classNames("altertable-refresh-content", contentProps?.className),
11150
11422
  "data-refreshing": refreshing && dimOnUpdate,
@@ -11154,8 +11426,8 @@ function RefreshRegion({
11154
11426
  });
11155
11427
  }
11156
11428
  // src/react/ui/UpdatedAt.tsx
11157
- import { useEffect as useEffect16, useState as useState20 } from "react";
11158
- import { jsx as jsx61, jsxs as jsxs44 } from "react/jsx-runtime";
11429
+ import { useEffect as useEffect16, useState as useState21 } from "react";
11430
+ import { jsx as jsx63, jsxs as jsxs45 } from "react/jsx-runtime";
11159
11431
  function UpdatedAt({
11160
11432
  timestamp,
11161
11433
  locale,
@@ -11164,7 +11436,7 @@ function UpdatedAt({
11164
11436
  triggerClassName,
11165
11437
  ...props
11166
11438
  }) {
11167
- const [now, setNow] = useState20(Date.now);
11439
+ const [now, setNow] = useState21(Date.now);
11168
11440
  useEffect16(() => {
11169
11441
  const interval = window.setInterval(() => setNow(Date.now()), 30000);
11170
11442
  return () => window.clearInterval(interval);
@@ -11179,11 +11451,11 @@ function UpdatedAt({
11179
11451
  else if (elapsedMinutes >= 1)
11180
11452
  age = relative.format(-elapsedMinutes, "minute");
11181
11453
  const date = new Date(timestamp);
11182
- return /* @__PURE__ */ jsx61(DateTimeTooltip, {
11454
+ return /* @__PURE__ */ jsx63(DateTimeTooltip, {
11183
11455
  ...props,
11184
11456
  date,
11185
11457
  triggerClassName: ["altertable-updated-at", triggerClassName].filter(Boolean).join(" "),
11186
- children: children ?? /* @__PURE__ */ jsxs44("time", {
11458
+ children: children ?? /* @__PURE__ */ jsxs45("time", {
11187
11459
  dateTime: date.toISOString(),
11188
11460
  children: [
11189
11461
  label,
@@ -11266,7 +11538,7 @@ function createDataContext(queryNames) {
11266
11538
  return bindDataContext;
11267
11539
  }
11268
11540
  // src/react/ui/data-identifiers.tsx
11269
- import { jsx as jsx62, jsxs as jsxs45 } from "react/jsx-runtime";
11541
+ import { jsx as jsx64, jsxs as jsxs46 } from "react/jsx-runtime";
11270
11542
  function qualifiedName(definition) {
11271
11543
  const table = definition.kind === "table" ? definition : definition.table;
11272
11544
  const path = [table.catalog, table.schema, table.name].join(".");
@@ -11302,23 +11574,23 @@ function defineDataIdentifiers({ tables, columns }) {
11302
11574
  const shown = display ?? (definition.kind === "table" ? "qualified" : "short");
11303
11575
  const table = definition.kind === "table" ? definition : definition.table;
11304
11576
  const prefix = definition.kind === "table" ? [table.catalog, table.schema] : [table.catalog, table.schema, table.name];
11305
- return /* @__PURE__ */ jsxs45("code", {
11577
+ return /* @__PURE__ */ jsxs46("code", {
11306
11578
  className: "altertable-data-identifier",
11307
11579
  "data-kind": definition.kind,
11308
11580
  title: qualified,
11309
11581
  "data-identifier-id": id,
11310
11582
  children: [
11311
- shown === "qualified" && /* @__PURE__ */ jsx62("span", {
11583
+ shown === "qualified" && /* @__PURE__ */ jsx64("span", {
11312
11584
  className: "altertable-data-identifier-path",
11313
- children: prefix.map((segment, index) => /* @__PURE__ */ jsxs45("span", {
11585
+ children: prefix.map((segment, index) => /* @__PURE__ */ jsxs46("span", {
11314
11586
  children: [
11315
11587
  segment,
11316
11588
  ".",
11317
- /* @__PURE__ */ jsx62("wbr", {})
11589
+ /* @__PURE__ */ jsx64("wbr", {})
11318
11590
  ]
11319
11591
  }, index))
11320
11592
  }),
11321
- /* @__PURE__ */ jsx62("span", {
11593
+ /* @__PURE__ */ jsx64("span", {
11322
11594
  className: "altertable-data-identifier-name",
11323
11595
  children: definition.name
11324
11596
  })
@@ -11331,7 +11603,7 @@ function defineDataIdentifiers({ tables, columns }) {
11331
11603
  };
11332
11604
  }
11333
11605
  // src/react/ui/GlossaryExplanation.tsx
11334
- import { jsx as jsx63 } from "react/jsx-runtime";
11606
+ import { jsx as jsx65 } from "react/jsx-runtime";
11335
11607
  function GlossaryExplanation({
11336
11608
  entry,
11337
11609
  empty,
@@ -11343,7 +11615,7 @@ function GlossaryExplanation({
11343
11615
  className,
11344
11616
  ...props
11345
11617
  }) {
11346
- return /* @__PURE__ */ jsx63(AboutData, {
11618
+ return /* @__PURE__ */ jsx65(AboutData, {
11347
11619
  ...props,
11348
11620
  shortcut: false,
11349
11621
  iconOnly: true,
@@ -11358,28 +11630,28 @@ function GlossaryExplanation({
11358
11630
  className: className ?? "altertable-inspect-trigger",
11359
11631
  tooltip: "Explore this term",
11360
11632
  "aria-label": props["aria-label"] ?? `Explore ${entry.term}`,
11361
- children: /* @__PURE__ */ jsx63(AppIcon, {
11633
+ children: /* @__PURE__ */ jsx65(AppIcon, {
11362
11634
  name: "openDetails"
11363
11635
  })
11364
11636
  });
11365
11637
  }
11366
11638
  // src/react/ui/GlossaryDefinition.tsx
11367
- import { jsx as jsx64, jsxs as jsxs46 } from "react/jsx-runtime";
11639
+ import { jsx as jsx66, jsxs as jsxs47 } from "react/jsx-runtime";
11368
11640
  function GlossaryDefinition({
11369
11641
  entry,
11370
11642
  children
11371
11643
  }) {
11372
- return /* @__PURE__ */ jsxs46(HelpPopover, {
11644
+ return /* @__PURE__ */ jsxs47(HelpPopover, {
11373
11645
  trigger: children ?? entry.term,
11374
11646
  triggerLabel: `Explain ${entry.term}`,
11375
11647
  label: entry.term,
11376
11648
  triggerClassName: "altertable-glossary-definition-trigger",
11377
11649
  panelClassName: "altertable-glossary-definition-popover",
11378
11650
  children: [
11379
- /* @__PURE__ */ jsx64("strong", {
11651
+ /* @__PURE__ */ jsx66("strong", {
11380
11652
  children: entry.term
11381
11653
  }),
11382
- /* @__PURE__ */ jsx64("div", {
11654
+ /* @__PURE__ */ jsx66("div", {
11383
11655
  children: entry.definition
11384
11656
  })
11385
11657
  ]
@@ -11479,4 +11751,4 @@ export {
11479
11751
  writeSearch
11480
11752
  };
11481
11753
 
11482
- //# debugId=087F64F77A0D4F5564756E2164756E21
11754
+ //# debugId=A6B15262EAC6BE2D64756E2164756E21