@perses-dev/table-plugin 0.13.0 → 0.14.0-beta.2

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 (216) hide show
  1. package/__mf/js/{Table.73b9cec1.js → Table.cede74c3.js} +3 -3
  2. package/__mf/js/async/1186.76f7a9c4.js +2 -0
  3. package/__mf/js/async/1522.f490bae9.js +22 -0
  4. package/__mf/js/async/1616.e459f6f7.js +1 -0
  5. package/__mf/js/async/2035.e9f08b1d.js +1 -0
  6. package/__mf/js/async/2043.ddbebd72.js +2 -0
  7. package/__mf/js/async/2251.2ab11c45.js +7 -0
  8. package/__mf/js/async/{1589.124ce93d.js.LICENSE.txt → 2251.2ab11c45.js.LICENSE.txt} +41 -1
  9. package/__mf/js/async/2465.b442bc56.js +1 -0
  10. package/__mf/js/async/2650.b874a7cd.js +3 -0
  11. package/__mf/js/async/392.3b464b91.js +2 -0
  12. package/__mf/js/async/3923.7b9985ff.js +1 -0
  13. package/__mf/js/async/4077.dfd731dd.js +1 -0
  14. package/__mf/js/async/4121.ed15fe74.js +2 -0
  15. package/__mf/js/async/4496.487e4f10.js +1 -0
  16. package/__mf/js/async/5002.fc50985b.js +1 -0
  17. package/__mf/js/async/5054.a0d861ae.js +1 -0
  18. package/__mf/js/async/5071.1e325f38.js +1 -0
  19. package/__mf/js/async/5153.8a046a40.js +1 -0
  20. package/__mf/js/async/5587.c9c77660.js +1 -0
  21. package/__mf/js/async/{868.507e984c.js → 5741.ef0c5df4.js} +6 -6
  22. package/__mf/js/async/6274.db89316a.js +2 -0
  23. package/__mf/js/async/7192.7e6af5a2.js +1 -0
  24. package/__mf/js/async/7534.63c81960.js +1 -0
  25. package/__mf/js/async/7862.cbf7b286.js +2 -0
  26. package/__mf/js/async/7968.f91456c8.js +1 -0
  27. package/__mf/js/async/7978.4553ce86.js +1 -0
  28. package/__mf/js/async/8356.d5d8a6a3.js +1 -0
  29. package/__mf/js/async/8470.f35cd609.js +2 -0
  30. package/__mf/js/async/873.fc45c2c6.js +1 -0
  31. package/__mf/js/async/8985.6cc7edf9.js +37 -0
  32. package/__mf/js/async/9148.1ff77cf0.js +1 -0
  33. package/__mf/js/async/9207.ca6ac0b2.js +1 -0
  34. package/__mf/js/async/9235.78a103e9.js +1 -0
  35. package/__mf/js/async/9321.ddbe25a2.js +1 -0
  36. package/__mf/js/async/941.96941f4e.js +2 -0
  37. package/__mf/js/async/9588.039ce076.js +1 -0
  38. package/__mf/js/async/__federation_expose_Table.e7708af8.js +1 -0
  39. package/__mf/js/async/lib-router.e968bcc8.js +2 -0
  40. package/__mf/js/{main.7b15c841.js → main.7815ee7c.js} +2 -2
  41. package/lib/Table.d.ts +3 -3
  42. package/lib/Table.d.ts.map +1 -1
  43. package/lib/Table.js +4 -4
  44. package/lib/Table.js.map +1 -1
  45. package/lib/TableExportAction.d.ts +3 -3
  46. package/lib/TableExportAction.d.ts.map +1 -1
  47. package/lib/TableExportAction.js +6 -6
  48. package/lib/TableExportAction.js.map +1 -1
  49. package/lib/bootstrap.js +2 -2
  50. package/lib/components/CellsEditor/CellsEditor.d.ts +2 -2
  51. package/lib/components/CellsEditor/CellsEditor.d.ts.map +1 -1
  52. package/lib/components/CellsEditor/CellsEditor.js +1 -1
  53. package/lib/components/CellsEditor/CellsEditor.js.map +1 -1
  54. package/lib/components/CellsEditor/index.js +1 -1
  55. package/lib/components/CellsEditor/index.js.map +1 -1
  56. package/lib/components/ColumnsEditor/ColumnEditor.d.ts +5 -4
  57. package/lib/components/ColumnsEditor/ColumnEditor.d.ts.map +1 -1
  58. package/lib/components/ColumnsEditor/ColumnEditor.js +29 -15
  59. package/lib/components/ColumnsEditor/ColumnEditor.js.map +1 -1
  60. package/lib/components/ColumnsEditor/ColumnEditorContainer.d.ts +3 -3
  61. package/lib/components/ColumnsEditor/ColumnEditorContainer.d.ts.map +1 -1
  62. package/lib/components/ColumnsEditor/ColumnEditorContainer.js +11 -10
  63. package/lib/components/ColumnsEditor/ColumnEditorContainer.js.map +1 -1
  64. package/lib/components/ColumnsEditor/ColumnsEditor.d.ts +4 -3
  65. package/lib/components/ColumnsEditor/ColumnsEditor.d.ts.map +1 -1
  66. package/lib/components/ColumnsEditor/ColumnsEditor.js +7 -6
  67. package/lib/components/ColumnsEditor/ColumnsEditor.js.map +1 -1
  68. package/lib/components/ColumnsEditor/DataLinkEditorDialog.d.ts +2 -2
  69. package/lib/components/ColumnsEditor/DataLinkEditorDialog.d.ts.map +1 -1
  70. package/lib/components/ColumnsEditor/DataLinkEditorDialog.js +4 -4
  71. package/lib/components/ColumnsEditor/DataLinkEditorDialog.js.map +1 -1
  72. package/lib/components/ColumnsEditor/EmbeddedPanelOptionsEditor.d.ts +2 -2
  73. package/lib/components/ColumnsEditor/EmbeddedPanelOptionsEditor.d.ts.map +1 -1
  74. package/lib/components/ColumnsEditor/EmbeddedPanelOptionsEditor.js +4 -4
  75. package/lib/components/ColumnsEditor/EmbeddedPanelOptionsEditor.js.map +1 -1
  76. package/lib/components/ColumnsEditor/index.js +3 -3
  77. package/lib/components/ColumnsEditor/index.js.map +1 -1
  78. package/lib/components/ConditionalPanel.d.ts +3 -3
  79. package/lib/components/ConditionalPanel.d.ts.map +1 -1
  80. package/lib/components/ConditionalPanel.js +7 -7
  81. package/lib/components/ConditionalPanel.js.map +1 -1
  82. package/lib/components/EmbeddedPanel.d.ts +3 -3
  83. package/lib/components/EmbeddedPanel.d.ts.map +1 -1
  84. package/lib/components/EmbeddedPanel.js +4 -4
  85. package/lib/components/EmbeddedPanel.js.map +1 -1
  86. package/lib/components/TableCellsEditor.d.ts +3 -3
  87. package/lib/components/TableCellsEditor.d.ts.map +1 -1
  88. package/lib/components/TableCellsEditor.js +1 -1
  89. package/lib/components/TableCellsEditor.js.map +1 -1
  90. package/lib/components/TableColumnsEditor.d.ts +3 -3
  91. package/lib/components/TableColumnsEditor.d.ts.map +1 -1
  92. package/lib/components/TableColumnsEditor.js +3 -2
  93. package/lib/components/TableColumnsEditor.js.map +1 -1
  94. package/lib/components/TableItemSelectionActionsEditor.d.ts +2 -2
  95. package/lib/components/TableItemSelectionActionsEditor.d.ts.map +1 -1
  96. package/lib/components/TableItemSelectionActionsEditor.js +2 -2
  97. package/lib/components/TableItemSelectionActionsEditor.js.map +1 -1
  98. package/lib/components/TablePanel.d.ts +4 -4
  99. package/lib/components/TablePanel.d.ts.map +1 -1
  100. package/lib/components/TablePanel.js +196 -99
  101. package/lib/components/TablePanel.js.map +1 -1
  102. package/lib/components/TableSettingsEditor.d.ts +2 -2
  103. package/lib/components/TableSettingsEditor.d.ts.map +1 -1
  104. package/lib/components/TableSettingsEditor.js +16 -2
  105. package/lib/components/TableSettingsEditor.js.map +1 -1
  106. package/lib/components/TableTransformsEditor.d.ts +2 -2
  107. package/lib/components/TableTransformsEditor.d.ts.map +1 -1
  108. package/lib/components/TableTransformsEditor.js +2 -2
  109. package/lib/components/TableTransformsEditor.js.map +1 -1
  110. package/lib/components/index.js +9 -9
  111. package/lib/components/index.js.map +1 -1
  112. package/lib/getPluginModule.d.ts +1 -1
  113. package/lib/getPluginModule.d.ts.map +1 -1
  114. package/lib/getPluginModule.js +3 -1
  115. package/lib/getPluginModule.js.map +1 -1
  116. package/lib/index-federation.js +1 -1
  117. package/lib/index.js +4 -4
  118. package/lib/index.js.map +1 -1
  119. package/lib/models/index.js +2 -2
  120. package/lib/models/index.js.map +1 -1
  121. package/lib/models/model.d.ts +1 -1
  122. package/lib/models/model.d.ts.map +1 -1
  123. package/lib/models/model.js.map +1 -1
  124. package/lib/models/table-model.d.ts +4 -3
  125. package/lib/models/table-model.d.ts.map +1 -1
  126. package/lib/models/table-model.js +2 -2
  127. package/lib/models/table-model.js.map +1 -1
  128. package/lib/setup-tests.d.ts +1 -1
  129. package/lib/setup-tests.d.ts.map +1 -1
  130. package/lib/setup-tests.js +8 -2
  131. package/lib/setup-tests.js.map +1 -1
  132. package/lib/table-data-utils.d.ts +3 -3
  133. package/lib/table-data-utils.d.ts.map +1 -1
  134. package/lib/table-data-utils.js.map +1 -1
  135. package/lib/test/mock-query-results.d.ts +1 -1
  136. package/lib/test/mock-query-results.d.ts.map +1 -1
  137. package/lib/test/mock-query-results.js.map +1 -1
  138. package/mf-manifest.json +48 -46
  139. package/mf-stats.json +52 -47
  140. package/package.json +11 -11
  141. package/__mf/js/async/1432.4e515509.js +0 -1
  142. package/__mf/js/async/1589.124ce93d.js +0 -2
  143. package/__mf/js/async/1616.4828085d.js +0 -1
  144. package/__mf/js/async/2043.1f09864b.js +0 -2
  145. package/__mf/js/async/2082.231e8397.js +0 -1
  146. package/__mf/js/async/2842.a52597e6.js +0 -1
  147. package/__mf/js/async/392.b6035b41.js +0 -2
  148. package/__mf/js/async/3981.52e94742.js +0 -3
  149. package/__mf/js/async/4014.cf88a118.js +0 -7
  150. package/__mf/js/async/4014.cf88a118.js.LICENSE.txt +0 -39
  151. package/__mf/js/async/4121.e7df36d6.js +0 -2
  152. package/__mf/js/async/5002.3eb39a8c.js +0 -1
  153. package/__mf/js/async/5021.c663603d.js +0 -1
  154. package/__mf/js/async/5071.839a8f1a.js +0 -1
  155. package/__mf/js/async/5481.6496fac9.js +0 -2
  156. package/__mf/js/async/5587.a8a428db.js +0 -1
  157. package/__mf/js/async/6274.8edae86d.js +0 -2
  158. package/__mf/js/async/629.8cff215d.js +0 -1
  159. package/__mf/js/async/6811.9d4b123a.js +0 -38
  160. package/__mf/js/async/7177.e0e5ba2f.js +0 -1
  161. package/__mf/js/async/7192.692181c8.js +0 -1
  162. package/__mf/js/async/7413.c9310b8a.js +0 -1
  163. package/__mf/js/async/7968.3a9a982e.js +0 -1
  164. package/__mf/js/async/7978.116e4d81.js +0 -1
  165. package/__mf/js/async/7984.a8edc213.js +0 -22
  166. package/__mf/js/async/8356.152d5686.js +0 -1
  167. package/__mf/js/async/8470.b9762117.js +0 -2
  168. package/__mf/js/async/873.264fedc9.js +0 -1
  169. package/__mf/js/async/9051.c4deebd7.js +0 -1
  170. package/__mf/js/async/9235.c67cdb1d.js +0 -1
  171. package/__mf/js/async/941.cc458a98.js +0 -2
  172. package/__mf/js/async/9588.d23e2ed3.js +0 -1
  173. package/__mf/js/async/9701.9c4cea02.js +0 -1
  174. package/__mf/js/async/__federation_expose_Table.5d0cfb46.js +0 -1
  175. package/__mf/js/async/lib-router.3493bbf9.js +0 -2
  176. package/lib/cjs/Table.js +0 -62
  177. package/lib/cjs/TableExportAction.js +0 -180
  178. package/lib/cjs/bootstrap.js +0 -26
  179. package/lib/cjs/components/CellsEditor/CellsEditor.js +0 -30
  180. package/lib/cjs/components/CellsEditor/index.js +0 -30
  181. package/lib/cjs/components/ColumnsEditor/ColumnEditor.js +0 -289
  182. package/lib/cjs/components/ColumnsEditor/ColumnEditorContainer.js +0 -152
  183. package/lib/cjs/components/ColumnsEditor/ColumnsEditor.js +0 -108
  184. package/lib/cjs/components/ColumnsEditor/DataLinkEditorDialog.js +0 -139
  185. package/lib/cjs/components/ColumnsEditor/EmbeddedPanelOptionsEditor.js +0 -124
  186. package/lib/cjs/components/ColumnsEditor/index.js +0 -32
  187. package/lib/cjs/components/ConditionalPanel.js +0 -367
  188. package/lib/cjs/components/EmbeddedPanel.js +0 -52
  189. package/lib/cjs/components/TableCellsEditor.js +0 -36
  190. package/lib/cjs/components/TableColumnsEditor.js +0 -36
  191. package/lib/cjs/components/TableItemSelectionActionsEditor.js +0 -44
  192. package/lib/cjs/components/TablePanel.js +0 -845
  193. package/lib/cjs/components/TableSettingsEditor.js +0 -144
  194. package/lib/cjs/components/TableTransformsEditor.js +0 -36
  195. package/lib/cjs/components/index.js +0 -38
  196. package/lib/cjs/env.d.js +0 -14
  197. package/lib/cjs/getPluginModule.js +0 -39
  198. package/lib/cjs/index-federation.js +0 -55
  199. package/lib/cjs/index.js +0 -39
  200. package/lib/cjs/models/index.js +0 -31
  201. package/lib/cjs/models/model.js +0 -16
  202. package/lib/cjs/models/table-model.js +0 -278
  203. package/lib/cjs/setup-tests.js +0 -19
  204. package/lib/cjs/table-data-utils.js +0 -84
  205. package/lib/cjs/test/mock-query-results.js +0 -524
  206. /package/__mf/css/async/{4014.85c2cbf6.css → 2251.85c2cbf6.css} +0 -0
  207. /package/__mf/js/async/{7984.a8edc213.js.LICENSE.txt → 1522.f490bae9.js.LICENSE.txt} +0 -0
  208. /package/__mf/js/async/{2043.1f09864b.js.LICENSE.txt → 2043.ddbebd72.js.LICENSE.txt} +0 -0
  209. /package/__mf/js/async/{392.b6035b41.js.LICENSE.txt → 392.3b464b91.js.LICENSE.txt} +0 -0
  210. /package/__mf/js/async/{4121.e7df36d6.js.LICENSE.txt → 4121.ed15fe74.js.LICENSE.txt} +0 -0
  211. /package/__mf/js/async/{868.507e984c.js.LICENSE.txt → 5741.ef0c5df4.js.LICENSE.txt} +0 -0
  212. /package/__mf/js/async/{6274.8edae86d.js.LICENSE.txt → 6274.db89316a.js.LICENSE.txt} +0 -0
  213. /package/__mf/js/async/{5481.6496fac9.js.LICENSE.txt → 7862.cbf7b286.js.LICENSE.txt} +0 -0
  214. /package/__mf/js/async/{8470.b9762117.js.LICENSE.txt → 8470.f35cd609.js.LICENSE.txt} +0 -0
  215. /package/__mf/js/async/{941.cc458a98.js.LICENSE.txt → 941.96941f4e.js.LICENSE.txt} +0 -0
  216. /package/__mf/js/async/{lib-router.3493bbf9.js.LICENSE.txt → lib-router.e968bcc8.js.LICENSE.txt} +0 -0
