@altertable/data-app 0.66.0 → 0.67.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 (131) hide show
  1. package/CONTRIBUTING.md +22 -16
  2. package/dist/chunks/{contract-19ckn3n7.js → index-23dktynd.js} +8 -6
  3. package/dist/chunks/index-23dktynd.js.map +10 -0
  4. package/dist/chunks/{contract-havnjmdr.js → index-8qfxv0h5.js} +2272 -1123
  5. package/dist/chunks/index-8qfxv0h5.js.map +108 -0
  6. package/dist/chunks/{contract-rfbakka4.js → index-ag0cgnvq.js} +169 -35
  7. package/dist/chunks/index-ag0cgnvq.js.map +13 -0
  8. package/dist/chunks/index-dq7b35fn.js +307 -0
  9. package/dist/chunks/index-dq7b35fn.js.map +13 -0
  10. package/dist/chunks/{contract-e11m4y7f.js → index-ev2b5aaf.js} +11 -6
  11. package/dist/chunks/{contract-e11m4y7f.js.map → index-ev2b5aaf.js.map} +3 -3
  12. package/dist/chunks/{contract-awa2d5b1.js → index-f5cnbrjz.js} +19 -2
  13. package/dist/chunks/{contract-awa2d5b1.js.map → index-f5cnbrjz.js.map} +4 -3
  14. package/dist/chunks/{contract-13j5zb3c.js → index-ktmvs916.js} +8 -7
  15. package/dist/chunks/index-ktmvs916.js.map +13 -0
  16. package/dist/chunks/index-mt93ff2b.js +28 -0
  17. package/dist/chunks/index-mt93ff2b.js.map +10 -0
  18. package/dist/chunks/{contract-tf8c3qpv.js → index-qd5xgx6y.js} +46 -5
  19. package/dist/chunks/index-qd5xgx6y.js.map +13 -0
  20. package/dist/chunks/{contract-pk603qj7.js → index-x69p7cv7.js} +12 -9
  21. package/dist/chunks/index-x69p7cv7.js.map +10 -0
  22. package/dist/client/index.js +6 -6
  23. package/dist/core/appearance.js +1 -1
  24. package/dist/core/config.js +7 -3
  25. package/dist/core/config.js.map +1 -1
  26. package/dist/core/contract.js +14 -6
  27. package/dist/core/contract.js.map +1 -1
  28. package/dist/core/format.js +1 -1
  29. package/dist/embed/index.js +12 -10
  30. package/dist/embed/index.js.map +4 -4
  31. package/dist/index.js +12 -0
  32. package/dist/index.js.map +9 -0
  33. package/dist/local.js +20 -30
  34. package/dist/local.js.map +7 -8
  35. package/dist/react/embed/index.js +1 -1
  36. package/dist/react/embed/index.js.map +2 -2
  37. package/dist/react/index.js +57 -19
  38. package/dist/react/index.js.map +4 -4
  39. package/dist/react/ui/index.js +836 -178
  40. package/dist/react/ui/index.js.map +15 -9
  41. package/dist/server.js +13 -26
  42. package/dist/server.js.map +6 -7
  43. package/dist/types/client/annotations.d.ts +4 -0
  44. package/dist/types/client/data-client.d.ts +1 -2
  45. package/dist/types/client/iframe.d.ts +4 -2
  46. package/dist/types/core/annotations.d.ts +2 -0
  47. package/dist/types/core/config.d.ts +48 -4
  48. package/dist/types/core/contract.d.ts +20 -12
  49. package/dist/types/core/dimension.d.ts +6 -4
  50. package/dist/types/core/filters.d.ts +44 -0
  51. package/dist/types/core/messages.d.ts +2 -0
  52. package/dist/types/core/operation-types.d.ts +5 -2
  53. package/dist/types/core/operation.d.ts +3 -4
  54. package/dist/types/core/queries.d.ts +16 -0
  55. package/dist/types/core/uuid.d.ts +2 -0
  56. package/dist/types/core/variables.d.ts +32 -13
  57. package/dist/types/embed/runtime-html.d.ts +2 -0
  58. package/dist/types/embed/source.d.ts +2 -1
  59. package/dist/types/index.d.ts +3 -0
  60. package/dist/types/react/annotations/AnnotationBar.d.ts +7 -1
  61. package/dist/types/react/annotations/AnnotationEditor.d.ts +2 -1
  62. package/dist/types/react/annotations/useDataAppAnnotations.d.ts +3 -0
  63. package/dist/types/react/app-context.d.ts +3 -0
  64. package/dist/types/react/index.d.ts +3 -3
  65. package/dist/types/react/mount.d.ts +6 -4
  66. package/dist/types/react/style-contract.d.ts +22 -2
  67. package/dist/types/react/ui/Button.d.ts +3 -3
  68. package/dist/types/react/ui/ChartLegend.d.ts +31 -0
  69. package/dist/types/react/ui/Checkbox.d.ts +15 -4
  70. package/dist/types/react/ui/CheckboxGroup.d.ts +7 -0
  71. package/dist/types/react/ui/{Combobox.d.ts → ChoicePicker.d.ts} +10 -15
  72. package/dist/types/react/ui/ComposedChart.d.ts +41 -0
  73. package/dist/types/react/ui/ComposedChartLegend.d.ts +8 -0
  74. package/dist/types/react/ui/DataAppFrame.d.ts +1 -2
  75. package/dist/types/react/ui/DimensionPicker.d.ts +1 -1
  76. package/dist/types/react/ui/FilterActions.d.ts +10 -0
  77. package/dist/types/react/ui/FilterBar.d.ts +3 -0
  78. package/dist/types/react/ui/GettingStarted.d.ts +2 -4
  79. package/dist/types/react/ui/Menu.d.ts +12 -0
  80. package/dist/types/react/ui/NumberField.d.ts +27 -0
  81. package/dist/types/react/ui/NumberFilterPicker.d.ts +9 -0
  82. package/dist/types/react/ui/PieChart.d.ts +5 -2
  83. package/dist/types/react/ui/RadioGroup.d.ts +18 -0
  84. package/dist/types/react/ui/SearchInput.d.ts +2 -2
  85. package/dist/types/react/ui/Select.d.ts +14 -0
  86. package/dist/types/react/ui/SelectionMark.d.ts +2 -1
  87. package/dist/types/react/ui/TooltipSurface.d.ts +3 -0
  88. package/dist/types/react/ui/chart-data.d.ts +1 -1
  89. package/dist/types/react/ui/chart-primitives.d.ts +20 -0
  90. package/dist/types/react/ui/icons.d.ts +1 -0
  91. package/dist/types/react/ui/index.d.ts +26 -2
  92. package/dist/types/react/ui/keyboard.d.ts +6 -0
  93. package/dist/types/react/ui/shortcuts.d.ts +7 -0
  94. package/dist/types/react/ui/useAppAppearance.d.ts +1 -1
  95. package/dist/types/react/ui/variables.d.ts +4 -2
  96. package/dist/types/react/view-controls.d.ts +3 -1
  97. package/dist/types/server/handler.d.ts +4 -4
  98. package/dist/worker.js +20 -737
  99. package/docs/app-authoring.md +15 -1
  100. package/docs/client.md +8 -8
  101. package/docs/contract.md +42 -20
  102. package/docs/data-context.md +8 -6
  103. package/docs/embed.md +10 -2
  104. package/docs/formatting-and-appearance.md +23 -7
  105. package/docs/hosted-apps.md +9 -2
  106. package/docs/layout.md +1 -1
  107. package/docs/react-embed.md +3 -2
  108. package/docs/react.md +4 -3
  109. package/docs/server-bun.md +1 -1
  110. package/docs/server.md +4 -4
  111. package/docs/styling.md +10 -3
  112. package/docs/ui.md +158 -3
  113. package/docs/variables.md +80 -7
  114. package/docs/views.md +4 -8
  115. package/docs/widgets.md +16 -13
  116. package/examples/starter-data-app/index.tsx +34 -32
  117. package/package.json +16 -11
  118. package/dist/chunks/contract-13j5zb3c.js.map +0 -13
  119. package/dist/chunks/contract-19ckn3n7.js.map +0 -10
  120. package/dist/chunks/contract-h8a6f559.js +0 -286
  121. package/dist/chunks/contract-h8a6f559.js.map +0 -12
  122. package/dist/chunks/contract-havnjmdr.js.map +0 -99
  123. package/dist/chunks/contract-pk603qj7.js.map +0 -10
  124. package/dist/chunks/contract-rfbakka4.js.map +0 -13
  125. package/dist/chunks/contract-tf8c3qpv.js.map +0 -11
  126. package/dist/chunks/contract-wz59z8pq.js +0 -8
  127. package/dist/chunks/contract-wz59z8pq.js.map +0 -10
  128. /package/dist/chunks/{contract-m6n8ctfc.js → index-m6n8ctfc.js} +0 -0
  129. /package/dist/chunks/{contract-m6n8ctfc.js.map → index-m6n8ctfc.js.map} +0 -0
  130. /package/dist/chunks/{contract-mev09s5v.js → index-mev09s5v.js} +0 -0
  131. /package/dist/chunks/{contract-mev09s5v.js.map → index-mev09s5v.js.map} +0 -0