@@ -1,4 +1,3 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
1
  // Copyright The Perses Authors
3
2
  // Licensed under the Apache License, Version 2.0 (the "License");
4
3
  // you may not use this file except in compliance with the License.
@@ -11,14 +10,16 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
11
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
11
  // See the License for the specific language governing permissions and
13
12
  // limitations under the License.
14
- import { Box, Typography, useTheme } from '@mui/material';
15
- import { formatValue, Table, transformData, useSelection } from '@perses-dev/components';
16
- import { useSelectionItemActions } from '@perses-dev/dashboards';
17
- import { CalculationsMap, replaceVariablesInString, useAllVariableValues } from '@perses-dev/plugin-system';
18
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
19
- import { evaluateConditionalFormatting } from '../models';
20
- import { buildRawTableData, getTablePanelQueryMode } from '../table-data-utils';
21
- import { EmbeddedPanel } from './EmbeddedPanel';
13
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
+ import { Box, Typography, useTheme } from "@mui/material";
15
+ import { formatValue, Table, transformData, useSelection } from "@perses-dev/components";
16
+ import { useSelectionItemActions } from "@perses-dev/dashboards";
17
+ import { CalculationsMap, replaceVariablesInString, useAllVariableValues } from "@perses-dev/plugin-system";
18
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
19
+ import { createPortal } from "react-dom";
20
+ import { evaluateConditionalFormatting } from "../models/index.js";
21
+ import { buildRawTableData, getTablePanelQueryMode } from "../table-data-utils.js";
22
+ import { EmbeddedPanel } from "./EmbeddedPanel.js";
22
23
  function parseNumericCellValue(value) {
23
24
  if (typeof value === 'number' && Number.isFinite(value)) {
24
25
  return value;
@@ -194,8 +195,8 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
194
195
  const [searchTerm, setSearchTerm] = useState('');
195
196
  const values = [
196
197
  ...new Set(allValues)
197
- ].filter((v)=>v !== null).sort();
198
- const filteredValues = searchTerm ? values.filter((v)=>String(v).toLowerCase().includes(searchTerm.toLowerCase())) : values;
198
+ ].filter((v)=>v !== null).toSorted();
199
+ const filteredValues = searchTerm ? values.filter((v)=>String(v.formatted).toLowerCase().includes(searchTerm.toLowerCase())) : values;
199
200
  if (values.length === 0) {
200
201
  return /*#__PURE__*/ _jsx("div", {
201
202
  "data-filter-dropdown": true,
@@ -291,19 +292,17 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
291
292
  style: {
292
293
  marginBottom: 4
293
294
  },
294
- children: /*#__PURE__*/ _jsxs("label", {
295
- style: {
295
+ children: /*#__PURE__*/ _jsxs(Box, {
296
+ component: "label",
297
+ sx: {
296
298
  display: 'flex',
297
299
  alignItems: 'center',
298
300
  cursor: 'pointer',
299
301
  padding: '2px 0',
300
- borderRadius: 2
301
- },
302
- onMouseEnter: (e)=>{
303
- e.currentTarget.style.backgroundColor = theme.palette.action.hover;
304
- },
305
- onMouseLeave: (e)=>{
306
- e.currentTarget.style.backgroundColor = 'transparent';
302
+ borderRadius: '2px',
303
+ '&:hover': {
304
+ backgroundColor: theme.palette.action.hover
305
+ }
307
306
  },
308
307
  children: [
309
308
  /*#__PURE__*/ _jsx("input", {
@@ -340,7 +339,7 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
340
339
  * Generate column config from column definitions, if a column has multiple definitions, the first one will be used.
341
340
  * If column is hidden, return undefined.
342
341
  * If column do not have a definition, return a default column config.
343
- */ function generateColumnConfig(name, columnSettings, allVariables, gaugeRangeByColumn, globalCellSettings = []) {
342
+ */ function generateColumnConfig(name, columnSettings, allVariables, gaugeRangeByColumn, globalCellSettings = [], defaultEnableSorting = false) {
344
343
  for (const column of columnSettings){
345
344
  if (column.name === name) {
346
345
  if (column.hide) {
@@ -355,7 +354,7 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
355
354
  accessorKey: name,
356
355
  header: header ?? name,
357
356
  headerDescription,
358
- enableSorting,
357
+ enableSorting: enableSorting ?? defaultEnableSorting,
359
358
  width,
360
359
  align,
361
360
  dataLink: modifiedDataLink,
@@ -365,7 +364,8 @@ function ColumnFilterDropdown({ allValues, selectedValues, onFilterChange, theme
365
364
  }
366
365
  return {
367
366
  accessorKey: name,
368
- header: name
367
+ header: name,
368
+ enableSorting: defaultEnableSorting
369
369
  };
370
370
  }
371
371
  export function getTablePanelQueryOptions(spec) {
@@ -386,6 +386,10 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
386
386
  variableState: allVariables
387
387
  });
388
388
  const filteredDataRef = useRef([]);
389
+ // Refs used to keep the filter row in sync with the table's horizontal
390
+ const panelContainerRef = useRef(null);
391
+ const filterRowInnerRef = useRef(null);
392
+ const filterCellRefs = useRef([]);
389
393
  // Convert selectionMap to TanStack's RowSelectionState format
390
394
  const rowSelection = useMemo(()=>{
391
395
  const result = {};
@@ -528,7 +532,7 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
528
532
  // Process columnSettings if they exist
529
533
  for (const columnSetting of spec.columnSettings ?? []){
530
534
  if (customizedColumns.has(columnSetting.name)) continue; // Skip duplicates
531
- const columnConfig = generateColumnConfig(columnSetting.name, spec.columnSettings ?? [], allVariables, gaugeRangeByColumn, spec.cellSettings ?? []);
535
+ const columnConfig = generateColumnConfig(columnSetting.name, spec.columnSettings ?? [], allVariables, gaugeRangeByColumn, spec.cellSettings ?? [], spec.enableSorting ?? false);
532
536
  if (columnConfig !== undefined) {
533
537
  columns.push(columnConfig);
534
538
  customizedColumns.add(columnSetting.name);
@@ -538,7 +542,7 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
538
542
  if (!spec.defaultColumnHidden) {
539
543
  for (const key of keys){
540
544
  if (!customizedColumns.has(key)) {
541
- const columnConfig = generateColumnConfig(key, spec.columnSettings ?? [], allVariables, gaugeRangeByColumn, spec.cellSettings ?? []);
545
+ const columnConfig = generateColumnConfig(key, spec.columnSettings ?? [], allVariables, gaugeRangeByColumn, spec.cellSettings ?? [], spec.enableSorting ?? false);
542
546
  if (columnConfig !== undefined) {
543
547
  columns.push(columnConfig);
544
548
  }
@@ -550,6 +554,7 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
550
554
  keys,
551
555
  spec.columnSettings,
552
556
  spec.defaultColumnHidden,
557
+ spec.enableSorting,
553
558
  allVariables,
554
559
  gaugeRangeByColumn,
555
560
  spec.cellSettings
@@ -650,6 +655,10 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
650
655
  const handleFilterClick = (event, columnId)=>{
651
656
  event.preventDefault();
652
657
  event.stopPropagation();
658
+ if (openFilterColumn === columnId) {
659
+ handleFilterClose();
660
+ return;
661
+ }
653
662
  setFilterAnchorEl({
654
663
  ...filterAnchorEl,
655
664
  [columnId]: event.currentTarget
@@ -699,6 +708,76 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
699
708
  spec.pagination,
700
709
  pagination
701
710
  ]);
711
+ // Sync the filter row's horizontal position with the table scroll.
712
+ useEffect(()=>{
713
+ if (!spec.enableFiltering) {
714
+ return;
715
+ }
716
+ const scrollContainer = panelContainerRef.current?.querySelector('.MuiTableContainer-root');
717
+ const filterRowInner = filterRowInnerRef.current;
718
+ if (!scrollContainer || !filterRowInner) {
719
+ return;
720
+ }
721
+ const syncFilterRowScroll = ()=>{
722
+ filterRowInner.style.transform = `translateX(-${scrollContainer.scrollLeft}px)`;
723
+ setOpenFilterColumn((current)=>current === null ? current : null);
724
+ setFilterAnchorEl((current)=>Object.keys(current).length === 0 ? current : {});
725
+ };
726
+ syncFilterRowScroll();
727
+ scrollContainer.addEventListener('scroll', syncFilterRowScroll, {
728
+ passive: true
729
+ });
730
+ return ()=>{
731
+ scrollContainer.removeEventListener('scroll', syncFilterRowScroll);
732
+ };
733
+ }, [
734
+ spec.enableFiltering,
735
+ columns,
736
+ contentDimensions
737
+ ]);
738
+ // Sync filter cell widths with the actual rendered table column widths to keep them aligned.
739
+ useEffect(()=>{
740
+ if (!spec.enableFiltering) {
741
+ return;
742
+ }
743
+ const scrollContainer = panelContainerRef.current?.querySelector('.MuiTableContainer-root');
744
+ if (!scrollContainer) {
745
+ return;
746
+ }
747
+ const headerRow = scrollContainer.querySelector('thead tr');
748
+ if (!headerRow) {
749
+ return;
750
+ }
751
+ const syncColumnWidths = ()=>{
752
+ const headerCells = scrollContainer.querySelectorAll('thead tr th');
753
+ columns.forEach((_, idx)=>{
754
+ const headerCell = headerCells[idx];
755
+ const filterCell = filterCellRefs.current[idx];
756
+ if (!headerCell || !filterCell) {
757
+ return;
758
+ }
759
+ const width = `${headerCell.getBoundingClientRect().width}px`;
760
+ filterCell.style.width = width;
761
+ filterCell.style.minWidth = width;
762
+ filterCell.style.maxWidth = width;
763
+ });
764
+ };
765
+ syncColumnWidths();
766
+ // Re-sync whenever the header row's size changes
767
+ const resizeObserver = new ResizeObserver(syncColumnWidths);
768
+ if (headerRow) {
769
+ resizeObserver.observe(headerRow);
770
+ }
771
+ return ()=>{
772
+ resizeObserver.disconnect();
773
+ };
774
+ }, [
775
+ spec.enableFiltering,
776
+ columns,
777
+ contentDimensions,
778
+ selectionEnabled,
779
+ actionButtons
780
+ ]);
702
781
  if (contentDimensions === undefined) {
703
782
  return null;
704
783
  }
@@ -715,89 +794,107 @@ export function TablePanel({ contentDimensions, spec, queryResults }) {
715
794
  })
716
795
  });
717
796
  }
718
- return /*#__PURE__*/ _jsxs(_Fragment, {
797
+ return /*#__PURE__*/ _jsxs("div", {
798
+ ref: panelContainerRef,
799
+ style: {
800
+ display: 'contents'
801
+ },
719
802
  children: [
720
803
  confirmDialog,
721
804
  spec.enableFiltering && /*#__PURE__*/ _jsx("div", {
722
805
  style: {
723
- display: 'flex',
806
+ overflow: 'hidden',
724
807
  background: theme.palette.background.default,
725
808
  borderBottom: `1px solid ${theme.palette.divider}`,
726
809
  width: contentDimensions.width,
727
810
  boxSizing: 'border-box'
728
811
  },
729
- children: columns.map((column, idx)=>{
730
- const filters = getSelectedFilterValues(column.accessorKey);
731
- const columnWidth = column.width || spec.defaultColumnWidth;
732
- return /*#__PURE__*/ _jsxs("div", {
733
- style: {
734
- padding: '8px',
735
- borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',
736
- width: columnWidth,
737
- minWidth: columnWidth,
738
- maxWidth: columnWidth,
739
- display: 'flex',
740
- alignItems: 'center',
741
- position: 'relative',
742
- boxSizing: 'border-box',
743
- flex: typeof columnWidth === 'number' ? 'none' : '1 1 auto'
744
- },
745
- children: [
746
- /*#__PURE__*/ _jsx("span", {
747
- style: {
748
- marginRight: 8,
749
- fontSize: '12px',
750
- color: theme.palette.text.secondary,
751
- flex: 1,
752
- overflow: 'hidden',
753
- textOverflow: 'ellipsis',
754
- whiteSpace: 'nowrap'
755
- },
756
- children: filters.length ? `${filters.length} items` : 'All'
757
- }),
758
- /*#__PURE__*/ _jsx("button", {
759
- onClick: (e)=>{
760
- handleFilterClick(e, column.accessorKey);
761
- },
762
- style: {
763
- border: `1px solid ${theme.palette.divider}`,
764
- background: theme.palette.background.paper,
765
- cursor: 'pointer',
766
- fontSize: '12px',
767
- color: filters.length ? theme.palette.primary.main : theme.palette.text.secondary,
768
- padding: '4px 8px',
769
- borderRadius: '4px',
770
- minWidth: '20px',
771
- height: '24px',
772
- flexShrink: 0,
773
- transition: 'all 0.2s ease'
774
- },
775
- onMouseEnter: (e)=>{
776
- e.currentTarget.style.background = theme.palette.action.hover;
777
- },
778
- onMouseLeave: (e)=>{
779
- e.currentTarget.style.background = theme.palette.background.paper;
780
- },
781
- type: "button",
782
- children: "▼"
783
- }),
784
- openFilterColumn === column.accessorKey && /*#__PURE__*/ _jsx("div", {
785
- style: {
786
- position: 'absolute',
787
- top: '100%',
788
- left: 0,
789
- zIndex: 1000,
790
- marginTop: 4
791
- },
792
- children: /*#__PURE__*/ _jsx(ColumnFilterDropdown, {
793
- allValues: columnUniqueValues[column.accessorKey] || [],
794
- selectedValues: filters,
795
- onFilterChange: (values)=>updateColumnFilter(column.accessorKey, values),
796
- theme: theme
797
- })
798
- })
799
- ]
800
- }, `filter-${idx}`);
812
+ children: /*#__PURE__*/ _jsx("div", {
813
+ ref: filterRowInnerRef,
814
+ style: {
815
+ display: 'flex',
816
+ width: 'max-content',
817
+ willChange: 'transform'
818
+ },
819
+ children: columns.map((column, idx)=>{
820
+ const filters = getSelectedFilterValues(column.accessorKey);
821
+ const columnWidth = column.width || spec.defaultColumnWidth;
822
+ const anchorEl = filterAnchorEl[column.accessorKey];
823
+ return /*#__PURE__*/ _jsxs("div", {
824
+ ref: (el)=>{
825
+ filterCellRefs.current[idx] = el;
826
+ },
827
+ style: {
828
+ padding: '8px',
829
+ borderRight: idx < columns.length - 1 ? `1px solid ${theme.palette.divider}` : 'none',
830
+ // These are just a starting size for the first paint —
831
+ // the width-sync effect above overwrites them with the
832
+ // table's actual rendered column widths.
833
+ width: columnWidth,
834
+ minWidth: columnWidth,
835
+ maxWidth: columnWidth,
836
+ display: 'flex',
837
+ alignItems: 'center',
838
+ position: 'relative',
839
+ boxSizing: 'border-box',
840
+ flex: 'none'
841
+ },
842
+ children: [
843
+ /*#__PURE__*/ _jsx("span", {
844
+ style: {
845
+ marginRight: 8,
846
+ fontSize: '12px',
847
+ color: theme.palette.text.secondary,
848
+ flex: 1,
849
+ overflow: 'hidden',
850
+ textOverflow: 'ellipsis',
851
+ whiteSpace: 'nowrap'
852
+ },
853
+ children: filters.length ? `${filters.length} items` : 'All'
854
+ }),
855
+ /*#__PURE__*/ _jsx("button", {
856
+ onClick: (e)=>{
857
+ handleFilterClick(e, column.accessorKey);
858
+ },
859
+ style: {
860
+ border: `1px solid ${theme.palette.divider}`,
861
+ background: theme.palette.background.paper,
862
+ cursor: 'pointer',
863
+ fontSize: '12px',
864
+ color: filters.length ? theme.palette.primary.main : theme.palette.text.secondary,
865
+ padding: '4px 8px',
866
+ borderRadius: '4px',
867
+ minWidth: '20px',
868
+ height: '24px',
869
+ flexShrink: 0,
870
+ transition: 'all 0.2s ease'
871
+ },
872
+ onMouseEnter: (e)=>{
873
+ e.currentTarget.style.background = theme.palette.action.hover;
874
+ },
875
+ onMouseLeave: (e)=>{
876
+ e.currentTarget.style.background = theme.palette.background.paper;
877
+ },
878
+ type: "button",
879
+ children: "▼"
880
+ }),
881
+ openFilterColumn === column.accessorKey && anchorEl && /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsx("div", {
882
+ style: {
883
+ position: 'fixed',
884
+ top: anchorEl.getBoundingClientRect().bottom + 4,
885
+ left: anchorEl.getBoundingClientRect().left,
886
+ zIndex: theme.zIndex.modal
887
+ },
888
+ children: /*#__PURE__*/ _jsx(ColumnFilterDropdown, {
889
+ allValues: columnUniqueValues[column.accessorKey] || [],
890
+ selectedValues: filters,
891
+ onFilterChange: (values)=>updateColumnFilter(column.accessorKey, values),
892
+ theme: theme
893
+ })
894
+ }), document.body)
895
+ ]
896
+ }, `column-${column.accessorKey}`);
897
+ })
801
898
  })
802
899
  }),
803
900
  /*#__PURE__*/ _jsx(Table, {