@@ -4,6 +4,8 @@ import {
4
4
  AppIcon2,
5
5
  classNames,
6
6
  Button2,
7
+ PressButton,
8
+ TooltipSurface,
7
9
  TooltipProvider2,
8
10
  Tooltip2,
9
11
  GradientScroll2,
@@ -17,18 +19,34 @@ import {
17
19
  AboutData2,
18
20
  DataAppProvider2,
19
21
  useDeclaredResult,
22
+ validateChoiceOptions,
20
23
  useAppVariables2,
24
+ Select2,
25
+ FilterActions2,
26
+ NumberField2,
27
+ NumberRangeField2,
28
+ NumberFilterPicker2,
21
29
  SearchField2,
22
30
  Skeleton2,
23
31
  SearchMatch2,
24
32
  searchItems2,
25
- Combobox2,
33
+ ChoicePicker2,
34
+ CheckboxGroupContext,
26
35
  Checkbox2,
27
36
  DateRangePicker2,
37
+ FilterBar2,
28
38
  DimensionPicker2,
29
39
  createDataHooks2,
40
+ isPlainKeyEvent2,
41
+ MenuTrigger2,
42
+ MenuSection2,
43
+ MenuPopover2,
44
+ Menu2,
45
+ MenuItem2,
46
+ MenuSeparator2,
30
47
  LiveControl2,
31
48
  PresentStory2,
49
+ VariableBar2,
32
50
  DataAppFrame,
33
51
  Grid2,
34
52
  DataWidget2,
@@ -43,18 +61,19 @@ import {
43
61
  TextWidget2,
44
62
  DataValue2,
45
63
  createDataContext2
46
- } from "../../chunks/contract-havnjmdr.js";
47
- import"../../chunks/contract-wz59z8pq.js";
48
- import"../../chunks/contract-mev09s5v.js";
49
- import {
50
- invariant
51
- } from "../../chunks/contract-rfbakka4.js";
52
- import"../../chunks/contract-m6n8ctfc.js";
64
+ } from "../../chunks/index-8qfxv0h5.js";
65
+ import"../../chunks/index-mev09s5v.js";
66
+ import"../../chunks/index-ag0cgnvq.js";
67
+ import"../../chunks/index-mt93ff2b.js";
68
+ import"../../chunks/index-m6n8ctfc.js";
53
69
  import {
54
70
  createDataClient2
55
- } from "../../chunks/contract-19ckn3n7.js";
56
- import"../../chunks/contract-pk603qj7.js";
57
- import"../../chunks/contract-e11m4y7f.js";
71
+ } from "../../chunks/index-23dktynd.js";
72
+ import"../../chunks/index-x69p7cv7.js";
73
+ import"../../chunks/index-ev2b5aaf.js";
74
+ import {
75
+ invariant
76
+ } from "../../chunks/index-qd5xgx6y.js";
58
77
 
59
78
  // src/react/shellStyles.ts
60
79
  function injectDataAppShellStyles(options = {}) {
@@ -64,6 +83,7 @@ function injectDataAppShellStyles(options = {}) {
64
83
  css: `/* src/react/tokens.css */
65
84
  @layer atbl.tokens {
66
85
  :root {
86
+ --atbl-control-text-size: var(--atbl-type-body-size);
67
87
  --atbl-background: var(--atbl-palette-background);
68
88
  --atbl-surface: var(--atbl-palette-surface);
69
89
  --atbl-subtle: var(--atbl-palette-subtle);
@@ -812,14 +832,10 @@ var connectionView = defineDataView({
812
832
  isEmpty: () => false,
813
833
  emptyFallback: { title: "No connection" }
814
834
  });
815
- function GettingStarted({
816
- config,
817
- dataContext
818
- }) {
835
+ function GettingStarted({ dataContext }) {
819
836
  const connection = useDeclaredResult(connectionView);
820
837
  const state = connection.view.kind === "error" || connection.view.kind === "stale-error" ? "error" : connection.refreshing || !connection.snapshot ? "checking" : "connected";
821
838
  return /* @__PURE__ */ jsxs(DataApp, {
822
- config,
823
839
  dataContext,
824
840
  description: "Check your lakehouse connection, then build a view around a real question.",
825
841
  queries: connection.queries,
@@ -1064,7 +1080,178 @@ function GlossaryDefinition({
1064
1080
  });
1065
1081
  }
1066
1082
  // src/react/ui/TrendChart.tsx
1067
- import { useLayoutEffect, useRef } from "react";
1083
+ import { useLayoutEffect, useRef, useState } from "react";
1084
+ import {
1085
+ AreaChart as RechartsAreaChart,
1086
+ LineChart as RechartsLineChart,
1087
+ ReferenceLine
1088
+ } from "recharts";
1089
+
1090
+ // src/react/ui/chart-primitives.tsx
1091
+ import {
1092
+ Area,
1093
+ Dot,
1094
+ Bar,
1095
+ Line,
1096
+ Scatter,
1097
+ XAxis,
1098
+ YAxis,
1099
+ CartesianGrid,
1100
+ Tooltip,
1101
+ DefaultTooltipContent
1102
+ } from "recharts";
1103
+ import { jsx as jsx6 } from "react/jsx-runtime";
1104
+ var chartBarFill = "var(--atbl-chart-fill, color-mix(in srgb, var(--atbl-accent) 75%, var(--atbl-surface)))";
1105
+ var accent = "var(--atbl-accent)";
1106
+ function ChartDot({
1107
+ active = false,
1108
+ stroke = accent,
1109
+ fill = active ? stroke : "var(--atbl-surface)",
1110
+ r = active ? 4.5 : 3,
1111
+ ...props
1112
+ }) {
1113
+ return /* @__PURE__ */ jsx6(Dot, {
1114
+ stroke,
1115
+ fill,
1116
+ r,
1117
+ strokeWidth: 2,
1118
+ ...props
1119
+ });
1120
+ }
1121
+ function ChartBar(props) {
1122
+ return /* @__PURE__ */ jsx6(Bar, {
1123
+ fill: chartBarFill,
1124
+ radius: [5, 5, 0, 0],
1125
+ maxBarSize: 30,
1126
+ activeBar: { fill: accent },
1127
+ isAnimationActive: false,
1128
+ ...props
1129
+ });
1130
+ }
1131
+ function ChartLine({
1132
+ stroke = accent,
1133
+ dot,
1134
+ activeDot,
1135
+ ...props
1136
+ }) {
1137
+ return /* @__PURE__ */ jsx6(Line, {
1138
+ type: "linear",
1139
+ stroke,
1140
+ strokeWidth: 2,
1141
+ strokeLinecap: "round",
1142
+ strokeLinejoin: "round",
1143
+ dot: dot === undefined || dot === true ? ({ cx, cy }) => /* @__PURE__ */ jsx6(ChartDot, {
1144
+ cx,
1145
+ cy,
1146
+ stroke
1147
+ }) : dot,
1148
+ activeDot: activeDot === undefined || activeDot === true ? ({ cx, cy }) => /* @__PURE__ */ jsx6(ChartDot, {
1149
+ cx,
1150
+ cy,
1151
+ stroke,
1152
+ active: true
1153
+ }) : activeDot,
1154
+ isAnimationActive: false,
1155
+ ...props
1156
+ });
1157
+ }
1158
+ function ChartArea({
1159
+ stroke = accent,
1160
+ dot,
1161
+ activeDot,
1162
+ ...props
1163
+ }) {
1164
+ return /* @__PURE__ */ jsx6(Area, {
1165
+ legendType: "square",
1166
+ type: "linear",
1167
+ stroke,
1168
+ strokeWidth: 2,
1169
+ strokeLinecap: "round",
1170
+ strokeLinejoin: "round",
1171
+ fill: stroke,
1172
+ fillOpacity: 0.14,
1173
+ dot: dot === undefined || dot === true ? ({ cx, cy }) => /* @__PURE__ */ jsx6(ChartDot, {
1174
+ cx,
1175
+ cy,
1176
+ stroke
1177
+ }) : dot,
1178
+ activeDot: activeDot === undefined || activeDot === true ? ({ cx, cy }) => /* @__PURE__ */ jsx6(ChartDot, {
1179
+ cx,
1180
+ cy,
1181
+ stroke,
1182
+ active: true
1183
+ }) : activeDot,
1184
+ isAnimationActive: false,
1185
+ ...props
1186
+ });
1187
+ }
1188
+ function ChartScatter(props) {
1189
+ return /* @__PURE__ */ jsx6(Scatter, {
1190
+ fill: accent,
1191
+ isAnimationActive: false,
1192
+ ...props
1193
+ });
1194
+ }
1195
+ function ChartXAxis(props) {
1196
+ return /* @__PURE__ */ jsx6(XAxis, {
1197
+ stroke: "var(--atbl-muted)",
1198
+ tickLine: false,
1199
+ axisLine: { stroke: "var(--atbl-border)" },
1200
+ tick: { fontSize: "var(--atbl-type-meta-size)" },
1201
+ ...props
1202
+ });
1203
+ }
1204
+ function ChartYAxis(props) {
1205
+ return /* @__PURE__ */ jsx6(YAxis, {
1206
+ stroke: "var(--atbl-muted)",
1207
+ tickLine: false,
1208
+ axisLine: false,
1209
+ tick: { fontSize: "var(--atbl-type-meta-size)" },
1210
+ ...props
1211
+ });
1212
+ }
1213
+ function ChartGrid(props) {
1214
+ return /* @__PURE__ */ jsx6(CartesianGrid, {
1215
+ stroke: "var(--atbl-border)",
1216
+ vertical: false,
1217
+ ...props
1218
+ });
1219
+ }
1220
+ function ChartTooltipContent(props) {
1221
+ if (!props.active)
1222
+ return null;
1223
+ return /* @__PURE__ */ jsx6(TooltipSurface, {
1224
+ "data-variant": "chart",
1225
+ role: "tooltip",
1226
+ children: /* @__PURE__ */ jsx6(DefaultTooltipContent, {
1227
+ ...props,
1228
+ contentStyle: {
1229
+ margin: 0,
1230
+ padding: 0,
1231
+ background: "transparent",
1232
+ border: 0,
1233
+ whiteSpace: "normal",
1234
+ ...props.contentStyle
1235
+ },
1236
+ labelStyle: {
1237
+ color: "var(--atbl-text)",
1238
+ fontSize: "var(--atbl-type-body-size)",
1239
+ fontWeight: 650,
1240
+ lineHeight: 1.2,
1241
+ ...props.labelStyle
1242
+ },
1243
+ itemStyle: { paddingTop: 2, paddingBottom: 0, ...props.itemStyle }
1244
+ })
1245
+ });
1246
+ }
1247
+ function ChartTooltip(props) {
1248
+ return /* @__PURE__ */ jsx6(Tooltip, {
1249
+ content: /* @__PURE__ */ jsx6(ChartTooltipContent, {}),
1250
+ cursor: false,
1251
+ isAnimationActive: false,
1252
+ ...props
1253
+ });
1254
+ }
1068
1255
 
1069
1256
  // src/react/ui/chart-data.ts
1070
1257
  function validateChartItems(kind, items) {
@@ -1085,7 +1272,7 @@ function validateChartItems(kind, items) {
1085
1272
  }
1086
1273
 
1087
1274
  // src/react/ui/TrendChart.tsx
1088
- import { jsx as jsx6, jsxs as jsxs4, Fragment } from "react/jsx-runtime";
1275
+ import { jsx as jsx7, jsxs as jsxs4, Fragment } from "react/jsx-runtime";
1089
1276
  function TrendChart({
1090
1277
  items,
1091
1278
  unit,
@@ -1094,6 +1281,8 @@ function TrendChart({
1094
1281
  area = false
1095
1282
  }) {
1096
1283
  validateChartItems(area ? "area" : "line", items);
1284
+ const Plot = area ? RechartsAreaChart : RechartsLineChart;
1285
+ const [activeIndex, setActiveIndex] = useState();
1097
1286
  const scrollport = useRef(null);
1098
1287
  useLayoutEffect(() => {
1099
1288
  const element = scrollport.current;
@@ -1103,64 +1292,77 @@ function TrendChart({
1103
1292
  const magnitude = items.reduce((max, item) => Math.max(max, Math.abs(item.value)), 1);
1104
1293
  const low = items.reduce((min, item) => Math.min(min, item.value / magnitude), 0);
1105
1294
  const high = items.reduce((max, item) => Math.max(max, item.value / magnitude), 0);
1106
- const span = high - low || 1;
1107
- function y(value) {
1108
- return 208 - (value / magnitude - low) / span * 196;
1109
- }
1110
- const points = items.map((item, index) => ({
1111
- x: (index + 0.5) / items.length * 1000,
1112
- y: y(item.value)
1113
- }));
1114
- const path = points.map((point, index) => `${index ? "L" : "M"}${point.x},${point.y}`).join(" ");
1115
- const first = points[0];
1116
- const last = points.at(-1);
1117
1295
  return /* @__PURE__ */ jsxs4("section", {
1118
1296
  className: "altertable-trend-chart",
1119
1297
  "aria-label": ariaLabel,
1120
1298
  children: [
1121
- items.length === 0 && /* @__PURE__ */ jsx6("span", {
1299
+ items.length === 0 && /* @__PURE__ */ jsx7("span", {
1122
1300
  children: "No data"
1123
1301
  }),
1124
- items.length > 0 && /* @__PURE__ */ jsx6(Fragment, {
1125
- children: /* @__PURE__ */ jsx6("div", {
1302
+ items.length > 0 && /* @__PURE__ */ jsx7(Fragment, {
1303
+ children: /* @__PURE__ */ jsx7("div", {
1126
1304
  className: "altertable-trend-scroll",
1127
1305
  ref: scrollport,
1128
1306
  children: /* @__PURE__ */ jsxs4("div", {
1129
1307
  className: "altertable-trend-plot",
1130
1308
  style: { minWidth: items.length * 40 },
1131
1309
  children: [
1132
- /* @__PURE__ */ jsxs4("svg", {
1133
- viewBox: "0 0 1000 220",
1134
- preserveAspectRatio: "none",
1310
+ /* @__PURE__ */ jsx7("div", {
1311
+ className: "altertable-chart-canvas",
1135
1312
  "aria-hidden": "true",
1136
- focusable: "false",
1137
- children: [
1138
- /* @__PURE__ */ jsx6("line", {
1139
- className: "altertable-trend-baseline",
1140
- x1: "0",
1141
- x2: "1000",
1142
- y1: y(0),
1143
- y2: y(0),
1144
- vectorEffect: "non-scaling-stroke"
1145
- }),
1146
- area && first && last && /* @__PURE__ */ jsx6("path", {
1147
- className: "altertable-trend-fill",
1148
- d: `${path} L${last.x},${y(0)} L${first.x},${y(0)} Z`
1149
- }),
1150
- /* @__PURE__ */ jsx6("path", {
1151
- className: "altertable-trend-line",
1152
- d: path,
1153
- vectorEffect: "non-scaling-stroke"
1154
- })
1155
- ]
1313
+ children: /* @__PURE__ */ jsxs4(Plot, {
1314
+ data: items.map((item) => ({
1315
+ ...item,
1316
+ plotValue: item.value / magnitude
1317
+ })),
1318
+ title: ariaLabel,
1319
+ responsive: true,
1320
+ width: "100%",
1321
+ height: 220,
1322
+ margin: { top: 12, right: 0, bottom: 12, left: 0 },
1323
+ accessibilityLayer: false,
1324
+ tabIndex: -1,
1325
+ children: [
1326
+ /* @__PURE__ */ jsx7(ChartXAxis, {
1327
+ hide: true,
1328
+ dataKey: "id",
1329
+ scale: "band"
1330
+ }),
1331
+ /* @__PURE__ */ jsx7(ChartYAxis, {
1332
+ hide: true,
1333
+ domain: [low, high === low ? low + 1 : high]
1334
+ }),
1335
+ /* @__PURE__ */ jsx7(ReferenceLine, {
1336
+ y: 0,
1337
+ stroke: "var(--atbl-border)"
1338
+ }),
1339
+ area && /* @__PURE__ */ jsx7(ChartArea, {
1340
+ dataKey: "plotValue",
1341
+ stroke: "none",
1342
+ fill: "var(--atbl-accent)",
1343
+ dot: false,
1344
+ activeDot: false
1345
+ }),
1346
+ /* @__PURE__ */ jsx7(ChartLine, {
1347
+ dataKey: "plotValue",
1348
+ dot: ({ cx, cy, index }) => /* @__PURE__ */ jsx7(ChartDot, {
1349
+ cx,
1350
+ cy,
1351
+ active: index === activeIndex
1352
+ }),
1353
+ activeDot: false
1354
+ })
1355
+ ]
1356
+ })
1156
1357
  }),
1157
- /* @__PURE__ */ jsx6("div", {
1358
+ /* @__PURE__ */ jsx7("div", {
1158
1359
  className: "altertable-trend-points",
1159
- children: items.map((item, index) => /* @__PURE__ */ jsx6(Tooltip2, {
1360
+ children: items.map((item, index) => /* @__PURE__ */ jsx7(Tooltip2, {
1160
1361
  variant: "chart",
1362
+ onOpenChange: (open) => setActiveIndex((current) => open ? index : current === index ? undefined : current),
1161
1363
  content: /* @__PURE__ */ jsxs4(Fragment, {
1162
1364
  children: [
1163
- /* @__PURE__ */ jsx6("strong", {
1365
+ /* @__PURE__ */ jsx7("strong", {
1164
1366
  children: item.label
1165
1367
  }),
1166
1368
  /* @__PURE__ */ jsxs4("span", {
@@ -1175,20 +1377,16 @@ function TrendChart({
1175
1377
  className: "altertable-chart-column",
1176
1378
  children: /* @__PURE__ */ jsxs4("button", {
1177
1379
  "data-atbl-focus": "ring",
1178
- "data-atbl-control": "action",
1380
+ "data-atbl-control": "default",
1179
1381
  type: "button",
1180
1382
  tabIndex: -1,
1181
1383
  className: "altertable-trend-point",
1182
1384
  "aria-label": `${item.label}: ${formatValue(item.value)} ${unit}`,
1183
1385
  children: [
1184
- /* @__PURE__ */ jsx6("span", {
1185
- className: "altertable-trend-hit",
1186
- children: /* @__PURE__ */ jsx6("span", {
1187
- className: "altertable-trend-dot",
1188
- style: { top: `${points[index].y / 220 * 100}%` }
1189
- })
1386
+ /* @__PURE__ */ jsx7("span", {
1387
+ className: "altertable-trend-hit"
1190
1388
  }),
1191
- /* @__PURE__ */ jsx6("span", {
1389
+ /* @__PURE__ */ jsx7("span", {
1192
1390
  className: "altertable-trend-label",
1193
1391
  children: item.label
1194
1392
  })
@@ -1205,33 +1403,187 @@ function TrendChart({
1205
1403
  }
1206
1404
 
1207
1405
  // src/react/ui/LineChart.tsx
1208
- import { jsx as jsx7 } from "react/jsx-runtime";
1406
+ import { jsx as jsx8 } from "react/jsx-runtime";
1209
1407
  function LineChart(props) {
1210
- return /* @__PURE__ */ jsx7(TrendChart, {
1408
+ return /* @__PURE__ */ jsx8(TrendChart, {
1211
1409
  ...props
1212
1410
  });
1213
1411
  }
1214
1412
  // src/react/ui/AreaChart.tsx
1215
- import { jsx as jsx8 } from "react/jsx-runtime";
1413
+ import { jsx as jsx9 } from "react/jsx-runtime";
1216
1414
  function AreaChart(props) {
1217
- return /* @__PURE__ */ jsx8(TrendChart, {
1415
+ return /* @__PURE__ */ jsx9(TrendChart, {
1218
1416
  ...props,
1219
1417
  area: true
1220
1418
  });
1221
1419
  }
1420
+ // src/react/ui/ChartLegend.tsx
1421
+ import {
1422
+ Children,
1423
+ useId,
1424
+ useState as useState2
1425
+ } from "react";
1426
+ import { jsx as jsx10, jsxs as jsxs5, Fragment as Fragment2 } from "react/jsx-runtime";
1427
+ function ChartLegendRoot({
1428
+ children,
1429
+ layout = "horizontal",
1430
+ align = "start",
1431
+ maxVisibleItems = 6,
1432
+ className,
1433
+ "aria-label": ariaLabel = "Chart legend",
1434
+ ...props
1435
+ }) {
1436
+ const [expanded, setExpanded] = useState2(false);
1437
+ const listId = useId();
1438
+ const items = Children.toArray(children);
1439
+ const limit = Number.isFinite(maxVisibleItems) ? Math.max(1, Math.floor(maxVisibleItems)) : 6;
1440
+ const visibleCount = items.length > limit ? limit - 1 : limit;
1441
+ const hiddenCount = Math.max(0, items.length - visibleCount);
1442
+ return /* @__PURE__ */ jsx10("div", {
1443
+ className: "altertable-chart-legend-container",
1444
+ children: /* @__PURE__ */ jsxs5("ul", {
1445
+ id: listId,
1446
+ ...props,
1447
+ "aria-label": ariaLabel,
1448
+ "data-layout": layout,
1449
+ "data-align": align,
1450
+ className: classNames("altertable-chart-legend", className),
1451
+ children: [
1452
+ expanded ? items : items.slice(0, visibleCount),
1453
+ hiddenCount > 0 && /* @__PURE__ */ jsx10("li", {
1454
+ className: "altertable-chart-legend-overflow",
1455
+ children: /* @__PURE__ */ jsx10("button", {
1456
+ type: "button",
1457
+ "data-atbl-control": "action",
1458
+ "data-atbl-focus": "ring",
1459
+ className: "altertable-chart-legend-action",
1460
+ "aria-expanded": expanded,
1461
+ "aria-controls": props.id ?? listId,
1462
+ onClick: () => setExpanded((value) => !value),
1463
+ children: expanded ? "Show fewer" : `+${hiddenCount} more`
1464
+ })
1465
+ })
1466
+ ]
1467
+ })
1468
+ });
1469
+ }
1470
+ function ChartLegendItem({
1471
+ inactive,
1472
+ className,
1473
+ ...props
1474
+ }) {
1475
+ return /* @__PURE__ */ jsx10("li", {
1476
+ ...props,
1477
+ "data-inactive": inactive || undefined,
1478
+ className: classNames("altertable-chart-legend-item", className)
1479
+ });
1480
+ }
1481
+ function ChartLegendMarker({
1482
+ kind,
1483
+ color = kind === "bar" ? chartBarFill : "var(--atbl-accent)",
1484
+ className,
1485
+ style,
1486
+ ...props
1487
+ }) {
1488
+ return /* @__PURE__ */ jsxs5("svg", {
1489
+ ...props,
1490
+ "aria-hidden": "true",
1491
+ focusable: "false",
1492
+ viewBox: "0 0 20 12",
1493
+ "data-kind": kind,
1494
+ className: classNames("altertable-chart-legend-marker", className),
1495
+ style: { color, ...style },
1496
+ children: [
1497
+ kind === "bar" && /* @__PURE__ */ jsx10("path", {
1498
+ d: "M6 11V3Q6 1 8 1H12Q14 1 14 3V11Z",
1499
+ fill: "currentColor"
1500
+ }),
1501
+ kind === "slice" && /* @__PURE__ */ jsx10("rect", {
1502
+ x: "5",
1503
+ y: "1",
1504
+ width: "10",
1505
+ height: "10",
1506
+ rx: "2",
1507
+ fill: "currentColor"
1508
+ }),
1509
+ kind === "point" && /* @__PURE__ */ jsx10("circle", {
1510
+ cx: "10",
1511
+ cy: "6",
1512
+ r: "3",
1513
+ fill: "currentColor"
1514
+ }),
1515
+ kind === "line" && /* @__PURE__ */ jsxs5(Fragment2, {
1516
+ children: [
1517
+ /* @__PURE__ */ jsx10("path", {
1518
+ d: "M1 6H19",
1519
+ fill: "none",
1520
+ stroke: "currentColor",
1521
+ strokeWidth: "2",
1522
+ strokeLinecap: "round"
1523
+ }),
1524
+ /* @__PURE__ */ jsx10("circle", {
1525
+ cx: "10",
1526
+ cy: "6",
1527
+ r: "2.5",
1528
+ fill: "var(--atbl-surface)",
1529
+ stroke: "currentColor",
1530
+ strokeWidth: "2"
1531
+ })
1532
+ ]
1533
+ }),
1534
+ kind === "area" && /* @__PURE__ */ jsxs5(Fragment2, {
1535
+ children: [
1536
+ /* @__PURE__ */ jsx10("path", {
1537
+ d: "M1 10L7 5L13 7L19 2V11H1Z",
1538
+ fill: "currentColor",
1539
+ fillOpacity: "0.14"
1540
+ }),
1541
+ /* @__PURE__ */ jsx10("path", {
1542
+ d: "M1 10L7 5L13 7L19 2",
1543
+ fill: "none",
1544
+ stroke: "currentColor",
1545
+ strokeWidth: "2",
1546
+ strokeLinejoin: "round",
1547
+ strokeLinecap: "round"
1548
+ })
1549
+ ]
1550
+ })
1551
+ ]
1552
+ });
1553
+ }
1554
+ function ChartLegendLabel({
1555
+ className,
1556
+ children,
1557
+ title,
1558
+ ...props
1559
+ }) {
1560
+ return /* @__PURE__ */ jsx10("span", {
1561
+ ...props,
1562
+ title: title ?? (typeof children === "string" ? children : undefined),
1563
+ className: classNames("altertable-chart-legend-label", className),
1564
+ children
1565
+ });
1566
+ }
1567
+ var ChartLegend = Object.assign(ChartLegendRoot, {
1568
+ Item: ChartLegendItem,
1569
+ Marker: ChartLegendMarker,
1570
+ Label: ChartLegendLabel
1571
+ });
1572
+
1222
1573
  // src/react/ui/PieChart.tsx
1223
- import { useState } from "react";
1224
- import { jsx as jsx9, jsxs as jsxs5, Fragment as Fragment2 } from "react/jsx-runtime";
1574
+ import { useState as useState3 } from "react";
1575
+ import { jsx as jsx11, jsxs as jsxs6, Fragment as Fragment3 } from "react/jsx-runtime";
1225
1576
  function PieChart({
1226
1577
  items,
1227
1578
  unit,
1228
1579
  ariaLabel,
1580
+ showLegend = true,
1229
1581
  formatValue = (value) => new Intl.NumberFormat().format(value)
1230
1582
  }) {
1231
1583
  validateChartItems("pie", items);
1232
- const [previewId, setPreviewId] = useState(null);
1233
- const [plotOpen, setPlotOpen] = useState(false);
1234
- const [legendId, setLegendId] = useState(null);
1584
+ const [previewId, setPreviewId] = useState3(null);
1585
+ const [plotOpen, setPlotOpen] = useState3(false);
1586
+ const [legendId, setLegendId] = useState3(null);
1235
1587
  const maximum = items.reduce((max, item) => Math.max(max, item.value), 0);
1236
1588
  const total = maximum ? items.reduce((sum, item) => sum + item.value / maximum, 0) : 0;
1237
1589
  let cursor = -Math.PI / 2;
@@ -1258,12 +1610,12 @@ function PieChart({
1258
1610
  }).format(share);
1259
1611
  }
1260
1612
  function detail(item) {
1261
- return /* @__PURE__ */ jsxs5(Fragment2, {
1613
+ return /* @__PURE__ */ jsxs6(Fragment3, {
1262
1614
  children: [
1263
- /* @__PURE__ */ jsx9("strong", {
1615
+ /* @__PURE__ */ jsx11("strong", {
1264
1616
  children: item.label
1265
1617
  }),
1266
- /* @__PURE__ */ jsxs5("span", {
1618
+ /* @__PURE__ */ jsxs6("span", {
1267
1619
  children: [
1268
1620
  formatValue(item.value),
1269
1621
  " ",
@@ -1276,37 +1628,37 @@ function PieChart({
1276
1628
  });
1277
1629
  }
1278
1630
  const preview = slices.find((item) => item.id === previewId);
1279
- return /* @__PURE__ */ jsxs5("section", {
1631
+ return /* @__PURE__ */ jsxs6("section", {
1280
1632
  className: "altertable-pie-chart",
1281
1633
  "aria-label": ariaLabel,
1282
1634
  children: [
1283
- items.length === 0 && /* @__PURE__ */ jsx9("span", {
1635
+ items.length === 0 && /* @__PURE__ */ jsx11("span", {
1284
1636
  children: "No data"
1285
1637
  }),
1286
- items.length > 0 && /* @__PURE__ */ jsxs5(Fragment2, {
1638
+ items.length > 0 && /* @__PURE__ */ jsxs6(Fragment3, {
1287
1639
  children: [
1288
- /* @__PURE__ */ jsxs5("div", {
1640
+ /* @__PURE__ */ jsxs6("div", {
1289
1641
  className: "altertable-pie-plot",
1290
1642
  children: [
1291
- /* @__PURE__ */ jsx9(Tooltip2, {
1643
+ /* @__PURE__ */ jsx11(Tooltip2, {
1292
1644
  variant: "chart",
1293
1645
  className: "altertable-pie-tooltip",
1294
1646
  onOpenChange: setPlotOpen,
1295
1647
  content: preview ? detail(preview) : null,
1296
- children: /* @__PURE__ */ jsx9("svg", {
1648
+ children: /* @__PURE__ */ jsx11("svg", {
1297
1649
  viewBox: "0 0 220 220",
1298
1650
  "aria-hidden": "true",
1299
1651
  focusable: "false",
1300
- children: total === 0 ? /* @__PURE__ */ jsx9("circle", {
1652
+ children: total === 0 ? /* @__PURE__ */ jsx11("circle", {
1301
1653
  cx: "110",
1302
1654
  cy: "110",
1303
1655
  r: "100",
1304
1656
  className: "altertable-pie-empty"
1305
- }) : slices.filter((item) => item.share > 0).map((item) => /* @__PURE__ */ jsx9("path", {
1657
+ }) : slices.filter((item) => item.share > 0).map((item) => /* @__PURE__ */ jsx11("path", {
1306
1658
  d: item.path,
1307
1659
  fill: item.color,
1308
1660
  className: "altertable-pie-slice",
1309
- "data-active": item.id === (plotOpen && previewId ? previewId : legendId) || undefined,
1661
+ "data-active": item.id === (plotOpen && previewId ? previewId : showLegend ? legendId : null) || undefined,
1310
1662
  onPointerDown: (event) => {
1311
1663
  if (plotOpen && previewId !== item.id)
1312
1664
  event.preventDefault();
@@ -1323,40 +1675,44 @@ function PieChart({
1323
1675
  }, item.id))
1324
1676
  })
1325
1677
  }),
1326
- total === 0 && /* @__PURE__ */ jsx9("span", {
1678
+ total === 0 && /* @__PURE__ */ jsx11("span", {
1327
1679
  className: "altertable-pie-empty-label",
1328
1680
  children: "No nonzero values"
1329
1681
  })
1330
1682
  ]
1331
1683
  }),
1332
- /* @__PURE__ */ jsx9("div", {
1684
+ showLegend && /* @__PURE__ */ jsx11(ChartLegend, {
1685
+ layout: "vertical",
1686
+ "aria-label": `${ariaLabel} legend`,
1333
1687
  className: "altertable-pie-legend",
1334
- children: slices.map((item) => /* @__PURE__ */ jsx9(Tooltip2, {
1335
- variant: "chart",
1336
- content: detail(item),
1337
- onOpenChange: (open) => setLegendId((current) => open ? item.id : current === item.id ? null : current),
1338
- children: /* @__PURE__ */ jsxs5("button", {
1339
- "data-atbl-focus": "ring",
1340
- "data-atbl-control": "action",
1341
- type: "button",
1342
- tabIndex: -1,
1343
- "aria-label": `${item.label}: ${formatValue(item.value)} ${unit}, ${percent(item.share)}`,
1344
- children: [
1345
- /* @__PURE__ */ jsx9("span", {
1346
- className: "altertable-pie-key",
1347
- style: { background: item.color }
1348
- }),
1349
- /* @__PURE__ */ jsx9("span", {
1350
- className: "altertable-pie-label",
1351
- children: item.label
1352
- }),
1353
- /* @__PURE__ */ jsx9("strong", {
1354
- children: formatValue(item.value)
1355
- }),
1356
- /* @__PURE__ */ jsx9("span", {
1357
- children: percent(item.share)
1358
- })
1359
- ]
1688
+ children: slices.map((item) => /* @__PURE__ */ jsx11(ChartLegend.Item, {
1689
+ children: /* @__PURE__ */ jsx11(Tooltip2, {
1690
+ variant: "chart",
1691
+ content: detail(item),
1692
+ onOpenChange: (open) => setLegendId((current) => open ? item.id : current === item.id ? null : current),
1693
+ children: /* @__PURE__ */ jsxs6("button", {
1694
+ "data-atbl-focus": "ring",
1695
+ "data-atbl-control": "default",
1696
+ type: "button",
1697
+ tabIndex: -1,
1698
+ "aria-label": `${item.label}: ${formatValue(item.value)} ${unit}, ${percent(item.share)}`,
1699
+ children: [
1700
+ /* @__PURE__ */ jsx11(ChartLegend.Marker, {
1701
+ kind: "slice",
1702
+ color: item.color
1703
+ }),
1704
+ /* @__PURE__ */ jsx11(ChartLegend.Label, {
1705
+ className: "altertable-pie-label",
1706
+ children: item.label
1707
+ }),
1708
+ /* @__PURE__ */ jsx11("strong", {
1709
+ children: formatValue(item.value)
1710
+ }),
1711
+ /* @__PURE__ */ jsx11("span", {
1712
+ children: percent(item.share)
1713
+ })
1714
+ ]
1715
+ })
1360
1716
  })
1361
1717
  }, item.id))
1362
1718
  })
@@ -1366,7 +1722,7 @@ function PieChart({
1366
1722
  });
1367
1723
  }
1368
1724
  // src/react/ui/ScatterChart.tsx
1369
- import { jsx as jsx10, jsxs as jsxs6, Fragment as Fragment3 } from "react/jsx-runtime";
1725
+ import { jsx as jsx12, jsxs as jsxs7, Fragment as Fragment4 } from "react/jsx-runtime";
1370
1726
  function formatNumber(value) {
1371
1727
  return new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value);
1372
1728
  }
@@ -1395,37 +1751,37 @@ function ScatterChart({
1395
1751
  validateChartItems("scatter", items);
1396
1752
  const xScale = scale(items.map((item) => item.x));
1397
1753
  const yScale = scale(items.map((item) => item.y));
1398
- return /* @__PURE__ */ jsxs6("section", {
1754
+ return /* @__PURE__ */ jsxs7("section", {
1399
1755
  className: "altertable-scatter-chart",
1400
1756
  "aria-label": ariaLabel,
1401
1757
  children: [
1402
- items.length === 0 && /* @__PURE__ */ jsx10("span", {
1758
+ items.length === 0 && /* @__PURE__ */ jsx12("span", {
1403
1759
  children: "No data"
1404
1760
  }),
1405
- items.length > 0 && /* @__PURE__ */ jsxs6(Fragment3, {
1761
+ items.length > 0 && /* @__PURE__ */ jsxs7(Fragment4, {
1406
1762
  children: [
1407
- /* @__PURE__ */ jsxs6("p", {
1763
+ /* @__PURE__ */ jsxs7("p", {
1408
1764
  className: "altertable-scatter-axis-title",
1409
1765
  children: [
1410
1766
  yLabel,
1411
1767
  yUnit && ` (${yUnit})`
1412
1768
  ]
1413
1769
  }),
1414
- /* @__PURE__ */ jsx10("div", {
1770
+ /* @__PURE__ */ jsx12("div", {
1415
1771
  className: "altertable-scatter-axes",
1416
- children: /* @__PURE__ */ jsxs6("div", {
1772
+ children: /* @__PURE__ */ jsxs7("div", {
1417
1773
  className: "altertable-scatter-plot",
1418
1774
  children: [
1419
- yScale.ticks.map((value, index) => /* @__PURE__ */ jsx10("div", {
1775
+ yScale.ticks.map((value, index) => /* @__PURE__ */ jsx12("div", {
1420
1776
  className: "altertable-scatter-gridline",
1421
1777
  style: { bottom: `${index * 50}%` },
1422
1778
  "aria-hidden": "true",
1423
- children: /* @__PURE__ */ jsx10("span", {
1779
+ children: /* @__PURE__ */ jsx12("span", {
1424
1780
  title: formatY(value),
1425
1781
  children: formatY(value)
1426
1782
  })
1427
1783
  }, index)),
1428
- xScale.ticks.map((value, index) => /* @__PURE__ */ jsx10("span", {
1784
+ xScale.ticks.map((value, index) => /* @__PURE__ */ jsx12("span", {
1429
1785
  className: "altertable-scatter-x-tick",
1430
1786
  "data-edge": index,
1431
1787
  style: { left: `${index * 50}%` },
@@ -1433,14 +1789,14 @@ function ScatterChart({
1433
1789
  title: formatX(value),
1434
1790
  children: formatX(value)
1435
1791
  }, index)),
1436
- items.map((item) => /* @__PURE__ */ jsx10(Tooltip2, {
1792
+ items.map((item) => /* @__PURE__ */ jsx12(Tooltip2, {
1437
1793
  variant: "chart",
1438
- content: /* @__PURE__ */ jsxs6(Fragment3, {
1794
+ content: /* @__PURE__ */ jsxs7(Fragment4, {
1439
1795
  children: [
1440
- /* @__PURE__ */ jsx10("strong", {
1796
+ /* @__PURE__ */ jsx12("strong", {
1441
1797
  children: item.label
1442
1798
  }),
1443
- /* @__PURE__ */ jsxs6("span", {
1799
+ /* @__PURE__ */ jsxs7("span", {
1444
1800
  children: [
1445
1801
  xLabel,
1446
1802
  ": ",
@@ -1449,7 +1805,7 @@ function ScatterChart({
1449
1805
  xUnit
1450
1806
  ]
1451
1807
  }),
1452
- /* @__PURE__ */ jsxs6("span", {
1808
+ /* @__PURE__ */ jsxs7("span", {
1453
1809
  children: [
1454
1810
  yLabel,
1455
1811
  ": ",
@@ -1465,20 +1821,20 @@ function ScatterChart({
1465
1821
  left: `${xScale.position(item.x)}%`,
1466
1822
  bottom: `${yScale.position(item.y)}%`
1467
1823
  },
1468
- children: /* @__PURE__ */ jsx10("button", {
1824
+ children: /* @__PURE__ */ jsx12("button", {
1469
1825
  "data-atbl-focus": "ring",
1470
- "data-atbl-control": "action",
1826
+ "data-atbl-control": "default",
1471
1827
  type: "button",
1472
1828
  tabIndex: -1,
1473
1829
  className: "altertable-scatter-point",
1474
1830
  "aria-label": `${item.label}: ${xLabel} ${formatX(item.x)} ${xUnit}, ${yLabel} ${formatY(item.y)} ${yUnit}`,
1475
- children: /* @__PURE__ */ jsx10("span", {})
1831
+ children: /* @__PURE__ */ jsx12("span", {})
1476
1832
  })
1477
1833
  }, item.id))
1478
1834
  ]
1479
1835
  })
1480
1836
  }),
1481
- /* @__PURE__ */ jsxs6("p", {
1837
+ /* @__PURE__ */ jsxs7("p", {
1482
1838
  className: "altertable-scatter-axis-title altertable-scatter-x-title",
1483
1839
  children: [
1484
1840
  xLabel,
@@ -1491,8 +1847,9 @@ function ScatterChart({
1491
1847
  });
1492
1848
  }
1493
1849
  // src/react/ui/BarChart.tsx
1494
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef2 } from "react";
1495
- import { jsx as jsx11, jsxs as jsxs7, Fragment as Fragment4 } from "react/jsx-runtime";
1850
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState as useState4 } from "react";
1851
+ import { BarChart as RechartsBarChart, Cell } from "recharts";
1852
+ import { jsx as jsx13, jsxs as jsxs8, Fragment as Fragment5 } from "react/jsx-runtime";
1496
1853
  function BarChart({
1497
1854
  items,
1498
1855
  unit,
@@ -1500,6 +1857,7 @@ function BarChart({
1500
1857
  formatValue = (value) => new Intl.NumberFormat().format(value)
1501
1858
  }) {
1502
1859
  validateChartItems("bar", items);
1860
+ const [activeId, setActiveId] = useState4();
1503
1861
  const scrollport = useRef2(null);
1504
1862
  useLayoutEffect2(() => {
1505
1863
  const element = scrollport.current;
@@ -1507,68 +1865,350 @@ function BarChart({
1507
1865
  element.scrollLeft = element.scrollWidth - element.clientWidth;
1508
1866
  }, [items]);
1509
1867
  const maximum = items.reduce((max, item) => Math.max(max, item.value), 1);
1510
- return /* @__PURE__ */ jsxs7("section", {
1868
+ return /* @__PURE__ */ jsxs8("section", {
1511
1869
  className: "altertable-selectable-bars",
1512
1870
  "aria-label": ariaLabel,
1513
1871
  children: [
1514
- items.length === 0 && /* @__PURE__ */ jsx11("span", {
1872
+ items.length === 0 && /* @__PURE__ */ jsx13("span", {
1515
1873
  children: "No data"
1516
1874
  }),
1517
- /* @__PURE__ */ jsx11("div", {
1875
+ /* @__PURE__ */ jsx13("div", {
1518
1876
  className: "altertable-selectable-bars-scroll",
1519
1877
  ref: scrollport,
1520
- children: items.map((item) => /* @__PURE__ */ jsx11(Tooltip2, {
1521
- variant: "chart",
1522
- content: /* @__PURE__ */ jsxs7(Fragment4, {
1523
- children: [
1524
- /* @__PURE__ */ jsx11("strong", {
1525
- children: item.label
1526
- }),
1527
- /* @__PURE__ */ jsxs7("span", {
1878
+ children: /* @__PURE__ */ jsxs8("div", {
1879
+ className: "altertable-selectable-bars-plot",
1880
+ style: { minWidth: items.length * 45 },
1881
+ children: [
1882
+ /* @__PURE__ */ jsx13("div", {
1883
+ className: "altertable-chart-canvas",
1884
+ "aria-hidden": "true",
1885
+ children: /* @__PURE__ */ jsxs8(RechartsBarChart, {
1886
+ data: items.map((item) => ({
1887
+ ...item,
1888
+ plotValue: item.value / maximum
1889
+ })),
1890
+ title: ariaLabel,
1891
+ responsive: true,
1892
+ width: "100%",
1893
+ height: 220,
1894
+ margin: { top: 0, right: 0, bottom: 0, left: 0 },
1895
+ accessibilityLayer: false,
1896
+ tabIndex: -1,
1897
+ barCategoryGap: "24%",
1528
1898
  children: [
1529
- formatValue(item.value),
1530
- " ",
1531
- unit
1899
+ /* @__PURE__ */ jsx13(ChartXAxis, {
1900
+ hide: true,
1901
+ dataKey: "id",
1902
+ scale: "band"
1903
+ }),
1904
+ /* @__PURE__ */ jsx13(ChartYAxis, {
1905
+ hide: true,
1906
+ domain: [0, 1],
1907
+ allowDataOverflow: true
1908
+ }),
1909
+ /* @__PURE__ */ jsx13(ChartBar, {
1910
+ dataKey: "plotValue",
1911
+ minPointSize: (value) => (value ?? 0) > 0 ? 7 : 0,
1912
+ children: items.map((item) => /* @__PURE__ */ jsx13(Cell, {
1913
+ fill: activeId === item.id ? "var(--atbl-accent)" : chartBarFill
1914
+ }, item.id))
1915
+ })
1532
1916
  ]
1533
1917
  })
1534
- ]
1535
- }),
1536
- className: "altertable-chart-column",
1537
- children: /* @__PURE__ */ jsxs7("button", {
1538
- "data-atbl-focus": "ring",
1539
- "data-atbl-control": "action",
1540
- type: "button",
1541
- tabIndex: -1,
1542
- className: "altertable-selectable-bars-item",
1543
- "aria-label": `${item.label}: ${formatValue(item.value)} ${unit}`,
1544
- children: [
1545
- /* @__PURE__ */ jsx11("span", {
1546
- className: "altertable-selectable-bars-area",
1547
- children: /* @__PURE__ */ jsx11("span", {
1548
- className: "altertable-selectable-bars-bar",
1549
- style: {
1550
- height: `${Math.max(item.value > 0 ? 3 : 0, item.value / maximum * 100)}%`
1551
- }
1918
+ }),
1919
+ /* @__PURE__ */ jsx13("div", {
1920
+ className: "altertable-selectable-bars-items",
1921
+ children: items.map((item) => /* @__PURE__ */ jsx13(Tooltip2, {
1922
+ variant: "chart",
1923
+ onOpenChange: (open) => setActiveId((current) => open ? item.id : current === item.id ? undefined : current),
1924
+ content: /* @__PURE__ */ jsxs8(Fragment5, {
1925
+ children: [
1926
+ /* @__PURE__ */ jsx13("strong", {
1927
+ children: item.label
1928
+ }),
1929
+ /* @__PURE__ */ jsxs8("span", {
1930
+ children: [
1931
+ formatValue(item.value),
1932
+ " ",
1933
+ unit
1934
+ ]
1935
+ })
1936
+ ]
1937
+ }),
1938
+ className: "altertable-chart-column",
1939
+ children: /* @__PURE__ */ jsxs8("button", {
1940
+ "data-atbl-focus": "ring",
1941
+ "data-atbl-control": "default",
1942
+ type: "button",
1943
+ tabIndex: -1,
1944
+ className: "altertable-selectable-bars-item",
1945
+ "aria-label": `${item.label}: ${formatValue(item.value)} ${unit}`,
1946
+ children: [
1947
+ /* @__PURE__ */ jsx13("span", {
1948
+ className: "altertable-selectable-bars-area"
1949
+ }),
1950
+ /* @__PURE__ */ jsx13("span", {
1951
+ className: "altertable-selectable-bars-label",
1952
+ children: item.label
1953
+ })
1954
+ ]
1552
1955
  })
1553
- }),
1554
- /* @__PURE__ */ jsx11("span", {
1555
- className: "altertable-selectable-bars-label",
1556
- children: item.label
1557
- })
1558
- ]
1559
- })
1560
- }, item.id))
1956
+ }, item.id))
1957
+ })
1958
+ ]
1959
+ })
1960
+ })
1961
+ ]
1962
+ });
1963
+ }
1964
+ // src/react/ui/RadioGroup.tsx
1965
+ import {
1966
+ RadioGroup as AriaRadioGroup,
1967
+ Radio as AriaRadio,
1968
+ Label
1969
+ } from "react-aria-components";
1970
+ import { jsx as jsx14, jsxs as jsxs9, Fragment as Fragment6 } from "react/jsx-runtime";
1971
+ function RadioGroup({
1972
+ label,
1973
+ className,
1974
+ children,
1975
+ ...props
1976
+ }) {
1977
+ return /* @__PURE__ */ jsxs9(AriaRadioGroup, {
1978
+ ...props,
1979
+ className: classNames("altertable-radio-group", className),
1980
+ children: [
1981
+ /* @__PURE__ */ jsx14(Label, {
1982
+ className: "altertable-control-label",
1983
+ children: label
1984
+ }),
1985
+ children
1986
+ ]
1987
+ });
1988
+ }
1989
+ function Radio({ className, children, ...props }) {
1990
+ return /* @__PURE__ */ jsx14(AriaRadio, {
1991
+ ...props,
1992
+ "data-atbl-control": "action",
1993
+ "data-atbl-focus": "ring",
1994
+ className: classNames("altertable-radio", className),
1995
+ children: (state) => /* @__PURE__ */ jsxs9(Fragment6, {
1996
+ children: [
1997
+ /* @__PURE__ */ jsx14("span", {
1998
+ className: "altertable-radio-mark",
1999
+ "aria-hidden": "true"
2000
+ }),
2001
+ typeof children === "function" ? children(state) : children
2002
+ ]
2003
+ })
2004
+ });
2005
+ }
2006
+ function SegmentedControl({
2007
+ options,
2008
+ className,
2009
+ ...props
2010
+ }) {
2011
+ validateChoiceOptions(options);
2012
+ return /* @__PURE__ */ jsx14(RadioGroup, {
2013
+ ...props,
2014
+ orientation: "horizontal",
2015
+ className: classNames("altertable-segmented-control", className),
2016
+ children: /* @__PURE__ */ jsx14("div", {
2017
+ className: "altertable-segmented-options",
2018
+ children: options.map((option) => /* @__PURE__ */ jsx14(Radio, {
2019
+ value: option.id,
2020
+ "data-atbl-internal-surface": "option",
2021
+ children: option.label
2022
+ }, option.id))
2023
+ })
2024
+ });
2025
+ }
2026
+ // src/react/ui/CheckboxGroup.tsx
2027
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
2028
+ function CheckboxGroup({
2029
+ label,
2030
+ values,
2031
+ onChange,
2032
+ className,
2033
+ children,
2034
+ disabled,
2035
+ ...props
2036
+ }) {
2037
+ invariant(new Set(values).size === values.length, "Checkbox group values must be unique.");
2038
+ return /* @__PURE__ */ jsxs10("fieldset", {
2039
+ ...props,
2040
+ disabled,
2041
+ className: classNames("altertable-checkbox-group", className),
2042
+ children: [
2043
+ /* @__PURE__ */ jsx15("legend", {
2044
+ children: label
2045
+ }),
2046
+ /* @__PURE__ */ jsx15(CheckboxGroupContext, {
2047
+ value: {
2048
+ values,
2049
+ disabled,
2050
+ onChange(value, checked) {
2051
+ onChange(checked ? [...values.filter((item) => item !== value), value] : values.filter((item) => item !== value));
2052
+ }
2053
+ },
2054
+ children
1561
2055
  })
1562
2056
  ]
1563
2057
  });
1564
2058
  }
2059
+ // src/react/ui/ComposedChartLegend.tsx
2060
+ import { Legend } from "recharts";
2061
+ import { jsx as jsx16, jsxs as jsxs11, Fragment as Fragment7 } from "react/jsx-runtime";
2062
+ var legendMarkerKinds = {
2063
+ square: "area",
2064
+ rect: "bar",
2065
+ line: "line",
2066
+ plainline: "line"
2067
+ };
2068
+ function LegendContent({
2069
+ payload = [],
2070
+ maxVisibleItems,
2071
+ formatter,
2072
+ layout,
2073
+ align,
2074
+ labelStyle,
2075
+ iconType,
2076
+ iconSize = 20,
2077
+ inactiveColor = "var(--atbl-muted)",
2078
+ position,
2079
+ verticalAlign,
2080
+ onClick,
2081
+ onMouseEnter,
2082
+ onMouseLeave,
2083
+ "aria-label": ariaLabel
2084
+ }) {
2085
+ if (!payload.some((entry) => entry.type !== "none"))
2086
+ return null;
2087
+ const vertical = layout === "vertical" || layout === "auto" && (position === "left" || position === "right");
2088
+ return /* @__PURE__ */ jsx16(ChartLegend, {
2089
+ "aria-label": ariaLabel,
2090
+ className: position === "top" || position == null && verticalAlign === "top" ? "altertable-composed-chart-legend-above" : position === "bottom" || position == null && verticalAlign !== "middle" && !vertical ? "altertable-composed-chart-legend-below" : undefined,
2091
+ maxVisibleItems,
2092
+ layout: vertical ? "vertical" : "horizontal",
2093
+ align: align === "right" ? "end" : align === "left" ? "start" : "center",
2094
+ children: payload.map((entry, index) => {
2095
+ if (entry.type === "none")
2096
+ return null;
2097
+ const type = iconType ?? entry.type;
2098
+ const kind = legendMarkerKinds[type ?? "none"] ?? "point";
2099
+ const formatLabel = entry.formatter ?? formatter;
2100
+ const label = formatLabel ? formatLabel(entry.value, entry, index) : entry.value;
2101
+ const content = /* @__PURE__ */ jsxs11(Fragment7, {
2102
+ children: [
2103
+ type !== "none" && (entry.legendIcon ?? /* @__PURE__ */ jsx16(ChartLegend.Marker, {
2104
+ kind,
2105
+ color: entry.inactive ? inactiveColor : entry.color,
2106
+ style: { width: iconSize, height: iconSize * 0.6 }
2107
+ })),
2108
+ /* @__PURE__ */ jsx16(ChartLegend.Label, {
2109
+ style: labelStyle,
2110
+ children: label
2111
+ })
2112
+ ]
2113
+ });
2114
+ return /* @__PURE__ */ jsx16(ChartLegend.Item, {
2115
+ inactive: entry.inactive,
2116
+ onMouseEnter: onMouseEnter ? (event) => onMouseEnter(entry, index, event) : undefined,
2117
+ onMouseLeave: onMouseLeave ? (event) => onMouseLeave(entry, index, event) : undefined,
2118
+ children: onClick ? /* @__PURE__ */ jsx16("button", {
2119
+ type: "button",
2120
+ "data-atbl-control": "action",
2121
+ "data-atbl-focus": "ring",
2122
+ className: "altertable-chart-legend-action",
2123
+ onClick: (event) => onClick(entry, index, event),
2124
+ children: content
2125
+ }) : content
2126
+ }, index);
2127
+ })
2128
+ });
2129
+ }
2130
+ function ComposedChartLegend({
2131
+ maxVisibleItems,
2132
+ ...props
2133
+ }) {
2134
+ return /* @__PURE__ */ jsx16(Legend, {
2135
+ iconSize: 20,
2136
+ inactiveColor: "var(--atbl-muted)",
2137
+ content: /* @__PURE__ */ jsx16(LegendContent, {
2138
+ maxVisibleItems
2139
+ }),
2140
+ ...props
2141
+ });
2142
+ }
2143
+
2144
+ // src/react/ui/ComposedChart.tsx
2145
+ import {
2146
+ ComposedChart as RechartsComposedChart,
2147
+ ZAxis,
2148
+ ReferenceLine as ReferenceLine2,
2149
+ ReferenceArea,
2150
+ ReferenceDot,
2151
+ Brush,
2152
+ Cell as Cell2,
2153
+ Label as Label2,
2154
+ LabelList,
2155
+ ErrorBar
2156
+ } from "recharts";
2157
+ import { jsx as jsx17 } from "react/jsx-runtime";
2158
+ function ComposedChartRoot({
2159
+ data,
2160
+ ariaLabel,
2161
+ width = "100%",
2162
+ height = 300,
2163
+ responsive = true,
2164
+ className,
2165
+ ...props
2166
+ }) {
2167
+ return /* @__PURE__ */ jsx17("section", {
2168
+ className: ["altertable-composed-chart", className].filter(Boolean).join(" "),
2169
+ "aria-label": ariaLabel,
2170
+ children: /* @__PURE__ */ jsx17(RechartsComposedChart, {
2171
+ "data-atbl-focus": "inset",
2172
+ ...props,
2173
+ data,
2174
+ width,
2175
+ height,
2176
+ responsive,
2177
+ title: ariaLabel
2178
+ })
2179
+ });
2180
+ }
2181
+ var ComposedChart = Object.assign(ComposedChartRoot, {
2182
+ Dot: ChartDot,
2183
+ Area: ChartArea,
2184
+ Bar: ChartBar,
2185
+ Line: ChartLine,
2186
+ Scatter: ChartScatter,
2187
+ XAxis: ChartXAxis,
2188
+ YAxis: ChartYAxis,
2189
+ ZAxis,
2190
+ CartesianGrid: ChartGrid,
2191
+ Tooltip: ChartTooltip,
2192
+ Legend: ComposedChartLegend,
2193
+ ReferenceLine: ReferenceLine2,
2194
+ ReferenceArea,
2195
+ ReferenceDot,
2196
+ Brush,
2197
+ Cell: Cell2,
2198
+ Label: Label2,
2199
+ LabelList,
2200
+ ErrorBar
2201
+ });
1565
2202
  export {
1566
2203
  AboutData2 as AboutData,
1567
2204
  AppIcon2 as AppIcon,
1568
2205
  AreaChart,
1569
2206
  BarChart,
2207
+ ChartLegend,
1570
2208
  Checkbox2 as Checkbox,
1571
- Combobox2 as Combobox,
2209
+ CheckboxGroup,
2210
+ ChoicePicker2 as ChoicePicker,
2211
+ ComposedChart,
1572
2212
  DataApp,
1573
2213
  DataAppProvider2 as DataAppProvider,
1574
2214
  DataAppSkeleton,
@@ -1580,6 +2220,8 @@ export {
1580
2220
  DataWidget2 as DataWidget,
1581
2221
  DateRangePicker2 as DateRangePicker,
1582
2222
  DimensionPicker2 as DimensionPicker,
2223
+ FilterActions2 as FilterActions,
2224
+ FilterBar2 as FilterBar,
1583
2225
  GettingStarted,
1584
2226
  GlossaryDefinition,
1585
2227
  GlossaryExplanation,
@@ -1587,12 +2229,26 @@ export {
1587
2229
  HelpPopover2 as HelpPopover,
1588
2230
  LineChart,
1589
2231
  LiveControl2 as LiveControl,
2232
+ Menu2 as Menu,
2233
+ PressButton as MenuButton,
2234
+ MenuItem2 as MenuItem,
2235
+ MenuPopover2 as MenuPopover,
2236
+ MenuSection2 as MenuSection,
2237
+ MenuSeparator2 as MenuSeparator,
2238
+ MenuTrigger2 as MenuTrigger,
1590
2239
  MetricWidget2 as MetricWidget,
2240
+ NumberField2 as NumberField,
2241
+ NumberFilterPicker2 as NumberFilterPicker,
2242
+ NumberRangeField2 as NumberRangeField,
1591
2243
  PieChart,
1592
2244
  PresentStory2 as PresentStory,
2245
+ Radio,
2246
+ RadioGroup,
1593
2247
  ScatterChart,
1594
2248
  SearchField2 as SearchField,
1595
2249
  SearchMatch2 as SearchMatch,
2250
+ SegmentedControl,
2251
+ Select2 as Select,
1596
2252
  Sheet2 as Sheet,
1597
2253
  Tab2 as Tab,
1598
2254
  TabList2 as TabList,
@@ -1603,12 +2259,14 @@ export {
1603
2259
  TextWidget2 as TextWidget,
1604
2260
  Tooltip2 as Tooltip,
1605
2261
  TooltipProvider2 as TooltipProvider,
2262
+ VariableBar2 as VariableBar,
1606
2263
  VisualizationWidget2 as VisualizationWidget,
1607
2264
  injectDataAppShellStyles,
1608
2265
  injectDataAppStyles2 as injectDataAppStyles,
2266
+ isPlainKeyEvent2 as isPlainKeyEvent,
1609
2267
  searchItems2 as searchItems,
1610
2268
  useAppVariables2 as useAppVariables,
1611
2269
  useViewTab2 as useViewTab
1612
2270
  };
1613
2271
 
1614
- //# debugId=44AF1347DDC5E0E164756E2164756E21
2272
+ //# debugId=FCD41F839B3A5B8964756E2164756E21