@jielga/tmdatagrid 0.2.0 → 0.5.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 (50) hide show
  1. package/dist/index.d.ts +1337 -94
  2. package/dist/index.js +2812 -1189
  3. package/dist/index.js.map +1 -1
  4. package/dist/styles.css +1 -1
  5. package/package.json +2 -2
  6. package/skills/columns/SKILL.md +1 -1
  7. package/skills/features/SKILL.md +61 -11
  8. package/skills/getting-started/SKILL.md +41 -6
  9. package/skills/options/SKILL.md +12 -2
  10. package/skills/server-side/SKILL.md +1 -1
  11. package/src/tmdatagrid/TMDataGridContext.ts +26 -0
  12. package/src/tmdatagrid/components/TMDataGrid.module.css +21 -1
  13. package/src/tmdatagrid/components/TMDataGrid.tsx +29 -1
  14. package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +12 -6
  15. package/src/tmdatagrid/components/TMDataGridDetailsColumn.module.css +33 -0
  16. package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +160 -0
  17. package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +15 -0
  18. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +192 -37
  19. package/src/tmdatagrid/components/TMDataGridFilterPills.module.css +35 -0
  20. package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +136 -0
  21. package/src/tmdatagrid/components/TMDataGridFooter.module.css +8 -0
  22. package/src/tmdatagrid/components/TMDataGridFooter.tsx +63 -43
  23. package/src/tmdatagrid/components/TMDataGridGroupColumn.module.css +48 -0
  24. package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +159 -0
  25. package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +18 -0
  26. package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +249 -44
  27. package/src/tmdatagrid/components/TMDataGridSearch.tsx +122 -0
  28. package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +103 -16
  29. package/src/tmdatagrid/components/TMDataGridTable.module.css +160 -5
  30. package/src/tmdatagrid/components/TMDataGridTable.tsx +1380 -43
  31. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +33 -7
  32. package/src/tmdatagrid/components/icons.ts +6 -0
  33. package/src/tmdatagrid/components/sticky.module.css +77 -16
  34. package/src/tmdatagrid/core/autosize.ts +125 -0
  35. package/src/tmdatagrid/core/capabilities.ts +122 -11
  36. package/src/tmdatagrid/core/cellExport.ts +321 -0
  37. package/src/tmdatagrid/core/cellNavigation.ts +103 -0
  38. package/src/tmdatagrid/core/cellRange.ts +118 -0
  39. package/src/tmdatagrid/core/columnOptions.ts +123 -0
  40. package/src/tmdatagrid/core/columnUtils.ts +18 -0
  41. package/src/tmdatagrid/core/expanding.ts +93 -0
  42. package/src/tmdatagrid/core/filterOperators.ts +198 -12
  43. package/src/tmdatagrid/core/grouping.ts +21 -0
  44. package/src/tmdatagrid/core/labels.ts +211 -0
  45. package/src/tmdatagrid/core/labelsSv.ts +108 -0
  46. package/src/tmdatagrid/core/persistence.ts +12 -0
  47. package/src/tmdatagrid/core/rowSelection.ts +202 -0
  48. package/src/tmdatagrid/core/summary.ts +35 -0
  49. package/src/tmdatagrid/index.ts +96 -2
  50. package/src/tmdatagrid/useTMDataGrid.tsx +558 -37
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["createContext","useContext","TMDataGridSize","TMDataGridApi","TMDataGridRowData","Record","TMDataGridContextValue","size","rowHeight","controlSize","TMDataGridContext","TMDataGridContextProvider","Provider","useTMDataGridContext","api","Error","TMDataGridColumnType","TMDataGridColumnMeta","ColumnLike","id","columnDef","header","meta","parent","getColumnLabel","column","label","getColumnType","type","getColumnAlign","align","isColumnReorderable","enableOrdering","undefined","Button","Checkbox","ScrollArea","Text","TextInput","useSelector","useState","classes","useTMDataGridContext","getColumnLabel","SearchIcon","TMDataGridColumnsPanel","$","_c","table","controlSize","search","setSearch","columnVisibility","store","_temp","T0","hideableColumns","shownCount","t0","t1","t2","t3","t4","t5","visibleInPanel","columns","getAllLeafColumns","needle","trim","toLowerCase","filter","column","includes","_temp2","t6","column_1","id","length","columnsPanel","t7","Symbol","for","event","currentTarget","value","t8","columnsPanelSearch","Autosize","columnsPanelList","t9","column_2","getCanHide","event_0","toggleVisibility","checked","map","t10","t11","event_1","toggleAllColumnsVisible","t12","t13","resetColumnVisibility","t14","columnsPanelFooter","t15","column_0","state","Row","RowData","TableFeatures","TMDataGridFilterValue","operator","TMDataGridFilterOperator","value","TMDataGridColumnType","FILTER_OPERATOR_LABELS","Record","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","isEmpty","isNotEmpty","STRING_OPERATORS","NUMBER_OPERATORS","VALUELESS_OPERATORS","getOperatorsForType","type","getDefaultOperator","operatorNeedsValue","includes","isTMDataGridFilterValue","isFilterActive","trim","matchesFilter","cellValue","undefined","filterText","numericCell","Number","NaN","numericFilter","compareNumeric","isNaN","cellText","String","toLowerCase","needle","tmDataGridFilterFn","row","TFeatures","TData","columnId","filterValue","getValue","ActionIcon","Button","Select","Stack","TextInput","useSelector","classes","useTMDataGridContext","getColumnLabel","getColumnType","TMDataGridFilterOperator","TMDataGridFilterValue","FILTER_OPERATOR_LABELS","getDefaultOperator","getOperatorsForType","isTMDataGridFilterValue","operatorNeedsValue","CloseIcon","FALLBACK_FILTER","operator","value","asFilterValue","TMDataGridFilterPanel","$","_c","table","ui","controlSize","opened","_temp","columnFilters","store","_temp2","filterableColumns","t0","getAllLeafColumns","filter","_temp3","map","_temp4","columnOptions","t1","removeFilter","columnId","remaining","id","setColumnFilters","length","actions","closeFilterPanel","t2","changeFilterColumn","fromColumnId","toColumnId","current","find","filter_0","target","getColumn","filter_1","filter_2","openFilterPanel","t3","patchFilter","columnId_0","patch","filter_3","t4","addFilter","nextColumn","column_1","some","filter_4","column","t5","t6","filter_5","column_2","type","needsValue","filterRow","next","_temp5","next_0","event","currentTarget","Symbol","for","alignSelf","t7","t8","filterPanel","label","column_0","getCanFilter","state_0","state","filterPanelOpen","Column","RowData","TMDataGridRowData","isColumnReorderable","TMDataGridFeatures","TMDataGridTable","UseTMDataGridOptions","TMDataGridRowSelectionMode","TMDataGridFeatureFlags","sorting","filtering","hiding","pinning","resizing","ordering","rowSelection","rowSelectionMode","highlightSelectedRows","pagination","readFeatureFlags","options","Pick","TData","enableSorting","enableColumnFilters","enableHiding","enableColumnPinning","enableColumnResizing","enableColumnOrdering","enableRowSelection","enablePagination","manualPagination","TMDataGridColumnCapabilities","canSort","canFilter","canHide","canPin","canResize","canReorder","getColumnCapabilities","column","features","getCanSort","getCanFilter","getCanHide","getCanPin","getCanResize","TMDataGridCapabilities","canSortAny","canFilterAny","canHideAny","canPinAny","canReorderAny","canSelectRows","canPaginate","getGridCapabilities","table","columns","getAllLeafColumns","any","predicate","capabilities","some","c","ActionIcon","Group","Select","Text","RowData","useSelector","ReactNode","classes","useTMDataGridContext","getGridCapabilities","ChevronLeftIcon","ChevronRightIcon","TMDataGridTable","TMDataGridPaginationApi","pageIndex","pageSize","pageCount","rowCount","canPreviousPage","canNextPage","setPageIndex","setPageSize","previousPage","nextPage","firstPage","lastPage","getTMDataGridPaginationApi","table","TData","store","state","pagination","getPageCount","getRowCount","getCanPreviousPage","getCanNextPage","index","size","TMDataGridFooterProps","pageSizeOptions","ReadonlyArray","api","TMDataGridFooter","t0","$","_c","t1","undefined","features","controlSize","canPaginate","t2","t3","footer","total","from","to","Math","min","sizeOptions","includes","sort","_temp","t4","map","String","t5","t6","value","Number","t7","t8","t9","t10","t11","t12","t13","Symbol","for","t14","t15","t16","t17","t18","t19","t20","t21","a","b","Column","ColumnPinningState","TMDataGridRowData","isColumnReorderable","TMDataGridFeatures","TMDataGridTable","GridColumn","GridTable","TMDataGridColumnRegion","TMDataGridDropSide","getColumnRegion","columnPinning","columnId","left","includes","right","moveInList","ids","ReadonlyArray","movedId","targetId","side","Array","remaining","filter","id","targetIndex","indexOf","splice","MoveColumnArgs","table","moveColumn","store","state","region","leafIds","getAllLeafColumns","map","column","setColumnOrder","setColumnPinning","previous","getRegionColumns","getLeftVisibleLeafColumns","getRightVisibleLeafColumns","getCenterVisibleLeafColumns","ColumnStepArgs","direction","getStepTargetColumn","columns","index","findIndex","target","moveColumnByStep","Checkbox","useSelector","ColumnDef","Row","RowData","TMDataGridFeatures","TMDataGridTable","SELECT_COLUMN_ID","SelectAllCheckbox","t0","$","_c","table","t1","getIsAllRowsSelected","allSelected","store","t2","getIsSomeRowsSelected","someSelected","t3","t4","getToggleAllRowsSelectedHandler","t5","SelectRowCheckbox","row","getIsSelected","selected","getIsSomeSelected","getCanSelect","t6","getToggleSelectedHandler","t7","_temp","event","stopPropagation","createSelectColumn","TData","id","meta","label","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enablePinning","header","cell","TableState","TMDataGridFeatures","GridState","DATA_STATE_SLICES","const","ReadonlyArray","SETTINGS_STATE_SLICES","TMDataGridDataSlice","TMDataGridSettingsSlice","TMDataGridPersistKey","key","slices","TSlice","TMDataGridStorageMode","TMDataGridPersistence","dataKey","settingsKey","storageMode","serialize","value","Partial","deserialize","ResolvedKey","resolveKey","entry","defaultSlices","resolveStorage","persistence","Storage","window","sessionStorage","localStorage","prop","Record","undefined","isString","isFiniteNumber","Number","isFinite","isArrayOf","isItem","item","Array","isArray","every","isRecordOf","Object","values","hasStringId","SLICE_GUARDS","columnFilters","globalFilter","sorting","pagination","pageIndex","pageSize","columnVisibility","columnSizing","columnOrder","columnPinning","isValidSlice","slice","guard","readSlices","storage","resolved","raw","getItem","parsed","record","restored","writeSlices","state","payload","setItem","resolveKeys","data","settings","hasPersistenceKeys","defaultDeserialize","JSON","parse","defaultSerialize","stringify","readPersistedState","writePersistedState","useCreateStore","ColumnDef","columnFacetingFeature","columnFilteringFeature","columnOrderingFeature","columnPinningFeature","columnResizingFeature","columnSizingFeature","columnVisibilityFeature","createColumnHelper","createFacetedMinMaxValues","createFacetedRowModel","createFacetedUniqueValues","createFilteredRowModel","createPaginatedRowModel","createSortedRowModel","filterFns","globalFilteringFeature","metaHelper","RowData","rowPaginationFeature","rowSelectionFeature","rowSortingFeature","sortFns","Table","tableFeatures","TableOptions","TableState","useTable","Store","useEffect","useMemo","useState","TMDataGridColumnType","tmDataGridFilterFn","getDefaultOperator","hasPersistenceKeys","readPersistedState","TMDataGridPersistence","writePersistedState","readFeatureFlags","TMDataGridFeatureFlags","TMDataGridRowSelectionMode","createSelectColumn","SELECT_COLUMN_ID","PERSIST_DEBOUNCE_MS","TMDataGridColumnMeta","label","type","flex","align","enableOrdering","TMDataGridTableMeta","loading","noResultsLabel","rowHeight","totalRowCount","tmDataGridFeatures","filteredRowModel","sortedRowModel","paginatedRowModel","facetedRowModel","facetedMinMaxValues","facetedUniqueValues","tmDataGrid","tableMeta","columnMeta","TMDataGridFeatures","TMDataGridTable","TData","createTMDataGridColumnHelper","TMDataGridUiState","filterPanelOpen","columnsPanelOpen","filterPanelColumnId","draggedColumnId","TMDataGridUiActions","openFilterPanel","columnId","closeFilterPanel","setColumnsPanelOpen","open","toggleColumnsPanel","startColumnDrag","endColumnDrag","TMDataGridUiStore","TMDataGridApi","table","ui","features","UseTMDataGridOptions","Omit","persist","enableColumnOrdering","enablePagination","rowSelectionMode","highlightSelectedRows","TMDataGridColumnDef","withTMDataGridDefaults","columns","ReadonlyArray","Array","map","column","isArray","filterFn","useTMDataGrid","t0","$","_c","options","selectionEnabled","enableRowSelection","pinningEnabled","enableColumnPinning","selectColumnEnabled","t1","base","t2","persistedState","t3","t4","t5","initialState","columnPinning","left","filter","_temp","t6","right","t7","t8","pagination","t9","pageIndex","pageSize","t10","t11","columnResizeMode","enableSorting","enableColumnResizing","globalFilterFn","t12","t13","store","state","timeout","pending","flush","undefined","subscription","subscribe","clearTimeout","setTimeout","unsubscribe","t14","Symbol","for","_temp5","t15","t16","setState","prev","_temp2","prev_1","_temp3","columnId_0","prev_3","_temp4","prev_4","prev_2","prev_0","id","openColumnFilter","api","getColumn","getFilterValue","setFilterValue","operator","columnDef","meta","value","actions","ActionIcon","Menu","Tooltip","flexRender","Header","useSelector","shallow","DragEvent","ReactNode","useRef","useState","classes","sticky","TMDataGridRowData","useTMDataGridContext","TMDataGridColumnLayout","getColumnCapabilities","getGridCapabilities","getColumnRegion","getStepTargetColumn","moveColumn","moveColumnByStep","TMDataGridDropSide","getColumnAlign","getColumnLabel","isFilterActive","ArrowDownIcon","ArrowUpIcon","ColumnsIcon","DotsVerticalIcon","EyeOffIcon","FilterIcon","MoveLeftIcon","MoveRightIcon","PinLeftIcon","PinOffIcon","PinRightIcon","SELECT_COLUMN_ID","TMDataGridFeatures","openColumnFilter","TMDataGridHeader","TMDataGridHeaderCell","t0","$","_c","header","layout","api","table","features","column","menuOpened","setMenuOpened","dropSide","setDropSide","cellRef","suppressSortRef","t1","Symbol","for","compare","sorting","columnFilters","resizingColumnId","columnPinning","store","_temp","draggedColumnId","ui","_temp2","isLeaf","subHeaders","length","t2","label","t3","align","t4","id","find","sort","desc","sortDirection","isSorted","undefined","t5","t6","filter","value","some","isFiltered","isResizing","pinnedAt","capabilities","canSort","canFilter","canHide","canPin","canResize","canReorder","t7","canHideAny","canManageColumns","isDragged","t8","isDropTarget","t9","handleDragStart","event","dataTransfer","effectAllowed","setData","actions","startColumnDrag","t10","handleDragOver","event_0","preventDefault","dropEffect","bounds","current","getBoundingClientRect","clientX","left","width","t11","handleDragLeave","event_1","next","relatedTarget","Node","currentTarget","contains","t12","handleDrop","event_2","endColumnDrag","columnId","targetId","side","t13","handleDragEnd","t14","setPinned","position","state","columnSizing","setColumnSizing","prev","Math","round","pin","menuItems","t15","t16","toggleSorting","t17","t18","t19","push","menuItemActive","t20","t21","t22","t23","t24","direction","previous","next_0","t25","toggleVisibility","setColumnsPanelOpen","isDivider","at","pop","headerCellSortable","headerCellDragging","headerCellDropBefore","headerCellDropAfter","isBoundary","stickyLeft","stickyRight","headerCell","Boolean","cellClass","join","t26","t27","t28","t29","t30","t31","offset","t32","t33","t34","t35","right","zIndex","t36","event_3","getToggleSortingHandler","t37","columnDef","isPlaceholder","headerTitle","getContext","t38","headerActions","headerAction","event_4","stopPropagation","event_5","_temp3","_temp4","t39","columnSeparatorResizable","t40","columnSeparatorActive","t41","columnSeparator","t42","t43","event_7","getResizeHandler","t44","t45","_temp5","t46","event_8","event_6","opened","state_0","columnResizing","isResizingColumn","columnOrder","node","type","Divider","Loader","Text","Cell","flexRender","Row","RowData","useSelector","useVirtualizer","useCallback","useEffect","useRef","classes","sticky","TMDataGridRowData","useTMDataGridContext","TMDataGridFilterPanel","TMDataGridHeaderCell","getColumnAlign","SearchIcon","TMDataGridFeatures","TMDataGridColumnLayout","pinnedAt","offset","isBoundary","UNPINNED_LAYOUT","TMDataGridBodyCell","t0","$","_c","cell","rowHeight","layout","t1","column","t2","stickyLeft","t3","stickyRight","t4","bodyCell","filter","Boolean","t5","join","t6","undefined","t7","t8","t9","t10","minHeight","left","right","position","zIndex","t11","columnDef","getContext","t12","cellContent","t13","TMDataGridTableProps","onRowClick","row","TData","TMDataGridTable","table","features","controlSize","store","loading","noResultsLabel","options","meta","scrollContainerRef","HTMLDivElement","rows","pagination","getPaginatedRowModel","getPrePaginatedRowModel","pageCount","getPageCount","state","pageIndex","setPageIndex","virtualizer","count","length","getScrollElement","current","estimateSize","getItemKey","index","id","overscan","initialRect","height","width","virtualItems","getVirtualItems","paddingTop","start","paddingBottom","getTotalSize","at","end","leftLeafColumns","getLeftLeafColumns","rightLeafColumns","getRightLeafColumns","centerLeafColumns","getCenterLeafColumns","orderedColumns","centerHeaderGroups","getCenterHeaderGroups","leftHeaderGroups","getLeftHeaderGroups","rightHeaderGroups","getRightHeaderGroups","headerGroups","map","group","headers","columnSizing","columnTracks","isFixed","minSize","maxSize","isResized","isPinned","getIsPinned","minWidth","track","getSize","flex","gridTemplateColumns","c","gridMinWidth","reduce","sum","columnLayout","Map","widthOf","columnId","findIndex","leftOffset","set","rightOffset","reverse","layoutFor","get","isEmpty","selectsOnRowClick","rowSelection","rowSelectionMode","rowIsInteractive","handleRowActivate","getCanSelect","toggleSelected","tableWrapper","scrollContainer","grid","display","headerGroup","groupIndex","headerRow","header","gridColumn","virtualItem","key","getIsSelected","highlightSelectedRows","bodyRow","cursor","event","target","currentTarget","preventDefault","getLeftVisibleCells","getCenterVisibleCells","getRightVisibleCells","messageRow","ActionIcon","Popover","Text","Tooltip","useSelector","ReactNode","classes","TMDataGridColumnsPanel","useTMDataGridContext","getGridCapabilities","isFilterActive","BurgerIcon","FilterIcon","openColumnFilter","TMDataGridToolbar","t0","$","_c","children","t1","toolbar","TMDataGridToolbarSpacer","Symbol","for","toolbarSpacer","TMDataGridSummaryCount","table","controlSize","store","undefined","getRowCount","shown","t2","options","meta","totalRowCount","getPreFilteredRowModel","rows","length","total","t3","TMDataGridColumnsButton","ui","features","opened","_temp","canHideAny","actions","toggleColumnsPanel","setColumnsPanelOpen","state","columnsPanelOpen","TMDataGridFilterButton","api","_temp2","columnFilters","_temp3","activeCount","filter","_temp4","canFilterAny","closeFilterPanel","firstFilterable","getAllLeafColumns","find","_temp5","id","openFilterPanel","t4","column","getCanFilter","value","state_0","filterPanelOpen","MantineSize","TMDataGridSize","DEFAULT_TMDATAGRID_SIZE","SIZE_ROW_HEIGHT","Record","xs","sm","md","lg","xl","SIZE_CONTROL_SIZE","RowData","CSSProperties","ReactNode","useMemo","classes","TMDataGridColumnsPanel","TMDataGridContextProvider","TMDataGridFilterPanel","TMDataGridFooter","TMDataGridTable","TMDataGridColumnsButton","TMDataGridFilterButton","TMDataGridSummaryCount","TMDataGridToolbar","TMDataGridToolbarSpacer","DEFAULT_TMDATAGRID_SIZE","SIZE_CONTROL_SIZE","SIZE_ROW_HEIGHT","TMDataGridSize","TMDataGridApi","TMDataGridProps","TData","children","size","className","style","Record","TMDataGridRoot","t0","$","_c","table","ui","features","t1","undefined","rowHeight","options","meta","t2","t3","controlSize","api","t4","root","filter","Boolean","t5","join","t6","t7","TMDataGrid","Object","assign","Toolbar","Spacer","SummaryCount","ColumnsButton","FilterButton","Table","Footer","FilterPanel","ColumnsPanel"],"sources":["../src/tmdatagrid/components/TMDataGrid.module.css","../src/tmdatagrid/components/TMDataGridColumnsPanel.module.css","../src/tmdatagrid/TMDataGridContext.ts","../src/tmdatagrid/core/columnUtils.ts","../src/tmdatagrid/components/TMDataGridColumnsPanel.tsx","../src/tmdatagrid/components/TMDataGridFilterPanel.module.css","../src/tmdatagrid/core/filterOperators.ts","../src/tmdatagrid/components/TMDataGridFilterPanel.tsx","../src/tmdatagrid/components/TMDataGridFooter.module.css","../src/tmdatagrid/core/capabilities.ts","../src/tmdatagrid/components/TMDataGridFooter.tsx","../src/tmdatagrid/components/TMDataGridTable.module.css","../src/tmdatagrid/components/sticky.module.css","../src/tmdatagrid/components/TMDataGridHeaderCell.module.css","../src/tmdatagrid/core/columnOrdering.ts","../src/tmdatagrid/components/TMDataGridSelectColumn.tsx","../src/tmdatagrid/core/persistence.ts","../src/tmdatagrid/useTMDataGrid.tsx","../src/tmdatagrid/components/TMDataGridHeaderCell.tsx","../src/tmdatagrid/components/TMDataGridTable.tsx","../src/tmdatagrid/components/TMDataGridToolbar.module.css","../src/tmdatagrid/components/TMDataGridToolbar.tsx","../src/tmdatagrid/core/sizes.ts","../src/tmdatagrid/components/TMDataGrid.tsx"],"sourcesContent":["/* The grid root: the size scale every other module reads, and the frame.\n Each component owns its own module; these variables cascade into all of\n them, and the pinned-column boundary shared by header and body cells lives\n in sticky.module.css. */\n\n/* Size scale. Row heights mirror SIZE_ROW_HEIGHT in core/sizes.ts — the\n virtualizer needs the number in JS, so the two have to agree. */\n.root[data-size=\"xs\"] {\n --dg-row-height: 34px;\n --dg-header-height: 32px;\n --dg-font-size: var(--mantine-font-size-xs);\n --dg-padding: 6px;\n}\n\n.root[data-size=\"sm\"] {\n --dg-row-height: 42px;\n --dg-header-height: 38px;\n --dg-font-size: var(--mantine-font-size-sm);\n --dg-padding: 8px;\n}\n\n.root[data-size=\"md\"] {\n --dg-row-height: 52px;\n --dg-header-height: 44px;\n --dg-font-size: var(--mantine-font-size-sm);\n --dg-padding: 10px;\n}\n\n.root[data-size=\"lg\"] {\n --dg-row-height: 62px;\n --dg-header-height: 52px;\n --dg-font-size: var(--mantine-font-size-md);\n --dg-padding: 14px;\n}\n\n.root[data-size=\"xl\"] {\n --dg-row-height: 72px;\n --dg-header-height: 60px;\n --dg-font-size: var(--mantine-font-size-lg);\n --dg-padding: 18px;\n}\n\n.root {\n /* Fallbacks, so the parts still work if rendered outside a sized root. */\n --dg-row-height: 52px;\n --dg-header-height: 44px;\n --dg-font-size: var(--mantine-font-size-sm);\n --dg-padding: 10px;\n /* Background of a highlighted (selected) row. Override it on the grid:\n <TMDataGrid style={{ \"--dg-row-selected-bg\": \"var(--mantine-color-blue-0)\" }} /> */\n --dg-row-selected-bg: var(--mantine-primary-color-light);\n\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n /* Header text is a stretched flex item, so an inherited `text-align: center`\n from the host page would centre headers away from their cell content. */\n text-align: left;\n border: 1px solid var(--mantine-color-default-border);\n border-radius: var(--mantine-radius-md);\n background-color: var(--mantine-color-body);\n}\n",".columnsPanel {\n width: 280px;\n display: flex;\n flex-direction: column;\n}\n\n.columnsPanelSearch {\n padding: var(--mantine-spacing-sm);\n}\n\n.columnsPanelList {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n padding: 0 var(--mantine-spacing-sm) var(--mantine-spacing-sm);\n}\n\n.columnsPanelFooter {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mantine-spacing-sm);\n padding: var(--mantine-spacing-sm);\n border-top: 1px solid var(--mantine-color-default-border);\n}\n","import { createContext, useContext } from \"react\";\nimport type { TMDataGridSize } from \"./core/sizes\";\nimport type { TMDataGridApi } from \"./useTMDataGrid\";\n\n/**\n * Row shape the chrome components work against. They only ever touch columns,\n * rows and cells generically, so the concrete row type is erased at the context\n * boundary — the same trick Mantine uses for its compound components.\n */\nexport type TMDataGridRowData = Record<string, unknown>;\n\nexport type TMDataGridContextValue = TMDataGridApi<TMDataGridRowData> & {\n size: TMDataGridSize;\n /** Row height in px, already resolved from `size` and `meta.rowHeight`. */\n rowHeight: number;\n /** Mantine control size that pairs with `size`. */\n controlSize: TMDataGridSize;\n};\n\nconst TMDataGridContext = createContext<unknown>(null);\n\nexport const TMDataGridContextProvider = TMDataGridContext.Provider;\n\nexport function useTMDataGridContext(): TMDataGridContextValue {\n const api = useContext(TMDataGridContext);\n if (!api) {\n throw new Error(\n \"TMDataGrid compound components must be rendered inside <TMDataGrid>\",\n );\n }\n return api as TMDataGridContextValue;\n}\n","import type { TMDataGridColumnType } from \"./filterOperators\";\nimport type { TMDataGridColumnMeta } from \"../useTMDataGrid\";\n\n/**\n * Structural shape of the column bits the chrome reads. Kept minimal so these\n * helpers work with any `Column`/`Header` instance without dragging generics\n * through every call site.\n */\ntype ColumnLike = {\n id: string;\n columnDef: { header?: unknown; meta?: TMDataGridColumnMeta };\n /** Set on a leaf that sits inside a header group. */\n parent?: unknown;\n};\n\n/** Menu- and panel-facing column name. */\nexport function getColumnLabel(column: ColumnLike): string {\n const label = column.columnDef.meta?.label;\n if (label) return label;\n const header = column.columnDef.header;\n return typeof header === \"string\" ? header : column.id;\n}\n\nexport function getColumnType(column: ColumnLike): TMDataGridColumnType {\n return column.columnDef.meta?.type ?? \"string\";\n}\n\nexport function getColumnAlign(column: ColumnLike): \"left\" | \"right\" | \"center\" {\n return column.columnDef.meta?.align ?? \"left\";\n}\n\n/**\n * Whether a column may be moved. Ordering is the one column feature TanStack\n * has no column option for, so the switch lives in `meta.enableOrdering`.\n *\n * A leaf inside a header group is never movable: `columnOrder` sequences leaf\n * columns, so moving one out of its group would leave the group header spanning\n * columns that no longer belong to it.\n */\nexport function isColumnReorderable(column: ColumnLike): boolean {\n if (column.columnDef.meta?.enableOrdering === false) return false;\n return column.parent === undefined;\n}\n","import { Button, Checkbox, ScrollArea, Text, TextInput } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useState } from \"react\";\nimport classes from \"./TMDataGridColumnsPanel.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getColumnLabel } from \"../core/columnUtils\";\nimport { SearchIcon } from \"./icons\";\n\n/**\n * The \"Manage columns\" surface. Reachable from every column header menu and\n * from the grid's burger menu, so it lives on its own and is rendered by\n * `TMDataGrid.ColumnsButton`.\n */\nexport function TMDataGridColumnsPanel() {\n const { table, controlSize } = useTMDataGridContext();\n const [search, setSearch] = useState(\"\");\n\n const columnVisibility = useSelector(\n table.store,\n (state) => state.columnVisibility,\n );\n\n const columns = table.getAllLeafColumns();\n const needle = search.trim().toLowerCase();\n const visibleInPanel = needle\n ? columns.filter((column) =>\n getColumnLabel(column).toLowerCase().includes(needle),\n )\n : columns;\n\n const hideableColumns = columns.filter((column) => column.getCanHide());\n const shownCount = hideableColumns.filter(\n (column) => columnVisibility[column.id] !== false,\n ).length;\n\n return (\n <div className={classes.columnsPanel}>\n <div className={classes.columnsPanelSearch}>\n <TextInput\n value={search}\n onChange={(event) => setSearch(event.currentTarget.value)}\n placeholder=\"Search\"\n leftSection={<SearchIcon size={16} stroke={1.6} />}\n size={controlSize}\n data-autofocus\n />\n </div>\n\n <ScrollArea.Autosize mah={260} type=\"auto\">\n <div className={classes.columnsPanelList}>\n {visibleInPanel.map((column) => (\n <Checkbox\n key={column.id}\n size={controlSize}\n label={getColumnLabel(column)}\n disabled={!column.getCanHide()}\n checked={columnVisibility[column.id] !== false}\n onChange={(event) =>\n column.toggleVisibility(event.currentTarget.checked)\n }\n />\n ))}\n {visibleInPanel.length === 0 && (\n <Text size={controlSize} c=\"dimmed\">\n No columns match “{search}”\n </Text>\n )}\n </div>\n </ScrollArea.Autosize>\n\n <div className={classes.columnsPanelFooter}>\n <Checkbox\n size={controlSize}\n label=\"Show/Hide All\"\n checked={shownCount === hideableColumns.length}\n indeterminate={shownCount > 0 && shownCount < hideableColumns.length}\n onChange={(event) =>\n table.toggleAllColumnsVisible(event.currentTarget.checked)\n }\n />\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n onClick={() => table.resetColumnVisibility()}\n >\n RESET\n </Button>\n </div>\n </div>\n );\n}\n","/* Floats over the first body rows, anchored to `.tableWrapper`. Sits just\n below the header row, so its offset follows the size scale rather than a\n fixed pixel count. */\n.filterPanel {\n position: absolute;\n top: calc(var(--dg-header-height) + 2px);\n left: var(--mantine-spacing-md);\n z-index: 5;\n padding: var(--mantine-spacing-sm);\n border-radius: var(--mantine-radius-md);\n border: 1px solid var(--mantine-color-default-border);\n background-color: var(--mantine-color-body);\n box-shadow: var(--mantine-shadow-md);\n}\n\n.filterRow {\n display: flex;\n align-items: flex-end;\n gap: var(--mantine-spacing-xs);\n}\n","import type { Row, RowData, TableFeatures } from \"@tanstack/react-table\";\n\n/**\n * The value shape stored in `columnFilters` for every TMDataGrid column.\n *\n * TanStack resolves `filterFn` statically per column, so the operator travels\n * inside the filter *value* instead. That keeps the whole filter model plain,\n * serialisable JSON — which is what makes it portable to a server-side\n * `manualFiltering` table (just forward `columnFilters` to the API).\n */\nexport type TMDataGridFilterValue = {\n operator: TMDataGridFilterOperator;\n value: string;\n};\n\nexport type TMDataGridColumnType = \"string\" | \"number\";\n\nexport type TMDataGridFilterOperator =\n | \"contains\"\n | \"equals\"\n | \"notEquals\"\n | \"startsWith\"\n | \"endsWith\"\n | \"greaterThan\"\n | \"greaterThanOrEqual\"\n | \"lessThan\"\n | \"lessThanOrEqual\"\n | \"isEmpty\"\n | \"isNotEmpty\";\n\nexport const FILTER_OPERATOR_LABELS: Record<TMDataGridFilterOperator, string> = {\n contains: \"contains\",\n equals: \"equals\",\n notEquals: \"does not equal\",\n startsWith: \"starts with\",\n endsWith: \"ends with\",\n greaterThan: \"is greater than\",\n greaterThanOrEqual: \"is greater than or equal to\",\n lessThan: \"is less than\",\n lessThanOrEqual: \"is less than or equal to\",\n isEmpty: \"is empty\",\n isNotEmpty: \"is not empty\",\n};\n\nconst STRING_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"contains\",\n \"equals\",\n \"notEquals\",\n \"startsWith\",\n \"endsWith\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\nconst NUMBER_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"equals\",\n \"notEquals\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\n/** Operators that ignore the value input (the input is disabled for these). */\nconst VALUELESS_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\nexport function getOperatorsForType(\n type: TMDataGridColumnType,\n): readonly TMDataGridFilterOperator[] {\n return type === \"number\" ? NUMBER_OPERATORS : STRING_OPERATORS;\n}\n\nexport function getDefaultOperator(\n type: TMDataGridColumnType,\n): TMDataGridFilterOperator {\n return type === \"number\" ? \"equals\" : \"contains\";\n}\n\nexport function operatorNeedsValue(operator: TMDataGridFilterOperator): boolean {\n return !VALUELESS_OPERATORS.includes(operator);\n}\n\nexport function isTMDataGridFilterValue(\n value: unknown,\n): value is TMDataGridFilterValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"operator\" in value &&\n typeof (value as TMDataGridFilterValue).operator === \"string\"\n );\n}\n\n/**\n * A filter only narrows the row set once it has something to compare against.\n * Half-typed filters stay in state (so the panel keeps rendering their row) but\n * are treated as inactive for the funnel indicator and for row matching.\n */\nexport function isFilterActive(value: unknown): boolean {\n if (!isTMDataGridFilterValue(value)) return false;\n return !operatorNeedsValue(value.operator) || value.value.trim() !== \"\";\n}\n\nexport function matchesFilter(\n cellValue: unknown,\n { operator, value }: TMDataGridFilterValue,\n): boolean {\n if (operator === \"isEmpty\") {\n return cellValue === null || cellValue === undefined || cellValue === \"\";\n }\n if (operator === \"isNotEmpty\") {\n return cellValue !== null && cellValue !== undefined && cellValue !== \"\";\n }\n\n const filterText = value.trim();\n if (filterText === \"\") return true;\n\n const numericCell = typeof cellValue === \"number\" ? cellValue : Number.NaN;\n const numericFilter = Number(filterText);\n const compareNumeric =\n !Number.isNaN(numericCell) && !Number.isNaN(numericFilter);\n\n switch (operator) {\n case \"greaterThan\":\n return compareNumeric && numericCell > numericFilter;\n case \"greaterThanOrEqual\":\n return compareNumeric && numericCell >= numericFilter;\n case \"lessThan\":\n return compareNumeric && numericCell < numericFilter;\n case \"lessThanOrEqual\":\n return compareNumeric && numericCell <= numericFilter;\n default:\n break;\n }\n\n const cellText = String(cellValue ?? \"\").toLowerCase();\n const needle = filterText.toLowerCase();\n\n switch (operator) {\n case \"contains\":\n return cellText.includes(needle);\n case \"equals\":\n return compareNumeric ? numericCell === numericFilter : cellText === needle;\n case \"notEquals\":\n return compareNumeric ? numericCell !== numericFilter : cellText !== needle;\n case \"startsWith\":\n return cellText.startsWith(needle);\n case \"endsWith\":\n return cellText.endsWith(needle);\n default:\n return true;\n }\n}\n\n/**\n * The single filter function every TMDataGrid column uses. It dispatches on the\n * operator carried by the filter value, which is what lets one column offer\n * \"contains\" / \"does not equal\" / \"is empty\" without redefining the column.\n */\nexport function tmDataGridFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown): boolean {\n if (!isTMDataGridFilterValue(filterValue)) return true;\n return matchesFilter(row.getValue(columnId), filterValue);\n}\n","import { ActionIcon, Button, Select, Stack, TextInput } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport classes from \"./TMDataGridFilterPanel.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getColumnLabel, getColumnType } from \"../core/columnUtils\";\nimport {\n type TMDataGridFilterOperator,\n type TMDataGridFilterValue,\n FILTER_OPERATOR_LABELS,\n getDefaultOperator,\n getOperatorsForType,\n isTMDataGridFilterValue,\n operatorNeedsValue,\n} from \"../core/filterOperators\";\nimport { CloseIcon } from \"./icons\";\n\nconst FALLBACK_FILTER: TMDataGridFilterValue = { operator: \"contains\", value: \"\" };\n\nfunction asFilterValue(value: unknown): TMDataGridFilterValue {\n return isTMDataGridFilterValue(value) ? value : FALLBACK_FILTER;\n}\n\n/**\n * The MUI-style filter surface: one row per active column filter, each row a\n * column / operator / value triple. It only ever reads and writes the table's\n * `columnFilters` state, so a `manualFiltering` grid gets the same panel for\n * free — the state is forwarded to the server instead of a row model.\n */\nexport function TMDataGridFilterPanel() {\n const { table, ui, controlSize } = useTMDataGridContext();\n const opened = useSelector(ui, (state) => state.filterPanelOpen);\n const columnFilters = useSelector(\n table.store,\n (state) => state.columnFilters,\n );\n\n if (!opened) return null;\n\n const filterableColumns = table\n .getAllLeafColumns()\n .filter((column) => column.getCanFilter());\n\n const columnOptions = filterableColumns.map((column) => ({\n value: column.id,\n label: getColumnLabel(column),\n }));\n\n function removeFilter(columnId: string) {\n const remaining = columnFilters.filter((filter) => filter.id !== columnId);\n table.setColumnFilters(remaining);\n if (remaining.length === 0) ui.actions.closeFilterPanel();\n }\n\n function changeFilterColumn(fromColumnId: string, toColumnId: string) {\n const current = asFilterValue(\n columnFilters.find((filter) => filter.id === fromColumnId)?.value,\n );\n const target = table.getColumn(toColumnId);\n table.setColumnFilters(\n columnFilters\n .filter((filter) => filter.id !== toColumnId)\n .map((filter) =>\n filter.id === fromColumnId\n ? {\n id: toColumnId,\n value: {\n operator: getDefaultOperator(\n target ? getColumnType(target) : \"string\",\n ),\n value: current.value,\n } satisfies TMDataGridFilterValue,\n }\n : filter,\n ),\n );\n ui.actions.openFilterPanel(toColumnId);\n }\n\n function patchFilter(columnId: string, patch: Partial<TMDataGridFilterValue>) {\n table.setColumnFilters(\n columnFilters.map((filter) =>\n filter.id === columnId\n ? { ...filter, value: { ...asFilterValue(filter.value), ...patch } }\n : filter,\n ),\n );\n }\n\n function addFilter() {\n const nextColumn = filterableColumns.find(\n (column) => !columnFilters.some((filter) => filter.id === column.id),\n );\n if (!nextColumn) return;\n table.setColumnFilters([\n ...columnFilters,\n {\n id: nextColumn.id,\n value: {\n operator: getDefaultOperator(getColumnType(nextColumn)),\n value: \"\",\n } satisfies TMDataGridFilterValue,\n },\n ]);\n }\n\n return (\n <div className={classes.filterPanel}>\n <Stack gap=\"xs\">\n {columnFilters.map((filter) => {\n const column = table.getColumn(filter.id);\n const value = asFilterValue(filter.value);\n const type = column ? getColumnType(column) : \"string\";\n const needsValue = operatorNeedsValue(value.operator);\n\n return (\n <div key={filter.id} className={classes.filterRow}>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"lg\"\n aria-label=\"Remove filter\"\n onClick={() => removeFilter(filter.id)}\n >\n <CloseIcon size={18} stroke={1.6} />\n </ActionIcon>\n\n <Select\n label=\"Column\"\n size={controlSize}\n w={160}\n allowDeselect={false}\n data={columnOptions}\n value={filter.id}\n onChange={(next) => next && changeFilterColumn(filter.id, next)}\n />\n\n <Select\n label=\"Operator\"\n size={controlSize}\n w={170}\n allowDeselect={false}\n data={getOperatorsForType(type).map((operator) => ({\n value: operator,\n label: FILTER_OPERATOR_LABELS[operator],\n }))}\n value={value.operator}\n onChange={(next) =>\n next &&\n patchFilter(filter.id, {\n operator: next as TMDataGridFilterOperator,\n })\n }\n />\n\n <TextInput\n label=\"Value\"\n size={controlSize}\n w={180}\n type={type === \"number\" && needsValue ? \"number\" : \"text\"}\n disabled={!needsValue}\n placeholder={needsValue ? \"Filter value\" : \"\"}\n value={needsValue ? value.value : \"\"}\n onChange={(event) =>\n patchFilter(filter.id, { value: event.currentTarget.value })\n }\n />\n </div>\n );\n })}\n\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n style={{ alignSelf: \"flex-start\" }}\n onClick={addFilter}\n >\n Add filter\n </Button>\n </Stack>\n </div>\n );\n}\n",".footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--mantine-spacing-lg);\n padding: 4px var(--mantine-spacing-sm);\n min-height: 48px;\n flex-shrink: 0;\n border-top: 1px solid var(--mantine-color-default-border);\n}\n","import type { Column, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport { isColumnReorderable } from \"./columnUtils\";\nimport type {\n TMDataGridFeatures,\n TMDataGridTable,\n UseTMDataGridOptions,\n} from \"../useTMDataGrid\";\n\n/**\n * Table-level feature switches, read straight off the options object.\n *\n * Why not just call `column.getCanSort()` everywhere? Because that is a method\n * call on a `column` whose identity survives an options change, so the React\n * Compiler caches the result and the chrome keeps rendering for a feature that\n * was switched off. Reading the options into a fresh object each render gives\n * every derived value something that actually changes to invalidate on.\n *\n * TanStack still decides: these flags are combined with `getCanX()`, which is\n * what applies the per-column overrides.\n */\n/**\n * How rows are selected — see `rowSelectionMode` on {@link UseTMDataGridOptions}.\n */\nexport type TMDataGridRowSelectionMode = \"checkbox\" | \"row\";\n\nexport type TMDataGridFeatureFlags = {\n sorting: boolean;\n filtering: boolean;\n hiding: boolean;\n pinning: boolean;\n resizing: boolean;\n ordering: boolean;\n rowSelection: boolean;\n /** Only meaningful while `rowSelection` is on. Defaults to `\"checkbox\"`. */\n rowSelectionMode: TMDataGridRowSelectionMode;\n /** Whether a selected row takes the highlight colour. Follows the mode. */\n highlightSelectedRows: boolean;\n /**\n * The one default-off flag: pagination must be asked for, either with the\n * grid's `enablePagination` or implicitly by declaring `manualPagination`.\n * Off, the grid renders every filtered row and relies on virtualization.\n */\n pagination: boolean;\n};\n\nexport function readFeatureFlags<TData extends RowData>(\n options: Pick<\n UseTMDataGridOptions<TData>,\n | \"enableSorting\"\n | \"enableColumnFilters\"\n | \"enableHiding\"\n | \"enableColumnPinning\"\n | \"enableColumnResizing\"\n | \"enableColumnOrdering\"\n | \"enableRowSelection\"\n | \"rowSelectionMode\"\n | \"highlightSelectedRows\"\n | \"enablePagination\"\n | \"manualPagination\"\n >,\n): TMDataGridFeatureFlags {\n return {\n sorting: options.enableSorting !== false,\n filtering: options.enableColumnFilters !== false,\n hiding: options.enableHiding !== false,\n pinning: options.enableColumnPinning !== false,\n resizing: options.enableColumnResizing !== false,\n ordering: options.enableColumnOrdering !== false,\n rowSelection: options.enableRowSelection !== false,\n rowSelectionMode: options.rowSelectionMode ?? \"checkbox\",\n // In \"row\" mode the highlight *is* the feedback for a click, so it is on.\n // With checkboxes the box already says it, so it is off unless asked for.\n highlightSelectedRows:\n options.highlightSelectedRows ?? options.rowSelectionMode === \"row\",\n pagination:\n options.enablePagination === true || options.manualPagination === true,\n };\n}\n\n/**\n * What one column's header may offer.\n *\n * | Affordance | Turned off by |\n * | ---------- | ------------- |\n * | Sort arrow, Sort ASC/DESC | `enableSorting` (table or column) |\n * | Filter item, panel entry | `enableColumnFilters` / `enableColumnFilter` |\n * | Hide column | `enableHiding` (table or column) |\n * | Pin to left / right | `enableColumnPinning` / `enablePinning` |\n * | Resize dragging | `enableColumnResizing` / `enableResizing` |\n * | Header dragging, Move left / right | `enableColumnOrdering` / `meta.enableOrdering` |\n */\nexport type TMDataGridColumnCapabilities = {\n canSort: boolean;\n canFilter: boolean;\n canHide: boolean;\n canPin: boolean;\n canResize: boolean;\n canReorder: boolean;\n};\n\nexport function getColumnCapabilities(\n column: Column<TMDataGridFeatures, TMDataGridRowData, unknown>,\n features: TMDataGridFeatureFlags,\n): TMDataGridColumnCapabilities {\n return {\n canSort: features.sorting && column.getCanSort(),\n canFilter: features.filtering && column.getCanFilter(),\n canHide: features.hiding && column.getCanHide(),\n canPin: features.pinning && column.getCanPin(),\n canResize: features.resizing && column.getCanResize(),\n // Ordering has no TanStack capability method — see isColumnReorderable.\n canReorder: features.ordering && isColumnReorderable(column),\n };\n}\n\n/** The same questions, asked of the whole grid — used to hide toolbar buttons. */\nexport type TMDataGridCapabilities = {\n canSortAny: boolean;\n canFilterAny: boolean;\n canHideAny: boolean;\n canPinAny: boolean;\n canReorderAny: boolean;\n canSelectRows: boolean;\n canPaginate: boolean;\n};\n\nexport function getGridCapabilities(\n table: TMDataGridTable<TMDataGridRowData>,\n features: TMDataGridFeatureFlags,\n): TMDataGridCapabilities {\n const columns = table.getAllLeafColumns();\n const any = (predicate: (capabilities: TMDataGridColumnCapabilities) => boolean) =>\n columns.some((column) => predicate(getColumnCapabilities(column, features)));\n\n return {\n canSortAny: any((c) => c.canSort),\n canFilterAny: any((c) => c.canFilter),\n canHideAny: any((c) => c.canHide),\n canPinAny: any((c) => c.canPin),\n canReorderAny: any((c) => c.canReorder),\n canSelectRows: features.rowSelection,\n canPaginate: features.pagination,\n };\n}\n","import { ActionIcon, Group, Select, Text } from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ReactNode } from \"react\";\nimport classes from \"./TMDataGridFooter.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getGridCapabilities } from \"../core/capabilities\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"./icons\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/** Distilled pagination state and actions for building a custom pager. */\nexport type TMDataGridPaginationApi = {\n pageIndex: number;\n pageSize: number;\n /** `-1` when a manual grid declares `pageCount: -1` (unknown total). */\n pageCount: number;\n rowCount: number;\n canPreviousPage: boolean;\n canNextPage: boolean;\n setPageIndex: (pageIndex: number) => void;\n setPageSize: (pageSize: number) => void;\n previousPage: () => void;\n nextPage: () => void;\n firstPage: () => void;\n lastPage: () => void;\n};\n\n/**\n * Reads {@link TMDataGridPaginationApi} off a table. The Footer feeds it to the\n * `pagination` render prop; a pager living outside the Footer can call it with\n * the table from `useTMDataGrid` directly.\n */\nexport function getTMDataGridPaginationApi<TData extends RowData>(\n table: TMDataGridTable<TData>,\n): TMDataGridPaginationApi {\n const { pageIndex, pageSize } = table.store.state.pagination;\n return {\n pageIndex,\n pageSize,\n pageCount: table.getPageCount(),\n rowCount: table.getRowCount(),\n canPreviousPage: table.getCanPreviousPage(),\n canNextPage: table.getCanNextPage(),\n setPageIndex: (index) => table.setPageIndex(index),\n setPageSize: (size) => table.setPageSize(size),\n previousPage: () => table.previousPage(),\n nextPage: () => table.nextPage(),\n firstPage: () => table.firstPage(),\n lastPage: () => table.lastPage(),\n };\n}\n\nexport type TMDataGridFooterProps = {\n pageSizeOptions?: ReadonlyArray<number>;\n /** Replaces the built-in pager. Receives the distilled pagination API. */\n pagination?: (api: TMDataGridPaginationApi) => ReactNode;\n};\n\n/**\n * MUI-style pager: \"Rows per page · from–to of total · ‹ ›\".\n *\n * Renders nothing unless pagination is enabled (`enablePagination` or\n * `manualPagination`) — the footer is a pager; extra footer content belongs in\n * your own layout.\n *\n * Row totals come from `table.getRowCount()`, which prefers `options.rowCount`\n * — so a server-paged grid shows the server's total without changes here.\n */\nexport function TMDataGridFooter({\n pageSizeOptions = [10, 25, 50, 100],\n pagination,\n}: TMDataGridFooterProps) {\n const { table, features, controlSize } = useTMDataGridContext();\n useSelector(table.store);\n\n if (!getGridCapabilities(table, features).canPaginate) return null;\n\n if (pagination) {\n return (\n <div className={classes.footer}>\n {pagination(getTMDataGridPaginationApi(table))}\n </div>\n );\n }\n\n const { pageIndex, pageSize } = table.store.state.pagination;\n const total = table.getRowCount();\n const from = total === 0 ? 0 : pageIndex * pageSize + 1;\n const to = Math.min(total, (pageIndex + 1) * pageSize);\n // A page size restored from storage, or set through `initialState`, need not\n // be one of the offered sizes. Without it in the list the Select renders\n // blank, so the current size is folded in rather than shown as nothing.\n const sizeOptions = pageSizeOptions.includes(pageSize)\n ? pageSizeOptions\n : [...pageSizeOptions, pageSize].sort((a, b) => a - b);\n\n return (\n <div className={classes.footer}>\n <Group gap=\"xs\" wrap=\"nowrap\">\n <Text size={controlSize} c=\"dimmed\">\n Rows per page:\n </Text>\n <Select\n size={controlSize}\n w={78}\n allowDeselect={false}\n variant=\"unstyled\"\n data={sizeOptions.map(String)}\n value={String(pageSize)}\n onChange={(value) => {\n table.setPageSize(Number(value) || pageSizeOptions[0]);\n table.setPageIndex(0);\n }}\n />\n </Group>\n\n <Text size={controlSize} c=\"dimmed\">\n {from}–{to} of {total}\n </Text>\n\n <Group gap={4} wrap=\"nowrap\">\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n aria-label=\"Previous page\"\n disabled={!table.getCanPreviousPage()}\n onClick={() => table.previousPage()}\n >\n <ChevronLeftIcon size={18} stroke={1.6} />\n </ActionIcon>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n aria-label=\"Next page\"\n disabled={!table.getCanNextPage()}\n onClick={() => table.nextPage()}\n >\n <ChevronRightIcon size={18} stroke={1.6} />\n </ActionIcon>\n </Group>\n </div>\n );\n}\n","/* Anchors the filter panel, which floats over the first body rows. */\n.tableWrapper {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.scrollContainer {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n\n/* Column tracks are set inline via gridTemplateColumns. */\n.grid {\n display: grid;\n}\n\n/* Rows are real layout boxes (not display: contents) so position: sticky works,\n and subgrid keeps their cells on the parent's column tracks. */\n.headerRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n top: 0;\n z-index: 3;\n}\n\n.bodyRow {\n --row-bg: var(--mantine-color-body);\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n align-items: stretch;\n}\n\n.bodyRow:hover {\n --row-bg: var(--mantine-color-default-hover);\n}\n\n/* Selection and highlight are separate: a row is always `data-selected`, but it\n only takes the highlight colour when `highlightSelectedRows` is on — the\n default in row selection mode, off with checkboxes. */\n.bodyRow[data-highlighted=\"true\"] {\n --row-bg: var(--dg-row-selected-bg);\n}\n\n/* Row selection mode: the row is the control, so it takes focus and must not\n start a text selection on the click that toggles it. */\n.bodyRow[data-selects-on-click=\"true\"] {\n user-select: none;\n}\n\n.bodyRow:focus-visible {\n outline: 2px solid var(--mantine-primary-color-filled);\n outline-offset: -2px;\n}\n\n/* Clipping lives on .cellContent, not here — a pinned cell has to let its\n boundary gradient escape past its own right/left edge. */\n.bodyCell {\n display: flex;\n align-items: center;\n padding: 0 var(--dg-padding);\n border-bottom: 1px solid var(--mantine-color-default-border);\n /* Inherited from .bodyRow — sticky cells need an opaque background. */\n background-color: var(--row-bg);\n font-size: var(--dg-font-size);\n}\n\n.cellContent {\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.bodyCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.bodyCell[data-align=\"center\"] {\n justify-content: center;\n}\n\n/* Only stretch to fill when left-aligned, so right/centre stay put. */\n.bodyCell[data-align=\"left\"] .cellContent {\n flex: 1 1 auto;\n}\n\n.messageRow {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-xl);\n}\n","/* Boundary of a pinned column group. Shared, because the edge is cast by both\n the header cell and every body cell in the same column — the two have to\n draw an identical band or the seam shows at the header.\n\n A box-shadow is drawn per cell, and its blur fades in at each cell's own top\n and bottom edge — stacked down a column that reads as banding at every row\n seam. Instead: a crisp 1px border for the hard edge, plus a gradient pseudo\n element pinned to `top: 0; bottom: 0` so consecutive cells butt together into\n one unbroken band. Mantine sets `color-scheme` on the root, so light-dark()\n resolves without a second selector. */\n.stickyLeft {\n border-right: 1px solid var(--mantine-color-default-border);\n}\n\n.stickyRight {\n border-left: 1px solid var(--mantine-color-default-border);\n}\n\n.stickyLeft::after,\n.stickyRight::after {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n width: 4px;\n pointer-events: none;\n}\n\n.stickyLeft::after {\n left: 100%;\n background: linear-gradient(\n to right,\n light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.28)),\n transparent\n );\n}\n\n.stickyRight::after {\n right: 100%;\n background: linear-gradient(\n to left,\n light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.28)),\n transparent\n );\n}\n",".headerCell {\n position: relative;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 var(--dg-padding);\n min-width: 0;\n min-height: var(--dg-header-height);\n font-weight: 600;\n font-size: var(--dg-font-size);\n background-color: var(--mantine-color-body);\n border-bottom: 1px solid var(--mantine-color-default-border);\n user-select: none;\n}\n\n.headerCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.headerCell[data-align=\"center\"] {\n justify-content: center;\n}\n\n/* Sorted or filtered columns read as active, like the MUI data grid. */\n.headerCell[data-active=\"true\"] .headerTitle {\n color: var(--mantine-primary-color-filled);\n}\n\n.headerTitle {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Right-aligned headers stay text so the ellipsis still works; centered ones\n hold a control (the select-all checkbox), so they become a flex box. */\n.headerCell[data-align=\"right\"] .headerTitle {\n text-align: right;\n}\n\n.headerCell[data-align=\"center\"] .headerTitle {\n display: flex;\n justify-content: center;\n}\n\n.headerActions {\n display: flex;\n align-items: center;\n gap: 0;\n flex-shrink: 0;\n margin-left: auto;\n}\n\n/* Actions always reserve their width. On right-aligned columns they move to the\n leading edge so the header text stays flush with the cell values below it. */\n.headerCell[data-align=\"right\"] .headerActions {\n order: -1;\n margin-left: 0;\n margin-right: auto;\n}\n\n/* Idle actions are removed from layout, not just faded — reserving their width\n would truncate header text that otherwise fits. Indicators that must stay\n visible (active sort, active filter, open menu) set data-pinned-visible. */\n.headerAction {\n display: none;\n}\n\n.headerCell:hover .headerAction,\n.headerCell:focus-within .headerAction,\n.headerAction[data-pinned-visible=\"true\"] {\n display: flex;\n}\n\n.headerCellSortable {\n cursor: pointer;\n}\n\n/* Column reordering. The dragged header stays in place and dims — the browser\n already carries a snapshot of it under the pointer — while the header being\n dragged over draws a bar on the edge the column will land against. */\n.headerCellDragging {\n opacity: 0.4;\n}\n\n.headerCellDropBefore::before,\n.headerCellDropAfter::before {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background-color: var(--mantine-primary-color-filled);\n z-index: 5;\n pointer-events: none;\n}\n\n.headerCellDropBefore::before {\n left: 0;\n}\n\n.headerCellDropAfter::before {\n right: 0;\n}\n\n/* Doubles as the column divider seen between every header cell. */\n.columnSeparator {\n position: absolute;\n top: 25%;\n right: 0;\n height: 50%;\n width: 10px;\n transform: translateX(50%);\n display: flex;\n justify-content: center;\n z-index: 1;\n}\n\n.columnSeparatorResizable {\n cursor: col-resize;\n touch-action: none;\n}\n\n/* The divider is a hover affordance, not permanent chrome — it only appears on\n the header cell you are pointing at, or on the column being resized. */\n.columnSeparator::after {\n content: \"\";\n width: 1px;\n height: 100%;\n background-color: transparent;\n transition:\n background-color 120ms ease,\n width 120ms ease;\n}\n\n.headerCell:hover .columnSeparator::after,\n.headerCell:focus-within .columnSeparator::after {\n background-color: var(--mantine-color-default-border);\n}\n\n.columnSeparatorResizable:hover::after,\n.columnSeparatorActive::after {\n width: 2px;\n background-color: var(--mantine-primary-color-filled);\n}\n\n/* Marks the pin position a column is currently in. */\n.menuItemActive {\n background-color: var(--mantine-color-default-hover);\n font-weight: 600;\n}\n","import type { Column, ColumnPinningState } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport { isColumnReorderable } from \"./columnUtils\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\ntype GridColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\ntype GridTable = TMDataGridTable<TMDataGridRowData>;\n\n/**\n * The lane a column renders in.\n *\n * Pinning splits the grid into three, and TanStack sequences them from two\n * different state slices: `columnPinning.left` / `.right` order the pinned\n * lanes, `columnOrder` orders the centre. A move therefore always stays inside\n * one lane — moving a column into another one would be a pin, not a reorder.\n */\nexport type TMDataGridColumnRegion = \"left\" | \"center\" | \"right\";\n\n/** Which edge of the column under the pointer a dragged column lands on. */\nexport type TMDataGridDropSide = \"before\" | \"after\";\n\nexport function getColumnRegion(\n columnPinning: ColumnPinningState,\n columnId: string,\n): TMDataGridColumnRegion {\n if (columnPinning.left.includes(columnId)) return \"left\";\n if (columnPinning.right.includes(columnId)) return \"right\";\n return \"center\";\n}\n\n/** Moves one id next to another, leaving every other id in place. */\nfunction moveInList(\n ids: ReadonlyArray<string>,\n movedId: string,\n targetId: string,\n side: TMDataGridDropSide,\n): Array<string> {\n const remaining = ids.filter((id) => id !== movedId);\n const targetIndex = remaining.indexOf(targetId);\n if (targetIndex === -1) return [...ids];\n remaining.splice(side === \"before\" ? targetIndex : targetIndex + 1, 0, movedId);\n return remaining;\n}\n\nexport type MoveColumnArgs = {\n table: GridTable;\n /** Column being moved. */\n columnId: string;\n /** Column it was dropped on. */\n targetId: string;\n side: TMDataGridDropSide;\n};\n\n/**\n * Moves a column next to another one. A no-op when the two are in different\n * pinned regions, or when either id is unknown.\n *\n * `columnOrder` is always written as the full leaf order, including hidden and\n * pinned columns, so a column keeps its place when it is later shown or\n * unpinned. Pinned lanes are read from `columnPinning`, so a move inside one\n * updates that array as well.\n */\nexport function moveColumn({\n table,\n columnId,\n targetId,\n side,\n}: MoveColumnArgs): void {\n if (columnId === targetId) return;\n\n const columnPinning = table.store.state.columnPinning;\n const region = getColumnRegion(columnPinning, columnId);\n if (region !== getColumnRegion(columnPinning, targetId)) return;\n\n const leafIds = table.getAllLeafColumns().map((column) => column.id);\n table.setColumnOrder(moveInList(leafIds, columnId, targetId, side));\n\n if (region !== \"center\") {\n table.setColumnPinning((previous) => ({\n ...previous,\n [region]: moveInList(previous[region], columnId, targetId, side),\n }));\n }\n}\n\n/** Visible leaf columns of one lane, in the order they render. */\nfunction getRegionColumns(\n table: GridTable,\n region: TMDataGridColumnRegion,\n): Array<GridColumn> {\n if (region === \"left\") return table.getLeftVisibleLeafColumns();\n if (region === \"right\") return table.getRightVisibleLeafColumns();\n return table.getCenterVisibleLeafColumns();\n}\n\nexport type ColumnStepArgs = {\n table: GridTable;\n columnId: string;\n /** `-1` moves towards the start of the lane, `1` towards its end. */\n direction: -1 | 1;\n};\n\n/**\n * The column a single step would swap with, or `null` when there is none.\n *\n * A neighbour that cannot be reordered acts as a wall rather than being skipped\n * — that is what keeps the checkbox column anchored at the start of the left\n * lane. Use it to enable or disable a \"move\" control.\n */\nexport function getStepTargetColumn({\n table,\n columnId,\n direction,\n}: ColumnStepArgs): GridColumn | null {\n const region = getColumnRegion(table.store.state.columnPinning, columnId);\n const columns = getRegionColumns(table, region);\n const index = columns.findIndex((column) => column.id === columnId);\n if (index === -1) return null;\n\n const target = columns[index + direction];\n if (!target || !isColumnReorderable(target)) return null;\n return target;\n}\n\n/** Moves a column one position within its lane. Hidden columns are stepped over. */\nexport function moveColumnByStep({\n table,\n columnId,\n direction,\n}: ColumnStepArgs): void {\n const target = getStepTargetColumn({ table, columnId, direction });\n if (!target) return;\n\n moveColumn({\n table,\n columnId,\n targetId: target.id,\n side: direction === -1 ? \"before\" : \"after\",\n });\n}\n","import { Checkbox } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ColumnDef, Row, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\nexport const SELECT_COLUMN_ID = \"__select__\";\n\n/**\n * Both checkboxes subscribe to the table store themselves rather than reading\n * the selection off the render they were handed.\n *\n * A cell is rendered by `flexRender`, which mounts the cell function as its own\n * component — but the body cell above it keeps the same props across a\n * selection change (row, column and layout identities all survive it), so the\n * React Compiler reuses the memoized element and the subtree never re-renders.\n * The row highlight would update, from state `TMDataGridTable` subscribes to,\n * while the box below it stayed unchecked.\n *\n * Selection is derived inside the selector, not from a method call in the\n * component body, for the same reason: `table` and `row` identities survive the\n * change, so a call in the body would be cached along with them.\n */\nfunction SelectAllCheckbox<TData extends RowData>({\n table,\n}: {\n table: TMDataGridTable<TData>;\n}) {\n const allSelected = useSelector(table.store, () =>\n table.getIsAllRowsSelected(),\n );\n const someSelected = useSelector(table.store, () =>\n table.getIsSomeRowsSelected(),\n );\n\n return (\n <Checkbox\n size=\"xs\"\n aria-label=\"Select all rows\"\n checked={allSelected}\n indeterminate={someSelected && !allSelected}\n onChange={table.getToggleAllRowsSelectedHandler()}\n />\n );\n}\n\nfunction SelectRowCheckbox<TData extends RowData>({\n row,\n}: {\n row: Row<TMDataGridFeatures, TData>;\n}) {\n const selected = useSelector(row.table.store, () => row.getIsSelected());\n const someSelected = useSelector(row.table.store, () =>\n row.getIsSomeSelected(),\n );\n\n return (\n <Checkbox\n size=\"xs\"\n aria-label=\"Select row\"\n checked={selected}\n disabled={!row.getCanSelect()}\n indeterminate={someSelected && !selected}\n onChange={row.getToggleSelectedHandler()}\n // A row can select on click too; the checkbox must not toggle twice.\n onClick={(event) => event.stopPropagation()}\n />\n );\n}\n\n/**\n * The generated checkbox column, prepended under\n * `rowSelectionMode: \"checkbox\"` — the default whenever row selection is on.\n */\nexport function createSelectColumn<TData extends RowData>(): ColumnDef<\n TMDataGridFeatures,\n TData,\n unknown\n> {\n return {\n id: SELECT_COLUMN_ID,\n meta: {\n label: \"Checkbox selection\",\n align: \"center\",\n // Structurally the first column; it also anchors the left pinned lane, so\n // no other column can be moved in front of it.\n enableOrdering: false,\n },\n size: 48,\n minSize: 48,\n maxSize: 48,\n enableResizing: false,\n enableSorting: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n // Structurally pinned to the left; users shouldn't be able to move it.\n enablePinning: false,\n header: ({ table }) => <SelectAllCheckbox table={table} />,\n cell: ({ row }) => <SelectRowCheckbox row={row} />,\n };\n}\n","import type { TableState } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\ntype GridState = TableState<TMDataGridFeatures>;\n\n/**\n * Persistence deliberately does not use Mantine's `useLocalStorage`.\n *\n * That hook owns a piece of state and returns `[value, setValue]`. Here the\n * table already owns the state and storage only mirrors it, so routing writes\n * through the hook would keep a second copy and trigger a React state update on\n * every change, including every pointer move during a column resize. Its\n * defaults also work against this use: `getInitialValueInEffect: true` delivers\n * the stored value after mount, while `initialState` is only read on the first\n * render, and `sync: true` would let two open tabs overwrite each other's\n * column layout.\n *\n * The option vocabulary follows Mantine's: `StorageType` is its type, and\n * `serialize` / `deserialize` behave as they do in `UseStorageOptions`.\n */\n\n/**\n * State slices describing what the user is looking at. Derived from the data,\n * so they can go stale as it changes.\n */\nexport const DATA_STATE_SLICES = [\n \"columnFilters\",\n \"globalFilter\",\n \"sorting\",\n \"pagination\",\n] as const satisfies ReadonlyArray<keyof GridState>;\n\n/**\n * State slices describing how the user configured the grid. Independent of the\n * data, and the ones users notice losing.\n */\nexport const SETTINGS_STATE_SLICES = [\n \"columnVisibility\",\n \"columnSizing\",\n \"columnOrder\",\n \"columnPinning\",\n] as const satisfies ReadonlyArray<keyof GridState>;\n\nexport type TMDataGridDataSlice = (typeof DATA_STATE_SLICES)[number];\nexport type TMDataGridSettingsSlice = (typeof SETTINGS_STATE_SLICES)[number];\n\n/**\n * A storage key, optionally narrowed to a subset of its group's slices.\n *\n * - `\"employees.data\"` — persists every slice in the group.\n * - `[\"employees.data\", [\"sorting\"]]` — persists only the listed slices.\n */\nexport type TMDataGridPersistKey<TSlice extends string> =\n | string\n | readonly [key: string, slices: readonly TSlice[]];\n\n/** Same values as Mantine's `StorageType`, which the package does not re-export. */\nexport type TMDataGridStorageMode = \"localStorage\" | \"sessionStorage\";\n\nexport type TMDataGridPersistence = {\n /** Key for filters, global filter, sorting and pagination. */\n dataKey?: TMDataGridPersistKey<TMDataGridDataSlice>;\n /** Key for column visibility, sizing, order and pinning. */\n settingsKey?: TMDataGridPersistKey<TMDataGridSettingsSlice>;\n /** Which storage area to use. Defaults to `\"localStorage\"`. */\n storageMode?: TMDataGridStorageMode;\n /** Serializes a payload before it is stored. Defaults to `JSON.stringify`. */\n serialize?: (value: Partial<GridState>) => string;\n /** Parses a stored payload. Defaults to `JSON.parse`. */\n deserialize?: (value: string) => unknown;\n};\n\ntype ResolvedKey = { key: string; slices: ReadonlyArray<keyof GridState> };\n\nfunction resolveKey<TSlice extends string>(\n entry: TMDataGridPersistKey<TSlice> | undefined,\n defaultSlices: ReadonlyArray<keyof GridState>,\n): ResolvedKey | null {\n if (!entry) return null;\n if (typeof entry === \"string\") return { key: entry, slices: defaultSlices };\n\n const [key, slices] = entry;\n if (!key) return null;\n // An empty list means nothing was selected, which is not the same as \"all\".\n return { key, slices: slices as ReadonlyArray<keyof GridState> };\n}\n\nfunction resolveStorage(\n persistence: TMDataGridPersistence | undefined,\n): Storage | null {\n if (!persistence) return null;\n // Absent under SSR, and access throws outright in some privacy modes.\n try {\n if (typeof window === \"undefined\") return null;\n return persistence.storageMode === \"sessionStorage\"\n ? window.sessionStorage\n : window.localStorage;\n } catch {\n return null;\n }\n}\n\n/**\n * Shape guards for restored state.\n *\n * A stored payload outlives the code that wrote it: a slice can change shape\n * between releases, and nothing stops anyone from editing storage by hand. The\n * value goes straight into `initialState`, where a wrong shape surfaces as a\n * crash inside TanStack rather than as a bad read here. A slice that fails its\n * guard is dropped; the rest still restore.\n */\nfunction prop(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)[key]\n : undefined;\n}\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nfunction isArrayOf(\n value: unknown,\n isItem: (item: unknown) => boolean,\n): boolean {\n return Array.isArray(value) && value.every(isItem);\n}\n\nfunction isRecordOf(\n value: unknown,\n isItem: (item: unknown) => boolean,\n): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n return Object.values(value).every(isItem);\n}\n\nconst hasStringId = (entry: unknown): boolean => isString(prop(entry, \"id\"));\n\nconst SLICE_GUARDS: Record<\n TMDataGridDataSlice | TMDataGridSettingsSlice,\n (value: unknown) => boolean\n> = {\n columnFilters: (value) => isArrayOf(value, hasStringId),\n // TanStack leaves the global filter value untyped — the grid's own default\n // filters on a string, but a consumer may store anything here.\n globalFilter: () => true,\n sorting: (value) =>\n isArrayOf(\n value,\n (entry) => hasStringId(entry) && typeof prop(entry, \"desc\") === \"boolean\",\n ),\n pagination: (value) => {\n const pageIndex = prop(value, \"pageIndex\");\n const pageSize = prop(value, \"pageSize\");\n return (\n isFiniteNumber(pageIndex) &&\n pageIndex >= 0 &&\n isFiniteNumber(pageSize) &&\n pageSize > 0\n );\n },\n columnVisibility: (value) =>\n isRecordOf(value, (entry) => typeof entry === \"boolean\"),\n columnSizing: (value) => isRecordOf(value, isFiniteNumber),\n columnOrder: (value) => isArrayOf(value, isString),\n columnPinning: (value) =>\n isArrayOf(prop(value, \"left\"), isString) &&\n isArrayOf(prop(value, \"right\"), isString),\n};\n\nfunction isValidSlice(slice: keyof GridState, value: unknown): boolean {\n const guard = SLICE_GUARDS[slice as keyof typeof SLICE_GUARDS];\n return guard === undefined || guard(value);\n}\n\nfunction readSlices(\n storage: Storage | null,\n resolved: ResolvedKey | null,\n deserialize: (value: string) => unknown,\n): Partial<GridState> {\n if (!storage || !resolved) return {};\n try {\n const raw = storage.getItem(resolved.key);\n if (!raw) return {};\n const parsed = deserialize(raw);\n if (typeof parsed !== \"object\" || parsed === null) return {};\n\n const record = parsed as Record<string, unknown>;\n const restored: Record<string, unknown> = {};\n // Only copy the selected slices. A payload written before the selection was\n // narrowed cannot reintroduce slices the caller has since opted out of.\n for (const slice of resolved.slices) {\n if (!(slice in record)) continue;\n if (!isValidSlice(slice, record[slice])) continue;\n restored[slice] = record[slice];\n }\n return restored as Partial<GridState>;\n } catch {\n return {};\n }\n}\n\nfunction writeSlices(\n storage: Storage | null,\n resolved: ResolvedKey | null,\n state: GridState,\n serialize: (value: Partial<GridState>) => string,\n): void {\n if (!storage || !resolved) return;\n const payload: Record<string, unknown> = {};\n for (const slice of resolved.slices) payload[slice] = state[slice];\n try {\n storage.setItem(resolved.key, serialize(payload as Partial<GridState>));\n } catch {\n // Quota exceeded or storage disabled. Persistence is best effort.\n }\n}\n\nfunction resolveKeys(persistence: TMDataGridPersistence | undefined) {\n return {\n data: resolveKey(persistence?.dataKey, DATA_STATE_SLICES),\n settings: resolveKey(persistence?.settingsKey, SETTINGS_STATE_SLICES),\n };\n}\n\n/** True when at least one key is configured. */\nexport function hasPersistenceKeys(\n persistence: TMDataGridPersistence | undefined,\n): boolean {\n const { data, settings } = resolveKeys(persistence);\n return data !== null || settings !== null;\n}\n\nconst defaultDeserialize = (value: string): unknown => JSON.parse(value);\nconst defaultSerialize = (value: Partial<GridState>): string =>\n JSON.stringify(value);\n\n/** State to merge into `initialState`, read once on mount. */\nexport function readPersistedState(\n persistence?: TMDataGridPersistence,\n): Partial<GridState> {\n const storage = resolveStorage(persistence);\n const { data, settings } = resolveKeys(persistence);\n const deserialize = persistence?.deserialize ?? defaultDeserialize;\n return {\n ...readSlices(storage, settings, deserialize),\n ...readSlices(storage, data, deserialize),\n };\n}\n\n/** Writes both payloads. Called on every table state change. */\nexport function writePersistedState(\n state: GridState,\n persistence?: TMDataGridPersistence,\n): void {\n const storage = resolveStorage(persistence);\n if (!storage) return;\n const { data, settings } = resolveKeys(persistence);\n const serialize = persistence?.serialize ?? defaultSerialize;\n writeSlices(storage, data, state, serialize);\n writeSlices(storage, settings, state, serialize);\n}\n","import { useCreateStore } from \"@tanstack/react-store\";\nimport {\n type ColumnDef,\n columnFacetingFeature,\n columnFilteringFeature,\n columnOrderingFeature,\n columnPinningFeature,\n columnResizingFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createColumnHelper,\n createFacetedMinMaxValues,\n createFacetedRowModel,\n createFacetedUniqueValues,\n createFilteredRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n filterFns,\n globalFilteringFeature,\n metaHelper,\n type RowData,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n sortFns,\n type Table,\n tableFeatures,\n type TableOptions,\n type TableState,\n useTable,\n} from \"@tanstack/react-table\";\nimport type { Store } from \"@tanstack/store\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport {\n type TMDataGridColumnType,\n tmDataGridFilterFn,\n getDefaultOperator,\n} from \"./core/filterOperators\";\nimport {\n hasPersistenceKeys,\n readPersistedState,\n type TMDataGridPersistence,\n writePersistedState,\n} from \"./core/persistence\";\nimport {\n readFeatureFlags,\n type TMDataGridFeatureFlags,\n type TMDataGridRowSelectionMode,\n} from \"./core/capabilities\";\nimport {\n createSelectColumn,\n SELECT_COLUMN_ID,\n} from \"./components/TMDataGridSelectColumn\";\n\n/**\n * How long the grid waits after the last state change before writing to\n * storage. Long enough to collapse a resize drag into one write, short enough\n * that a reload right after a change still sees it.\n */\nconst PERSIST_DEBOUNCE_MS = 200;\n\n/** Per-column configuration the TMDataGrid chrome reads. */\nexport type TMDataGridColumnMeta = {\n /** Name shown in menus and the column manager. Falls back to a string header. */\n label?: string;\n /** Drives which filter operators are offered. Defaults to `\"string\"`. */\n type?: TMDataGridColumnType;\n /** Share of the leftover width this column claims. Defaults to `1`. */\n flex?: number;\n align?: \"left\" | \"right\" | \"center\";\n /**\n * `false` keeps the column where it is: no header dragging, no move items.\n * Column ordering is the one feature TanStack defines no column option for,\n * so its switch lives here rather than on the column definition.\n */\n enableOrdering?: boolean;\n};\n\n/** Grid-wide configuration passed through `options.meta`. */\nexport type TMDataGridTableMeta = {\n loading?: boolean;\n noResultsLabel?: string;\n /** Row height used by the virtualizer. Defaults to `52`. */\n rowHeight?: number;\n /**\n * Unfiltered row total. Only needed for server-driven grids, where the client\n * never holds the full data set — `TMDataGrid.SummaryCount` uses it as denominator.\n */\n totalRowCount?: number;\n};\n\n/**\n * Every feature the TMDataGrid chrome can drive. Defined at module scope so the\n * reference stays stable across renders (see the TanStack table-state skill).\n */\nexport const tmDataGridFeatures = tableFeatures({\n columnFilteringFeature,\n globalFilteringFeature,\n rowSortingFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n columnPinningFeature,\n columnVisibilityFeature,\n columnOrderingFeature,\n columnSizingFeature,\n columnResizingFeature,\n columnFacetingFeature,\n\n filteredRowModel: createFilteredRowModel(),\n sortedRowModel: createSortedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n facetedRowModel: createFacetedRowModel(),\n facetedMinMaxValues: createFacetedMinMaxValues(),\n facetedUniqueValues: createFacetedUniqueValues(),\n\n filterFns: { ...filterFns, tmDataGrid: tmDataGridFilterFn },\n sortFns,\n\n tableMeta: metaHelper<TMDataGridTableMeta>(),\n columnMeta: metaHelper<TMDataGridColumnMeta>(),\n});\n\nexport type TMDataGridFeatures = typeof tmDataGridFeatures;\n\nexport type TMDataGridTable<TData extends RowData> = Table<\n TMDataGridFeatures,\n TData\n>;\n\nexport function createTMDataGridColumnHelper<TData extends RowData>() {\n return createColumnHelper<TMDataGridFeatures, TData>();\n}\n\n/**\n * Chrome state that is *not* table state: which panels are open, and which\n * column opened the filter panel. Kept in a TanStack Store so consumers can\n * subscribe to it the same way they subscribe to `table.store`.\n */\nexport type TMDataGridUiState = {\n filterPanelOpen: boolean;\n columnsPanelOpen: boolean;\n /** Column whose filter row should be focused when the panel opens. */\n filterPanelColumnId: string | null;\n /**\n * Column being dragged by its header, if any. Held here rather than read from\n * `dataTransfer`, which browsers keep unreadable until the drop.\n */\n draggedColumnId: string | null;\n};\n\nexport type TMDataGridUiActions = {\n openFilterPanel: (columnId?: string | null) => void;\n closeFilterPanel: () => void;\n setColumnsPanelOpen: (open: boolean) => void;\n toggleColumnsPanel: () => void;\n startColumnDrag: (columnId: string) => void;\n endColumnDrag: () => void;\n};\n\nexport type TMDataGridUiStore = Store<TMDataGridUiState, TMDataGridUiActions>;\n\n/** What `useTMDataGrid` returns — spread straight onto `<TMDataGrid />`. */\nexport type TMDataGridApi<TData extends RowData> = {\n table: TMDataGridTable<TData>;\n ui: TMDataGridUiStore;\n /** Table-level feature switches, re-read from options on every render. */\n features: TMDataGridFeatureFlags;\n};\n\nexport type UseTMDataGridOptions<TData extends RowData> = Omit<\n TableOptions<TMDataGridFeatures, TData>,\n \"features\"\n> & {\n /**\n * Restore and persist table state across mounts. Two keys, because the two\n * kinds of state have different lifetimes — see {@link TMDataGridPersistence}.\n *\n * Keep the object referentially stable (module scope or `useMemo`); it is a\n * dependency of the subscription that writes back.\n */\n persist?: TMDataGridPersistence;\n /**\n * Header drag-and-drop and the move items in the column menu. Defaults to\n * `true`.\n *\n * The one feature switch the grid defines itself: TanStack's\n * `columnOrderingFeature` ships state and APIs but no `enable` option, since\n * reordering is entirely a matter of interface.\n */\n enableColumnOrdering?: boolean;\n /**\n * Client-side pagination and the built-in `TMDataGrid.Footer` pager.\n * Defaults to `false`: the grid renders every filtered row and relies on\n * virtualization.\n *\n * The second grid-defined switch (TanStack defines no `enablePagination`\n * option). `manualPagination: true` implies it — a server-paged grid needs\n * no extra flag.\n */\n enablePagination?: boolean;\n /**\n * How rows are selected. Defaults to `\"checkbox\"`.\n *\n * - `\"checkbox\"` — the generated checkbox column selects; clicking a row\n * elsewhere does not.\n * - `\"row\"` — no checkbox column; clicking a row toggles it. Other rows keep\n * their state, so a click never clears the rest of the selection.\n *\n * Ignored when `enableRowSelection` is `false`. Both modes write to the same\n * `rowSelection` state.\n */\n rowSelectionMode?: TMDataGridRowSelectionMode;\n /**\n * Give selected rows the highlight background. Defaults to `true` under\n * `rowSelectionMode: \"row\"`, where the highlight is the only feedback a click\n * gives, and `false` under `\"checkbox\"`, where the box already shows it.\n *\n * The colour is the `--dg-row-selected-bg` CSS variable, so it can be changed\n * without turning the flag on or off:\n *\n * ```tsx\n * <TMDataGrid\n * {...grid}\n * style={{ \"--dg-row-selected-bg\": \"var(--mantine-color-blue-0)\" }}\n * />\n * ```\n */\n highlightSelectedRows?: boolean;\n};\n\ntype TMDataGridColumnDef<TData extends RowData> = ColumnDef<\n TMDataGridFeatures,\n TData,\n unknown\n>;\n\n/**\n * Point every column at the operator-dispatching filter function unless the\n * column opted into its own.\n */\nfunction withTMDataGridDefaults<TData extends RowData>(\n columns: ReadonlyArray<TMDataGridColumnDef<TData>>,\n): Array<TMDataGridColumnDef<TData>> {\n return columns.map((column) => {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n return {\n ...column,\n columns: withTMDataGridDefaults<TData>(column.columns),\n };\n }\n return { filterFn: \"tmDataGrid\", ...column } as TMDataGridColumnDef<TData>;\n });\n}\n\n/**\n * Builds a TMDataGrid table plus its chrome store.\n *\n * Every `TableOptions` field passes straight through, so a server-driven grid\n * only needs `manualPagination` / `manualFiltering` / `manualSorting`,\n * `rowCount` and the matching `onXChange` callbacks — the chrome reads\n * `getRowCount()` / `getPageCount()` / `getPaginatedRowModel()`, all of which\n * already respect manual mode. `manualPagination` also switches the pagination\n * flag on, so `<TMDataGrid.Footer />` renders its pager without further\n * options.\n */\nexport function useTMDataGrid<TData extends RowData>({\n persist,\n // Not TanStack options, so they are kept out of what `useTable` receives.\n enableColumnOrdering,\n enablePagination,\n rowSelectionMode,\n highlightSelectedRows,\n ...options\n}: UseTMDataGridOptions<TData>): TMDataGridApi<TData> {\n const selectionEnabled = options.enableRowSelection !== false;\n const pinningEnabled = options.enableColumnPinning !== false;\n // Only \"checkbox\" mode owns a column; \"row\" mode selects from the row itself.\n const selectColumnEnabled =\n selectionEnabled && rowSelectionMode !== \"row\";\n\n const columns = useMemo(() => {\n const base = withTMDataGridDefaults<TData>(\n options.columns as ReadonlyArray<TMDataGridColumnDef<TData>>,\n );\n return selectColumnEnabled ? [createSelectColumn<TData>(), ...base] : base;\n }, [options.columns, selectColumnEnabled]);\n\n // Read once on mount: `initialState` is only consumed on the first render,\n // and re-reading later would fight the user's live edits.\n const [persistedState] = useState(() => readPersistedState(persist));\n\n const table = useTable({\n columnResizeMode: \"onChange\",\n enableSorting: true,\n enableColumnResizing: true,\n globalFilterFn: \"includesString\",\n ...options,\n features: tmDataGridFeatures,\n columns: columns as TableOptions<TMDataGridFeatures, TData>[\"columns\"],\n initialState: {\n ...options.initialState,\n ...persistedState,\n columnPinning: {\n // The checkbox column is structurally pinned, so it is re-applied on\n // top of anything restored from storage.\n left: [\n ...(selectColumnEnabled && pinningEnabled ? [SELECT_COLUMN_ID] : []),\n ...(\n persistedState.columnPinning?.left ??\n options.initialState?.columnPinning?.left ??\n []\n ).filter((id) => id !== SELECT_COLUMN_ID),\n ],\n right:\n persistedState.columnPinning?.right ??\n options.initialState?.columnPinning?.right ??\n [],\n },\n pagination: {\n pageIndex: 0,\n pageSize: 25,\n ...options.initialState?.pagination,\n ...persistedState.pagination,\n },\n },\n });\n\n // Mirror every state change back to storage. Subscribing (rather than writing\n // from an effect on a state snapshot) means nothing is missed, including\n // changes made straight through the table API by the consumer.\n //\n // Writes are debounced because `columnResizeMode: \"onChange\"` publishes a new\n // state on every pointer move of a resize drag, and `setItem` serialises\n // synchronously on the main thread. The trailing edge is enough: storage only\n // has to agree with the table once the user stops.\n useEffect(() => {\n if (!hasPersistenceKeys(persist)) return;\n writePersistedState(table.store.state, persist);\n\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let pending: TableState<TMDataGridFeatures> | null = null;\n\n const flush = () => {\n timeout = undefined;\n if (pending === null) return;\n writePersistedState(pending, persist);\n pending = null;\n };\n\n const subscription = table.store.subscribe((state) => {\n pending = state;\n if (timeout !== undefined) clearTimeout(timeout);\n timeout = setTimeout(flush, PERSIST_DEBOUNCE_MS);\n });\n\n return () => {\n subscription.unsubscribe();\n if (timeout !== undefined) clearTimeout(timeout);\n // An unmount mid-debounce would otherwise drop the last change.\n flush();\n };\n }, [persist, table]);\n\n const ui = useCreateStore<TMDataGridUiState, TMDataGridUiActions>(\n {\n filterPanelOpen: false,\n columnsPanelOpen: false,\n filterPanelColumnId: null,\n draggedColumnId: null,\n },\n ({ setState }) => ({\n openFilterPanel: (columnId = null) =>\n setState((prev) => ({\n ...prev,\n filterPanelOpen: true,\n filterPanelColumnId: columnId,\n })),\n closeFilterPanel: () =>\n setState((prev) => ({\n ...prev,\n filterPanelOpen: false,\n filterPanelColumnId: null,\n })),\n setColumnsPanelOpen: (open) =>\n setState((prev) => ({ ...prev, columnsPanelOpen: open })),\n toggleColumnsPanel: () =>\n setState((prev) => ({ ...prev, columnsPanelOpen: !prev.columnsPanelOpen })),\n startColumnDrag: (columnId) =>\n setState((prev) => ({ ...prev, draggedColumnId: columnId })),\n endColumnDrag: () =>\n setState((prev) => ({ ...prev, draggedColumnId: null })),\n }),\n );\n\n // Deliberately not memoized on `table`: the flags must re-derive whenever the\n // caller passes different options, and `table` keeps the same identity when\n // they do. See readFeatureFlags.\n const features = readFeatureFlags({\n ...options,\n enableColumnOrdering,\n enablePagination,\n rowSelectionMode,\n highlightSelectedRows,\n });\n\n return { table, ui, features };\n}\n\n/**\n * Opens the filter panel for a column, seeding an empty filter row when the\n * column has none yet — mirrors \"Filter\" in the column header menu.\n */\nexport function openColumnFilter<TData extends RowData>(\n api: TMDataGridApi<TData>,\n columnId: string,\n): void {\n const column = api.table.getColumn(columnId);\n if (column && column.getFilterValue() === undefined) {\n column.setFilterValue({\n operator: getDefaultOperator(column.columnDef.meta?.type ?? \"string\"),\n value: \"\",\n });\n }\n api.ui.actions.openFilterPanel(columnId);\n}\n","import { ActionIcon, Menu, Tooltip } from \"@mantine/core\";\nimport { flexRender, type Header } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { shallow } from \"@tanstack/store\";\nimport { type DragEvent, type ReactNode, useRef, useState } from \"react\";\nimport classes from \"./TMDataGridHeaderCell.module.css\";\nimport sticky from \"./sticky.module.css\";\nimport {\n type TMDataGridRowData,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport type { TMDataGridColumnLayout } from \"./TMDataGridTable\";\nimport { getColumnCapabilities, getGridCapabilities } from \"../core/capabilities\";\nimport {\n getColumnRegion,\n getStepTargetColumn,\n moveColumn,\n moveColumnByStep,\n type TMDataGridDropSide,\n} from \"../core/columnOrdering\";\nimport { getColumnAlign, getColumnLabel } from \"../core/columnUtils\";\nimport { isFilterActive } from \"../core/filterOperators\";\nimport {\n ArrowDownIcon,\n ArrowUpIcon,\n ColumnsIcon,\n DotsVerticalIcon,\n EyeOffIcon,\n FilterIcon,\n MoveLeftIcon,\n MoveRightIcon,\n PinLeftIcon,\n PinOffIcon,\n PinRightIcon,\n} from \"./icons\";\nimport { SELECT_COLUMN_ID } from \"./TMDataGridSelectColumn\";\nimport { type TMDataGridFeatures, openColumnFilter } from \"../useTMDataGrid\";\n\nexport type TMDataGridHeader = Header<\n TMDataGridFeatures,\n TMDataGridRowData,\n unknown\n>;\n\nexport function TMDataGridHeaderCell({\n header,\n layout,\n}: {\n header: TMDataGridHeader;\n layout: TMDataGridColumnLayout;\n}) {\n const api = useTMDataGridContext();\n const { table, features } = api;\n const column = header.column;\n const [menuOpened, setMenuOpened] = useState(false);\n const [dropSide, setDropSide] = useState<TMDataGridDropSide | null>(null);\n const cellRef = useRef<HTMLDivElement>(null);\n // A resize drag ends with a click that bubbles to the header — without this\n // every resize would also toggle the column's sort order.\n const suppressSortRef = useRef(false);\n\n // Subscribing to the slices this cell renders from keeps it live even when the\n // surrounding tree is memoized (React Compiler) or the table lives elsewhere.\n // `columnOrder` is in the list because the move menu items are derived from\n // the column's neighbours, which is exactly what an order change invalidates.\n const { sorting, columnFilters, resizingColumnId, columnPinning } =\n useSelector(\n table.store,\n (state) => ({\n sorting: state.sorting,\n columnFilters: state.columnFilters,\n resizingColumnId: state.columnResizing.isResizingColumn,\n columnPinning: state.columnPinning,\n columnOrder: state.columnOrder,\n }),\n { compare: shallow },\n );\n const draggedColumnId = useSelector(api.ui, (state) => state.draggedColumnId);\n\n const isLeaf = header.subHeaders.length === 0;\n const label = getColumnLabel(column);\n const align = getColumnAlign(column);\n const sortDirection = sorting.find((sort) => sort.id === column.id)?.desc;\n const isSorted = sortDirection !== undefined;\n const isFiltered = columnFilters.some(\n (filter) => filter.id === column.id && isFilterActive(filter.value),\n );\n const isResizing = resizingColumnId === column.id;\n const pinnedAt = layout.pinnedAt;\n\n // Every affordance below mirrors a TanStack capability check, so switching a\n // feature off through the table options removes the markup with it.\n const capabilities = getColumnCapabilities(column, features);\n const canSort = isLeaf && capabilities.canSort;\n const canFilter = isLeaf && capabilities.canFilter;\n const canHide = isLeaf && capabilities.canHide;\n const canPin = isLeaf && capabilities.canPin;\n const canResize = capabilities.canResize;\n const canReorder = isLeaf && capabilities.canReorder;\n const canManageColumns =\n isLeaf && getGridCapabilities(table, features).canHideAny;\n\n // A column only moves inside its own pinned lane, so a header in another one\n // never lights up as a target. See TMDataGridColumnRegion.\n const isDragged = draggedColumnId === column.id;\n const isDropTarget =\n canReorder &&\n draggedColumnId !== null &&\n !isDragged &&\n getColumnRegion(columnPinning, draggedColumnId) ===\n getColumnRegion(columnPinning, column.id);\n\n function handleDragStart(event: DragEvent<HTMLDivElement>) {\n event.dataTransfer.effectAllowed = \"move\";\n // Some browsers refuse to start a drag with an empty payload.\n event.dataTransfer.setData(\"text/plain\", column.id);\n api.ui.actions.startColumnDrag(column.id);\n }\n\n function handleDragOver(event: DragEvent<HTMLDivElement>) {\n if (!isDropTarget) return;\n // Only a prevented dragover marks an element as a drop target.\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n const bounds = cellRef.current?.getBoundingClientRect();\n if (!bounds) return;\n setDropSide(\n event.clientX < bounds.left + bounds.width / 2 ? \"before\" : \"after\",\n );\n }\n\n function handleDragLeave(event: DragEvent<HTMLDivElement>) {\n // dragleave also fires when the pointer crosses into a child element.\n const next = event.relatedTarget;\n if (next instanceof Node && event.currentTarget.contains(next)) return;\n setDropSide(null);\n }\n\n function handleDrop(event: DragEvent<HTMLDivElement>) {\n event.preventDefault();\n setDropSide(null);\n api.ui.actions.endColumnDrag();\n if (!isDropTarget || !dropSide || !draggedColumnId) return;\n moveColumn({\n table,\n columnId: draggedColumnId,\n targetId: column.id,\n side: dropSide,\n });\n }\n\n function handleDragEnd() {\n setDropSide(null);\n api.ui.actions.endColumnDrag();\n }\n\n /**\n * Pinned columns are positioned with `getStart()` / `getAfter()`, which sum\n * `column.getSize()`. Fluid (`fr`) columns don't report their rendered width\n * there, so freeze the measured width into `columnSizing` as we pin — that\n * keeps the column looking the same and keeps the offsets exact.\n */\n function setPinned(position: \"left\" | \"right\" | false) {\n if (position && !(column.id in table.store.state.columnSizing)) {\n const width = cellRef.current?.getBoundingClientRect().width;\n if (width) {\n table.setColumnSizing((prev) => ({\n ...prev,\n [column.id]: Math.round(width),\n }));\n }\n }\n column.pin(position);\n }\n\n const menuItems: ReactNode[] = [];\n if (canSort) {\n menuItems.push(\n <Menu.Item\n key=\"sort-asc\"\n leftSection={<ArrowUpIcon size={16} stroke={1.6} />}\n onClick={() => column.toggleSorting(false)}\n >\n Sort by ASC\n </Menu.Item>,\n <Menu.Item\n key=\"sort-desc\"\n leftSection={<ArrowDownIcon size={16} stroke={1.6} />}\n onClick={() => column.toggleSorting(true)}\n >\n Sort by DESC\n </Menu.Item>,\n <Menu.Divider key=\"sort-divider\" />,\n );\n }\n if (canFilter) {\n menuItems.push(\n <Menu.Item\n key=\"filter\"\n leftSection={<FilterIcon size={16} stroke={1.6} />}\n onClick={() => openColumnFilter(api, column.id)}\n >\n Filter\n </Menu.Item>,\n <Menu.Divider key=\"filter-divider\" />,\n );\n }\n if (canPin) {\n menuItems.push(\n <Menu.Item\n key=\"pin-left\"\n className={pinnedAt === \"left\" ? classes.menuItemActive : undefined}\n leftSection={<PinLeftIcon size={16} stroke={1.6} />}\n onClick={() => setPinned(pinnedAt === \"left\" ? false : \"left\")}\n >\n Pin to left\n </Menu.Item>,\n <Menu.Item\n key=\"pin-right\"\n className={pinnedAt === \"right\" ? classes.menuItemActive : undefined}\n leftSection={<PinRightIcon size={16} stroke={1.6} />}\n onClick={() => setPinned(pinnedAt === \"right\" ? false : \"right\")}\n >\n Pin to right\n </Menu.Item>,\n );\n if (pinnedAt) {\n menuItems.push(\n <Menu.Item\n key=\"unpin\"\n leftSection={<PinOffIcon size={16} stroke={1.6} />}\n onClick={() => setPinned(false)}\n >\n Unpin\n </Menu.Item>,\n );\n }\n menuItems.push(<Menu.Divider key=\"pin-divider\" />);\n }\n if (canReorder) {\n // The keyboard path to reordering, and the discoverable one — a header you\n // can drag looks no different from one you cannot.\n const previous = getStepTargetColumn({\n table,\n columnId: column.id,\n direction: -1,\n });\n const next = getStepTargetColumn({\n table,\n columnId: column.id,\n direction: 1,\n });\n if (previous || next) {\n menuItems.push(\n <Menu.Item\n key=\"move-left\"\n disabled={!previous}\n leftSection={<MoveLeftIcon size={16} stroke={1.6} />}\n onClick={() =>\n moveColumnByStep({ table, columnId: column.id, direction: -1 })\n }\n >\n Move left\n </Menu.Item>,\n <Menu.Item\n key=\"move-right\"\n disabled={!next}\n leftSection={<MoveRightIcon size={16} stroke={1.6} />}\n onClick={() =>\n moveColumnByStep({ table, columnId: column.id, direction: 1 })\n }\n >\n Move right\n </Menu.Item>,\n <Menu.Divider key=\"move-divider\" />,\n );\n }\n }\n if (canHide) {\n menuItems.push(\n <Menu.Item\n key=\"hide\"\n leftSection={<EyeOffIcon size={16} stroke={1.6} />}\n onClick={() => column.toggleVisibility(false)}\n >\n Hide column\n </Menu.Item>,\n );\n }\n if (canManageColumns) {\n menuItems.push(\n <Menu.Item\n key=\"manage\"\n leftSection={<ColumnsIcon size={16} stroke={1.6} />}\n onClick={() => api.ui.actions.setColumnsPanelOpen(true)}\n >\n Manage columns\n </Menu.Item>,\n );\n }\n // A trailing divider reads as a dropped item — drop the divider instead.\n while (menuItems.length > 0 && isDivider(menuItems.at(-1))) {\n menuItems.pop();\n }\n\n const cellClass = [\n classes.headerCell,\n canSort ? classes.headerCellSortable : \"\",\n isDragged ? classes.headerCellDragging : \"\",\n dropSide === \"before\" ? classes.headerCellDropBefore : \"\",\n dropSide === \"after\" ? classes.headerCellDropAfter : \"\",\n layout.isBoundary && pinnedAt === \"left\" ? sticky.stickyLeft : \"\",\n layout.isBoundary && pinnedAt === \"right\" ? sticky.stickyRight : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={cellRef}\n role=\"columnheader\"\n data-testid={`dg-header-${column.id}`}\n data-active={isSorted || isFiltered}\n data-align={align}\n // Only meaningful on a sortable column: \"none\" advertises that this\n // header sorts, which is a lie on one that doesn't.\n aria-sort={\n canSort\n ? isSorted\n ? sortDirection\n ? \"descending\"\n : \"ascending\"\n : \"none\"\n : undefined\n }\n className={cellClass}\n // Dropped while a resize is running, so that dragging the separator\n // resizes the column instead of starting to move it. The resize handler\n // records the column on mousedown, before the first pointer move.\n draggable={canReorder && !isResizing}\n onDragStart={canReorder ? handleDragStart : undefined}\n onDragEnd={canReorder ? handleDragEnd : undefined}\n onDragOver={isDropTarget ? handleDragOver : undefined}\n onDragLeave={isDropTarget ? handleDragLeave : undefined}\n onDrop={isDropTarget ? handleDrop : undefined}\n style={{\n left: pinnedAt === \"left\" ? layout.offset : undefined,\n right: pinnedAt === \"right\" ? layout.offset : undefined,\n position: pinnedAt ? \"sticky\" : undefined,\n zIndex: pinnedAt ? 4 : undefined,\n }}\n onClick={\n canSort\n ? (event) => {\n if (suppressSortRef.current) {\n suppressSortRef.current = false;\n return;\n }\n column.getToggleSortingHandler()?.(event);\n }\n : undefined\n }\n >\n {header.isPlaceholder ? null : (\n <Tooltip label={label} openDelay={600} withinPortal disabled={!isLeaf}>\n <span className={classes.headerTitle}>\n {flexRender(column.columnDef.header, header.getContext())}\n </span>\n </Tooltip>\n )}\n\n {isLeaf && (\n <div className={classes.headerActions}>\n {isFiltered && (\n <ActionIcon\n className={classes.headerAction}\n data-pinned-visible=\"true\"\n variant=\"subtle\"\n color=\"gray\"\n size=\"xs\"\n aria-label={`Filter on ${label}`}\n onClick={(event) => {\n event.stopPropagation();\n openColumnFilter(api, column.id);\n }}\n >\n <FilterIcon size={14} stroke={1.6} />\n </ActionIcon>\n )}\n\n {canSort && (\n <ActionIcon\n className={classes.headerAction}\n data-pinned-visible={isSorted}\n variant=\"subtle\"\n color=\"gray\"\n size=\"xs\"\n aria-label={`Sort ${label}`}\n onClick={column.getToggleSortingHandler()}\n >\n {sortDirection ? (\n <ArrowDownIcon size={14} stroke={1.6} />\n ) : (\n <ArrowUpIcon size={14} stroke={1.6} />\n )}\n </ActionIcon>\n )}\n\n {menuItems.length > 0 && column.id !== SELECT_COLUMN_ID && (\n <Menu\n opened={menuOpened}\n onChange={setMenuOpened}\n position=\"bottom-start\"\n shadow=\"md\"\n width={220}\n withinPortal\n >\n <Menu.Target>\n <ActionIcon\n className={classes.headerAction}\n data-pinned-visible={menuOpened}\n variant=\"subtle\"\n color=\"gray\"\n size=\"xs\"\n aria-label={`${label} column menu`}\n onClick={(event) => {\n event.stopPropagation();\n setMenuOpened((opened) => !opened);\n }}\n >\n <DotsVerticalIcon size={14} stroke={1.6} />\n </ActionIcon>\n </Menu.Target>\n <Menu.Dropdown onClick={(event) => event.stopPropagation()}>\n {menuItems}\n </Menu.Dropdown>\n </Menu>\n )}\n </div>\n )}\n\n <div\n className={[\n classes.columnSeparator,\n canResize ? classes.columnSeparatorResizable : \"\",\n isResizing ? classes.columnSeparatorActive : \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n // Keeps a drag that starts on the separator from being picked up by the\n // draggable header around it.\n draggable={false}\n onMouseDown={\n canResize\n ? (event) => {\n suppressSortRef.current = true;\n header.getResizeHandler()(event);\n }\n : undefined\n }\n onTouchStart={canResize ? header.getResizeHandler() : undefined}\n onClick={(event) => event.stopPropagation()}\n />\n </div>\n );\n}\n\nfunction isDivider(node: ReactNode): boolean {\n return (\n typeof node === \"object\" &&\n node !== null &&\n \"type\" in node &&\n node.type === Menu.Divider\n );\n}\n","import { Loader, Text } from \"@mantine/core\";\nimport {\n type Cell,\n flexRender,\n type Row,\n type RowData,\n} from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport sticky from \"./sticky.module.css\";\nimport { type TMDataGridRowData, useTMDataGridContext } from \"../TMDataGridContext\";\nimport { TMDataGridFilterPanel } from \"./TMDataGridFilterPanel\";\nimport { TMDataGridHeaderCell } from \"./TMDataGridHeaderCell\";\nimport { getColumnAlign } from \"../core/columnUtils\";\nimport { SearchIcon } from \"./icons\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\n/** Where a column sits relative to the pinned regions, resolved once per render. */\nexport type TMDataGridColumnLayout = {\n pinnedAt: \"left\" | \"right\" | false;\n /** Distance in px from the grid's left or right edge. */\n offset: number;\n /** Last left-pinned / first right-pinned column — the one that casts the edge. */\n isBoundary: boolean;\n};\n\nconst UNPINNED_LAYOUT: TMDataGridColumnLayout = {\n pinnedAt: false,\n offset: 0,\n isBoundary: false,\n};\n\nfunction TMDataGridBodyCell({\n cell,\n rowHeight,\n layout,\n}: {\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n rowHeight: number;\n layout: TMDataGridColumnLayout;\n}) {\n return (\n <div\n role=\"cell\"\n data-align={getColumnAlign(cell.column)}\n className={[\n classes.bodyCell,\n layout.isBoundary && layout.pinnedAt === \"left\" ? sticky.stickyLeft : \"\",\n layout.isBoundary && layout.pinnedAt === \"right\"\n ? sticky.stickyRight\n : \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{\n minHeight: rowHeight,\n left: layout.pinnedAt === \"left\" ? layout.offset : undefined,\n right: layout.pinnedAt === \"right\" ? layout.offset : undefined,\n position: layout.pinnedAt ? \"sticky\" : undefined,\n zIndex: layout.pinnedAt ? 2 : undefined,\n }}\n >\n <span className={classes.cellContent}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </span>\n </div>\n );\n}\n\nexport type TMDataGridTableProps<TData extends RowData> = {\n /**\n * Called when a body row is clicked. Runs in addition to row selection under\n * `rowSelectionMode: \"row\"`, not instead of it.\n */\n onRowClick?: (row: Row<TMDataGridFeatures, TData>) => void;\n};\n\n/**\n * The scrollable grid surface. Always virtualized: only the rows inside the\n * viewport (plus overscan) are mounted — which is what makes the default\n * no-pagination mode viable at any row count. Pagination is opt-in via\n * `enablePagination` (or implied by `manualPagination`).\n */\nexport function TMDataGridTable<TData extends RowData = TMDataGridRowData>({\n onRowClick,\n}: TMDataGridTableProps<TData>) {\n const { table, features, rowHeight, controlSize } = useTMDataGridContext();\n\n // The body depends on every state slice (sorting, filters, paging, sizing,\n // visibility, selection), so it subscribes to the whole table store.\n useSelector(table.store);\n\n const { loading, noResultsLabel = \"No rows match your filters\" } =\n table.options.meta ?? {};\n\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n // Pagination off (the default): every filtered+sorted row, virtualized.\n // Pagination on: the current page; under `manualPagination` TanStack returns\n // the rows as delivered, so the same branch serves server paging.\n const rows = features.pagination\n ? table.getPaginatedRowModel().rows\n : table.getPrePaginatedRowModel().rows;\n\n // A persisted pageIndex can outlive the data that produced it; TanStack only\n // auto-resets on live filter/sort/data changes, not on restored state. The\n // guard makes the dependency-free effect idempotent.\n useEffect(() => {\n if (!features.pagination) return;\n const pageCount = table.getPageCount();\n if (pageCount > 0 && table.store.state.pagination.pageIndex >= pageCount) {\n table.setPageIndex(pageCount - 1);\n }\n });\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollContainerRef.current,\n estimateSize: useCallback(() => rowHeight, [rowHeight]),\n getItemKey: useCallback((index: number) => rows[index]?.id ?? index, [rows]),\n overscan: 6,\n initialRect: { height: 600, width: 1200 },\n });\n\n const virtualItems = virtualizer.getVirtualItems();\n const paddingTop = virtualItems[0]?.start ?? 0;\n const paddingBottom =\n virtualizer.getTotalSize() - (virtualItems.at(-1)?.end ?? 0);\n\n const leftLeafColumns = table.getLeftLeafColumns();\n const rightLeafColumns = table.getRightLeafColumns();\n const centerLeafColumns = table.getCenterLeafColumns();\n\n const orderedColumns = [\n ...leftLeafColumns,\n ...centerLeafColumns,\n ...rightLeafColumns,\n ];\n\n // Headers and cells must follow the same left → center → right order as the\n // column tracks, otherwise pinning a column would shuffle it out of its lane.\n const centerHeaderGroups = table.getCenterHeaderGroups();\n const leftHeaderGroups = table.getLeftHeaderGroups();\n const rightHeaderGroups = table.getRightHeaderGroups();\n const headerGroups = centerHeaderGroups.map((group, index) => ({\n id: group.id,\n headers: [\n ...(leftHeaderGroups[index]?.headers ?? []),\n ...group.headers,\n ...(rightHeaderGroups[index]?.headers ?? []),\n ],\n }));\n // Unresized columns stay fluid (`minmax(min, flex fr)`) so the grid fills the\n // viewport; dragging a resize handle pins that column to an exact pixel width.\n // minWidth is the sum of those floors — anything wider and the grid would\n // force a horizontal scrollbar it doesn't need.\n //\n // Pinned columns are always exact: their sticky offsets come from\n // `getStart()` / `getAfter()`, which sum `getSize()` and cannot see an `fr`.\n const columnSizing = table.store.state.columnSizing;\n const columnTracks = orderedColumns.map((column) => {\n const isFixed = column.columnDef.minSize === column.columnDef.maxSize;\n const isResized = column.id in columnSizing;\n const isPinned = column.getIsPinned() !== false;\n const minWidth = column.columnDef.minSize ?? 80;\n if (isFixed || isResized || isPinned) {\n return { track: `${column.getSize()}px`, minWidth: column.getSize() };\n }\n return {\n track: `minmax(${minWidth}px, ${column.columnDef.meta?.flex ?? 1}fr)`,\n minWidth,\n };\n });\n const gridTemplateColumns = columnTracks.map((c) => c.track).join(\" \");\n const gridMinWidth = columnTracks.reduce((sum, c) => sum + c.minWidth, 0);\n\n /**\n * Sticky offsets are derived here, from state this component subscribes to,\n * and handed down as props.\n *\n * Deriving them inside the cell via `column.getIsPinned()` /\n * `column.getStart()` looks equivalent but isn't: those are plain calls on a\n * `column` object whose identity survives a pin, so the React Compiler caches\n * the result and the cell keeps rendering with stale pinning. Building the\n * offsets from the same widths as the grid tracks also guarantees the two\n * agree to the pixel.\n */\n const columnLayout = new Map<string, TMDataGridColumnLayout>();\n const widthOf = (columnId: string) =>\n columnTracks[orderedColumns.findIndex((c) => c.id === columnId)]?.minWidth ??\n 0;\n\n let leftOffset = 0;\n for (const column of leftLeafColumns) {\n columnLayout.set(column.id, {\n pinnedAt: \"left\",\n offset: leftOffset,\n isBoundary: column.id === leftLeafColumns.at(-1)?.id,\n });\n leftOffset += widthOf(column.id);\n }\n let rightOffset = 0;\n for (const column of [...rightLeafColumns].reverse()) {\n columnLayout.set(column.id, {\n pinnedAt: \"right\",\n offset: rightOffset,\n isBoundary: column.id === rightLeafColumns[0]?.id,\n });\n rightOffset += widthOf(column.id);\n }\n for (const column of centerLeafColumns) {\n columnLayout.set(column.id, {\n pinnedAt: false,\n offset: 0,\n isBoundary: false,\n });\n }\n const layoutFor = (columnId: string) =>\n columnLayout.get(columnId) ?? UNPINNED_LAYOUT;\n\n const isEmpty = rows.length === 0;\n\n // \"row\" mode: the row itself is the selection control — clicking it toggles\n // that row and leaves the rest of the selection alone.\n const selectsOnRowClick =\n features.rowSelection && features.rowSelectionMode === \"row\";\n const rowIsInteractive = selectsOnRowClick || onRowClick !== undefined;\n\n const handleRowActivate = (row: Row<TMDataGridFeatures, TMDataGridRowData>) => {\n if (selectsOnRowClick && row.getCanSelect()) row.toggleSelected();\n onRowClick?.(row as unknown as Row<TMDataGridFeatures, TData>);\n };\n\n return (\n <div className={classes.tableWrapper}>\n <div ref={scrollContainerRef} className={classes.scrollContainer}>\n <div\n role=\"table\"\n className={classes.grid}\n // Virtualization means most rows are not in the DOM, so the counts\n // have to be stated rather than inferred from what is rendered. Every\n // row carries its aria-rowindex for the same reason.\n aria-rowcount={rows.length + headerGroups.length}\n aria-colcount={orderedColumns.length}\n style={{ gridTemplateColumns, minWidth: gridMinWidth }}\n >\n <div role=\"rowgroup\" style={{ display: \"contents\" }}>\n {headerGroups.map((headerGroup, groupIndex) => (\n <div\n key={headerGroup.id}\n role=\"row\"\n aria-rowindex={groupIndex + 1}\n className={classes.headerRow}\n >\n {headerGroup.headers.map((header) => (\n <TMDataGridHeaderCell\n key={header.id}\n header={header}\n layout={layoutFor(header.column.id)}\n />\n ))}\n </div>\n ))}\n </div>\n\n {paddingTop > 0 && (\n <div aria-hidden style={{ gridColumn: \"1/-1\", height: paddingTop }} />\n )}\n\n <div role=\"rowgroup\" style={{ display: \"contents\" }}>\n {virtualItems.map((virtualItem) => {\n const row = rows[virtualItem.index];\n if (!row) return null;\n return (\n <div\n key={virtualItem.key}\n role=\"row\"\n aria-rowindex={virtualItem.index + headerGroups.length + 1}\n data-testid={`dg-row-${row.id}`}\n data-selected={row.getIsSelected()}\n // Selection is state; the highlight is a display choice, so\n // the two are separate attributes.\n data-highlighted={\n features.highlightSelectedRows && row.getIsSelected()\n }\n data-selects-on-click={selectsOnRowClick}\n aria-selected={\n features.rowSelection ? row.getIsSelected() : undefined\n }\n className={classes.bodyRow}\n style={{\n minHeight: rowHeight,\n cursor: rowIsInteractive ? \"pointer\" : undefined,\n }}\n // Keyboard parity with the checkbox the row replaces.\n tabIndex={selectsOnRowClick ? 0 : undefined}\n onClick={\n rowIsInteractive ? () => handleRowActivate(row) : undefined\n }\n onKeyDown={\n selectsOnRowClick\n ? (event) => {\n if (event.key !== \" \" && event.key !== \"Enter\") return;\n if (event.target !== event.currentTarget) return;\n event.preventDefault();\n handleRowActivate(row);\n }\n : undefined\n }\n >\n {[\n ...row.getLeftVisibleCells(),\n ...row.getCenterVisibleCells(),\n ...row.getRightVisibleCells(),\n ].map((cell) => (\n <TMDataGridBodyCell\n key={cell.id}\n cell={cell}\n rowHeight={rowHeight}\n layout={layoutFor(cell.column.id)}\n />\n ))}\n </div>\n );\n })}\n </div>\n\n {isEmpty && loading === true && (\n <div role=\"row\" className={classes.messageRow}>\n <Loader size=\"lg\" />\n </div>\n )}\n\n {isEmpty && loading !== true && (\n <div role=\"row\" className={classes.messageRow}>\n <SearchIcon size={40} stroke={1.4} opacity={0.4} />\n <Text size={controlSize} c=\"dimmed\">\n {noResultsLabel}\n </Text>\n </div>\n )}\n\n {paddingBottom > 0 && (\n <div\n aria-hidden\n style={{ gridColumn: \"1/-1\", height: paddingBottom }}\n />\n )}\n </div>\n </div>\n\n <TMDataGridFilterPanel />\n </div>\n );\n}\n",".toolbar {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n padding: 6px var(--mantine-spacing-xs);\n min-height: 42px;\n flex-shrink: 0;\n}\n\n.toolbarSpacer {\n flex: 1;\n}\n","import { ActionIcon, Popover, Text, Tooltip } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ReactNode } from \"react\";\nimport classes from \"./TMDataGridToolbar.module.css\";\nimport { TMDataGridColumnsPanel } from \"./TMDataGridColumnsPanel\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getGridCapabilities } from \"../core/capabilities\";\nimport { isFilterActive } from \"../core/filterOperators\";\nimport { BurgerIcon, FilterIcon } from \"./icons\";\nimport { openColumnFilter } from \"../useTMDataGrid\";\n\n/** Row above the grid. Compose it from the pieces below, or anything else. */\nexport function TMDataGridToolbar({ children }: { children?: ReactNode }) {\n return <div className={classes.toolbar}>{children}</div>;\n}\n\n/** Pushes the following toolbar items to the right. */\nexport function TMDataGridToolbarSpacer() {\n return <div className={classes.toolbarSpacer} />;\n}\n\n/**\n * Visible rows over total rows. On a server-driven grid, set\n * `meta.totalRowCount` for the denominator — the client never sees every row.\n */\nexport function TMDataGridSummaryCount({ children }: { children?: ReactNode }) {\n const { table, controlSize } = useTMDataGridContext();\n useSelector(table.store);\n\n if (children !== undefined) {\n return (\n <Text size={controlSize} c=\"dimmed\">\n {children}\n </Text>\n );\n }\n\n const shown = table.getRowCount();\n const total =\n table.options.meta?.totalRowCount ??\n table.getPreFilteredRowModel().rows.length;\n\n return (\n <Text size={controlSize} c=\"dimmed\">\n {shown} / {total}\n </Text>\n );\n}\n\n/**\n * Burger menu in the grid's top-right corner — opens \"Manage columns\".\n * Renders nothing when no column can be hidden (`enableHiding: false`).\n */\nexport function TMDataGridColumnsButton() {\n const { table, ui, features, controlSize } = useTMDataGridContext();\n const opened = useSelector(ui, (state) => state.columnsPanelOpen);\n\n if (!getGridCapabilities(table, features).canHideAny) return null;\n\n return (\n <Popover\n opened={opened}\n onChange={ui.actions.setColumnsPanelOpen}\n position=\"bottom-end\"\n shadow=\"md\"\n radius=\"md\"\n withinPortal\n trapFocus\n >\n <Popover.Target>\n <Tooltip label=\"Manage columns\" openDelay={400}>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size={controlSize}\n aria-label=\"Manage columns\"\n onClick={ui.actions.toggleColumnsPanel}\n >\n <BurgerIcon size={18} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Popover.Target>\n <Popover.Dropdown p={0}>\n <TMDataGridColumnsPanel />\n </Popover.Dropdown>\n </Popover>\n );\n}\n\n/**\n * Toggles the filter panel, seeding a filter row on the first filterable column.\n * Renders nothing when no column can be filtered (`enableColumnFilters: false`).\n */\nexport function TMDataGridFilterButton() {\n const api = useTMDataGridContext();\n const { table, ui, features, controlSize } = api;\n const opened = useSelector(ui, (state) => state.filterPanelOpen);\n const columnFilters = useSelector(\n table.store,\n (state) => state.columnFilters,\n );\n const activeCount = columnFilters.filter((filter) =>\n isFilterActive(filter.value),\n ).length;\n\n if (!getGridCapabilities(table, features).canFilterAny) return null;\n\n return (\n <Tooltip label=\"Filters\" openDelay={400}>\n <ActionIcon\n variant={opened || activeCount > 0 ? \"light\" : \"subtle\"}\n color={activeCount > 0 ? undefined : \"gray\"}\n size={controlSize}\n aria-label=\"Filters\"\n onClick={() => {\n if (opened) {\n ui.actions.closeFilterPanel();\n return;\n }\n const firstFilterable = table\n .getAllLeafColumns()\n .find((column) => column.getCanFilter());\n if (firstFilterable) openColumnFilter(api, firstFilterable.id);\n else ui.actions.openFilterPanel();\n }}\n >\n <FilterIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n );\n}\n","import type { MantineSize } from \"@mantine/core\";\n\nexport type TMDataGridSize = MantineSize;\n\nexport const DEFAULT_TMDATAGRID_SIZE: TMDataGridSize = \"md\";\n\n/**\n * Row height per size, in px.\n *\n * The virtualizer needs this as a number — it cannot read the CSS variable —\n * so the scale lives here and `TMDataGrid.module.css` mirrors it. `meta.rowHeight`\n * overrides it when a grid needs a height the scale doesn't offer.\n */\nexport const SIZE_ROW_HEIGHT: Record<TMDataGridSize, number> = {\n xs: 34,\n sm: 42,\n md: 52,\n lg: 62,\n xl: 72,\n};\n\n/** Size of the Mantine controls rendered inside the grid chrome. */\nexport const SIZE_CONTROL_SIZE: Record<TMDataGridSize, MantineSize> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"sm\",\n lg: \"sm\",\n xl: \"md\",\n};\n","import type { RowData } from \"@tanstack/react-table\";\nimport { type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport classes from \"./TMDataGrid.module.css\";\nimport { TMDataGridColumnsPanel } from \"./TMDataGridColumnsPanel\";\nimport { TMDataGridContextProvider } from \"../TMDataGridContext\";\nimport { TMDataGridFilterPanel } from \"./TMDataGridFilterPanel\";\nimport { TMDataGridFooter } from \"./TMDataGridFooter\";\nimport { TMDataGridTable } from \"./TMDataGridTable\";\nimport {\n TMDataGridColumnsButton,\n TMDataGridFilterButton,\n TMDataGridSummaryCount,\n TMDataGridToolbar,\n TMDataGridToolbarSpacer,\n} from \"./TMDataGridToolbar\";\nimport {\n DEFAULT_TMDATAGRID_SIZE,\n SIZE_CONTROL_SIZE,\n SIZE_ROW_HEIGHT,\n type TMDataGridSize,\n} from \"../core/sizes\";\nimport type { TMDataGridApi } from \"../useTMDataGrid\";\n\nexport type TMDataGridProps<TData extends RowData> = TMDataGridApi<TData> & {\n children: ReactNode;\n /**\n * Mantine size scale. Drives row height, font size, cell padding and the\n * size of the controls in the chrome. `meta.rowHeight` still wins if set.\n */\n size?: TMDataGridSize;\n className?: string;\n /**\n * Inline styles. Widened to accept CSS variables, which is how the grid's\n * colours are themed — `--dg-row-selected-bg` for the selected row\n * background. Plain `CSSProperties` rejects `--*` keys.\n */\n style?: CSSProperties & Record<`--${string}`, string | number>;\n};\n\n/**\n * Root of the grid. Takes the object returned by `useTMDataGrid` — spread it —\n * and publishes it to the compound components below it:\n *\n * ```tsx\n * const grid = useTMDataGrid({ data, columns });\n *\n * <TMDataGrid {...grid}>\n * <TMDataGrid.Toolbar>\n * <TMDataGrid.SummaryCount />\n * <TMDataGrid.Spacer />\n * <TMDataGrid.ColumnsButton />\n * </TMDataGrid.Toolbar>\n * <TMDataGrid.Table />\n * <TMDataGrid.Footer />\n * </TMDataGrid>\n * ```\n */\nfunction TMDataGridRoot<TData extends RowData>({\n table,\n ui,\n features,\n size = DEFAULT_TMDATAGRID_SIZE,\n children,\n className,\n style,\n}: TMDataGridProps<TData>) {\n const rowHeight = table.options.meta?.rowHeight ?? SIZE_ROW_HEIGHT[size];\n\n const api = useMemo(\n () => ({\n table,\n ui,\n features,\n size,\n rowHeight,\n controlSize: SIZE_CONTROL_SIZE[size],\n }),\n [table, ui, features, size, rowHeight],\n );\n\n return (\n <TMDataGridContextProvider value={api}>\n <div\n data-size={size}\n className={[classes.root, className].filter(Boolean).join(\" \")}\n style={style}\n >\n {children}\n </div>\n </TMDataGridContextProvider>\n );\n}\n\nexport const TMDataGrid = Object.assign(TMDataGridRoot, {\n Toolbar: TMDataGridToolbar,\n Spacer: TMDataGridToolbarSpacer,\n SummaryCount: TMDataGridSummaryCount,\n ColumnsButton: TMDataGridColumnsButton,\n FilterButton: TMDataGridFilterButton,\n Table: TMDataGridTable,\n Footer: TMDataGridFooter,\n /** Rendered by `TMDataGrid.Table`; exported for custom layouts. */\n FilterPanel: TMDataGridFilterPanel,\n /** Rendered by `TMDataGrid.ColumnsButton`; exported for custom layouts. */\n ColumnsPanel: TMDataGridColumnsPanel,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["createContext","useContext","TMDataGridSize","TMDataGridApi","TMDataGridRowData","Record","TMDataGridContextValue","size","rowHeight","controlSize","TMDataGridContext","TMDataGridContextProvider","Provider","useTMDataGridContext","api","Error","useCellControlTabIndex","features","cellSelection","ExpandedState","Row","RowData","TMDataGridFeatures","TMDataGridExpandTarget","isTarget","row","TData","target","getIsGrouped","toExpandedMap","rows","ReadonlyArray","expanded","Record","all","id","TMDataGridExpandAllArgs","areAllRowsExpanded","found","resolveExpandAll","expand","next","UnstyledButton","useCellControlTabIndex","useTMDataGridContext","ColumnDef","Row","RowData","useSelector","classes","ChevronRightIcon","areAllRowsExpanded","resolveExpandAll","TMDataGridFeatures","TMDataGridTable","DETAILS_COLUMN_ID","DetailsCell","t0","$","_c","row","labels","t1","getIsExpanded","expanded","table","store","tabIndex","getIsGrouped","t2","hideDetails","showDetails","t3","event","stopPropagation","toggleExpanded","t4","Symbol","for","t5","chevron","t6","detailsToggle","DetailsHeader","getPrePaginatedRowModel","flatRows","detailRows","state","rows","target","allExpanded","collapseAllDetails","expandAllDetails","setExpanded","expand","t7","createDetailsColumn","label","TData","id","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","header","cell","Row","RowData","TMDataGridFeatures","getGroupDataRows","row","TData","Array","subRows","length","getLeafRows","filter","leaf","Row","RowData","RowSelectionState","TMDataGridFeatureFlags","getGroupDataRows","TMDataGridFeatures","TMDataGridTable","getDisplayedRows","table","TData","features","Array","isPagingActive","getPaginatedRowModel","rows","getPrePaginatedRowModel","pagination","store","state","grouping","length","TMDataGridRowClickModifiers","toggle","extend","ResolveRowSelectionClickArgs","ReadonlyArray","rowId","anchorRowId","modifiers","selection","canReplaceSelection","ResolvedRowSelection","getSelectableRowIds","row","filter","dataRow","getCanSelect","map","id","resolveRowSelectionClick","index","findIndex","clickedRow","undefined","targets","getCanMultiSelect","only","untick","anchorIndex","from","Math","min","to","max","next","slice","allSelected","every","Checkbox","useSelector","ColumnDef","Row","RowData","useCellControlTabIndex","useTMDataGridContext","getDisplayedRows","getSelectableRowIds","resolveRowSelectionClick","TMDataGridFeatures","TMDataGridTable","SELECT_COLUMN_ID","SelectAllCheckbox","t0","$","_c","table","labels","t1","getIsAllRowsSelected","allSelected","store","t2","getIsSomeRowsSelected","someSelected","t3","selectAllRows","t4","t5","getToggleAllRowsSelectedHandler","t6","SelectAllHeader","features","multiRowSelection","SelectRowCheckbox","row","ui","tabIndex","isGroupRow","subRows","length","getIsAllSubRowsSelected","getIsSelected","selected","getIsSomeSelected","selectableIds","getCanMultiSelect","selectGroup","selectRow","t7","id","actions","state","selectionAnchorRowId","event","native","nativeEvent","isMouse","MouseEvent","resolved","rows","rowId","anchorRowId","modifiers","toggle","ctrlKey","metaKey","extend","shiftKey","selection","rowSelection","canReplaceSelection","setRowSelection","setSelectionAnchor","t8","_temp","event_0","stopPropagation","createSelectColumn","label","TData","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enablePinning","header","cell","aggregatedCell","TMDataGridColumnType","DETAILS_COLUMN_ID","SELECT_COLUMN_ID","TMDataGridColumnMeta","ColumnLike","id","columnDef","header","meta","parent","getColumnLabel","column","label","getColumnType","type","getColumnAlign","align","isControlColumn","columnId","isColumnReorderable","enableOrdering","undefined","UnstyledButton","useCellControlTabIndex","useTMDataGridContext","ColumnDef","Row","RowData","useSelector","shallow","classes","ChevronRightIcon","getColumnLabel","getGroupDataRows","TMDataGridFeatures","TMDataGridTable","GROUP_COLUMN_ID","INDENT_STEP","BLANK_GROUP_LABEL","formatGroupValue","value","blankLabel","undefined","Date","toLocaleDateString","String","GroupCell","t0","$","_c","row","labels","t1","getIsExpanded","expanded","table","store","tabIndex","getIsGrouped","T0","label","t2","t3","t4","t5","t6","depth","groupingValue","blankGroupValue","groupToggle","t7","paddingInlineStart","collapseGroup","expandGroup","event","stopPropagation","toggleExpanded","t8","Symbol","for","t9","chevron","t10","groupLabel","t11","t12","length","groupCount","t13","GroupHeader","compare","grouping","_temp","groupColumnLabel","columnId","column","getColumn","map","join","state","createGroupColumn","TData","id","meta","enableOrdering","size","minSize","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","cell","aggregatedCell","header","Button","Checkbox","ScrollArea","Text","TextInput","useSelector","useState","classes","useTMDataGridContext","getColumnLabel","GROUP_COLUMN_ID","SearchIcon","TMDataGridColumnsPanel","$","_c","table","labels","controlSize","search","setSearch","columnVisibility","store","_temp","T0","hideableColumns","shownCount","t0","t1","t2","t3","t4","t5","visibleInPanel","columnsSearchPlaceholder","columns","getAllLeafColumns","filter","_temp2","needle","trim","toLowerCase","column_0","column","includes","_temp3","t6","column_2","id","length","columnsPanel","t7","Symbol","for","event","currentTarget","value","t8","columnsPanelSearch","Autosize","columnsPanelList","t9","column_3","getCanHide","event_0","toggleVisibility","checked","map","columnsNoMatch","t10","t11","event_1","toggleAllColumnsVisible","t12","columnsShowHideAll","t13","resetColumnVisibility","t14","columnsReset","t15","columnsPanelFooter","t16","column_1","state","Column","Row","TMDataGridRowData","TMDataGridFeatures","TMDataGridTable","TMDataGridOption","value","label","color","disabled","group","TMDataGridOptionsArgs","table","column","row","fallback","TMDataGridOptionsSource","ReadonlyArray","args","addFacetValue","target","Set","undefined","add","String","resolveColumnOptions","Array","source","columnDef","meta","options","values","key","getFacetedUniqueValues","keys","isArray","entry","sort","a","b","localeCompare","numeric","map","list","option","ComboboxItem","ComboboxData","items","optionsToComboboxData","ungrouped","groups","Map","item","push","bucket","get","set","Row","RowData","TableFeatures","TMDataGridFilterValue","operator","TMDataGridFilterOperator","value","ReadonlyArray","TMDataGridColumnType","FILTER_OPERATOR_LABELS","Record","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","before","after","onOrBefore","onOrAfter","isAnyOf","isNoneOf","isEmpty","isNotEmpty","STRING_OPERATORS","NUMBER_OPERATORS","DATE_OPERATORS","BOOLEAN_OPERATORS","SELECT_OPERATORS","VALUELESS_OPERATORS","ARRAY_OPERATORS","OPERATORS_BY_TYPE","string","number","boolean","date","select","multiSelect","DEFAULT_OPERATOR_BY_TYPE","getOperatorsForType","type","getDefaultOperator","operatorNeedsValue","includes","operatorTakesArrayValue","isTMDataGridFilterValue","isFilterActive","Array","isArray","length","trim","formatFilterLabel","label","filter","operatorLabels","text","join","String","toIsoDay","Date","Number","isNaN","getTime","toLocaleDateString","match","exec","isEmptyCell","cellValue","undefined","matchesFilter","set","map","entry","toLowerCase","cellEntries","hit","some","filterText","cellDay","filterDay","numericCell","NaN","numericFilter","compareNumeric","cellText","needle","tmDataGridFilterFn","row","TFeatures","TData","columnId","filterValue","getValue","ActionIcon","Button","MultiSelect","Select","Stack","Text","TextInput","useSelector","useEffect","useRef","classes","useTMDataGridContext","optionsToComboboxData","resolveColumnOptions","getColumnLabel","getColumnType","TMDataGridFilterOperator","TMDataGridFilterValue","getDefaultOperator","getOperatorsForType","isTMDataGridFilterValue","operatorNeedsValue","operatorTakesArrayValue","CloseIcon","FALLBACK_FILTER","operator","value","asFilterValue","TMDataGridFilterPanel","$","_c","table","ui","labels","controlSize","opened","_temp","columnFilters","store","_temp2","panelRef","t0","t1","handlePointerDown","event","target","Element","current","contains","closest","actions","closeFilterPanel","document","addEventListener","removeEventListener","addFilter","changeFilterColumn","changeOperator","clearAllFilters","columnOptions","patchFilter","removeFilter","t2","filterableColumns","getAllLeafColumns","filter","_temp3","map","_temp4","columnId","remaining","id","setColumnFilters","length","fromColumnId","toColumnId","find","filter_0","target_0","getColumn","Array","isArray","filter_1","filter_2","openFilterPanel","t3","columnId_0","patch","filter_3","t4","columnId_1","operator_0","current_0","filter_4","value_0","t5","nextColumn","column_1","some","filter_5","column","t6","column_2","filter_6","canAddFilter","filters","event_0","key","stopPropagation","Symbol","for","t7","closeFilters","t8","filterPanelHeader","t9","booleanFalse","booleanTrue","filterColumn","filterOperator","filterValue","filterValuePlaceholder","operators","t10","filter_7","column_3","value_1","type","needsValue","takesArray","scalarValue","filterRow","withinPortal","next","operator_1","label","next_0","fallback","next_1","next_2","event_1","currentTarget","t11","t12","t13","t14","filterPanelFooter","t15","t16","filterPanel","column_0","getCanFilter","state_0","state","filterPanelOpen","FILTER_OPERATOR_LABELS","TMDataGridFilterOperator","TMDataGridLabels","operators","Record","manageColumns","filters","searchPlaceholder","searchLabel","clearSearch","columnsSearchPlaceholder","columnsNoMatch","search","columnsShowHideAll","columnsReset","filterColumn","filterOperator","filterValue","filterValuePlaceholder","booleanTrue","booleanFalse","addFilter","clearAllFilters","closeFilters","removeFilter","activeFilters","clearFilter","column","sortAsc","sortDesc","filterMenuItem","groupBy","ungroup","expandAllGroups","collapseAllGroups","pinLeft","pinRight","unpin","moveLeft","moveRight","autosizeColumn","hideColumn","filterOn","sortColumn","columnMenu","rowsPerPage","pageRange","args","from","to","total","groupedAllRows","pagingSuspendedHint","previousPage","nextPage","noResults","loading","cellCount","count","copy","exportCsv","includeHeaders","selectColumnLabel","selectAllRows","selectRow","selectGroup","detailsColumnLabel","showDetails","hideDetails","expandAllDetails","collapseAllDetails","groupColumnLabel","blankGroupValue","expandGroup","label","collapseGroup","TMDataGridLabelsOverride","Partial","Omit","TMDATAGRID_LABELS_EN","mergeLabels","override","TableState","TMDataGridFeatures","GridState","DATA_STATE_SLICES","const","ReadonlyArray","SETTINGS_STATE_SLICES","TMDataGridDataSlice","TMDataGridSettingsSlice","TMDataGridPersistKey","key","slices","TSlice","TMDataGridStorageMode","TMDataGridPersistence","dataKey","settingsKey","storageMode","serialize","value","Partial","deserialize","ResolvedKey","resolveKey","entry","defaultSlices","resolveStorage","persistence","Storage","window","sessionStorage","localStorage","prop","Record","undefined","isString","isFiniteNumber","Number","isFinite","isArrayOf","isItem","item","Array","isArray","every","isRecordOf","Object","values","hasStringId","SLICE_GUARDS","columnFilters","globalFilter","sorting","pagination","pageIndex","pageSize","expanded","columnVisibility","columnSizing","columnOrder","columnPinning","grouping","isValidSlice","slice","guard","readSlices","storage","resolved","raw","getItem","parsed","record","restored","writeSlices","state","payload","setItem","resolveKeys","data","settings","hasPersistenceKeys","defaultDeserialize","JSON","parse","defaultSerialize","stringify","readPersistedState","writePersistedState","Column","RowData","TMDataGridRowData","isColumnReorderable","TMDataGridFeatures","TMDataGridTable","UseTMDataGridOptions","TMDataGridSelectionMode","TMDataGridCellSelectionMode","TMDataGridFeatureFlags","sorting","filtering","globalFiltering","hiding","pinning","resizing","ordering","rowSelection","selectionMode","selectColumn","rowClickSelects","multiRowSelection","showSelectedBackground","highlightRow","cellSelection","cellSelectionMode","cellRangeSelection","pagination","grouping","readFeatureFlags","options","Pick","TData","enableRowSelection","enableSorting","enableColumnFilters","enableGlobalFilter","enableHiding","enableColumnPinning","enableColumnResizing","enableColumnOrdering","enableMultiRowSelection","enablePagination","manualPagination","enableGrouping","TMDataGridColumnCapabilities","canSort","canFilter","canHide","canPin","canResize","canReorder","canGroup","getColumnCapabilities","column","features","getCanSort","getCanFilter","getCanHide","getCanPin","getCanResize","getCanGroup","TMDataGridCapabilities","canSortAny","canFilterAny","canHideAny","canPinAny","canReorderAny","canGroupAny","canSelectRows","canPaginate","canSearch","getGridCapabilities","table","columns","getAllLeafColumns","any","predicate","capabilities","some","c","getCanGlobalFilter","TMDataGridCellPosition","rowId","columnId","TMDataGridCellCoords","rowIndex","columnIndex","ResolveCellMoveArgs","key","ctrlKey","from","rowCount","columnCount","pageRows","clamp","value","max","Math","min","resolveCellMove","lastRow","lastColumn","at","isSameCell","a","b","useCreateStore","aggregationFns","ColumnDef","columnFacetingFeature","columnFilteringFeature","columnGroupingFeature","columnOrderingFeature","columnPinningFeature","columnResizingFeature","columnSizingFeature","columnVisibilityFeature","createColumnHelper","createExpandedRowModel","createFacetedMinMaxValues","createFacetedRowModel","createFacetedUniqueValues","createFilteredRowModel","createGroupedRowModel","createPaginatedRowModel","createSortedRowModel","filterFns","globalFilteringFeature","metaHelper","Row","RowData","rowExpandingFeature","rowPaginationFeature","rowSelectionFeature","rowSortingFeature","sortFns","Table","tableFeatures","TableOptions","TableState","useTable","Store","ReactNode","useEffect","useMemo","useRef","useState","TMDataGridOptionsSource","TMDataGridColumnType","tmDataGridFilterFn","getDefaultOperator","mergeLabels","TMDataGridLabels","TMDataGridLabelsOverride","hasPersistenceKeys","readPersistedState","TMDataGridPersistence","writePersistedState","readFeatureFlags","TMDataGridCellSelectionMode","TMDataGridFeatureFlags","TMDataGridSelectionMode","isSameCell","TMDataGridCellPosition","TMDataGridCellRange","createSelectColumn","SELECT_COLUMN_ID","createGroupColumn","GROUP_COLUMN_ID","createDetailsColumn","DETAILS_COLUMN_ID","PERSIST_DEBOUNCE_MS","TMDataGridColumnMeta","label","type","options","flex","align","autoSize","enableOrdering","TMDataGridTableMeta","loading","noResultsLabel","rowHeight","totalRowCount","tmDataGridFeatures","filteredRowModel","groupedRowModel","sortedRowModel","expandedRowModel","paginatedRowModel","facetedRowModel","facetedMinMaxValues","facetedUniqueValues","tmDataGrid","tableMeta","columnMeta","TMDataGridFeatures","TMDataGridTable","TData","createTMDataGridColumnHelper","TMDataGridDetailsArgs","row","table","TMDataGridDetailsRenderer","args","DEFAULT_DETAILS_EST_HEIGHT","DEFAULT_OVERSCAN","TMDataGridUiState","filterPanelOpen","columnsPanelOpen","filterPanelColumnId","draggedColumnId","highlightedRowId","selectionAnchorRowId","focusedCell","cellRange","TMDataGridUiActions","openFilterPanel","columnId","closeFilterPanel","setColumnsPanelOpen","open","toggleColumnsPanel","startColumnDrag","endColumnDrag","setHighlightedRow","rowId","setSelectionAnchor","setFocusedCell","cell","setCellRange","range","TMDataGridUiStore","TMDataGridApi","ui","features","labels","renderDetails","renderDetailsEstHeight","overscan","UseTMDataGridOptions","Omit","persist","enableColumnOrdering","enablePagination","selectionMode","showSelectedBackground","defaultHighlightedRowId","onHighlightedRowChange","cellSelection","onFocusedCellChange","TMDataGridColumnDef","withTMDataGridDefaults","columns","ReadonlyArray","Array","map","column","isArray","filterFn","aggregationFn","undefined","aggregatedCell","useTMDataGrid","labelsOverride","pinningEnabled","enableColumnPinning","selectColumnEnabled","selectColumn","groupColumnEnabled","grouping","detailsColumnEnabled","selectColumnLabel","groupColumnLabel","detailsColumnLabel","base","persistedState","initialGrouping","initialState","columnResizeMode","enableSorting","enableColumnResizing","globalFilterFn","groupedColumnMode","getRowCanExpand","columnVisibility","length","columnPinning","left","filter","id","right","pagination","pageIndex","pageSize","previousGrouping","store","state","subscription","subscribe","setColumnVisibility","old","setColumnOrder","unsubscribe","timeout","ReturnType","setTimeout","pending","flush","clearTimeout","setState","prev","anchor","focus","onHighlightedRowChangeRef","current","previous","onFocusedCellChangeRef","openColumnFilter","api","getColumn","getFilterValue","setFilterValue","operator","columnDef","meta","value","actions","Button","Pill","UnstyledButton","RowData","useSelector","classes","getColumnLabel","getColumnType","formatFilterLabel","isFilterActive","isTMDataGridFilterValue","TMDataGridSize","openColumnFilter","TMDataGridApi","TMDataGridFilterPillsProps","api","TData","size","showClearAll","onPillClick","columnId","className","TMDataGridFilterPills","t0","$","_c","t1","t2","undefined","table","labels","columnFilters","store","_temp","T0","activeFilters","t3","t4","t5","t6","t7","t8","Symbol","for","bb0","filter","_temp2","length","t9","filterPills","Boolean","join","Group","t10","filter_0","column","getColumn","id","label","value","pill","setColumnFilters","other","clearFilter","tabIndex","pillLabel","type","operatorLabels","operators","map","clearAllFilters","t11","state","ActionIcon","Group","Select","Text","Tooltip","RowData","useSelector","ReactNode","classes","useTMDataGridContext","getGridCapabilities","isPagingActive","ChevronLeftIcon","ChevronRightIcon","TMDataGridTable","TMDataGridPaginationApi","pageIndex","pageSize","pageCount","rowCount","canPreviousPage","canNextPage","setPageIndex","setPageSize","previousPage","nextPage","firstPage","lastPage","getTMDataGridPaginationApi","table","TData","store","state","pagination","getPageCount","getRowCount","getCanPreviousPage","getCanNextPage","index","size","TMDataGridFooterProps","pageSizeOptions","ReadonlyArray","api","TMDataGridFooter","t0","$","_c","t1","undefined","features","labels","controlSize","canPaginate","t2","t3","footer","paging","total","from","to","Math","min","sizeOptions","includes","sort","_temp","T0","pagingSuspendedHint","t4","t5","t6","t7","t9","t10","rowsPerPage","t11","t12","map","String","t13","t14","value","Number","t15","t16","T1","t17","t18","pageRange","groupedAllRows","getFilteredRowModel","rows","length","t19","t20","t21","t22","Symbol","for","t23","t24","t25","t26","t27","t28","t29","t8","t30","a","b","ActionIcon","TextInput","useSelector","useEffect","useRef","useState","useTMDataGridContext","getGridCapabilities","CloseIcon","SearchIcon","TMDataGridSearchProps","placeholder","debounce","w","TMDataGridSearch","t0","$","_c","t1","t2","undefined","table","features","labels","controlSize","globalFilter","store","_temp","draft","setDraft","timeoutRef","lastWrittenRef","t3","t4","current","t5","t6","Symbol","for","clearTimeout","canSearch","t7","value","setGlobalFilter","commit","t8","value_0","setTimeout","handleChange","t9","event","currentTarget","t10","searchPlaceholder","t11","t12","clearSearch","t13","searchLabel","state","RowData","TMDataGridRowData","TMDataGridTable","HEADER_ACTIONS_ALLOWANCE","CONTENT_ALLOWANCE","contentSpanWidth","content","HTMLElement","range","document","createRange","selectNodeContents","width","getBoundingClientRect","scrollWidth","measureColumnContentWidth","container","columnId","widest","cells","querySelectorAll","CSS","escape","cell","firstElementChild","styles","getComputedStyle","padding","Number","parseFloat","paddingLeft","paddingRight","Math","max","title","querySelector","header","closest","autosizeColumn","table","TData","erased","column","getColumn","getCanResize","measured","minSize","columnDef","maxSize","POSITIVE_INFINITY","round","min","setColumnSizing","previous","Column","ColumnPinningState","TMDataGridRowData","isColumnReorderable","TMDataGridFeatures","TMDataGridTable","GridColumn","GridTable","TMDataGridColumnRegion","TMDataGridDropSide","getColumnRegion","columnPinning","columnId","left","includes","right","moveInList","ids","ReadonlyArray","movedId","targetId","side","Array","remaining","filter","id","targetIndex","indexOf","splice","MoveColumnArgs","table","moveColumn","store","state","region","leafIds","getAllLeafColumns","map","column","setColumnOrder","setColumnPinning","previous","getRegionColumns","getLeftVisibleLeafColumns","getRightVisibleLeafColumns","getCenterVisibleLeafColumns","ColumnStepArgs","direction","getStepTargetColumn","columns","index","findIndex","target","moveColumnByStep","ActionIcon","Menu","Tooltip","flexRender","Header","useSelector","shallow","DragEvent","ReactNode","useRef","useState","classes","sticky","TMDataGridRowData","useTMDataGridContext","TMDataGridColumnLayout","getColumnCapabilities","getGridCapabilities","autosizeColumn","getColumnRegion","getStepTargetColumn","moveColumn","moveColumnByStep","TMDataGridDropSide","getColumnAlign","getColumnLabel","isControlColumn","resolveExpandAll","isFilterActive","ArrowDownIcon","ArrowUpIcon","AutosizeIcon","CollapseAllIcon","ColumnsIcon","DotsVerticalIcon","ExpandAllIcon","EyeOffIcon","FilterIcon","GroupIcon","MoveLeftIcon","MoveRightIcon","PinLeftIcon","PinOffIcon","PinRightIcon","UngroupIcon","GROUP_COLUMN_ID","TMDataGridFeatures","openColumnFilter","TMDataGridHeader","TMDataGridHeaderCell","t0","$","_c","header","layout","api","table","features","labels","column","menuOpened","setMenuOpened","contextMenuOpened","setContextMenuOpened","dropSide","setDropSide","cellRef","suppressSortRef","t1","Symbol","for","compare","sorting","columnFilters","resizingColumnId","columnPinning","grouping","store","_temp","draggedColumnId","ui","_temp2","isLeaf","subHeaders","length","align","autosize","canReorder","canResize","canSort","handleDragEnd","handleDragLeave","handleDragOver","handleDragStart","handleDrop","isDragged","isDropTarget","isFiltered","isResizing","isSorted","label","menuItems","pinnedAt","sortDirection","sortIndex","t2","t3","id","find","sort","desc","undefined","t4","findIndex","sort_0","t5","t6","filter","value","some","capabilities","canFilter","canHide","canPin","canGroup","canManageColumns","canHideAny","t7","includes","isGrouped","isGroupingActive","t8","t9","event","dataTransfer","effectAllowed","setData","actions","startColumnDrag","t10","event_0","preventDefault","dropEffect","bounds","current","getBoundingClientRect","clientX","left","width","t11","event_1","next","relatedTarget","Node","currentTarget","contains","t12","event_2","endColumnDrag","columnId","targetId","side","t13","t14","container","closest","t15","setPinned","position","state","columnSizing","setColumnSizing","prev","Math","round","pin","t16","t17","toggleSorting","t18","sortAsc","t19","t20","t21","sortDesc","t22","push","filterMenuItem","menuItemActive","getToggleGroupingHandler","ungroup","groupBy","groupedId","groupedColumn","getColumn","toggleGrouping","expand","setExpanded","rows","getPrePaginatedRowModel","flatRows","expanded","target","expandAllGroups","collapseAllGroups","pinLeft","t23","pinRight","t24","t25","t26","unpin","direction","previous","next_0","moveLeft","moveRight","toggleVisibility","hideColumn","setColumnsPanelOpen","manageColumns","isDivider","at","pop","hasMenu","headerCellSortable","headerCellDragging","headerCellDropBefore","headerCellDropAfter","isBoundary","stickyLeft","stickyRight","headerCell","Boolean","cellClass","join","offset","right","zIndex","_temp3","event_4","getToggleSortingHandler","t27","columnDef","isPlaceholder","headerTitle","getContext","t28","headerActions","headerAction","filterOn","event_5","stopPropagation","sortColumn","columnMenu","event_6","_temp4","_temp5","t29","columnSeparator","columnSeparatorResizable","columnSeparatorActive","event_8","getResizeHandler","_temp6","event_10","t30","cell","t31","opened_0","opened","t32","t33","_temp7","t34","event_11","event_9","event_7","event_3","shiftKey","state_0","columnResizing","isResizingColumn","columnOrder","node","type","Divider","TMDataGridCellPosition","TMDataGridCellRange","anchor","focus","TMDataGridRangeBounds","top","bottom","left","right","ResolveRangeBoundsArgs","range","rowIndexOf","rowId","columnIndexOf","columnId","resolveRangeBounds","anchorRow","focusRow","anchorColumn","focusColumn","Math","min","max","isWithinBounds","bounds","rowIndex","columnIndex","boundsCellCount","boundsEdges","Column","Row","RowData","TMDataGridRowData","TMDataGridFeatures","TMDataGridTable","TMDataGridRangeBounds","getColumnLabel","isControlColumn","UTF8_BOM","String","fromCharCode","TMDataGridCellMatrix","Array","TMDataGridCellExportOptions","separator","decimalComma","includeHeaders","fileName","ResolvedExportOptions","Required","DEFAULT_CELL_EXPORT_OPTIONS","formatExportValue","value","undefined","Number","isFinite","text","replace","isArray","map","entry","join","Date","isNaN","getTime","toLocaleString","JSON","stringify","BuildCellMatrixArgs","rows","ReadonlyArray","columns","bounds","buildCellMatrix","selectedColumns","slice","left","right","filter","column","id","length","matrix","push","index","top","bottom","row","getValue","buildGridCellMatrix","table","TData","erased","getLeftVisibleLeafColumns","getCenterVisibleLeafColumns","getRightVisibleLeafColumns","walk","list","getIsGrouped","subRows","getSortedRowModel","exportGridToCsv","options","resolved","downloadTextFile","toExcelCsv","escapeField","needsQuotes","includes","replaceAll","toClipboardText","body","writeClipboardText","Promise","navigator","clipboard","writeText","mimeType","url","URL","createObjectURL","Blob","type","anchor","document","createElement","href","download","style","display","append","click","remove","setTimeout","revokeObjectURL","Checkbox","Loader","Menu","MenuProps","Text","Cell","flexRender","Row","RowData","Table","useSelector","useVirtualizer","KeyboardEvent","MouseEvent","ReactNode","useCallback","useEffect","useRef","useState","classes","sticky","TMDataGridRowData","useTMDataGridContext","TMDataGridFilterPanel","TMDataGridHeaderCell","getColumnAlign","isControlColumn","resolveCellMove","TMDataGridCellPosition","boundsCellCount","boundsEdges","isWithinBounds","resolveRangeBounds","buildCellMatrix","DEFAULT_CELL_EXPORT_OPTIONS","downloadTextFile","toClipboardText","toExcelCsv","writeClipboardText","TMDataGridCellExportOptions","autosizeColumn","getDisplayedRows","getSelectableRowIds","resolveRowSelectionClick","SearchIcon","TMDataGridFeatures","TMDataGridColumnLayout","pinnedAt","offset","isBoundary","UNPINNED_LAYOUT","FOCUSABLE_IN_CELL","join","findCellElement","container","HTMLElement","cell","querySelector","CSS","escape","rowId","columnId","keepColumnInView","cellElement","leftPinnedWidth","rightPinnedWidth","cellRect","getBoundingClientRect","containerRect","leftBound","left","rightBound","right","scrollLeft","renderCellContent","getIsPlaceholder","getIsAggregated","column","columnDef","getContext","aggregatedCell","aggregationFn","undefined","TMDataGridCellNav","columnIndex","focused","tabIndex","selected","edges","top","bottom","TMDataGridBodyCell","t0","$","_c","rowHeight","layout","nav","onFocus","onMouseDown","onMouseEnter","onContextMenu","t1","t2","t3","t4","t5","t6","id","t7","t8","t9","t10","t11","t12","t13","t14","t15","t16","stickyLeft","t17","stickyRight","t18","bodyCell","filter","Boolean","t19","t20","t21","t22","t23","t24","minHeight","position","zIndex","t25","t26","cellContent","t27","TMDataGridBodyRowGroup","enabled","menuContent","menuProps","onClose","children","Symbol","for","display","rowGroup","opened","TMDataGridRowContextMenuArgs","table","TData","row","close","TMDataGridRowContextMenu","args","TMDataGridTableProps","onRowClick","rowContextMenu","rowContextMenuProps","Omit","cellExport","onReachEnd","reachEndThreshold","TMDataGridTable","ui","features","labels","controlSize","renderDetails","renderDetailsEstHeight","overscan","store","highlightedRowId","state","focusedCell","cellRange","loading","noResultsLabel","noResults","options","meta","scrollContainerRef","HTMLDivElement","rows","showsDetails","getIsGrouped","getIsExpanded","autoSizedRef","current","orderedColumns","autoSize","columnSizing","pagination","pageCount","getPageCount","pageIndex","setPageIndex","virtualizer","count","length","getScrollElement","estimateSize","index","measureElement","element","_entry","instance","height","indexFromElement","getItemKey","initialRect","width","virtualItems","getVirtualItems","paddingTop","start","paddingBottom","getTotalSize","at","end","reachEndFiredForCountRef","warnedReachEndPaginationRef","lastMountedIndex","console","warn","leftLeafColumns","getLeftVisibleLeafColumns","rightLeafColumns","getRightVisibleLeafColumns","centerLeafColumns","getCenterVisibleLeafColumns","centerHeaderGroups","getCenterHeaderGroups","leftHeaderGroups","getLeftHeaderGroups","rightHeaderGroups","getRightHeaderGroups","headerGroups","map","group","headers","columnTracks","isFixed","minSize","maxSize","isResized","isPinned","getIsPinned","minWidth","track","getSize","flex","gridTemplateColumns","c","gridMinWidth","reduce","sum","columnLayout","Map","widthOf","findIndex","leftOffset","set","rightOffset","reverse","layoutFor","get","isEmpty","leafHeaders","hasSummaryRow","some","footer","selectsOnRowClick","rowClickSelects","rowIsInteractive","highlightRow","rowGesturesFor","handleRowActivate","modifiers","toggle","extend","getCanSelect","resolved","anchorRowId","selectionAnchorRowId","selection","rowSelection","canReplaceSelection","setRowSelection","actions","setSelectionAnchor","setHighlightedRow","cellSelection","cellRangeSelection","wantsCellFocusRef","appliedCellRef","focusedRowIndex","focusedColumnIndex","focusedCellIsMounted","item","firstMountedRow","tabStopCell","isCellAt","rangeBounds","range","rowIndexOf","columnIndexOf","setRangeTo","anchor","setCellRange","focus","selectionBounds","selectedCellCount","selectedDataColumnCount","slice","exportOptions","exportIncludesHeaders","setExportIncludesHeaders","includeHeaders","buildSelectionMatrix","columns","bounds","decimalComma","copySelection","matrix","isDraggingRange","setIsDraggingRange","stop","window","addEventListener","removeEventListener","startRangeDrag","setFocusedCell","exportSelectionCsv","fileName","text","separator","moveFocusedCell","coords","rowIndex","selectRowFromCell","handleGridKeyDown","event","target","dataset","key","closest","preventDefault","ctrlKey","metaKey","interactive","shiftKey","next","from","rowCount","columnCount","pageRows","Math","max","floor","clientHeight","scrollToIndex","align","contains","document","activeElement","preventScroll","contextMenuTarget","setContextMenuTarget","closeContextMenu","contextMenuRowRef","contextMenuColumnRef","handleContextMenu","contextMenuRow","find","rowMenuContent","getAllCells","cellMenuContent","cellCount","copy","exportCsv","previous","input","cursor","contextMenuContent","handleScroll","tableWrapper","scrollContainer","multiRowSelection","grid","headerGroup","groupIndex","headerRow","header","gridColumn","virtualItem","isGroupRow","isInteractive","takesKeyboard","depth","getIsSelected","showSelectedBackground","bodyRow","currentTarget","getLeftVisibleCells","getCenterVisibleCells","getRightVisibleCells","cellIndex","button","detailsCell","stopPropagation","messageRow","summaryRow","summaryCell","isPlaceholder","ActionIcon","Loader","Popover","Text","Tooltip","useSelector","ReactNode","classes","TMDataGridColumnsPanel","useTMDataGridContext","getGridCapabilities","isFilterActive","BurgerIcon","FilterIcon","openColumnFilter","TMDataGridToolbar","t0","$","_c","children","t1","toolbar","TMDataGridToolbarSpacer","Symbol","for","toolbarSpacer","TMDataGridLoadingIndicator","table","labels","options","meta","loading","TMDataGridSummaryCount","controlSize","store","undefined","getRowCount","shown","t2","totalRowCount","getPreFilteredRowModel","rows","length","total","t3","TMDataGridColumnsButton","ui","features","opened","_temp","canHideAny","manageColumns","actions","toggleColumnsPanel","t4","setColumnsPanelOpen","state","columnsPanelOpen","TMDataGridFilterButton","api","_temp2","columnFilters","_temp3","activeCount","filter","_temp4","canFilterAny","closeFilterPanel","firstFilterable","getAllLeafColumns","find","_temp5","id","openFilterPanel","filters","t5","column","getCanFilter","value","state_0","filterPanelOpen","MantineSize","TMDataGridSize","DEFAULT_TMDATAGRID_SIZE","SIZE_ROW_HEIGHT","Record","xs","sm","md","lg","xl","SIZE_CONTROL_SIZE","RowData","CSSProperties","ReactNode","useMemo","classes","TMDataGridColumnsPanel","TMDataGridContextProvider","TMDataGridFilterPanel","TMDataGridFilterPills","TMDataGridFooter","TMDataGridSearch","TMDataGridTable","TMDataGridColumnsButton","TMDataGridFilterButton","TMDataGridLoadingIndicator","TMDataGridSummaryCount","TMDataGridToolbar","TMDataGridToolbarSpacer","DEFAULT_TMDATAGRID_SIZE","SIZE_CONTROL_SIZE","SIZE_ROW_HEIGHT","TMDataGridSize","TMDataGridApi","TMDataGridProps","TData","children","size","className","style","Record","TMDataGridRoot","t0","$","_c","table","ui","features","labels","renderDetails","renderDetailsEstHeight","overscan","t1","undefined","rowHeight","options","meta","t2","t3","controlSize","api","t4","root","filter","Boolean","t5","join","t6","t7","TMDataGrid","Object","assign","Toolbar","Spacer","SummaryCount","LoadingIndicator","Search","ColumnsButton","FilterButton","Table","Footer","FilterPanel","FilterPills","ColumnsPanel","TMDataGridLabels","TMDATAGRID_LABELS_SV","operators","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","before","after","onOrBefore","onOrAfter","isAnyOf","isNoneOf","isEmpty","isNotEmpty","manageColumns","filters","searchPlaceholder","searchLabel","clearSearch","columnsSearchPlaceholder","columnsNoMatch","search","columnsShowHideAll","columnsReset","filterColumn","filterOperator","filterValue","filterValuePlaceholder","booleanTrue","booleanFalse","addFilter","clearAllFilters","closeFilters","removeFilter","activeFilters","clearFilter","column","sortAsc","sortDesc","filterMenuItem","groupBy","ungroup","expandAllGroups","collapseAllGroups","pinLeft","pinRight","unpin","moveLeft","moveRight","autosizeColumn","hideColumn","filterOn","sortColumn","columnMenu","rowsPerPage","pageRange","from","to","total","groupedAllRows","pagingSuspendedHint","previousPage","nextPage","noResults","loading","cellCount","count","copy","exportCsv","includeHeaders","selectColumnLabel","selectAllRows","selectRow","selectGroup","detailsColumnLabel","showDetails","hideDetails","expandAllDetails","collapseAllDetails","groupColumnLabel","blankGroupValue","expandGroup","label","collapseGroup","aggregationFns","RowData","TMDataGridRowData","TMDataGridTable","TMDataGridAggregationName","aggregateColumn","table","columnId","fn","TData","erased","rows","getFilteredRowModel"],"sources":["../src/tmdatagrid/components/TMDataGrid.module.css","../src/tmdatagrid/components/TMDataGridColumnsPanel.module.css","../src/tmdatagrid/TMDataGridContext.ts","../src/tmdatagrid/components/TMDataGridDetailsColumn.module.css","../src/tmdatagrid/core/expanding.ts","../src/tmdatagrid/components/TMDataGridDetailsColumn.tsx","../src/tmdatagrid/core/grouping.ts","../src/tmdatagrid/core/rowSelection.ts","../src/tmdatagrid/components/TMDataGridSelectColumn.tsx","../src/tmdatagrid/core/columnUtils.ts","../src/tmdatagrid/components/TMDataGridGroupColumn.module.css","../src/tmdatagrid/components/TMDataGridGroupColumn.tsx","../src/tmdatagrid/components/TMDataGridColumnsPanel.tsx","../src/tmdatagrid/components/TMDataGridFilterPanel.module.css","../src/tmdatagrid/core/columnOptions.ts","../src/tmdatagrid/core/filterOperators.ts","../src/tmdatagrid/components/TMDataGridFilterPanel.tsx","../src/tmdatagrid/components/TMDataGridFilterPills.module.css","../src/tmdatagrid/core/labels.ts","../src/tmdatagrid/core/persistence.ts","../src/tmdatagrid/core/capabilities.ts","../src/tmdatagrid/core/cellNavigation.ts","../src/tmdatagrid/useTMDataGrid.tsx","../src/tmdatagrid/components/TMDataGridFilterPills.tsx","../src/tmdatagrid/components/TMDataGridFooter.module.css","../src/tmdatagrid/components/TMDataGridFooter.tsx","../src/tmdatagrid/components/TMDataGridSearch.tsx","../src/tmdatagrid/components/TMDataGridTable.module.css","../src/tmdatagrid/components/sticky.module.css","../src/tmdatagrid/components/TMDataGridHeaderCell.module.css","../src/tmdatagrid/core/autosize.ts","../src/tmdatagrid/core/columnOrdering.ts","../src/tmdatagrid/components/TMDataGridHeaderCell.tsx","../src/tmdatagrid/core/cellRange.ts","../src/tmdatagrid/core/cellExport.ts","../src/tmdatagrid/components/TMDataGridTable.tsx","../src/tmdatagrid/components/TMDataGridToolbar.module.css","../src/tmdatagrid/components/TMDataGridToolbar.tsx","../src/tmdatagrid/core/sizes.ts","../src/tmdatagrid/components/TMDataGrid.tsx","../src/tmdatagrid/core/labelsSv.ts","../src/tmdatagrid/core/summary.ts"],"sourcesContent":["/* The grid root: the size scale every other module reads, and the frame.\n Each component owns its own module; these variables cascade into all of\n them, and the pinned-column boundary shared by header and body cells lives\n in sticky.module.css. */\n\n/* Size scale. Row heights mirror SIZE_ROW_HEIGHT in core/sizes.ts — the\n virtualizer needs the number in JS, so the two have to agree. */\n.root[data-size=\"xs\"] {\n --dg-row-height: 34px;\n --dg-header-height: 32px;\n --dg-font-size: var(--mantine-font-size-xs);\n --dg-padding: 6px;\n}\n\n.root[data-size=\"sm\"] {\n --dg-row-height: 42px;\n --dg-header-height: 38px;\n --dg-font-size: var(--mantine-font-size-sm);\n --dg-padding: 8px;\n}\n\n.root[data-size=\"md\"] {\n --dg-row-height: 52px;\n --dg-header-height: 44px;\n --dg-font-size: var(--mantine-font-size-sm);\n --dg-padding: 10px;\n}\n\n.root[data-size=\"lg\"] {\n --dg-row-height: 62px;\n --dg-header-height: 52px;\n --dg-font-size: var(--mantine-font-size-md);\n --dg-padding: 14px;\n}\n\n.root[data-size=\"xl\"] {\n --dg-row-height: 72px;\n --dg-header-height: 60px;\n --dg-font-size: var(--mantine-font-size-lg);\n --dg-padding: 18px;\n}\n\n.root {\n /* Fallbacks, so the parts still work if rendered outside a sized root. */\n --dg-row-height: 52px;\n --dg-header-height: 44px;\n --dg-font-size: var(--mantine-font-size-sm);\n --dg-padding: 10px;\n /* Background of a selected row, when `showSelectedBackground` is on. Override\n it on the grid:\n <TMDataGrid style={{ \"--dg-row-selected-bg\": \"var(--mantine-color-blue-0)\" }} /> */\n --dg-row-selected-bg: var(--mantine-primary-color-light);\n /* Background of the highlighted row, under a selectionMode that has one.\n Stronger than the selected background by default, since under\n \"checkboxAndHighlight\" the two show up together. */\n --dg-row-highlight-bg: var(--mantine-primary-color-light-hover);\n /* Background of a group row. Transparent by default — the bold label and the\n chevron are enough, and with the tree collapsed every row on screen is a\n group row, so a tint would grey out the whole grid. Set it to give groups a\n band of their own. */\n --dg-row-group-bg: var(--mantine-color-body);\n\n /* The stacking ladder, stated once. Body cells sit at auto (0); everything\n sticky stacks over them in this order, and a sticky row crossing a sticky\n column takes the row's slot plus one. */\n --dg-z-pinned-cell: 2;\n --dg-z-focused-cell: 3;\n --dg-z-summary-row: 4;\n --dg-z-summary-pinned-cell: 5;\n --dg-z-header: 6;\n --dg-z-header-pinned-cell: 7;\n\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n /* Header text is a stretched flex item, so an inherited `text-align: center`\n from the host page would centre headers away from their cell content. */\n text-align: left;\n border: 1px solid var(--mantine-color-default-border);\n border-radius: var(--mantine-radius-md);\n background-color: var(--mantine-color-body);\n}\n",".columnsPanel {\n width: 280px;\n display: flex;\n flex-direction: column;\n}\n\n.columnsPanelSearch {\n padding: var(--mantine-spacing-sm);\n}\n\n.columnsPanelList {\n display: flex;\n flex-direction: column;\n gap: var(--mantine-spacing-sm);\n padding: 0 var(--mantine-spacing-sm) var(--mantine-spacing-sm);\n}\n\n.columnsPanelFooter {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mantine-spacing-sm);\n padding: var(--mantine-spacing-sm);\n border-top: 1px solid var(--mantine-color-default-border);\n}\n","import { createContext, useContext } from \"react\";\nimport type { TMDataGridSize } from \"./core/sizes\";\nimport type { TMDataGridApi } from \"./useTMDataGrid\";\n\n/**\n * Row shape the chrome components work against. They only ever touch columns,\n * rows and cells generically, so the concrete row type is erased at the context\n * boundary — the same trick Mantine uses for its compound components.\n */\nexport type TMDataGridRowData = Record<string, unknown>;\n\nexport type TMDataGridContextValue = TMDataGridApi<TMDataGridRowData> & {\n size: TMDataGridSize;\n /** Row height in px, already resolved from `size` and `meta.rowHeight`. */\n rowHeight: number;\n /** Mantine control size that pairs with `size`. */\n controlSize: TMDataGridSize;\n};\n\nconst TMDataGridContext = createContext<unknown>(null);\n\nexport const TMDataGridContextProvider = TMDataGridContext.Provider;\n\nexport function useTMDataGridContext(): TMDataGridContextValue {\n const api = useContext(TMDataGridContext);\n if (!api) {\n throw new Error(\n \"TMDataGrid compound components must be rendered inside <TMDataGrid>\",\n );\n }\n return api as TMDataGridContextValue;\n}\n\n/**\n * What a control inside a *body* cell should put in its `tabIndex`.\n *\n * `-1` once cell selection is on, and this is what makes the promise of one tab\n * stop true. Without it the browser walks Tab into the checkbox of every\n * mounted row — a grid showing twenty rows would be twenty tab stops, and\n * scrolling would change how many. Enter or F2 steps into the cell instead,\n * which reaches a `-1` control perfectly well.\n *\n * Header controls are not covered: the header row is not part of cell\n * navigation, so its sort buttons and menus stay in the tab order, where they\n * are the only way to reach them.\n *\n * A custom cell renderer with a control in it wants the same:\n *\n * ```tsx\n * cell: ({ row }) => (\n * <Button tabIndex={useCellControlTabIndex()} onClick={...}>Open</Button>\n * )\n * ```\n */\nexport function useCellControlTabIndex(): 0 | -1 {\n const { features } = useTMDataGridContext();\n return features.cellSelection ? -1 : 0;\n}\n","/* The details lane is a fixed track holding one control, so the button fills it\n and the whole cell is the hit target. */\n.detailsToggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n color: inherit;\n}\n\n.detailsToggle:hover .chevron {\n color: var(--mantine-color-text);\n}\n\n.chevron {\n display: flex;\n align-items: center;\n color: var(--mantine-color-dimmed);\n transition: transform 120ms ease;\n}\n\n.chevron[data-expanded=\"true\"] {\n transform: rotate(90deg);\n}\n\n/* One icon rotated rather than two swapped: the turn is what reads as the\n expand, and a swap would jump. */\n@media (prefers-reduced-motion: reduce) {\n .chevron {\n transition: none;\n }\n}\n","import type { ExpandedState, Row, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\n/**\n * Which rows an expand-all control is about.\n *\n * TanStack keeps one `expanded` state, and the grid opens two unrelated things\n * out of it: a group row opens into its children, a data row opens into its\n * detail panel. So `toggleAllRowsExpanded` — which writes the state's\n * whole-table form — is the wrong verb for either control. \"Expand all groups\"\n * in the tree menu would open every panel in the grid, and the details lane's\n * chevron would unfold the whole tree.\n *\n * These helpers narrow both to the rows their control is for, and leave the\n * other kind exactly as it was.\n */\nexport type TMDataGridExpandTarget = \"groups\" | \"details\";\n\nfunction isTarget<TData extends RowData>(\n row: Row<TMDataGridFeatures, TData>,\n target: TMDataGridExpandTarget,\n): boolean {\n return target === \"groups\" ? row.getIsGrouped() : !row.getIsGrouped();\n}\n\n/**\n * The state as a map. `true` is the whole-table form, which has to be written\n * out before one kind of row can be taken back out of it — the same thing\n * TanStack does before toggling a single row.\n */\nfunction toExpandedMap<TData extends RowData>(\n rows: ReadonlyArray<Row<TMDataGridFeatures, TData>>,\n expanded: ExpandedState,\n): Record<string, boolean> {\n if (expanded !== true) return { ...expanded };\n const all: Record<string, boolean> = {};\n for (const row of rows) all[row.id] = true;\n return all;\n}\n\nexport type TMDataGridExpandAllArgs<TData extends RowData> = {\n /**\n * Every row in the model, groups and records alike — `flatRows` off any of\n * them. A grouped model lists its leaves both under their group and in the\n * flat list, so this may repeat rows; both helpers are written so that a\n * repeat costs nothing.\n */\n rows: ReadonlyArray<Row<TMDataGridFeatures, TData>>;\n expanded: ExpandedState;\n target: TMDataGridExpandTarget;\n};\n\n/**\n * Whether every row of this kind is open — what the control shows, and what a\n * bare toggle inverts.\n *\n * `false` when there are none of them, matching TanStack's own\n * `getIsAllRowsExpanded()` on an empty state: an empty set is nothing to\n * collapse.\n */\nexport function areAllRowsExpanded<TData extends RowData>({\n rows,\n expanded,\n target,\n}: TMDataGridExpandAllArgs<TData>): boolean {\n let found = false;\n for (const row of rows) {\n if (!isTarget(row, target)) continue;\n found = true;\n if (expanded === true) continue;\n if (expanded[row.id] !== true) return false;\n }\n return found;\n}\n\n/**\n * The next `expanded` state after an expand-all or collapse-all on one kind of\n * row. Rows of the other kind keep whatever they had.\n */\nexport function resolveExpandAll<TData extends RowData>({\n rows,\n expanded,\n target,\n expand,\n}: TMDataGridExpandAllArgs<TData> & { expand: boolean }): ExpandedState {\n const next = toExpandedMap(rows, expanded);\n for (const row of rows) {\n if (!isTarget(row, target)) continue;\n if (expand) next[row.id] = true;\n else delete next[row.id];\n }\n return next;\n}\n","import { UnstyledButton } from \"@mantine/core\";\nimport {\n useCellControlTabIndex,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport type { ColumnDef, Row, RowData } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport classes from \"./TMDataGridDetailsColumn.module.css\";\nimport { ChevronRightIcon } from \"./icons\";\nimport { areAllRowsExpanded, resolveExpandAll } from \"../core/expanding\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\nexport const DETAILS_COLUMN_ID = \"__details__\";\n\n/**\n * The chevron that opens a row's detail panel.\n *\n * Expansion is read through a subscription rather than from\n * `row.getIsExpanded()` in the component body: the `row` identity survives an\n * expand, so the React Compiler would cache the call along with it and the\n * chevron would never turn. Same reason the select checkbox subscribes.\n */\nfunction DetailsCell<TData extends RowData>({\n row,\n}: {\n row: Row<TMDataGridFeatures, TData>;\n}) {\n const { labels } = useTMDataGridContext();\n const expanded = useSelector(row.table.store, () => row.getIsExpanded());\n // See useCellControlTabIndex: a body control is reached by stepping into its\n // cell, not by Tab, or the grid would have one tab stop per mounted row.\n const tabIndex = useCellControlTabIndex();\n\n // Group rows open into their children, not into a panel — see the body's\n // `showsDetails`. Their cells are aggregated, so this lane is already blank\n // on them; the guard is what makes that a decision rather than a side effect.\n if (row.getIsGrouped()) return null;\n\n return (\n <UnstyledButton\n className={classes.detailsToggle}\n tabIndex={tabIndex}\n aria-expanded={expanded}\n aria-label={expanded ? labels.hideDetails : labels.showDetails}\n // The row underneath may select or highlight on click; opening a panel is\n // its own gesture and must not also trigger those.\n onClick={(event) => {\n event.stopPropagation();\n row.toggleExpanded();\n }}\n >\n <span className={classes.chevron} data-expanded={expanded}>\n <ChevronRightIcon size={16} stroke={1.6} />\n </span>\n </UnstyledButton>\n );\n}\n\n/**\n * Expand-all / collapse-all for the lane, the way the checkbox column's header\n * selects and clears every row.\n *\n * Deliberately not `table.toggleAllRowsExpanded()`: that writes the `expanded`\n * state's whole-table form, and one state holds both the tree and the panels —\n * so it would unfold every group as well. Only the data rows are touched here;\n * whatever the tree was showing, it goes on showing. See resolveExpandAll.\n */\nfunction DetailsHeader<TData extends RowData>({\n table,\n}: {\n table: TMDataGridTable<TData>;\n}) {\n const { labels } = useTMDataGridContext();\n // Pre-paginated: expand-all means every row the filters left, not the page\n // that happens to be on screen. Same model `getCanSomeRowsExpand` reads.\n const detailRows = () => table.getPrePaginatedRowModel().flatRows;\n\n const allExpanded = useSelector(table.store, (state) =>\n areAllRowsExpanded({\n rows: detailRows(),\n expanded: state.expanded,\n target: \"details\",\n }),\n );\n\n return (\n <UnstyledButton\n className={classes.detailsToggle}\n aria-expanded={allExpanded}\n aria-label={\n allExpanded ? labels.collapseAllDetails : labels.expandAllDetails\n }\n // Partly expanded opens the rest rather than closing what is already\n // open — the same reading as an indeterminate select-all box.\n onClick={() =>\n table.setExpanded(\n resolveExpandAll({\n rows: detailRows(),\n expanded: table.store.state.expanded,\n target: \"details\",\n expand: !allExpanded,\n }),\n )\n }\n >\n <span className={classes.chevron} data-expanded={allExpanded}>\n <ChevronRightIcon size={16} stroke={1.6} />\n </span>\n </UnstyledButton>\n );\n}\n\n/**\n * The generated details lane, prepended whenever `renderDetails` is set.\n *\n * Structural, like the checkbox and tree columns: fixed width, pinned to the\n * left after both of them, not hideable, not movable and not resizable. A\n * toggle that wandered off to the right of the grid — or hid itself — would\n * leave rows with panels no one can open.\n *\n * Last of the three because it acts on one record: the checkbox picks rows out\n * and the tree says which group they are in, and only then is there a row to\n * open.\n *\n * Nothing stops a second toggle elsewhere: `row.toggleExpanded()` is the whole\n * interface, and this lane is only the one the grid ships.\n */\nexport function createDetailsColumn<TData extends RowData>(\n label = \"Details\",\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n return {\n id: DETAILS_COLUMN_ID,\n meta: {\n label,\n align: \"center\",\n // Structurally the last of the generated lanes.\n enableOrdering: false,\n },\n // A system lane: as wide as the control it holds and no wider. Fixed at\n // every scale — the control does not grow with the font size, so neither\n // should its track.\n size: 36,\n minSize: 36,\n maxSize: 36,\n enableResizing: false,\n enableSorting: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n // Its visibility is not the user's to set: hiding it would strand every\n // panel behind a control that is no longer there.\n enableHiding: false,\n // Structurally pinned to the left; users shouldn't be able to move it.\n enablePinning: false,\n header: ({ table }) => <DetailsHeader table={table} />,\n cell: ({ row }) => <DetailsCell row={row} />,\n // Deliberately no `aggregatedCell`: on a group row every cell outside the\n // grouped column counts as aggregated, and blank is the right answer here —\n // groups expand into their rows, not into a panel.\n };\n}\n","import type { Row, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\n/**\n * The data rows under a group row, at any depth.\n *\n * Not `row.getLeafRows()`, despite the name: that flattens the whole subtree\n * and keeps the branches, so a group nested two deep reports its sub-groups\n * alongside the records. Grouping `city` then `name` would have Stockholm\n * counting four rows and three names as seven, and one tick on it selecting\n * ids that hold no record.\n *\n * A row with no subRows is a data row, which also makes this the identity on an\n * ungrouped grid.\n */\nexport function getGroupDataRows<TData extends RowData>(\n row: Row<TMDataGridFeatures, TData>,\n): Array<Row<TMDataGridFeatures, TData>> {\n if (row.subRows.length === 0) return [row];\n return row.getLeafRows().filter((leaf) => leaf.subRows.length === 0);\n}\n","import type { Row, RowData, RowSelectionState } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatureFlags } from \"./capabilities\";\nimport { getGroupDataRows } from \"./grouping\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\n/**\n * Rows in the order they are displayed, which is the order a shift-click range\n * is measured over — so a range follows the active sort and skips filtered-out\n * rows. Under pagination it is the current page, so a range cannot cross a page\n * boundary.\n *\n * Once a column is grouped this includes the group rows, and only the leaves of\n * groups that are open — and paging is suspended, so it is the whole tree. That\n * is the right list for a range: it is what the user can see, and a range that\n * swept collapsed rows would select things off screen. What a group row in the\n * range contributes is decided by {@link getSelectableRowIds}.\n */\nexport function getDisplayedRows<TData extends RowData>(\n table: TMDataGridTable<TData>,\n features: TMDataGridFeatureFlags,\n): Array<Row<TMDataGridFeatures, TData>> {\n return isPagingActive(table, features)\n ? table.getPaginatedRowModel().rows\n : table.getPrePaginatedRowModel().rows;\n}\n\n/**\n * Whether the built-in pager is actually slicing anything.\n *\n * Grouping suspends it. A page can only count one kind of thing, and once the\n * rows are a tree neither answer works: counting every row splits a group\n * across a page boundary and strands the rest of the tree on pages the user has\n * to go looking for, and counting only the top-level rows quietly redefines\n * \"rows per page\" as groups per page, so a page of 25 can hold thousands of\n * rows. Rather than pick, the grid renders the whole tree and leans on the\n * virtualizer — which is its default mode anyway, pagination being opt-in.\n *\n * `TMDataGrid.Footer` reads this too, and greys the pager out rather than\n * hiding it, so the pager going quiet is visible instead of mysterious.\n */\nexport function isPagingActive<TData extends RowData>(\n table: TMDataGridTable<TData>,\n features: TMDataGridFeatureFlags,\n): boolean {\n return features.pagination && table.store.state.grouping.length === 0;\n}\n\n/**\n * Which modifiers were held. Named for what they mean rather than for the keys,\n * because the keys differ per platform — `toggle` is Ctrl on Windows/Linux and\n * Cmd on macOS.\n */\nexport type TMDataGridRowClickModifiers = {\n toggle: boolean;\n extend: boolean;\n};\n\nexport type ResolveRowSelectionClickArgs<TData extends RowData> = {\n /** Displayed order — see {@link getDisplayedRows}. */\n rows: ReadonlyArray<Row<TMDataGridFeatures, TData>>;\n rowId: string;\n /** The pivot a shift-click extends from. */\n anchorRowId: string | null;\n modifiers: TMDataGridRowClickModifiers;\n selection: RowSelectionState;\n /**\n * Whether this gesture is allowed to clear rows it did not touch.\n *\n * `true` for a bare row click, where replacing is the whole point. `false` for\n * a checkbox, which is only ever additive — ticking one box has never cleared\n * the others, and shift-clicking one adds the range rather than becoming it.\n */\n canReplaceSelection: boolean;\n};\n\nexport type ResolvedRowSelection = {\n selection: RowSelectionState;\n anchorRowId: string | null;\n};\n\n/**\n * The row ids one gesture on this row selects.\n *\n * A group row is never selected itself: it holds no record, and TanStack\n * derives its checked state from its descendants. So ticking a group means\n * ticking every selectable leaf under it, which is also what makes the group's\n * own box light up.\n *\n * Leaves rather than direct children, so one click on a top-level group takes\n * the whole subtree however deeply it nests.\n */\nexport function getSelectableRowIds<TData extends RowData>(\n row: Row<TMDataGridFeatures, TData>,\n): Array<string> {\n return getGroupDataRows(row)\n .filter((dataRow) => dataRow.getCanSelect())\n .map((dataRow) => dataRow.id);\n}\n\n/**\n * Turns one click into the next selection, following the convention every\n * desktop list uses:\n *\n * | Gesture | Effect |\n * | ------- | ------ |\n * | Click | selection becomes only this row |\n * | Ctrl/Cmd + click | toggle this row, leave the rest |\n * | Shift + click | selection becomes the range anchor → this row |\n * | Ctrl/Cmd + Shift + click | add that range to the selection |\n *\n * The anchor is a *pivot*, not \"the last row touched\": only a plain or\n * Ctrl-click moves it, which is what lets a run of shift-clicks grow and shrink\n * the same range from a fixed point.\n *\n * Selection state is rebuilt here and handed to `setRowSelection` wholesale\n * rather than going through `row.toggleSelected()` per row, which would publish\n * one state update each. That skips TanStack's sub-row cascade, so the cascade\n * is done here instead: every row in the gesture is expanded through\n * {@link getSelectableRowIds} before it reaches the map. Under grouping that is\n * what makes one tick on a group select all of it.\n */\nexport function resolveRowSelectionClick<TData extends RowData>({\n rows,\n rowId,\n anchorRowId,\n modifiers,\n selection,\n canReplaceSelection,\n}: ResolveRowSelectionClickArgs<TData>): ResolvedRowSelection {\n const index = rows.findIndex((row) => row.id === rowId);\n const clickedRow = rows[index];\n // Clicked row is not in the displayed set — nothing sensible to resolve.\n if (index === -1 || clickedRow === undefined) return { selection, anchorRowId };\n\n const targets = getSelectableRowIds(clickedRow);\n // Nothing selectable under this gesture: a row the predicate refuses, or a\n // group whose every leaf refuses.\n if (targets.length === 0) return { selection, anchorRowId };\n\n // `enableMultiRowSelection: false`, or the per-row predicate saying no: one\n // row at a time, so the modifiers have nothing to build on and every gesture\n // collapses to a single id.\n //\n // This has to be enforced here. Rebuilding the map and handing it to\n // `setRowSelection` skips `mutateRowIsSelected`, which is where TanStack\n // clears the other rows — so without this, Ctrl and Shift would quietly\n // produce the multi-selection the option ruled out.\n if (!clickedRow.getCanMultiSelect()) {\n // A group stands for several rows, which single-select cannot express. The\n // checkbox column drops the box on those rows for the same reason.\n const only = targets.length === 1 ? targets[0] : undefined;\n if (only === undefined) return { selection, anchorRowId };\n // A checkbox must still be able to untick the one selected row; a row click\n // only ever sets, so re-clicking it cannot empty the selection.\n const untick = !canReplaceSelection && selection[only] === true;\n return {\n selection: untick ? {} : { [only]: true },\n anchorRowId: rowId,\n };\n }\n\n const anchorIndex =\n anchorRowId === null\n ? -1\n : rows.findIndex((row) => row.id === anchorRowId);\n\n // A range needs a pivot that is still on screen. When the anchor has been\n // filtered or paged away, fall through and treat this as a fresh click.\n if (modifiers.extend && anchorIndex !== -1) {\n const from = Math.min(anchorIndex, index);\n const to = Math.max(anchorIndex, index);\n // Ctrl+Shift adds to what is already selected; Shift alone becomes the\n // range — unless the gesture may not replace, in which case it also adds.\n const next: RowSelectionState =\n modifiers.toggle || !canReplaceSelection ? { ...selection } : {};\n for (const row of rows.slice(from, to + 1)) {\n // A group row inside the range brings its whole subtree, including leaves\n // that are collapsed out of `rows` — sweeping past a closed group selects\n // it entire, which is the only reading that matches what it displays.\n for (const id of getSelectableRowIds(row)) next[id] = true;\n }\n // The pivot deliberately stays put.\n return { selection: next, anchorRowId };\n }\n\n if (modifiers.toggle || !canReplaceSelection) {\n const next: RowSelectionState = { ...selection };\n // Asked of the targets rather than of `rowId`: a group row carries no id in\n // the map, so it counts as selected exactly when all of its leaves do —\n // which is also when its checkbox shows a tick rather than a dash.\n const allSelected = targets.every((id) => selection[id] === true);\n for (const id of targets) {\n if (allSelected) delete next[id];\n else next[id] = true;\n }\n return { selection: next, anchorRowId: rowId };\n }\n\n const next: RowSelectionState = {};\n for (const id of targets) next[id] = true;\n return { selection: next, anchorRowId: rowId };\n}\n","import { Checkbox } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ColumnDef, Row, RowData } from \"@tanstack/react-table\";\nimport {\n useCellControlTabIndex,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport {\n getDisplayedRows,\n getSelectableRowIds,\n resolveRowSelectionClick,\n} from \"../core/rowSelection\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\nexport const SELECT_COLUMN_ID = \"__select__\";\n\n/**\n * Both checkboxes subscribe to the table store themselves rather than reading\n * the selection off the render they were handed.\n *\n * A cell is rendered by `flexRender`, which mounts the cell function as its own\n * component — but the body cell above it keeps the same props across a\n * selection change (row, column and layout identities all survive it), so the\n * React Compiler reuses the memoized element and the subtree never re-renders.\n * The row highlight would update, from state `TMDataGridTable` subscribes to,\n * while the box below it stayed unchecked.\n *\n * Selection is derived inside the selector, not from a method call in the\n * component body, for the same reason: `table` and `row` identities survive the\n * change, so a call in the body would be cached along with them.\n */\nfunction SelectAllCheckbox<TData extends RowData>({\n table,\n}: {\n table: TMDataGridTable<TData>;\n}) {\n const { labels } = useTMDataGridContext();\n const allSelected = useSelector(table.store, () =>\n table.getIsAllRowsSelected(),\n );\n const someSelected = useSelector(table.store, () =>\n table.getIsSomeRowsSelected(),\n );\n\n return (\n <Checkbox\n size=\"xs\"\n aria-label={labels.selectAllRows}\n checked={allSelected}\n indeterminate={someSelected && !allSelected}\n onChange={table.getToggleAllRowsSelectedHandler()}\n />\n );\n}\n\n/**\n * Drops the select-all box when only one row may be selected. Read from the\n * feature flags rather than `table.options.enableMultiRowSelection` directly:\n * the flags are re-derived from a fresh object every render, so the switch\n * cannot be cached along with a `table` identity that survives an options\n * change — the same reason the rest of the chrome reads them. See\n * readFeatureFlags.\n */\nfunction SelectAllHeader<TData extends RowData>({\n table,\n}: {\n table: TMDataGridTable<TData>;\n}) {\n const { features } = useTMDataGridContext();\n if (!features.multiRowSelection) return null;\n return <SelectAllCheckbox table={table} />;\n}\n\nfunction SelectRowCheckbox<TData extends RowData>({\n row,\n}: {\n row: Row<TMDataGridFeatures, TData>;\n}) {\n // Cells render inside the grid's provider, so the checkbox can reach the\n // chrome store — it needs the shift-click pivot, and the feature flags to know\n // which row model a range is measured over.\n const { ui, features, labels } = useTMDataGridContext();\n // Out of the tab order once the grid has a cell cursor — see\n // useCellControlTabIndex. Enter on the lane still steps in, and Space on any\n // cell of the row ticks it.\n const tabIndex = useCellControlTabIndex();\n const isGroupRow = row.subRows.length > 0;\n\n // A group row is never selected by id: `rowSelection` only ever holds the\n // leaves, and TanStack's `getIsSelected()` is a plain lookup in that map. So\n // a group asks about its descendants instead, which is also the honest\n // reading — the box means \"all of these\", and it goes indeterminate as soon\n // as that stops being true.\n const selected = useSelector(row.table.store, () =>\n isGroupRow ? row.getIsAllSubRowsSelected() : row.getIsSelected(),\n );\n const someSelected = useSelector(row.table.store, () =>\n row.getIsSomeSelected(),\n );\n\n // The resolver expands a tick back out to the descendant ids; all the group\n // case needs here is to know whether any of them may be selected at all.\n const selectableIds = getSelectableRowIds(row);\n\n // Single-select has no way to express \"this group\": one box for several rows\n // would either overrun the limit or lie about what it did.\n if (isGroupRow && !row.getCanMultiSelect()) return null;\n\n return (\n <Checkbox\n size=\"xs\"\n tabIndex={tabIndex}\n aria-label={isGroupRow ? labels.selectGroup : labels.selectRow}\n checked={selected}\n disabled={selectableIds.length === 0}\n indeterminate={someSelected && !selected}\n // Every tick goes through the resolver, shift held or not — plain becomes\n // a toggle that moves the pivot, so a later shift-click extends from the\n // box the user last touched.\n //\n // All of it in `onChange`, not split with an `onClick`: React derives a\n // checkbox's change event from the click, so the modifier keys ride along\n // on the native event, and a `preventDefault()` in a click handler cannot\n // stop the change from firing anyway. Trying to do the range in `onClick`\n // silently loses the clicked row, which `onChange` then toggles back off.\n onChange={(event) => {\n const native = event.nativeEvent;\n const isMouse = native instanceof MouseEvent;\n const resolved = resolveRowSelectionClick({\n rows: getDisplayedRows(row.table, features),\n rowId: row.id,\n anchorRowId: ui.state.selectionAnchorRowId,\n modifiers: {\n toggle: isMouse && (native.ctrlKey || native.metaKey),\n extend: isMouse && native.shiftKey,\n },\n selection: row.table.store.state.rowSelection,\n // A checkbox is only ever additive — ticking one has never cleared\n // the others, so `canReplaceSelection` stays false whatever is held.\n canReplaceSelection: false,\n });\n row.table.setRowSelection(resolved.selection);\n ui.actions.setSelectionAnchor(resolved.anchorRowId);\n }}\n // A row can select on click too; the checkbox must not toggle twice.\n onClick={(event) => event.stopPropagation()}\n />\n );\n}\n\n/**\n * The generated checkbox column, prepended under\n * `selectionMode: \"checkbox\"` (the default) or `\"checkboxAndHighlight\"`.\n */\nexport function createSelectColumn<TData extends RowData>(\n label = \"Checkbox selection\",\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n return {\n id: SELECT_COLUMN_ID,\n meta: {\n label,\n align: \"center\",\n // Structurally the first column; it also anchors the left pinned lane, so\n // no other column can be moved in front of it.\n enableOrdering: false,\n },\n // A system lane: as wide as the control it holds and no wider. Fixed at\n // every scale — the control does not grow with the font size, so neither\n // should its track.\n size: 36,\n minSize: 36,\n maxSize: 36,\n enableResizing: false,\n enableSorting: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n // Structurally pinned to the left; users shouldn't be able to move it.\n enablePinning: false,\n header: ({ table }) => <SelectAllHeader table={table} />,\n cell: ({ row }) => <SelectRowCheckbox row={row} />,\n // Every cell on a group row that is not the grouped column counts as\n // aggregated, this lane included, and an aggregated cell with nothing\n // declared renders blank. Without this the checkbox would disappear from\n // exactly the rows that select a whole group. See renderCellContent.\n aggregatedCell: ({ row }) => <SelectRowCheckbox row={row} />,\n };\n}\n","import type { TMDataGridColumnType } from \"./filterOperators\";\nimport { DETAILS_COLUMN_ID } from \"../components/TMDataGridDetailsColumn\";\nimport { SELECT_COLUMN_ID } from \"../components/TMDataGridSelectColumn\";\nimport type { TMDataGridColumnMeta } from \"../useTMDataGrid\";\n\n/**\n * Structural shape of the column bits the chrome reads. Kept minimal so these\n * helpers work with any `Column`/`Header` instance without dragging generics\n * through every call site.\n */\ntype ColumnLike = {\n id: string;\n columnDef: { header?: unknown; meta?: TMDataGridColumnMeta };\n /** Set on a leaf that sits inside a header group. */\n parent?: unknown;\n};\n\n/** Menu- and panel-facing column name. */\nexport function getColumnLabel(column: ColumnLike): string {\n const label = column.columnDef.meta?.label;\n if (label) return label;\n const header = column.columnDef.header;\n return typeof header === \"string\" ? header : column.id;\n}\n\nexport function getColumnType(column: ColumnLike): TMDataGridColumnType {\n return column.columnDef.meta?.type ?? \"string\";\n}\n\nexport function getColumnAlign(column: ColumnLike): \"left\" | \"right\" | \"center\" {\n return column.columnDef.meta?.align ?? \"left\";\n}\n\n/**\n * A generated lane holding one control at a fixed width — the checkbox and the\n * details chevron.\n *\n * They are laid out differently from every other column: cell padding is sized\n * for text and grows with the scale, which at `xl` squeezed a 16px checkbox out\n * of its track, so these lanes centre their control in an unpadded cell.\n * Their headers are controls too, and carry no column menu.\n *\n * The tree column is deliberately not one of them: it holds a label as well as a\n * chevron, and wants the padding.\n */\nexport function isControlColumn(columnId: string): boolean {\n return columnId === SELECT_COLUMN_ID || columnId === DETAILS_COLUMN_ID;\n}\n\n/**\n * Whether a column may be moved. Ordering is the one column feature TanStack\n * has no column option for, so the switch lives in `meta.enableOrdering`.\n *\n * A leaf inside a header group is never movable: `columnOrder` sequences leaf\n * columns, so moving one out of its group would leave the group header spanning\n * columns that no longer belong to it.\n */\nexport function isColumnReorderable(column: ColumnLike): boolean {\n if (column.columnDef.meta?.enableOrdering === false) return false;\n return column.parent === undefined;\n}\n","/* The tree lane. Fills its cell so the whole indented width is a hit target,\n which is what makes a deeply nested group as easy to click as a top-level\n one. */\n.groupToggle {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n min-width: 0;\n font-size: var(--dg-font-size);\n color: inherit;\n}\n\n.chevron {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n color: var(--mantine-color-dimmed);\n transition: transform 120ms ease;\n}\n\n.chevron[data-expanded=\"true\"] {\n transform: rotate(90deg);\n}\n\n/* One icon rotated rather than two swapped: the turn is what reads as the\n expand, and a swap would jump. */\n@media (prefers-reduced-motion: reduce) {\n .chevron {\n transition: none;\n }\n}\n\n.groupLabel {\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-weight: 600;\n}\n\n/* Never squeezed out by a long group value — the count is the part that tells\n you whether the group is worth opening. */\n.groupCount {\n flex: 0 0 auto;\n color: var(--mantine-color-dimmed);\n font-variant-numeric: tabular-nums;\n}\n","import { UnstyledButton } from \"@mantine/core\";\nimport {\n useCellControlTabIndex,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport type { ColumnDef, Row, RowData } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { shallow } from \"@tanstack/store\";\nimport classes from \"./TMDataGridGroupColumn.module.css\";\nimport { ChevronRightIcon } from \"./icons\";\nimport { getColumnLabel } from \"../core/columnUtils\";\nimport { getGroupDataRows } from \"../core/grouping\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\nexport const GROUP_COLUMN_ID = \"__group__\";\n\n/** Indent added per level of nesting, in px. */\nconst INDENT_STEP = 16;\n\n/** Shown for a group whose value is empty — `String(null)` would read as \"null\". */\nconst BLANK_GROUP_LABEL = \"(Blank)\";\n\n/**\n * How a grouping value is written into the tree cell.\n *\n * Deliberately not the grouped column's own `cell` renderer: that renderer is\n * written for a data row and is free to reach into `row.original`, which on a\n * group row is the first leaf's record rather than anything about the group.\n */\nexport function formatGroupValue(\n value: unknown,\n blankLabel = BLANK_GROUP_LABEL,\n): string {\n if (value === null || value === undefined || value === \"\") {\n return blankLabel;\n }\n if (value instanceof Date) return value.toLocaleDateString();\n return String(value);\n}\n\n/**\n * The tree cell: chevron, group value and leaf count, indented by depth.\n *\n * Expansion is read through a subscription rather than from `row.getIsExpanded()`\n * in the component body for the same reason the select checkbox does it — the\n * `row` identity survives an expand, so the React Compiler would cache the call\n * along with it and the chevron would never turn. See TMDataGridSelectColumn.\n */\nfunction GroupCell<TData extends RowData>({\n row,\n}: {\n row: Row<TMDataGridFeatures, TData>;\n}) {\n const { labels } = useTMDataGridContext();\n const expanded = useSelector(row.table.store, () => row.getIsExpanded());\n // See useCellControlTabIndex: reached by stepping into the cell, not by Tab.\n const tabIndex = useCellControlTabIndex();\n\n // Leaf rows keep the lane empty: their values are in the data columns, and\n // the indent alone is what places them under their group.\n if (!row.getIsGrouped()) return null;\n\n const label = formatGroupValue(row.groupingValue, labels.blankGroupValue);\n\n return (\n <UnstyledButton\n className={classes.groupToggle}\n // Padding rather than margin, so the whole indented width stays clickable.\n style={{ paddingInlineStart: row.depth * INDENT_STEP }}\n tabIndex={tabIndex}\n aria-expanded={expanded}\n aria-label={\n expanded ? labels.collapseGroup(label) : labels.expandGroup(label)\n }\n // The row underneath may select or highlight on click; expanding is its\n // own gesture and must not also trigger those.\n onClick={(event) => {\n event.stopPropagation();\n row.toggleExpanded();\n }}\n >\n <span className={classes.chevron} data-expanded={expanded}>\n <ChevronRightIcon size={16} stroke={1.6} />\n </span>\n <span className={classes.groupLabel}>{label}</span>\n {/* Data rows, not direct children and not `getLeafRows()`: a nested group\n counts the records under it, never the sub-groups in between. */}\n <span className={classes.groupCount}>\n ({getGroupDataRows(row).length})\n </span>\n </UnstyledButton>\n );\n}\n\n/**\n * Names the columns currently grouped on, so the lane says what it is showing\n * rather than a static \"Group\".\n */\nfunction GroupHeader<TData extends RowData>({\n table,\n}: {\n table: TMDataGridTable<TData>;\n}) {\n const { labels } = useTMDataGridContext();\n const grouping = useSelector(table.store, (state) => state.grouping, {\n compare: shallow,\n });\n\n if (grouping.length === 0) return labels.groupColumnLabel;\n return grouping\n .map((columnId) => {\n const column = table.getColumn(columnId);\n return column ? getColumnLabel(column) : columnId;\n })\n .join(\" / \");\n}\n\n/**\n * The generated tree column, prepended whenever grouping is enabled and hidden\n * again while `grouping` is empty — see the visibility effect in\n * `useTMDataGrid`.\n *\n * It exists because TanStack ships no auto group column: `groupedColumnMode:\n * \"remove\"` takes the grouped column out of the grid, so something has to hold\n * the tree. Modelled on the checkbox column, which is generated the same way.\n *\n * Not groupable itself, and nothing had to be written to make that true —\n * `column.getCanGroup()` requires an `accessorFn`, which a display column has\n * no reason to have.\n */\nexport function createGroupColumn<TData extends RowData>(\n label = \"Group\",\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n return {\n id: GROUP_COLUMN_ID,\n meta: {\n label,\n // Structurally the first column after the checkbox lane.\n enableOrdering: false,\n },\n size: 260,\n minSize: 180,\n enableSorting: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n // Keeps it out of the columns panel and out of the header menu: its\n // visibility is not the user's to set, it follows the grouping state.\n enableHiding: false,\n // Structurally pinned to the left; users shouldn't be able to move it.\n enablePinning: false,\n cell: ({ row }) => <GroupCell row={row} />,\n // A group row has subRows, so every cell on it that is not the grouped\n // column reports `getIsAggregated()` — this lane included. Without an\n // `aggregatedCell` the body would take that as \"nothing to summarise\" and\n // render the tree lane blank on exactly the rows it exists for.\n aggregatedCell: ({ row }) => <GroupCell row={row} />,\n header: ({ table }) => <GroupHeader table={table} />,\n };\n}\n","import { Button, Checkbox, ScrollArea, Text, TextInput } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useState } from \"react\";\nimport classes from \"./TMDataGridColumnsPanel.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getColumnLabel } from \"../core/columnUtils\";\nimport { GROUP_COLUMN_ID } from \"./TMDataGridGroupColumn\";\nimport { SearchIcon } from \"./icons\";\n\n/**\n * The \"Manage columns\" surface. Reachable from every column header menu and\n * from the grid's burger menu, so it lives on its own and is rendered by\n * `TMDataGrid.ColumnsButton`.\n */\nexport function TMDataGridColumnsPanel() {\n const { table, labels, controlSize } = useTMDataGridContext();\n const [search, setSearch] = useState(\"\");\n\n const columnVisibility = useSelector(\n table.store,\n (state) => state.columnVisibility,\n );\n\n // The tree column is left out rather than listed and disabled: its visibility\n // is not a setting at all, it follows the grouping state, so an unchecked box\n // that cannot be ticked would only invite the question.\n const columns = table\n .getAllLeafColumns()\n .filter((column) => column.id !== GROUP_COLUMN_ID);\n const needle = search.trim().toLowerCase();\n const visibleInPanel = needle\n ? columns.filter((column) =>\n getColumnLabel(column).toLowerCase().includes(needle),\n )\n : columns;\n\n const hideableColumns = columns.filter((column) => column.getCanHide());\n const shownCount = hideableColumns.filter(\n (column) => columnVisibility[column.id] !== false,\n ).length;\n\n return (\n <div className={classes.columnsPanel}>\n <div className={classes.columnsPanelSearch}>\n <TextInput\n value={search}\n onChange={(event) => setSearch(event.currentTarget.value)}\n placeholder={labels.columnsSearchPlaceholder}\n leftSection={<SearchIcon size={16} stroke={1.6} />}\n size={controlSize}\n data-autofocus\n />\n </div>\n\n <ScrollArea.Autosize mah={260} type=\"auto\">\n <div className={classes.columnsPanelList}>\n {visibleInPanel.map((column) => (\n <Checkbox\n key={column.id}\n size={controlSize}\n label={getColumnLabel(column)}\n disabled={!column.getCanHide()}\n checked={columnVisibility[column.id] !== false}\n onChange={(event) =>\n column.toggleVisibility(event.currentTarget.checked)\n }\n />\n ))}\n {visibleInPanel.length === 0 && (\n <Text size={controlSize} c=\"dimmed\">\n {labels.columnsNoMatch(search)}\n </Text>\n )}\n </div>\n </ScrollArea.Autosize>\n\n <div className={classes.columnsPanelFooter}>\n <Checkbox\n size={controlSize}\n label={labels.columnsShowHideAll}\n checked={shownCount === hideableColumns.length}\n indeterminate={shownCount > 0 && shownCount < hideableColumns.length}\n onChange={(event) =>\n table.toggleAllColumnsVisible(event.currentTarget.checked)\n }\n />\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n onClick={() => table.resetColumnVisibility()}\n >\n {labels.columnsReset}\n </Button>\n </div>\n </div>\n );\n}\n","/* Floats over the first body rows, anchored to `.tableWrapper`. Sits just\n below the header row, so its offset follows the size scale rather than a\n fixed pixel count. */\n.filterPanel {\n position: absolute;\n top: calc(var(--dg-header-height) + 2px);\n left: var(--mantine-spacing-md);\n z-index: 5;\n padding: var(--mantine-spacing-sm);\n border-radius: var(--mantine-radius-md);\n border: 1px solid var(--mantine-color-default-border);\n background-color: var(--mantine-color-body);\n box-shadow: var(--mantine-shadow-md);\n}\n\n.filterRow {\n display: flex;\n align-items: flex-end;\n gap: var(--mantine-spacing-xs);\n}\n\n.filterPanelHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mantine-spacing-md);\n padding-bottom: var(--mantine-spacing-xs);\n}\n\n.filterPanelFooter {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--mantine-spacing-md);\n}\n","import type { Column, Row } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\n/**\n * One choice of a `select` / `multiSelect` column. A bare string in any options\n * list is shorthand for `{ value }`.\n */\nexport type TMDataGridOption = {\n value: string;\n /** Shown in dropdowns. Defaults to the value itself. */\n label?: string;\n /** Mantine colour for the value's badge, where a cell renders one. */\n color?: string;\n disabled?: boolean;\n /** Dropdown group heading. Ungrouped options render first. */\n group?: string;\n};\n\nexport type TMDataGridOptionsArgs = {\n table: TMDataGridTable<TMDataGridRowData>;\n column: Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\n /** The row an editor is standing on. Absent when the filter panel asks. */\n row?: Row<TMDataGridFeatures, TMDataGridRowData>;\n /**\n * Source to use when the column declares none. The filter panel passes\n * `\"faceted\"` so a select column with no `meta.options` still offers the\n * values that exist, rather than an empty dropdown.\n */\n fallback?: TMDataGridOptionsSource;\n};\n\n/**\n * Where a column's options come from — `meta.options`. One declaration feeds\n * both the filter panel's value control and the cell editor.\n *\n * | Form | For |\n * | --- | --- |\n * | array | a known, fixed set |\n * | `\"faceted\"` | low-cardinality data columns: the distinct values present, via `getFacetedUniqueValues` |\n * | function | large or contextual sets — `row` is set when an editor asks, so options can depend on the record (city given country) |\n */\nexport type TMDataGridOptionsSource =\n | ReadonlyArray<TMDataGridOption | string>\n | \"faceted\"\n | ((args: TMDataGridOptionsArgs) => ReadonlyArray<TMDataGridOption | string>);\n\nfunction addFacetValue(target: Set<string>, value: unknown): void {\n if (value === null || value === undefined || value === \"\") return;\n target.add(String(value));\n}\n\n/**\n * A column's options as a normalised list, whatever form `meta.options` took.\n * Empty for a column that declares none.\n *\n * `\"faceted\"` reads the distinct values actually present in the data. A\n * multiSelect cell holds an array, so array values contribute their elements\n * rather than the array itself.\n */\nexport function resolveColumnOptions({\n table,\n column,\n row,\n fallback,\n}: TMDataGridOptionsArgs): Array<TMDataGridOption> {\n const source = column.columnDef.meta?.options ?? fallback;\n if (!source) return [];\n\n if (source === \"faceted\") {\n const values = new Set<string>();\n for (const key of column.getFacetedUniqueValues().keys()) {\n if (Array.isArray(key)) {\n for (const entry of key) addFacetValue(values, entry);\n } else {\n addFacetValue(values, key);\n }\n }\n return [...values]\n .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))\n .map((value) => ({ value }));\n }\n\n const list = typeof source === \"function\" ? source({ table, column, row }) : source;\n return list.map((option) =>\n typeof option === \"string\" ? { value: option } : option,\n );\n}\n\ntype ComboboxItem = { value: string; label: string; disabled?: boolean };\ntype ComboboxData = Array<ComboboxItem | { group: string; items: ComboboxItem[] }>;\n\n/**\n * The same list in the shape Mantine's `Select` / `MultiSelect` take, with\n * `group` fields folded into Mantine's group entries. Ungrouped options come\n * first, then the groups in first-appearance order.\n */\nexport function optionsToComboboxData(\n options: ReadonlyArray<TMDataGridOption>,\n): ComboboxData {\n const ungrouped: ComboboxItem[] = [];\n const groups = new Map<string, ComboboxItem[]>();\n\n for (const option of options) {\n const item: ComboboxItem = {\n value: option.value,\n label: option.label ?? option.value,\n ...(option.disabled ? { disabled: true } : {}),\n };\n if (option.group === undefined) {\n ungrouped.push(item);\n } else {\n const bucket = groups.get(option.group);\n if (bucket) bucket.push(item);\n else groups.set(option.group, [item]);\n }\n }\n\n return [\n ...ungrouped,\n ...[...groups].map(([group, items]) => ({ group, items })),\n ];\n}\n","import type { Row, RowData, TableFeatures } from \"@tanstack/react-table\";\n\n/**\n * The value shape stored in `columnFilters` for every TMDataGrid column.\n *\n * TanStack resolves `filterFn` statically per column, so the operator travels\n * inside the filter *value* instead. That keeps the whole filter model plain,\n * serialisable JSON — which is what makes it portable to a server-side\n * `manualFiltering` table (just forward `columnFilters` to the API).\n *\n * `value` is a string array under `isAnyOf` / `isNoneOf` (the set the cell is\n * tested against) and a single string everywhere else — dates travel as ISO\n * `YYYY-MM-DD` strings, booleans as `\"true\"` / `\"false\"`. Still plain JSON.\n */\nexport type TMDataGridFilterValue = {\n operator: TMDataGridFilterOperator;\n value: string | ReadonlyArray<string>;\n};\n\nexport type TMDataGridColumnType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"select\"\n | \"multiSelect\";\n\nexport type TMDataGridFilterOperator =\n | \"contains\"\n | \"equals\"\n | \"notEquals\"\n | \"startsWith\"\n | \"endsWith\"\n | \"greaterThan\"\n | \"greaterThanOrEqual\"\n | \"lessThan\"\n | \"lessThanOrEqual\"\n | \"before\"\n | \"after\"\n | \"onOrBefore\"\n | \"onOrAfter\"\n | \"isAnyOf\"\n | \"isNoneOf\"\n | \"isEmpty\"\n | \"isNotEmpty\";\n\nexport const FILTER_OPERATOR_LABELS: Record<TMDataGridFilterOperator, string> = {\n contains: \"contains\",\n equals: \"equals\",\n notEquals: \"does not equal\",\n startsWith: \"starts with\",\n endsWith: \"ends with\",\n greaterThan: \"is greater than\",\n greaterThanOrEqual: \"is greater than or equal to\",\n lessThan: \"is less than\",\n lessThanOrEqual: \"is less than or equal to\",\n before: \"is before\",\n after: \"is after\",\n onOrBefore: \"is on or before\",\n onOrAfter: \"is on or after\",\n isAnyOf: \"is any of\",\n isNoneOf: \"is none of\",\n isEmpty: \"is empty\",\n isNotEmpty: \"is not empty\",\n};\n\nconst STRING_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"contains\",\n \"equals\",\n \"notEquals\",\n \"startsWith\",\n \"endsWith\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\nconst NUMBER_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"equals\",\n \"notEquals\",\n \"greaterThan\",\n \"greaterThanOrEqual\",\n \"lessThan\",\n \"lessThanOrEqual\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\n// `equals` doubles as a date's \"is\": it compares by calendar day whenever the\n// cell holds a Date (see matchesFilter), so a separate `is` operator would be\n// the same comparison under a second name.\nconst DATE_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"equals\",\n \"notEquals\",\n \"before\",\n \"after\",\n \"onOrBefore\",\n \"onOrAfter\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\nconst BOOLEAN_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"equals\",\n \"notEquals\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\n// One set for both select types: the operators are about membership in the\n// filter's set, which reads the same whether the cell holds one value or many.\nconst SELECT_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"isAnyOf\",\n \"isNoneOf\",\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\n/** Operators that ignore the value input (the input is disabled for these). */\nconst VALUELESS_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"isEmpty\",\n \"isNotEmpty\",\n];\n\n/** Operators whose value is a set of strings rather than one. */\nconst ARRAY_OPERATORS: readonly TMDataGridFilterOperator[] = [\n \"isAnyOf\",\n \"isNoneOf\",\n];\n\nconst OPERATORS_BY_TYPE: Record<\n TMDataGridColumnType,\n readonly TMDataGridFilterOperator[]\n> = {\n string: STRING_OPERATORS,\n number: NUMBER_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n date: DATE_OPERATORS,\n select: SELECT_OPERATORS,\n multiSelect: SELECT_OPERATORS,\n};\n\nconst DEFAULT_OPERATOR_BY_TYPE: Record<\n TMDataGridColumnType,\n TMDataGridFilterOperator\n> = {\n string: \"contains\",\n number: \"equals\",\n boolean: \"equals\",\n date: \"equals\",\n select: \"isAnyOf\",\n multiSelect: \"isAnyOf\",\n};\n\nexport function getOperatorsForType(\n type: TMDataGridColumnType,\n): readonly TMDataGridFilterOperator[] {\n return OPERATORS_BY_TYPE[type];\n}\n\nexport function getDefaultOperator(\n type: TMDataGridColumnType,\n): TMDataGridFilterOperator {\n return DEFAULT_OPERATOR_BY_TYPE[type];\n}\n\nexport function operatorNeedsValue(operator: TMDataGridFilterOperator): boolean {\n return !VALUELESS_OPERATORS.includes(operator);\n}\n\n/** Whether the operator's value is a string array — `isAnyOf` / `isNoneOf`. */\nexport function operatorTakesArrayValue(\n operator: TMDataGridFilterOperator,\n): boolean {\n return ARRAY_OPERATORS.includes(operator);\n}\n\nexport function isTMDataGridFilterValue(\n value: unknown,\n): value is TMDataGridFilterValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"operator\" in value &&\n typeof (value as TMDataGridFilterValue).operator === \"string\"\n );\n}\n\n/**\n * A filter only narrows the row set once it has something to compare against.\n * Half-typed filters stay in state (so the panel keeps rendering their row) but\n * are treated as inactive for the funnel indicator and for row matching.\n */\nexport function isFilterActive(value: unknown): boolean {\n if (!isTMDataGridFilterValue(value)) return false;\n if (!operatorNeedsValue(value.operator)) return true;\n return Array.isArray(value.value)\n ? value.value.length > 0\n : typeof value.value === \"string\" && value.value.trim() !== \"\";\n}\n\n/**\n * One-line description of a single filter, as shown on a filter pill.\n *\n * The type's default operator is left implicit — \"First name: Sofia\" reads the\n * way a person would say it — while any other operator is spelled out, since\n * that is the part a reader cannot guess.\n */\nexport function formatFilterLabel({\n label,\n type,\n filter,\n operatorLabels = FILTER_OPERATOR_LABELS,\n}: {\n label: string;\n type: TMDataGridColumnType;\n filter: TMDataGridFilterValue;\n /** Localized operator names — `labels.operators`. Defaults to English. */\n operatorLabels?: Record<TMDataGridFilterOperator, string>;\n}): string {\n const { operator, value } = filter;\n if (!operatorNeedsValue(operator)) {\n return `${label} ${operatorLabels[operator]}`;\n }\n const text = Array.isArray(value) ? value.join(\", \") : String(value).trim();\n if (operator === getDefaultOperator(type)) return `${label}: ${text}`;\n return `${label} ${operatorLabels[operator]} ${text}`;\n}\n\n/**\n * A value's calendar day as `YYYY-MM-DD`, or `null` for anything that has no\n * day to speak of. A `Date` is read in local time — `sv-SE` formats as ISO,\n * which is the shape `<input type=\"date\">` produced on the other side — and a\n * string contributes its leading ISO day, so both `2026-07-31` and a full\n * timestamp compare by day.\n */\nfunction toIsoDay(value: unknown): string | null {\n if (value instanceof Date) {\n return Number.isNaN(value.getTime())\n ? null\n : value.toLocaleDateString(\"sv-SE\");\n }\n if (typeof value === \"string\") {\n const match = /^(\\d{4}-\\d{2}-\\d{2})/.exec(value.trim());\n return match ? match[1] : null;\n }\n return null;\n}\n\nfunction isEmptyCell(cellValue: unknown): boolean {\n return (\n cellValue === null ||\n cellValue === undefined ||\n cellValue === \"\" ||\n (Array.isArray(cellValue) && cellValue.length === 0)\n );\n}\n\nexport function matchesFilter(\n cellValue: unknown,\n { operator, value }: TMDataGridFilterValue,\n): boolean {\n if (operator === \"isEmpty\") return isEmptyCell(cellValue);\n if (operator === \"isNotEmpty\") return !isEmptyCell(cellValue);\n\n // Set membership. The cell side is also a list — a multiSelect cell holds an\n // array — so \"any of\" is an intersection test and \"none of\" its complement.\n if (operator === \"isAnyOf\" || operator === \"isNoneOf\") {\n const set = (Array.isArray(value) ? value : [value])\n .map((entry) => String(entry).toLowerCase())\n .filter((entry) => entry !== \"\");\n if (set.length === 0) return true;\n const cellEntries = Array.isArray(cellValue) ? cellValue : [cellValue];\n const hit = cellEntries.some((entry) =>\n set.includes(String(entry ?? \"\").toLowerCase()),\n );\n return operator === \"isAnyOf\" ? hit : !hit;\n }\n\n const filterText =\n typeof value === \"string\" ? value.trim() : value.join(\",\").trim();\n if (filterText === \"\") return true;\n\n // Day ordering. ISO days compare correctly as strings, which keeps this\n // free of timezone arithmetic — the whole comparison lives in local days.\n switch (operator) {\n case \"before\":\n case \"after\":\n case \"onOrBefore\":\n case \"onOrAfter\": {\n const cellDay = toIsoDay(cellValue);\n const filterDay = toIsoDay(filterText);\n if (cellDay === null || filterDay === null) return false;\n if (operator === \"before\") return cellDay < filterDay;\n if (operator === \"after\") return cellDay > filterDay;\n if (operator === \"onOrBefore\") return cellDay <= filterDay;\n return cellDay >= filterDay;\n }\n default:\n break;\n }\n\n const numericCell = typeof cellValue === \"number\" ? cellValue : Number.NaN;\n const numericFilter = Number(filterText);\n const compareNumeric =\n !Number.isNaN(numericCell) && !Number.isNaN(numericFilter);\n\n switch (operator) {\n case \"greaterThan\":\n return compareNumeric && numericCell > numericFilter;\n case \"greaterThanOrEqual\":\n return compareNumeric && numericCell >= numericFilter;\n case \"lessThan\":\n return compareNumeric && numericCell < numericFilter;\n case \"lessThanOrEqual\":\n return compareNumeric && numericCell <= numericFilter;\n default:\n break;\n }\n\n // A Date compares by its calendar day, which is what makes `equals` on a\n // date column mean \"is this day\" rather than a doomed string comparison\n // against the Date's default stringification.\n const cellText = (\n cellValue instanceof Date\n ? (toIsoDay(cellValue) ?? \"\")\n : String(cellValue ?? \"\")\n ).toLowerCase();\n const needle = filterText.toLowerCase();\n\n switch (operator) {\n case \"contains\":\n return cellText.includes(needle);\n case \"equals\":\n return compareNumeric ? numericCell === numericFilter : cellText === needle;\n case \"notEquals\":\n return compareNumeric ? numericCell !== numericFilter : cellText !== needle;\n case \"startsWith\":\n return cellText.startsWith(needle);\n case \"endsWith\":\n return cellText.endsWith(needle);\n default:\n return true;\n }\n}\n\n/**\n * The single filter function every TMDataGrid column uses. It dispatches on the\n * operator carried by the filter value, which is what lets one column offer\n * \"contains\" / \"does not equal\" / \"is empty\" without redefining the column.\n */\nexport function tmDataGridFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(row: Row<TFeatures, TData>, columnId: string, filterValue: unknown): boolean {\n if (!isTMDataGridFilterValue(filterValue)) return true;\n return matchesFilter(row.getValue(columnId), filterValue);\n}\n","import {\n ActionIcon,\n Button,\n MultiSelect,\n Select,\n Stack,\n Text,\n TextInput,\n} from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useEffect, useRef } from \"react\";\nimport classes from \"./TMDataGridFilterPanel.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport {\n optionsToComboboxData,\n resolveColumnOptions,\n} from \"../core/columnOptions\";\nimport { getColumnLabel, getColumnType } from \"../core/columnUtils\";\nimport {\n type TMDataGridFilterOperator,\n type TMDataGridFilterValue,\n getDefaultOperator,\n getOperatorsForType,\n isTMDataGridFilterValue,\n operatorNeedsValue,\n operatorTakesArrayValue,\n} from \"../core/filterOperators\";\nimport { CloseIcon } from \"./icons\";\n\nconst FALLBACK_FILTER: TMDataGridFilterValue = { operator: \"contains\", value: \"\" };\n\nfunction asFilterValue(value: unknown): TMDataGridFilterValue {\n return isTMDataGridFilterValue(value) ? value : FALLBACK_FILTER;\n}\n\n/**\n * The MUI-style filter surface: one row per active column filter, each row a\n * column / operator / value triple. It only ever reads and writes the table's\n * `columnFilters` state, so a `manualFiltering` grid gets the same panel for\n * free — the state is forwarded to the server instead of a row model.\n */\nexport function TMDataGridFilterPanel() {\n const { table, ui, labels, controlSize } = useTMDataGridContext();\n const opened = useSelector(ui, (state) => state.filterPanelOpen);\n const columnFilters = useSelector(\n table.store,\n (state) => state.columnFilters,\n );\n const panelRef = useRef<HTMLDivElement>(null);\n\n // Clicking away hides the panel, the way any floating surface behaves. On\n // pointerdown rather than click, so a press that starts outside dismisses it\n // even when the pointer is released somewhere else.\n useEffect(() => {\n if (!opened) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n if (panelRef.current?.contains(target)) return;\n // The toolbar button toggles the panel itself. Closing from here first\n // would leave its click reopening what the user meant to close.\n if (target.closest(\"[data-dg-filter-toggle]\")) return;\n ui.actions.closeFilterPanel();\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [opened, ui]);\n\n if (!opened) return null;\n\n const filterableColumns = table\n .getAllLeafColumns()\n .filter((column) => column.getCanFilter());\n\n const columnOptions = filterableColumns.map((column) => ({\n value: column.id,\n label: getColumnLabel(column),\n }));\n\n function removeFilter(columnId: string) {\n const remaining = columnFilters.filter((filter) => filter.id !== columnId);\n table.setColumnFilters(remaining);\n if (remaining.length === 0) ui.actions.closeFilterPanel();\n }\n\n function changeFilterColumn(fromColumnId: string, toColumnId: string) {\n const current = asFilterValue(\n columnFilters.find((filter) => filter.id === fromColumnId)?.value,\n );\n const target = table.getColumn(toColumnId);\n const operator = getDefaultOperator(\n target ? getColumnType(target) : \"string\",\n );\n // The typed value only survives the move while it still fits the new\n // operator — a text needle has no meaning to an `isAnyOf` set, or a set\n // to a text input.\n const value =\n operatorTakesArrayValue(operator) === Array.isArray(current.value)\n ? current.value\n : operatorTakesArrayValue(operator)\n ? []\n : \"\";\n table.setColumnFilters(\n columnFilters\n .filter((filter) => filter.id !== toColumnId)\n .map((filter) =>\n filter.id === fromColumnId\n ? {\n id: toColumnId,\n value: { operator, value } satisfies TMDataGridFilterValue,\n }\n : filter,\n ),\n );\n ui.actions.openFilterPanel(toColumnId);\n }\n\n function patchFilter(columnId: string, patch: Partial<TMDataGridFilterValue>) {\n table.setColumnFilters(\n columnFilters.map((filter) =>\n filter.id === columnId\n ? { ...filter, value: { ...asFilterValue(filter.value), ...patch } }\n : filter,\n ),\n );\n }\n\n function changeOperator(columnId: string, operator: TMDataGridFilterOperator) {\n const current = asFilterValue(\n columnFilters.find((filter) => filter.id === columnId)?.value,\n );\n // Same arity rule as changing the column: keep the value across operators\n // of the same shape, reset it across the array/scalar boundary.\n const value =\n operatorTakesArrayValue(operator) === Array.isArray(current.value)\n ? current.value\n : operatorTakesArrayValue(operator)\n ? []\n : \"\";\n patchFilter(columnId, { operator, value });\n }\n\n /** Clears every filter, including half-typed ones the pills never showed. */\n function clearAllFilters() {\n table.setColumnFilters([]);\n // Same exit as removing the last filter row by hand: an empty panel has\n // nothing to show but its own buttons.\n ui.actions.closeFilterPanel();\n }\n\n function addFilter() {\n const nextColumn = filterableColumns.find(\n (column) => !columnFilters.some((filter) => filter.id === column.id),\n );\n if (!nextColumn) return;\n table.setColumnFilters([\n ...columnFilters,\n {\n id: nextColumn.id,\n value: {\n operator: getDefaultOperator(getColumnType(nextColumn)),\n value: \"\",\n } satisfies TMDataGridFilterValue,\n },\n ]);\n }\n\n const canAddFilter = filterableColumns.some(\n (column) => !columnFilters.some((filter) => filter.id === column.id),\n );\n\n return (\n <div\n ref={panelRef}\n role=\"group\"\n aria-label={labels.filters}\n className={classes.filterPanel}\n // Escape is what closes a floating surface, and every control that can\n // hold focus in here sits inside this element.\n onKeyDown={(event) => {\n if (event.key !== \"Escape\") return;\n event.stopPropagation();\n ui.actions.closeFilterPanel();\n }}\n >\n <div className={classes.filterPanelHeader}>\n <Text size={controlSize} fw={600}>\n {labels.filters}\n </Text>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n aria-label={labels.closeFilters}\n onClick={ui.actions.closeFilterPanel}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </div>\n\n <Stack gap=\"xs\">\n {columnFilters.map((filter) => {\n const column = table.getColumn(filter.id);\n const value = asFilterValue(filter.value);\n const type = column ? getColumnType(column) : \"string\";\n const needsValue = operatorNeedsValue(value.operator);\n const takesArray = operatorTakesArrayValue(value.operator);\n const scalarValue = typeof value.value === \"string\" ? value.value : \"\";\n\n return (\n <div key={filter.id} className={classes.filterRow}>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"lg\"\n aria-label={labels.removeFilter}\n onClick={() => removeFilter(filter.id)}\n >\n <CloseIcon size={18} stroke={1.6} />\n </ActionIcon>\n\n <Select\n label={labels.filterColumn}\n size={controlSize}\n w={160}\n allowDeselect={false}\n // Both dropdowns render inside the panel: a portalled one is\n // outside it in the DOM, and picking an option would read as a\n // click away and close the panel under the user.\n comboboxProps={{ withinPortal: false }}\n data={columnOptions}\n value={filter.id}\n onChange={(next) => next && changeFilterColumn(filter.id, next)}\n />\n\n <Select\n label={labels.filterOperator}\n size={controlSize}\n w={170}\n allowDeselect={false}\n comboboxProps={{ withinPortal: false }}\n data={getOperatorsForType(type).map((operator) => ({\n value: operator,\n label: labels.operators[operator],\n }))}\n value={value.operator}\n onChange={(next) =>\n next &&\n changeOperator(filter.id, next as TMDataGridFilterOperator)\n }\n />\n\n {takesArray && column ? (\n // The set the cell is tested against. Options come from\n // `meta.options`; a select column that declares none still\n // gets the values present in the data, via the faceted index.\n <MultiSelect\n label={labels.filterValue}\n size={controlSize}\n w={180}\n comboboxProps={{ withinPortal: false }}\n searchable\n data={optionsToComboboxData(\n resolveColumnOptions({ table, column, fallback: \"faceted\" }),\n )}\n value={Array.isArray(value.value) ? [...value.value] : []}\n onChange={(next) => patchFilter(filter.id, { value: next })}\n />\n ) : type === \"boolean\" ? (\n <Select\n label={labels.filterValue}\n size={controlSize}\n w={180}\n comboboxProps={{ withinPortal: false }}\n disabled={!needsValue}\n clearable\n placeholder={needsValue ? labels.filterValuePlaceholder : \"\"}\n data={[\n { value: \"true\", label: labels.booleanTrue },\n { value: \"false\", label: labels.booleanFalse },\n ]}\n value={needsValue && scalarValue !== \"\" ? scalarValue : null}\n onChange={(next) =>\n patchFilter(filter.id, { value: next ?? \"\" })\n }\n />\n ) : (\n <TextInput\n label={labels.filterValue}\n size={controlSize}\n w={180}\n type={\n !needsValue\n ? \"text\"\n : type === \"number\"\n ? \"number\"\n : type === \"date\"\n ? \"date\"\n : \"text\"\n }\n disabled={!needsValue}\n placeholder={needsValue ? labels.filterValuePlaceholder : \"\"}\n value={needsValue ? scalarValue : \"\"}\n onChange={(event) =>\n patchFilter(filter.id, { value: event.currentTarget.value })\n }\n />\n )}\n </div>\n );\n })}\n\n <div className={classes.filterPanelFooter}>\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n disabled={!canAddFilter}\n onClick={addFilter}\n >\n {labels.addFilter}\n </Button>\n <Button\n variant=\"subtle\"\n color=\"gray\"\n size=\"compact-sm\"\n disabled={columnFilters.length === 0}\n onClick={clearAllFilters}\n >\n {labels.clearAllFilters}\n </Button>\n </div>\n </Stack>\n </div>\n );\n}\n","/* Wraps rather than scrolls: the pills are a summary, and a summary that goes\n off-screen is not one. */\n.filterPills {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--mantine-spacing-xs);\n}\n\n/* Mantine's dark-scheme pill is `dark-7` — the same colour as the body — so a\n pill sitting on the page rather than inside a `PillsInput` disappears. Both\n schemes are restated here so the two stay a pair, with a border to keep the\n shape readable against any surface. Scoped through `.filterPills` for the\n specificity to beat Mantine's own rule whichever stylesheet loads last. */\n.filterPills .pill {\n background-color: light-dark(\n var(--mantine-color-gray-1),\n var(--mantine-color-dark-5)\n );\n color: light-dark(var(--mantine-color-black), var(--mantine-color-dark-0));\n border: 1px solid\n light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-3));\n}\n\n/* The label is a button so a pill can be clicked back open, but it must read as\n part of the pill — Mantine's own label styles carry the font. */\n.pillLabel {\n font: inherit;\n color: inherit;\n cursor: pointer;\n}\n\n.pillLabel:hover {\n text-decoration: underline;\n}\n","import {\n FILTER_OPERATOR_LABELS,\n type TMDataGridFilterOperator,\n} from \"./filterOperators\";\n\n/**\n * Every user-facing string in the grid — menu items, panels, tooltips, the\n * pager, and the `aria-label`s a screen reader speaks. One flat object, so an\n * override is a spread rather than a deep merge; `operators` is the single\n * nested record and {@link mergeLabels} folds it separately.\n *\n * Labels that carry a value are functions rather than template strings, so a\n * language is free to put the value wherever its grammar wants it.\n */\nexport type TMDataGridLabels = {\n /** Filter operator names, as shown in the operator dropdown and on pills. */\n operators: Record<TMDataGridFilterOperator, string>;\n\n // Toolbar\n /** \"Manage columns\" — the burger button and the header menu item. */\n manageColumns: string;\n /** \"Filters\" — the funnel button and the filter panel's title. */\n filters: string;\n searchPlaceholder: string;\n searchLabel: string;\n clearSearch: string;\n\n // Columns panel\n columnsSearchPlaceholder: string;\n columnsNoMatch: (search: string) => string;\n columnsShowHideAll: string;\n columnsReset: string;\n\n // Filter panel\n filterColumn: string;\n filterOperator: string;\n filterValue: string;\n filterValuePlaceholder: string;\n /** What a boolean column's `true` reads as — its filter choice and cell text. */\n booleanTrue: string;\n booleanFalse: string;\n addFilter: string;\n clearAllFilters: string;\n closeFilters: string;\n removeFilter: string;\n\n // Filter pills\n activeFilters: string;\n clearFilter: (column: string) => string;\n\n // Header menu\n sortAsc: string;\n sortDesc: string;\n filterMenuItem: string;\n groupBy: (column: string) => string;\n ungroup: (column: string) => string;\n expandAllGroups: string;\n collapseAllGroups: string;\n pinLeft: string;\n pinRight: string;\n unpin: string;\n moveLeft: string;\n moveRight: string;\n autosizeColumn: string;\n hideColumn: string;\n filterOn: (column: string) => string;\n sortColumn: (column: string) => string;\n columnMenu: (column: string) => string;\n\n // Footer / pager\n rowsPerPage: string;\n pageRange: (args: { from: number; to: number; total: number }) => string;\n groupedAllRows: (total: number) => string;\n pagingSuspendedHint: string;\n previousPage: string;\n nextPage: string;\n\n // Body\n noResults: string;\n loading: string;\n\n // Cell selection menu\n cellCount: (count: number) => string;\n copy: string;\n exportCsv: string;\n includeHeaders: string;\n\n // Generated checkbox lane\n selectColumnLabel: string;\n selectAllRows: string;\n selectRow: string;\n selectGroup: string;\n\n // Generated details lane\n detailsColumnLabel: string;\n showDetails: string;\n hideDetails: string;\n expandAllDetails: string;\n collapseAllDetails: string;\n\n // Generated tree lane\n groupColumnLabel: string;\n blankGroupValue: string;\n expandGroup: (label: string) => string;\n collapseGroup: (label: string) => string;\n};\n\n/**\n * What the `labels` option accepts: any subset, merged over the English\n * defaults — so `{ noResults: \"Inga rader\" }` is a complete configuration.\n */\nexport type TMDataGridLabelsOverride = Partial<\n Omit<TMDataGridLabels, \"operators\">\n> & {\n operators?: Partial<Record<TMDataGridFilterOperator, string>>;\n};\n\n/** The built-in defaults. Also the reference for what a preset must cover. */\nexport const TMDATAGRID_LABELS_EN: TMDataGridLabels = {\n operators: FILTER_OPERATOR_LABELS,\n\n manageColumns: \"Manage columns\",\n filters: \"Filters\",\n searchPlaceholder: \"Search\",\n searchLabel: \"Search rows\",\n clearSearch: \"Clear search\",\n\n columnsSearchPlaceholder: \"Search\",\n columnsNoMatch: (search) => `No columns match “${search}”`,\n columnsShowHideAll: \"Show/Hide All\",\n columnsReset: \"RESET\",\n\n filterColumn: \"Column\",\n filterOperator: \"Operator\",\n filterValue: \"Value\",\n filterValuePlaceholder: \"Filter value\",\n booleanTrue: \"Yes\",\n booleanFalse: \"No\",\n addFilter: \"Add filter\",\n clearAllFilters: \"Clear all\",\n closeFilters: \"Close filters\",\n removeFilter: \"Remove filter\",\n\n activeFilters: \"Active filters\",\n clearFilter: (column) => `Clear ${column} filter`,\n\n sortAsc: \"Sort by ASC\",\n sortDesc: \"Sort by DESC\",\n filterMenuItem: \"Filter\",\n groupBy: (column) => `Group by ${column}`,\n ungroup: (column) => `Ungroup ${column}`,\n expandAllGroups: \"Expand all groups\",\n collapseAllGroups: \"Collapse all groups\",\n pinLeft: \"Pin to left\",\n pinRight: \"Pin to right\",\n unpin: \"Unpin\",\n moveLeft: \"Move left\",\n moveRight: \"Move right\",\n autosizeColumn: \"Autosize column\",\n hideColumn: \"Hide column\",\n filterOn: (column) => `Filter on ${column}`,\n sortColumn: (column) => `Sort ${column}`,\n columnMenu: (column) => `${column} column menu`,\n\n rowsPerPage: \"Rows per page:\",\n pageRange: ({ from, to, total }) => `${from}–${to} of ${total}`,\n groupedAllRows: (total) => `Grouped · all ${total} rows`,\n pagingSuspendedHint:\n \"Paging is off while the rows are grouped: the whole tree is rendered and virtualized. Ungroup to page again.\",\n previousPage: \"Previous page\",\n nextPage: \"Next page\",\n\n noResults: \"No rows match your filters\",\n loading: \"Loading\",\n\n cellCount: (count) => (count === 1 ? \"1 cell\" : `${count} cells`),\n copy: \"Copy\",\n exportCsv: \"Export as CSV for Excel\",\n includeHeaders: \"Include headers\",\n\n selectColumnLabel: \"Checkbox selection\",\n selectAllRows: \"Select all rows\",\n selectRow: \"Select row\",\n selectGroup: \"Select group\",\n\n detailsColumnLabel: \"Details\",\n showDetails: \"Show details\",\n hideDetails: \"Hide details\",\n expandAllDetails: \"Expand all details\",\n collapseAllDetails: \"Collapse all details\",\n\n groupColumnLabel: \"Group\",\n blankGroupValue: \"(Blank)\",\n expandGroup: (label) => `Expand ${label}`,\n collapseGroup: (label) => `Collapse ${label}`,\n};\n\n/** A partial override folded over the English defaults. */\nexport function mergeLabels(\n override?: TMDataGridLabelsOverride,\n): TMDataGridLabels {\n if (!override) return TMDATAGRID_LABELS_EN;\n return {\n ...TMDATAGRID_LABELS_EN,\n ...override,\n operators: {\n ...TMDATAGRID_LABELS_EN.operators,\n ...override.operators,\n },\n };\n}\n","import type { TableState } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\ntype GridState = TableState<TMDataGridFeatures>;\n\n/**\n * Persistence deliberately does not use Mantine's `useLocalStorage`.\n *\n * That hook owns a piece of state and returns `[value, setValue]`. Here the\n * table already owns the state and storage only mirrors it, so routing writes\n * through the hook would keep a second copy and trigger a React state update on\n * every change, including every pointer move during a column resize. Its\n * defaults also work against this use: `getInitialValueInEffect: true` delivers\n * the stored value after mount, while `initialState` is only read on the first\n * render, and `sync: true` would let two open tabs overwrite each other's\n * column layout.\n *\n * The option vocabulary follows Mantine's: `StorageType` is its type, and\n * `serialize` / `deserialize` behave as they do in `UseStorageOptions`.\n */\n\n/**\n * State slices describing what the user is looking at. Derived from the data,\n * so they can go stale as it changes.\n */\nexport const DATA_STATE_SLICES = [\n \"columnFilters\",\n \"globalFilter\",\n \"sorting\",\n \"pagination\",\n // Which groups are open. Keyed by group ids built from the values themselves\n // (`department:Design`), so a restored entry for a group the data no longer\n // produces is simply never looked up.\n \"expanded\",\n] as const satisfies ReadonlyArray<keyof GridState>;\n\n/**\n * State slices describing how the user configured the grid. Independent of the\n * data, and the ones users notice losing.\n */\nexport const SETTINGS_STATE_SLICES = [\n \"columnVisibility\",\n \"columnSizing\",\n \"columnOrder\",\n \"columnPinning\",\n // Which columns the rows are grouped by. A settings slice rather than a data\n // one: it names columns, not values, so it survives the data changing under\n // it the way the column layout does.\n \"grouping\",\n] as const satisfies ReadonlyArray<keyof GridState>;\n\nexport type TMDataGridDataSlice = (typeof DATA_STATE_SLICES)[number];\nexport type TMDataGridSettingsSlice = (typeof SETTINGS_STATE_SLICES)[number];\n\n/**\n * A storage key, optionally narrowed to a subset of its group's slices.\n *\n * - `\"employees.data\"` — persists every slice in the group.\n * - `[\"employees.data\", [\"sorting\"]]` — persists only the listed slices.\n */\nexport type TMDataGridPersistKey<TSlice extends string> =\n | string\n | readonly [key: string, slices: readonly TSlice[]];\n\n/** Same values as Mantine's `StorageType`, which the package does not re-export. */\nexport type TMDataGridStorageMode = \"localStorage\" | \"sessionStorage\";\n\nexport type TMDataGridPersistence = {\n /** Key for filters, global filter, sorting and pagination. */\n dataKey?: TMDataGridPersistKey<TMDataGridDataSlice>;\n /** Key for column visibility, sizing, order and pinning. */\n settingsKey?: TMDataGridPersistKey<TMDataGridSettingsSlice>;\n /** Which storage area to use. Defaults to `\"localStorage\"`. */\n storageMode?: TMDataGridStorageMode;\n /** Serializes a payload before it is stored. Defaults to `JSON.stringify`. */\n serialize?: (value: Partial<GridState>) => string;\n /** Parses a stored payload. Defaults to `JSON.parse`. */\n deserialize?: (value: string) => unknown;\n};\n\ntype ResolvedKey = { key: string; slices: ReadonlyArray<keyof GridState> };\n\nfunction resolveKey<TSlice extends string>(\n entry: TMDataGridPersistKey<TSlice> | undefined,\n defaultSlices: ReadonlyArray<keyof GridState>,\n): ResolvedKey | null {\n if (!entry) return null;\n if (typeof entry === \"string\") return { key: entry, slices: defaultSlices };\n\n const [key, slices] = entry;\n if (!key) return null;\n // An empty list means nothing was selected, which is not the same as \"all\".\n return { key, slices: slices as ReadonlyArray<keyof GridState> };\n}\n\nfunction resolveStorage(\n persistence: TMDataGridPersistence | undefined,\n): Storage | null {\n if (!persistence) return null;\n // Absent under SSR, and access throws outright in some privacy modes.\n try {\n if (typeof window === \"undefined\") return null;\n return persistence.storageMode === \"sessionStorage\"\n ? window.sessionStorage\n : window.localStorage;\n } catch {\n return null;\n }\n}\n\n/**\n * Shape guards for restored state.\n *\n * A stored payload outlives the code that wrote it: a slice can change shape\n * between releases, and nothing stops anyone from editing storage by hand. The\n * value goes straight into `initialState`, where a wrong shape surfaces as a\n * crash inside TanStack rather than as a bad read here. A slice that fails its\n * guard is dropped; the rest still restore.\n */\nfunction prop(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)[key]\n : undefined;\n}\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isFinite(value);\n\nfunction isArrayOf(\n value: unknown,\n isItem: (item: unknown) => boolean,\n): boolean {\n return Array.isArray(value) && value.every(isItem);\n}\n\nfunction isRecordOf(\n value: unknown,\n isItem: (item: unknown) => boolean,\n): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n return Object.values(value).every(isItem);\n}\n\nconst hasStringId = (entry: unknown): boolean => isString(prop(entry, \"id\"));\n\nconst SLICE_GUARDS: Record<\n TMDataGridDataSlice | TMDataGridSettingsSlice,\n (value: unknown) => boolean\n> = {\n columnFilters: (value) => isArrayOf(value, hasStringId),\n // TanStack leaves the global filter value untyped — the grid's own default\n // filters on a string, but a consumer may store anything here.\n globalFilter: () => true,\n sorting: (value) =>\n isArrayOf(\n value,\n (entry) => hasStringId(entry) && typeof prop(entry, \"desc\") === \"boolean\",\n ),\n pagination: (value) => {\n const pageIndex = prop(value, \"pageIndex\");\n const pageSize = prop(value, \"pageSize\");\n return (\n isFiniteNumber(pageIndex) &&\n pageIndex >= 0 &&\n isFiniteNumber(pageSize) &&\n pageSize > 0\n );\n },\n // `true` is a legal ExpandedState of its own, meaning every row is open.\n expanded: (value) =>\n value === true || isRecordOf(value, (entry) => typeof entry === \"boolean\"),\n columnVisibility: (value) =>\n isRecordOf(value, (entry) => typeof entry === \"boolean\"),\n columnSizing: (value) => isRecordOf(value, isFiniteNumber),\n columnOrder: (value) => isArrayOf(value, isString),\n columnPinning: (value) =>\n isArrayOf(prop(value, \"left\"), isString) &&\n isArrayOf(prop(value, \"right\"), isString),\n grouping: (value) => isArrayOf(value, isString),\n};\n\nfunction isValidSlice(slice: keyof GridState, value: unknown): boolean {\n const guard = SLICE_GUARDS[slice as keyof typeof SLICE_GUARDS];\n return guard === undefined || guard(value);\n}\n\nfunction readSlices(\n storage: Storage | null,\n resolved: ResolvedKey | null,\n deserialize: (value: string) => unknown,\n): Partial<GridState> {\n if (!storage || !resolved) return {};\n try {\n const raw = storage.getItem(resolved.key);\n if (!raw) return {};\n const parsed = deserialize(raw);\n if (typeof parsed !== \"object\" || parsed === null) return {};\n\n const record = parsed as Record<string, unknown>;\n const restored: Record<string, unknown> = {};\n // Only copy the selected slices. A payload written before the selection was\n // narrowed cannot reintroduce slices the caller has since opted out of.\n for (const slice of resolved.slices) {\n if (!(slice in record)) continue;\n if (!isValidSlice(slice, record[slice])) continue;\n restored[slice] = record[slice];\n }\n return restored as Partial<GridState>;\n } catch {\n return {};\n }\n}\n\nfunction writeSlices(\n storage: Storage | null,\n resolved: ResolvedKey | null,\n state: GridState,\n serialize: (value: Partial<GridState>) => string,\n): void {\n if (!storage || !resolved) return;\n const payload: Record<string, unknown> = {};\n for (const slice of resolved.slices) payload[slice] = state[slice];\n try {\n storage.setItem(resolved.key, serialize(payload as Partial<GridState>));\n } catch {\n // Quota exceeded or storage disabled. Persistence is best effort.\n }\n}\n\nfunction resolveKeys(persistence: TMDataGridPersistence | undefined) {\n return {\n data: resolveKey(persistence?.dataKey, DATA_STATE_SLICES),\n settings: resolveKey(persistence?.settingsKey, SETTINGS_STATE_SLICES),\n };\n}\n\n/** True when at least one key is configured. */\nexport function hasPersistenceKeys(\n persistence: TMDataGridPersistence | undefined,\n): boolean {\n const { data, settings } = resolveKeys(persistence);\n return data !== null || settings !== null;\n}\n\nconst defaultDeserialize = (value: string): unknown => JSON.parse(value);\nconst defaultSerialize = (value: Partial<GridState>): string =>\n JSON.stringify(value);\n\n/** State to merge into `initialState`, read once on mount. */\nexport function readPersistedState(\n persistence?: TMDataGridPersistence,\n): Partial<GridState> {\n const storage = resolveStorage(persistence);\n const { data, settings } = resolveKeys(persistence);\n const deserialize = persistence?.deserialize ?? defaultDeserialize;\n return {\n ...readSlices(storage, settings, deserialize),\n ...readSlices(storage, data, deserialize),\n };\n}\n\n/** Writes both payloads. Called on every table state change. */\nexport function writePersistedState(\n state: GridState,\n persistence?: TMDataGridPersistence,\n): void {\n const storage = resolveStorage(persistence);\n if (!storage) return;\n const { data, settings } = resolveKeys(persistence);\n const serialize = persistence?.serialize ?? defaultSerialize;\n writeSlices(storage, data, state, serialize);\n writeSlices(storage, settings, state, serialize);\n}\n","import type { Column, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport { isColumnReorderable } from \"./columnUtils\";\nimport type {\n TMDataGridFeatures,\n TMDataGridTable,\n UseTMDataGridOptions,\n} from \"../useTMDataGrid\";\n\n/**\n * Table-level feature switches, read straight off the options object.\n *\n * Why not just call `column.getCanSort()` everywhere? Because that is a method\n * call on a `column` whose identity survives an options change, so the React\n * Compiler caches the result and the chrome keeps rendering for a feature that\n * was switched off. Reading the options into a fresh object each render gives\n * every derived value something that actually changes to invalidate on.\n *\n * TanStack still decides: these flags are combined with `getCanX()`, which is\n * what applies the per-column overrides.\n */\n/**\n * How rows are selected — see `selectionMode` on {@link UseTMDataGridOptions}.\n *\n * One axis, because the two things a config could set independently — which\n * chrome selects, and what a bare row click does — cannot both be free: a click\n * can either toggle a multi-selection or move the highlight, never both. Folding\n * them into one value makes that conflict unrepresentable rather than something\n * to warn about.\n */\nexport type TMDataGridSelectionMode =\n /** Checkbox column, multi-select. Clicking a row elsewhere does nothing. */\n | \"checkbox\"\n /** No checkbox column; row click multi-selects, with Ctrl/Shift modifiers. */\n | \"row\"\n /** Checkbox column multi-selects, and a row click highlights one row. */\n | \"checkboxAndHighlight\"\n /** No selection at all — a row click only highlights. Master-detail. */\n | \"highlight\";\n\n/**\n * How cells are selected — see `cellSelection` on {@link UseTMDataGridOptions}.\n *\n * A mode rather than a pair of booleans, for the reason\n * {@link TMDataGridSelectionMode} is one: \"cells can be selected\" and \"more\n * than one at a time\" are not independent, and a range that cannot be anchored\n * anywhere is not a state worth being able to write down.\n */\nexport type TMDataGridCellSelectionMode =\n /** No cell cursor at all. The body's tab stop stays on the row. */\n | \"none\"\n /** One cell takes the focus and the arrow keys move it. */\n | \"single\"\n /** As `\"single\"`, plus a rectangle: drag, Shift+click, Shift+arrows, Ctrl+C. */\n | \"range\";\n\nexport type TMDataGridFeatureFlags = {\n sorting: boolean;\n filtering: boolean;\n /** Whether the quick search may filter — `enableGlobalFilter`. */\n globalFiltering: boolean;\n hiding: boolean;\n pinning: boolean;\n resizing: boolean;\n ordering: boolean;\n /** Whether any row selection is possible. Off outright under `\"highlight\"`. */\n rowSelection: boolean;\n /** Defaults to `\"checkbox\"`. */\n selectionMode: TMDataGridSelectionMode;\n /** Whether the generated checkbox column is prepended. */\n selectColumn: boolean;\n /** Whether a bare row click toggles the selection. Only under `\"row\"`. */\n rowClickSelects: boolean;\n /**\n * Whether more than one row can be selected at once — TanStack's\n * `enableMultiRowSelection`. Off, the grid drops the select-all header\n * checkbox: TanStack's `toggleAllRowsSelected` only consults `getCanSelect`,\n * so that control would select every row and walk straight past the limit.\n *\n * A per-row predicate counts as on, since some rows may still multi-select.\n */\n multiRowSelection: boolean;\n /** Whether a selected row takes the highlight colour. Follows the mode. */\n showSelectedBackground: boolean;\n /**\n * The single highlighted row — clicking a row highlights it, for a detail\n * panel to follow. State of its own, not a slice of `rowSelection`, which is\n * what lets it coexist with a checkbox multi-selection.\n */\n highlightRow: boolean;\n /**\n * Whether cells can be selected at all. Off unless `cellSelection` asks for\n * it — it takes the body's tab stop off the row and puts it on a cell, and\n * reports the grid to assistive technology as a `grid` rather than a `table`,\n * which is a different promise about what the keyboard does.\n */\n cellSelection: boolean;\n /** Defaults to `\"none\"`. */\n cellSelectionMode: TMDataGridCellSelectionMode;\n /** Whether a rectangle of cells can be selected. Only under `\"range\"`. */\n cellRangeSelection: boolean;\n /**\n * The one default-off flag: pagination must be asked for, either with the\n * grid's `enablePagination` or implicitly by declaring `manualPagination`.\n * Off, the grid renders every filtered row and relies on virtualization.\n */\n pagination: boolean;\n /**\n * Row grouping: the \"Group by\" items in the header menu and the generated\n * tree column. On unless `enableGrouping: false`, since an ungrouped grid\n * looks and behaves exactly as it did before — `grouping` starts empty, and\n * an empty grouping state passes straight through the row model.\n *\n * The exception is `manualPagination`, where the client holds one page rather\n * than the whole set: grouping that page would build groups out of an\n * arbitrary slice and quietly show wrong counts. A server-side grid that does\n * its own grouping can still say `enableGrouping: true` to override.\n */\n grouping: boolean;\n};\n\nexport function readFeatureFlags<TData extends RowData>(\n options: Pick<\n UseTMDataGridOptions<TData>,\n | \"enableSorting\"\n | \"enableColumnFilters\"\n | \"enableGlobalFilter\"\n | \"enableHiding\"\n | \"enableColumnPinning\"\n | \"enableColumnResizing\"\n | \"enableColumnOrdering\"\n | \"enableRowSelection\"\n | \"enableMultiRowSelection\"\n | \"selectionMode\"\n | \"showSelectedBackground\"\n | \"cellSelection\"\n | \"enablePagination\"\n | \"manualPagination\"\n | \"enableGrouping\"\n >,\n): TMDataGridFeatureFlags {\n const selectionMode = options.selectionMode ?? \"checkbox\";\n const cellSelectionMode = options.cellSelection ?? \"none\";\n // `\"highlight\"` is the master-detail mode: no selection to speak of, so the\n // checkbox column and the click-to-select behaviour both fall away. Otherwise\n // `enableRowSelection` still has the final say, including its predicate form.\n const rowSelection =\n selectionMode !== \"highlight\" && options.enableRowSelection !== false;\n\n return {\n sorting: options.enableSorting !== false,\n filtering: options.enableColumnFilters !== false,\n globalFiltering: options.enableGlobalFilter !== false,\n hiding: options.enableHiding !== false,\n pinning: options.enableColumnPinning !== false,\n resizing: options.enableColumnResizing !== false,\n ordering: options.enableColumnOrdering !== false,\n rowSelection,\n selectionMode,\n selectColumn:\n rowSelection &&\n (selectionMode === \"checkbox\" || selectionMode === \"checkboxAndHighlight\"),\n rowClickSelects: rowSelection && selectionMode === \"row\",\n multiRowSelection: options.enableMultiRowSelection !== false,\n // In \"row\" mode the highlight *is* the feedback for a click, so it is on.\n // With checkboxes the box already says it, so it is off unless asked for.\n showSelectedBackground:\n options.showSelectedBackground ?? selectionMode === \"row\",\n highlightRow:\n selectionMode === \"checkboxAndHighlight\" || selectionMode === \"highlight\",\n cellSelection: cellSelectionMode !== \"none\",\n cellSelectionMode,\n cellRangeSelection: cellSelectionMode === \"range\",\n pagination:\n options.enablePagination === true || options.manualPagination === true,\n grouping: options.enableGrouping ?? options.manualPagination !== true,\n };\n}\n\n/**\n * What one column's header may offer.\n *\n * | Affordance | Turned off by |\n * | ---------- | ------------- |\n * | Sort arrow, Sort ASC/DESC | `enableSorting` (table or column) |\n * | Filter item, panel entry | `enableColumnFilters` / `enableColumnFilter` |\n * | Hide column | `enableHiding` (table or column) |\n * | Pin to left / right | `enableColumnPinning` / `enablePinning` |\n * | Resize dragging | `enableColumnResizing` / `enableResizing` |\n * | Header dragging, Move left / right | `enableColumnOrdering` / `meta.enableOrdering` |\n * | Group by / Ungroup | `enableGrouping` (table or column) |\n */\nexport type TMDataGridColumnCapabilities = {\n canSort: boolean;\n canFilter: boolean;\n canHide: boolean;\n canPin: boolean;\n canResize: boolean;\n canReorder: boolean;\n canGroup: boolean;\n};\n\nexport function getColumnCapabilities(\n column: Column<TMDataGridFeatures, TMDataGridRowData, unknown>,\n features: TMDataGridFeatureFlags,\n): TMDataGridColumnCapabilities {\n return {\n canSort: features.sorting && column.getCanSort(),\n canFilter: features.filtering && column.getCanFilter(),\n canHide: features.hiding && column.getCanHide(),\n canPin: features.pinning && column.getCanPin(),\n canResize: features.resizing && column.getCanResize(),\n // Ordering has no TanStack capability method — see isColumnReorderable.\n canReorder: features.ordering && isColumnReorderable(column),\n // `getCanGroup()` also insists on an accessor, which is what keeps the\n // generated checkbox and tree columns from offering to group on themselves.\n canGroup: features.grouping && column.getCanGroup(),\n };\n}\n\n/** The same questions, asked of the whole grid — used to hide toolbar buttons. */\nexport type TMDataGridCapabilities = {\n canSortAny: boolean;\n canFilterAny: boolean;\n canHideAny: boolean;\n canPinAny: boolean;\n canReorderAny: boolean;\n canGroupAny: boolean;\n canSelectRows: boolean;\n canPaginate: boolean;\n /** At least one leaf column takes part in the global quick search. */\n canSearch: boolean;\n};\n\nexport function getGridCapabilities(\n table: TMDataGridTable<TMDataGridRowData>,\n features: TMDataGridFeatureFlags,\n): TMDataGridCapabilities {\n const columns = table.getAllLeafColumns();\n const any = (predicate: (capabilities: TMDataGridColumnCapabilities) => boolean) =>\n columns.some((column) => predicate(getColumnCapabilities(column, features)));\n\n return {\n canSortAny: any((c) => c.canSort),\n canFilterAny: any((c) => c.canFilter),\n canHideAny: any((c) => c.canHide),\n canPinAny: any((c) => c.canPin),\n canReorderAny: any((c) => c.canReorder),\n canGroupAny: any((c) => c.canGroup),\n canSelectRows: features.rowSelection,\n canPaginate: features.pagination,\n canSearch:\n features.globalFiltering &&\n columns.some((column) => column.getCanGlobalFilter()),\n };\n}\n","/**\n * Which cell has the focus, by id rather than by position.\n *\n * Ids, because every other thing the grid does moves cells around: sorting\n * reorders rows, filtering removes them, dragging a header reorders columns. A\n * coordinate pair would silently come to mean a different cell after any of\n * them, while a pair of ids either still resolves or does not resolve at all —\n * and \"does not resolve\" is a state the grid can handle honestly.\n *\n * Indices are what navigation is actually computed in, so they are resolved\n * from the ids on each keystroke and turned straight back. See resolveCellMove.\n */\nexport type TMDataGridCellPosition = {\n rowId: string;\n columnId: string;\n};\n\n/** Where the focused cell sits in the rows and columns on screen. */\nexport type TMDataGridCellCoords = {\n rowIndex: number;\n columnIndex: number;\n};\n\nexport type ResolveCellMoveArgs = {\n /** `KeyboardEvent.key`. */\n key: string;\n /** Ctrl or Cmd — Home and End jump to the corner rather than the row end. */\n ctrlKey: boolean;\n from: TMDataGridCellCoords;\n rowCount: number;\n columnCount: number;\n /**\n * How far PageUp and PageDown travel: one viewport of rows. Passed in rather\n * than assumed, since only the body knows how tall it is.\n */\n pageRows: number;\n};\n\nconst clamp = (value: number, max: number) =>\n Math.min(Math.max(value, 0), Math.max(max, 0));\n\n/**\n * The next cell for a navigation key, or `null` when the key is not one.\n *\n * Moves clamp at the edges instead of wrapping. Wrapping suits a menu, where\n * the items are a short ring; a grid is a coordinate space, and a Right at the\n * last column that lands on the first column of the next row loses the one\n * thing arrow keys are for — knowing where you will end up without looking.\n *\n * A clamped move returns the position it started from rather than `null`. The\n * caller still needs to know the key was handled: an arrow at the last row must\n * not fall through to the scroll container, which would scroll the body out\n * from under a focus that did not move.\n */\nexport function resolveCellMove({\n key,\n ctrlKey,\n from,\n rowCount,\n columnCount,\n pageRows,\n}: ResolveCellMoveArgs): TMDataGridCellCoords | null {\n if (rowCount === 0 || columnCount === 0) return null;\n\n const lastRow = rowCount - 1;\n const lastColumn = columnCount - 1;\n const at = (rowIndex: number, columnIndex: number): TMDataGridCellCoords => ({\n rowIndex: clamp(rowIndex, lastRow),\n columnIndex: clamp(columnIndex, lastColumn),\n });\n\n switch (key) {\n case \"ArrowDown\":\n return at(from.rowIndex + 1, from.columnIndex);\n case \"ArrowUp\":\n return at(from.rowIndex - 1, from.columnIndex);\n case \"ArrowRight\":\n return at(from.rowIndex, from.columnIndex + 1);\n case \"ArrowLeft\":\n return at(from.rowIndex, from.columnIndex - 1);\n case \"PageDown\":\n return at(from.rowIndex + Math.max(pageRows, 1), from.columnIndex);\n case \"PageUp\":\n return at(from.rowIndex - Math.max(pageRows, 1), from.columnIndex);\n // Ctrl+Home / Ctrl+End address the grid, plain Home / End the row — the\n // convention every spreadsheet and APG's own grid pattern share.\n case \"Home\":\n return ctrlKey ? at(0, 0) : at(from.rowIndex, 0);\n case \"End\":\n return ctrlKey ? at(lastRow, lastColumn) : at(from.rowIndex, lastColumn);\n default:\n return null;\n }\n}\n\n/** Whether two positions address the same cell. `null` equals only `null`. */\nexport function isSameCell(\n a: TMDataGridCellPosition | null,\n b: TMDataGridCellPosition | null,\n): boolean {\n if (a === null || b === null) return a === b;\n return a.rowId === b.rowId && a.columnId === b.columnId;\n}\n","import { useCreateStore } from \"@tanstack/react-store\";\nimport {\n aggregationFns,\n type ColumnDef,\n columnFacetingFeature,\n columnFilteringFeature,\n columnGroupingFeature,\n columnOrderingFeature,\n columnPinningFeature,\n columnResizingFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createColumnHelper,\n createExpandedRowModel,\n createFacetedMinMaxValues,\n createFacetedRowModel,\n createFacetedUniqueValues,\n createFilteredRowModel,\n createGroupedRowModel,\n createPaginatedRowModel,\n createSortedRowModel,\n filterFns,\n globalFilteringFeature,\n metaHelper,\n type Row,\n type RowData,\n rowExpandingFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n rowSortingFeature,\n sortFns,\n type Table,\n tableFeatures,\n type TableOptions,\n type TableState,\n useTable,\n} from \"@tanstack/react-table\";\nimport type { Store } from \"@tanstack/store\";\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { TMDataGridOptionsSource } from \"./core/columnOptions\";\nimport {\n type TMDataGridColumnType,\n tmDataGridFilterFn,\n getDefaultOperator,\n} from \"./core/filterOperators\";\nimport {\n mergeLabels,\n type TMDataGridLabels,\n type TMDataGridLabelsOverride,\n} from \"./core/labels\";\nimport {\n hasPersistenceKeys,\n readPersistedState,\n type TMDataGridPersistence,\n writePersistedState,\n} from \"./core/persistence\";\nimport {\n readFeatureFlags,\n type TMDataGridCellSelectionMode,\n type TMDataGridFeatureFlags,\n type TMDataGridSelectionMode,\n} from \"./core/capabilities\";\nimport {\n isSameCell,\n type TMDataGridCellPosition,\n} from \"./core/cellNavigation\";\nimport type { TMDataGridCellRange } from \"./core/cellRange\";\nimport {\n createSelectColumn,\n SELECT_COLUMN_ID,\n} from \"./components/TMDataGridSelectColumn\";\nimport {\n createGroupColumn,\n GROUP_COLUMN_ID,\n} from \"./components/TMDataGridGroupColumn\";\nimport {\n createDetailsColumn,\n DETAILS_COLUMN_ID,\n} from \"./components/TMDataGridDetailsColumn\";\n\n/**\n * How long the grid waits after the last state change before writing to\n * storage. Long enough to collapse a resize drag into one write, short enough\n * that a reload right after a change still sees it.\n */\nconst PERSIST_DEBOUNCE_MS = 200;\n\n/** Per-column configuration the TMDataGrid chrome reads. */\nexport type TMDataGridColumnMeta = {\n /** Name shown in menus and the column manager. Falls back to a string header. */\n label?: string;\n /**\n * Drives which filter operators are offered and, once editing is on, which\n * editor the cell opens. Defaults to `\"string\"`.\n */\n type?: TMDataGridColumnType;\n /**\n * The choices of a `select` / `multiSelect` column — one declaration feeding\n * the filter panel's value control and the cell editor alike. A static\n * array, `\"faceted\"` (the distinct values present in the data), or a\n * function of the table, column and — for editors — the row. See\n * {@link TMDataGridOptionsSource}.\n */\n options?: TMDataGridOptionsSource;\n /** Share of the leftover width this column claims. Defaults to `1`. */\n flex?: number;\n align?: \"left\" | \"right\" | \"center\";\n /**\n * Size the column to its widest mounted content once, after the first rows\n * render — unless a persisted or user-set width already covers it. The same\n * measurement as double-clicking the resize divider; see `autosizeColumn`.\n */\n autoSize?: boolean;\n /**\n * `false` keeps the column where it is: no header dragging, no move items.\n * Column ordering is the one feature TanStack defines no column option for,\n * so its switch lives here rather than on the column definition.\n */\n enableOrdering?: boolean;\n};\n\n/** Grid-wide configuration passed through `options.meta`. */\nexport type TMDataGridTableMeta = {\n loading?: boolean;\n noResultsLabel?: string;\n /** Row height used by the virtualizer. Defaults to `52`. */\n rowHeight?: number;\n /**\n * Unfiltered row total. Only needed for server-driven grids, where the client\n * never holds the full data set — `TMDataGrid.SummaryCount` uses it as denominator.\n */\n totalRowCount?: number;\n};\n\n/**\n * Every feature the TMDataGrid chrome can drive. Defined at module scope so the\n * reference stays stable across renders (see the TanStack table-state skill).\n */\nexport const tmDataGridFeatures = tableFeatures({\n columnFilteringFeature,\n globalFilteringFeature,\n rowSortingFeature,\n rowPaginationFeature,\n rowSelectionFeature,\n columnPinningFeature,\n columnVisibilityFeature,\n columnOrderingFeature,\n columnSizingFeature,\n columnResizingFeature,\n columnFacetingFeature,\n columnGroupingFeature,\n // Registered for grouping's sake rather than for tree data: the grouped row\n // model builds the parent rows, and this is what flattens the expanded ones\n // back into the flat list the body virtualizes.\n rowExpandingFeature,\n\n filteredRowModel: createFilteredRowModel(),\n groupedRowModel: createGroupedRowModel(),\n sortedRowModel: createSortedRowModel(),\n expandedRowModel: createExpandedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n facetedRowModel: createFacetedRowModel(),\n facetedMinMaxValues: createFacetedMinMaxValues(),\n facetedUniqueValues: createFacetedUniqueValues(),\n\n filterFns: { ...filterFns, tmDataGrid: tmDataGridFilterFn },\n sortFns,\n // The names `columnDef.aggregationFn` accepts. Only consulted for columns\n // that ask for one — a column with no `aggregationFn` reports `undefined` on\n // a group row, which is what keeps a plain \"group by\" free of aggregates.\n aggregationFns,\n\n tableMeta: metaHelper<TMDataGridTableMeta>(),\n columnMeta: metaHelper<TMDataGridColumnMeta>(),\n});\n\nexport type TMDataGridFeatures = typeof tmDataGridFeatures;\n\nexport type TMDataGridTable<TData extends RowData> = Table<\n TMDataGridFeatures,\n TData\n>;\n\nexport function createTMDataGridColumnHelper<TData extends RowData>() {\n return createColumnHelper<TMDataGridFeatures, TData>();\n}\n\n/** What the `renderDetails` render prop is handed for an expanded row. */\nexport type TMDataGridDetailsArgs<TData extends RowData> = {\n row: Row<TMDataGridFeatures, TData>;\n table: TMDataGridTable<TData>;\n};\n\n/** Builds the panel shown underneath an expanded row. See `renderDetails`. */\nexport type TMDataGridDetailsRenderer<TData extends RowData> = (\n args: TMDataGridDetailsArgs<TData>,\n) => ReactNode;\n\n/**\n * What the virtualizer assumes a detail panel it has not measured yet is worth.\n * Only a seed — every mounted row is measured, so the real height replaces it.\n */\nconst DEFAULT_DETAILS_EST_HEIGHT = 160;\n\n/** Rows kept mounted on each side of the viewport. See `overscan`. */\nconst DEFAULT_OVERSCAN = 6;\n\n/**\n * Chrome state that is *not* table state: which panels are open, and which\n * column opened the filter panel. Kept in a TanStack Store so consumers can\n * subscribe to it the same way they subscribe to `table.store`.\n */\nexport type TMDataGridUiState = {\n filterPanelOpen: boolean;\n columnsPanelOpen: boolean;\n /** Column whose filter row should be focused when the panel opens. */\n filterPanelColumnId: string | null;\n /**\n * Column being dragged by its header, if any. Held here rather than read from\n * `dataTransfer`, which browsers keep unreadable until the drop.\n */\n draggedColumnId: string | null;\n /**\n * The single highlighted row — the one a detail panel would be showing. Its\n * own concept, not a slice of `rowSelection`: under\n * `selectionMode: \"checkboxAndHighlight\"` the two coexist, and TanStack's one\n * selection map cannot hold both.\n *\n * Not pruned when the row is filtered out, paged away or dropped from `data`,\n * matching how TanStack treats `rowSelection` — nothing there resets it\n * either. The row simply renders unhighlighted, and highlights again if it\n * comes back.\n */\n highlightedRowId: string | null;\n /** The pivot a shift-click extends from. See resolveRowSelectionClick. */\n selectionAnchorRowId: string | null;\n /**\n * The cell the keyboard is on, under `enableCellSelection`. `null` until the\n * grid is first entered — and again whenever a consumer clears it.\n *\n * The state is the source of truth and DOM focus follows it, not the other\n * way around: under virtualization the cell it names is often not mounted,\n * which is exactly what a coordinate has to survive. Held as ids for the\n * same reason — see {@link TMDataGridCellPosition}.\n */\n focusedCell: TMDataGridCellPosition | null;\n /**\n * The selected rectangle, under `cellSelection: \"range\"`. Held as the two\n * cells that span it — see {@link TMDataGridCellRange}.\n *\n * Always covers the focused cell: every gesture that moves the focus either\n * extends the rectangle or collapses it onto the new cell, so the two never\n * describe different places.\n */\n cellRange: TMDataGridCellRange | null;\n};\n\nexport type TMDataGridUiActions = {\n openFilterPanel: (columnId?: string | null) => void;\n closeFilterPanel: () => void;\n setColumnsPanelOpen: (open: boolean) => void;\n toggleColumnsPanel: () => void;\n startColumnDrag: (columnId: string) => void;\n endColumnDrag: () => void;\n /**\n * Moves the active row, or clears it with `null` — which is how a consumer\n * closing its detail panel puts the grid back in step.\n */\n setHighlightedRow: (rowId: string | null) => void;\n setSelectionAnchor: (rowId: string | null) => void;\n /**\n * Moves the focused cell, or clears it with `null`. DOM focus follows while\n * the grid holds it — so this both moves the keyboard and, when the row is\n * off screen, scrolls it into view. Called for every arrow key, and available\n * for a consumer putting the keyboard somewhere itself.\n */\n setFocusedCell: (cell: TMDataGridCellPosition | null) => void;\n /**\n * Sets the selected rectangle, or clears it with `null`. Does not move the\n * focused cell — the two are set together by the gestures that change both,\n * which is what keeps \"extend the selection\" and \"move the cursor\" separable.\n */\n setCellRange: (range: TMDataGridCellRange | null) => void;\n};\n\nexport type TMDataGridUiStore = Store<TMDataGridUiState, TMDataGridUiActions>;\n\n/** What `useTMDataGrid` returns — spread straight onto `<TMDataGrid />`. */\nexport type TMDataGridApi<TData extends RowData> = {\n table: TMDataGridTable<TData>;\n ui: TMDataGridUiStore;\n /** Table-level feature switches, re-read from options on every render. */\n features: TMDataGridFeatureFlags;\n /** Every string the chrome renders, `labels` merged over the English defaults. */\n labels: TMDataGridLabels;\n /** The detail renderer, when row details are on. See `renderDetails`. */\n renderDetails?: TMDataGridDetailsRenderer<TData>;\n /** Detail estimate in px: the option, or {@link DEFAULT_DETAILS_EST_HEIGHT}. */\n renderDetailsEstHeight: number;\n /** Virtualizer overscan: the option, or {@link DEFAULT_OVERSCAN}. */\n overscan: number;\n};\n\nexport type UseTMDataGridOptions<TData extends RowData> = Omit<\n TableOptions<TMDataGridFeatures, TData>,\n \"features\"\n> & {\n /**\n * Restore and persist table state across mounts. Two keys, because the two\n * kinds of state have different lifetimes — see {@link TMDataGridPersistence}.\n *\n * Keep the object referentially stable (module scope or `useMemo`); it is a\n * dependency of the subscription that writes back.\n */\n persist?: TMDataGridPersistence;\n /**\n * Overrides for the grid's strings — menu items, panels, the pager, and\n * every `aria-label`. Any subset, merged over the English defaults; a full\n * Swedish dictionary ships as `TMDATAGRID_LABELS_SV`.\n *\n * ```tsx\n * useTMDataGrid({ data, columns, labels: TMDATAGRID_LABELS_SV });\n * useTMDataGrid({ data, columns, labels: { noResults: \"Inga rader\" } });\n * ```\n *\n * Keep the object referentially stable (module scope or `useMemo`) — the\n * chrome re-renders when its identity changes.\n */\n labels?: TMDataGridLabelsOverride;\n /**\n * Header drag-and-drop and the move items in the column menu. Defaults to\n * `true`.\n *\n * The one feature switch the grid defines itself: TanStack's\n * `columnOrderingFeature` ships state and APIs but no `enable` option, since\n * reordering is entirely a matter of interface.\n */\n enableColumnOrdering?: boolean;\n /**\n * Client-side pagination and the built-in `TMDataGrid.Footer` pager.\n * Defaults to `false`: the grid renders every filtered row and relies on\n * virtualization.\n *\n * The second grid-defined switch (TanStack defines no `enablePagination`\n * option). `manualPagination: true` implies it — a server-paged grid needs\n * no extra flag.\n */\n enablePagination?: boolean;\n /**\n * How rows are selected. Defaults to `\"checkbox\"`.\n *\n * | Mode | Checkbox column | Row click |\n * | ---- | --------------- | --------- |\n * | `\"checkbox\"` | yes, multi-select | nothing |\n * | `\"row\"` | no | multi-selects, Ctrl/Shift modifiers |\n * | `\"checkboxAndHighlight\"` | yes, multi-select | highlights one row |\n * | `\"highlight\"` | no | highlights one row, no selection at all |\n *\n * One option rather than two, so the combination that cannot work — a click\n * that both toggles a multi-selection and moves the highlight — is not\n * expressible.\n *\n * The first two write to TanStack's `rowSelection`. The highlight is separate\n * state, which is what lets `\"checkboxAndHighlight\"` run both at once: tick\n * rows for a bulk action, click one to open its detail panel. See\n * `defaultHighlightedRowId` / `onHighlightedRowChange`.\n *\n * `enableRowSelection` still gates the selection half, predicate form\n * included; under `\"highlight\"` there is nothing for it to gate.\n */\n selectionMode?: TMDataGridSelectionMode;\n /**\n * Give selected rows the highlight background. Defaults to `true` under\n * `selectionMode: \"row\"`, where the highlight is the only feedback a click\n * gives, and `false` under `\"checkbox\"`, where the box already shows it.\n *\n * The colour is the `--dg-row-selected-bg` CSS variable, so it can be changed\n * without turning the flag on or off:\n *\n * ```tsx\n * <TMDataGrid\n * {...grid}\n * style={{ \"--dg-row-selected-bg\": \"var(--mantine-color-blue-0)\" }}\n * />\n * ```\n */\n showSelectedBackground?: boolean;\n /**\n * The row that starts out highlighted, under a `selectionMode` that has a\n * highlight. Read once on mount, like `initialState`.\n *\n * The grid never persists the highlighted row. Pair this with\n * {@link onHighlightedRowChange} and keep it wherever it belongs — for a\n * detail panel that is usually the route, which gets you a shareable link and\n * a working back button as well as surviving a reload:\n *\n * ```tsx\n * const { rowId } = useParams();\n * useTMDataGrid({\n * selectionMode: \"highlight\",\n * defaultHighlightedRowId: rowId,\n * onHighlightedRowChange: (id) => navigate(id ? `/employees/${id}` : \"/employees\"),\n * });\n * ```\n */\n defaultHighlightedRowId?: string | null;\n /**\n * Called with the newly highlighted row id, or `null` when it is cleared.\n * Fires for `ui.actions.setHighlightedRow` too, not only for clicks.\n */\n onHighlightedRowChange?: (rowId: string | null) => void;\n /**\n * How cells are selected. Defaults to `\"none\"`.\n *\n * | Mode | What it gives |\n * | ---- | ------------- |\n * | `\"none\"` | nothing; the body's tab stop stays on the row |\n * | `\"single\"` | one focused cell, moved with the arrow keys |\n * | `\"range\"` | as `\"single\"`, plus a rectangle of cells |\n *\n * Under either live mode:\n *\n * | Key | Moves to |\n * | --- | --- |\n * | Arrows | the neighbouring cell, clamped at the edges |\n * | PageUp / PageDown | one viewport of rows |\n * | Home / End | first / last cell of the row |\n * | Ctrl+Home / Ctrl+End | first / last cell of the grid |\n * | Enter or F2 | into the cell — the checkbox, link or button it holds |\n * | Escape | back out to the cell |\n * | Space | selects the row, as it does in row-selection mode |\n *\n * And under `\"range\"`, additionally:\n *\n * | Gesture | Does |\n * | ------- | ---- |\n * | Drag across cells | selects the rectangle they span |\n * | Shift+click, Shift+arrows | extends the rectangle from its anchor |\n * | Ctrl+C | copies it as tab-separated text — paste lands in Excel's cells |\n * | Right-click inside it | offers the CSV export, headers optional |\n *\n * Off, nothing about the body changes. On, three things do: the body's tab\n * stop moves from the row to a cell, so the whole grid is one Tab stop; the\n * grid reports itself as a `grid` of `gridcell`s rather than a `table` of\n * `cell`s, which is what tells a screen reader the arrow keys are live; and\n * the cells take `data-focused` / `data-selected` for the ring and the tint.\n *\n * The state is `ui.state.focusedCell` and `ui.state.cellRange`, and moving it\n * is `ui.actions.setFocusedCell` / `setCellRange` — so a consumer can put the\n * keyboard on a cell, or follow it:\n *\n * ```tsx\n * const grid = useTMDataGrid({\n * data,\n * columns,\n * cellSelection: \"range\",\n * onFocusedCellChange: (cell) => setStatus(cell?.columnId ?? \"\"),\n * });\n * ```\n *\n * Ids rather than a row/column index pair, so sorting, filtering and column\n * reordering move the selection with the cells instead of leaving it over\n * whatever slid into those positions.\n */\n cellSelection?: TMDataGridCellSelectionMode;\n /**\n * Called with the newly focused cell, or `null` when it is cleared. Fires for\n * `ui.actions.setFocusedCell` too, not only for keys and clicks.\n */\n onFocusedCellChange?: (cell: TMDataGridCellPosition | null) => void;\n /**\n * Renders a panel underneath an expanded row, spanning every column. Setting\n * it is what turns row details on.\n *\n * Which rows are open is TanStack's own `expanded` state, so opening one is\n * `row.toggleExpanded()` from wherever suits — a chevron in a cell, a button\n * in the context menu, a double-click:\n *\n * ```tsx\n * const grid = useTMDataGrid({\n * data,\n * columns,\n * renderDetails: ({ row }) => <EmployeeCard employee={row.original} />,\n * });\n * ```\n *\n * The panel is as tall as what it renders — see {@link renderDetailsEstHeight}\n * for what the virtualizer assumes before it has measured one.\n *\n * Group rows are left out: expanding one opens its children, and a panel there\n * would be about an arbitrary one of them. The same reason they sit out\n * `onRowClick`.\n *\n * Row details and `selectionMode: \"highlight\"` are two answers to the same\n * question. Details keep the record in place and in context, which suits a few\n * fields or an action strip; a highlight-driven side panel has room for more\n * and survives scrolling. Nothing stops a grid from doing both.\n */\n renderDetails?: TMDataGridDetailsRenderer<TData>;\n /**\n * What the virtualizer assumes an unmeasured detail panel is worth, in px.\n * Defaults to 160.\n *\n * An estimate, not a height: every mounted row is measured, so the real one\n * takes over as soon as the panel is on screen. It keeps the scrollbar honest\n * for panels that open off screen — restored `expanded` state, say — and being\n * roughly right is enough.\n */\n renderDetailsEstHeight?: number;\n /**\n * Rows the virtualizer keeps mounted above and below the viewport. Defaults\n * to 6.\n *\n * Raise it to trade memory for a scroll that stays painted — fast wheel or\n * touch flings can outrun the virtualizer and flash blank rows, and a larger\n * buffer covers the gap. Lower it when rows are expensive to render.\n */\n overscan?: number;\n};\n\ntype TMDataGridColumnDef<TData extends RowData> = ColumnDef<\n TMDataGridFeatures,\n TData,\n unknown\n>;\n\n/**\n * Point every column at the operator-dispatching filter function, and take\n * grouping's aggregation defaults back off, unless the column opted into its\n * own. Anything the consumer set wins — it is spread over these.\n *\n * The aggregation pair needs explaining. TanStack's grouping feature hands\n * every column `aggregationFn: \"auto\"` and an `aggregatedCell` that stringifies\n * whatever comes out, so merely registering the feature would have every\n * numeric column silently sum itself and every date column show a range the\n * moment anything is grouped. That is a summary table, and \"group by\" is not a\n * request for one. Cleared here, so a grouped grid is a tree until a column\n * says otherwise — `aggregationFn: \"sum\"` on the column that wants it.\n */\nfunction withTMDataGridDefaults<TData extends RowData>(\n columns: ReadonlyArray<TMDataGridColumnDef<TData>>,\n): Array<TMDataGridColumnDef<TData>> {\n return columns.map((column) => {\n if (\"columns\" in column && Array.isArray(column.columns)) {\n return {\n ...column,\n columns: withTMDataGridDefaults<TData>(column.columns),\n };\n }\n return {\n filterFn: \"tmDataGrid\",\n aggregationFn: undefined,\n aggregatedCell: undefined,\n ...column,\n } as TMDataGridColumnDef<TData>;\n });\n}\n\n/**\n * Builds a TMDataGrid table plus its chrome store.\n *\n * Every `TableOptions` field passes straight through, so a server-driven grid\n * only needs `manualPagination` / `manualFiltering` / `manualSorting`,\n * `rowCount` and the matching `onXChange` callbacks — the chrome reads\n * `getRowCount()` / `getPageCount()` / `getPaginatedRowModel()`, all of which\n * already respect manual mode. `manualPagination` also switches the pagination\n * flag on, so `<TMDataGrid.Footer />` renders its pager without further\n * options.\n */\nexport function useTMDataGrid<TData extends RowData>({\n persist,\n // Not TanStack options, so they are kept out of what `useTable` receives.\n labels: labelsOverride,\n enableColumnOrdering,\n enablePagination,\n selectionMode,\n showSelectedBackground,\n defaultHighlightedRowId,\n onHighlightedRowChange,\n cellSelection,\n onFocusedCellChange,\n renderDetails,\n renderDetailsEstHeight = DEFAULT_DETAILS_EST_HEIGHT,\n overscan = DEFAULT_OVERSCAN,\n ...options\n}: UseTMDataGridOptions<TData>): TMDataGridApi<TData> {\n // Derived up here, rather than just before the return, because the rest of the\n // hook needs `selectColumn` — one place decides what each mode means.\n //\n // Deliberately not memoized on `table`: the flags must re-derive whenever the\n // caller passes different options, and `table` keeps the same identity when\n // they do. See readFeatureFlags.\n const features = readFeatureFlags({\n ...options,\n enableColumnOrdering,\n enablePagination,\n selectionMode,\n showSelectedBackground,\n cellSelection,\n });\n\n // Resolved on the override's identity, so a module-scope dictionary costs one\n // merge for the lifetime of the grid.\n const labels = useMemo(() => mergeLabels(labelsOverride), [labelsOverride]);\n\n const pinningEnabled = options.enableColumnPinning !== false;\n const selectColumnEnabled = features.selectColumn;\n const groupColumnEnabled = features.grouping;\n // The lane that opens the panels. Nothing to switch on: a grid with no\n // `renderDetails` has nothing for it to open.\n const detailsColumnEnabled = renderDetails !== undefined;\n\n // The generated lanes bake `meta.label` into their definitions, so the memo\n // depends on the three strings rather than on the labels object — a fresh\n // inline `labels` must not rebuild the table's columns.\n const selectColumnLabel = labels.selectColumnLabel;\n const groupColumnLabel = labels.groupColumnLabel;\n const detailsColumnLabel = labels.detailsColumnLabel;\n\n const columns = useMemo(() => {\n const base = withTMDataGridDefaults<TData>(\n options.columns as ReadonlyArray<TMDataGridColumnDef<TData>>,\n );\n // Every generated column is present whenever its feature is on, and the\n // tree column hides itself while nothing is grouped. Adding it to the array\n // only once a column is grouped would make the column list depend on table\n // state, which is the one thing that cannot be a `useMemo` dependency here\n // — the table is built from these columns.\n //\n // The order is the order they are pinned in, and it follows what each one\n // is about: tick a row, find it in the tree the user grouped it into, then\n // open it. The details chevron sits last because it acts on the record the\n // lanes to its left have narrowed down to.\n return [\n ...(selectColumnEnabled\n ? [createSelectColumn<TData>(selectColumnLabel)]\n : []),\n ...(groupColumnEnabled ? [createGroupColumn<TData>(groupColumnLabel)] : []),\n ...(detailsColumnEnabled\n ? [createDetailsColumn<TData>(detailsColumnLabel)]\n : []),\n ...base,\n ];\n }, [\n options.columns,\n selectColumnEnabled,\n detailsColumnEnabled,\n groupColumnEnabled,\n selectColumnLabel,\n groupColumnLabel,\n detailsColumnLabel,\n ]);\n\n // Read once on mount: `initialState` is only consumed on the first render,\n // and re-reading later would fight the user's live edits.\n const [persistedState] = useState(() => readPersistedState(persist));\n\n // Restored grouping decides whether the tree column starts out visible, so a\n // reload comes back to the tree the user left rather than to a hidden lane.\n const initialGrouping =\n persistedState.grouping ?? options.initialState?.grouping ?? [];\n\n const table = useTable({\n columnResizeMode: \"onChange\",\n enableSorting: true,\n enableColumnResizing: true,\n globalFilterFn: \"includesString\",\n // Grouping by a column takes it out of the grid, the way AG Grid does it:\n // its values have moved into the tree column, so leaving it in place would\n // show every row the same value it was grouped under. Overridable — pass\n // `\"reorder\"` to keep the column and have it moved to the front instead.\n groupedColumnMode: \"remove\",\n ...options,\n // Row details ride on `expanded`, the same state the tree uses — but a data\n // row answers `getCanExpand()` false, since TanStack's fallback is\n // `subRows.length > 0`. `() => true` is the right answer for a group row\n // too, so nothing here has to tell the two apart, and a consumer passing\n // their own predicate still wins.\n ...(renderDetails !== undefined\n ? { getRowCanExpand: options.getRowCanExpand ?? (() => true) }\n : {}),\n features: tmDataGridFeatures,\n columns: columns as TableOptions<TMDataGridFeatures, TData>[\"columns\"],\n initialState: {\n ...options.initialState,\n ...persistedState,\n columnVisibility: {\n ...options.initialState?.columnVisibility,\n ...persistedState.columnVisibility,\n // Last word, because the tree column's visibility is not a user setting\n // — it tracks the grouping state. See the effect below.\n ...(groupColumnEnabled\n ? { [GROUP_COLUMN_ID]: initialGrouping.length > 0 }\n : {}),\n },\n columnPinning: {\n // The generated columns are structurally pinned, so they are re-applied\n // on top of anything restored from storage.\n left: [\n ...(selectColumnEnabled && pinningEnabled ? [SELECT_COLUMN_ID] : []),\n ...(groupColumnEnabled && pinningEnabled ? [GROUP_COLUMN_ID] : []),\n ...(detailsColumnEnabled && pinningEnabled ? [DETAILS_COLUMN_ID] : []),\n ...(\n persistedState.columnPinning?.left ??\n options.initialState?.columnPinning?.left ??\n []\n ).filter(\n (id) =>\n id !== SELECT_COLUMN_ID &&\n id !== DETAILS_COLUMN_ID &&\n id !== GROUP_COLUMN_ID,\n ),\n ],\n right:\n persistedState.columnPinning?.right ??\n options.initialState?.columnPinning?.right ??\n [],\n },\n pagination: {\n pageIndex: 0,\n pageSize: 25,\n ...options.initialState?.pagination,\n ...persistedState.pagination,\n },\n },\n });\n\n // Two things have to happen whenever `grouping` changes.\n //\n // One: the tree column appears with the first grouped column and goes away\n // with the last, so an ungrouped grid looks exactly as it did before grouping\n // existed. Driven from a subscription rather than by rebuilding the column\n // array, because the array is what the table is built from — deriving it from\n // table state would close the loop. Visibility is the one column property\n // that can be changed after the fact without touching the definitions.\n //\n // Two, and this one is a workaround. In table-core 9.0.0-beta.21 the\n // per-region column APIs do not list `grouping` among their memo\n // dependencies, even though they all derive from `getAllLeafColumns()`, which\n // does:\n //\n // | API | Declares |\n // | --- | --- |\n // | `getLeft/Center/RightVisibleLeafColumns` | columns, columnPinning, columnVisibility, columnOrder |\n // | `getLeft/Center/RightHeaderGroups` | columnPinning, columnOrder |\n // | `row.getLeft/Center/RightVisibleCells` | columnPinning, columnVisibility |\n //\n // So grouping a *second* column leaves every one of them returning the\n // previous list: the column TanStack removed keeps its header and its grid\n // track, and the row cells no longer line up with them. The first grouping\n // appears to work only because the visibility write above happens to touch a\n // dependency they share.\n //\n // Re-publishing `columnVisibility` and `columnOrder` — same contents, new\n // identity — invalidates all three families. `columnOrder` is the only\n // dependency the header groups declare, and `columnVisibility` the only one\n // the cells do, so both are needed. Remove this once the deps are fixed\n // upstream; the test that fails without it groups two columns and asserts the\n // second one leaves the grid.\n //\n // Writing back into the store from its own subscriber is safe: the guard is\n // on `grouping`'s identity, and neither write touches it, so the callback\n // these writes trigger short-circuits.\n useEffect(() => {\n if (!groupColumnEnabled) return;\n let previousGrouping = table.store.state.grouping;\n\n const subscription = table.store.subscribe((state) => {\n if (state.grouping === previousGrouping) return;\n previousGrouping = state.grouping;\n\n table.setColumnVisibility((old) => ({\n ...old,\n [GROUP_COLUMN_ID]: state.grouping.length > 0,\n }));\n table.setColumnOrder((old) => [...old]);\n });\n\n return () => subscription.unsubscribe();\n }, [groupColumnEnabled, table]);\n\n // Mirror every state change back to storage. Subscribing (rather than writing\n // from an effect on a state snapshot) means nothing is missed, including\n // changes made straight through the table API by the consumer.\n //\n // Writes are debounced because `columnResizeMode: \"onChange\"` publishes a new\n // state on every pointer move of a resize drag, and `setItem` serialises\n // synchronously on the main thread. The trailing edge is enough: storage only\n // has to agree with the table once the user stops.\n useEffect(() => {\n if (!hasPersistenceKeys(persist)) return;\n writePersistedState(table.store.state, persist);\n\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let pending: TableState<TMDataGridFeatures> | null = null;\n\n const flush = () => {\n timeout = undefined;\n if (pending === null) return;\n writePersistedState(pending, persist);\n pending = null;\n };\n\n const subscription = table.store.subscribe((state) => {\n pending = state;\n if (timeout !== undefined) clearTimeout(timeout);\n timeout = setTimeout(flush, PERSIST_DEBOUNCE_MS);\n });\n\n return () => {\n subscription.unsubscribe();\n if (timeout !== undefined) clearTimeout(timeout);\n // An unmount mid-debounce would otherwise drop the last change.\n flush();\n };\n }, [persist, table]);\n\n const ui = useCreateStore<TMDataGridUiState, TMDataGridUiActions>(\n {\n filterPanelOpen: false,\n columnsPanelOpen: false,\n filterPanelColumnId: null,\n draggedColumnId: null,\n // `useCreateStore` builds the store once per mount, so this is a genuine\n // default rather than a value that would fight later clicks.\n highlightedRowId: defaultHighlightedRowId ?? null,\n selectionAnchorRowId: null,\n focusedCell: null,\n cellRange: null,\n },\n ({ setState }) => ({\n openFilterPanel: (columnId = null) =>\n setState((prev) => ({\n ...prev,\n filterPanelOpen: true,\n filterPanelColumnId: columnId,\n })),\n closeFilterPanel: () =>\n setState((prev) => ({\n ...prev,\n filterPanelOpen: false,\n filterPanelColumnId: null,\n })),\n setColumnsPanelOpen: (open) =>\n setState((prev) => ({ ...prev, columnsPanelOpen: open })),\n toggleColumnsPanel: () =>\n setState((prev) => ({ ...prev, columnsPanelOpen: !prev.columnsPanelOpen })),\n startColumnDrag: (columnId) =>\n setState((prev) => ({ ...prev, draggedColumnId: columnId })),\n endColumnDrag: () =>\n setState((prev) => ({ ...prev, draggedColumnId: null })),\n setHighlightedRow: (rowId) =>\n setState((prev) => ({ ...prev, highlightedRowId: rowId })),\n setSelectionAnchor: (rowId) =>\n setState((prev) => ({ ...prev, selectionAnchorRowId: rowId })),\n setFocusedCell: (cell) =>\n setState((prev) =>\n // Same cell, same object: the body re-renders on every scroll frame\n // and mouse events land on the cell that already has the focus, so a\n // fresh identity here would republish the store for nothing.\n isSameCell(prev.focusedCell, cell)\n ? prev\n : { ...prev, focusedCell: cell },\n ),\n setCellRange: (range) =>\n setState((prev) =>\n // Same guard as above, and it earns more here: a drag publishes a new\n // corner on every mouse move, and most of those land on the cell the\n // range already ends at.\n isSameCell(prev.cellRange?.anchor ?? null, range?.anchor ?? null) &&\n isSameCell(prev.cellRange?.focus ?? null, range?.focus ?? null)\n ? prev\n : { ...prev, cellRange: range },\n ),\n }),\n );\n\n // `onHighlightedRowChange` is fired from a subscription rather than from the store\n // action, so it covers every route to a new active row — a row click, and a\n // consumer calling `setHighlightedRow` itself. Held in a ref because the store is\n // built once and its actions would otherwise close over the first render's\n // callback.\n const onHighlightedRowChangeRef = useRef(onHighlightedRowChange);\n useEffect(() => {\n onHighlightedRowChangeRef.current = onHighlightedRowChange;\n }, [onHighlightedRowChange]);\n\n useEffect(() => {\n // Seeded from the current value so mounting with a `defaultHighlightedRowId`\n // does not report a change that nothing made.\n let previous = ui.state.highlightedRowId;\n const subscription = ui.subscribe((state) => {\n if (state.highlightedRowId === previous) return;\n previous = state.highlightedRowId;\n onHighlightedRowChangeRef.current?.(state.highlightedRowId);\n });\n return () => subscription.unsubscribe();\n }, [ui]);\n\n // Same shape for the focused cell, and for the same reason: arrow keys, a\n // click and `setFocusedCell` all have to report through one place.\n const onFocusedCellChangeRef = useRef(onFocusedCellChange);\n useEffect(() => {\n onFocusedCellChangeRef.current = onFocusedCellChange;\n }, [onFocusedCellChange]);\n\n useEffect(() => {\n let previous = ui.state.focusedCell;\n const subscription = ui.subscribe((state) => {\n // Identity is enough: `setFocusedCell` keeps the previous object when the\n // cell has not changed, so a new one always means a new cell.\n if (state.focusedCell === previous) return;\n previous = state.focusedCell;\n onFocusedCellChangeRef.current?.(state.focusedCell);\n });\n return () => subscription.unsubscribe();\n }, [ui]);\n\n return {\n table,\n ui,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n };\n}\n\n/**\n * Opens the filter panel for a column, seeding an empty filter row when the\n * column has none yet — mirrors \"Filter\" in the column header menu.\n */\nexport function openColumnFilter<TData extends RowData>(\n api: TMDataGridApi<TData>,\n columnId: string,\n): void {\n const column = api.table.getColumn(columnId);\n if (column && column.getFilterValue() === undefined) {\n column.setFilterValue({\n operator: getDefaultOperator(column.columnDef.meta?.type ?? \"string\"),\n value: \"\",\n });\n }\n api.ui.actions.openFilterPanel(columnId);\n}\n","import { Button, Pill, UnstyledButton } from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport classes from \"./TMDataGridFilterPills.module.css\";\nimport { getColumnLabel, getColumnType } from \"../core/columnUtils\";\nimport {\n formatFilterLabel,\n isFilterActive,\n isTMDataGridFilterValue,\n} from \"../core/filterOperators\";\nimport type { TMDataGridSize } from \"../core/sizes\";\nimport { openColumnFilter, type TMDataGridApi } from \"../useTMDataGrid\";\n\nexport type TMDataGridFilterPillsProps<TData extends RowData> = {\n /** The object returned by `useTMDataGrid`. */\n api: TMDataGridApi<TData>;\n /** Mantine size of the pills. Defaults to `\"sm\"`. */\n size?: TMDataGridSize;\n /** \"Clear all\" button, shown once two filters are active. Defaults to `true`. */\n showClearAll?: boolean;\n /**\n * Replaces what a click on a pill's label does. The default opens the grid's\n * filter panel on that column.\n */\n onPillClick?: (columnId: string) => void;\n className?: string;\n};\n\n/**\n * One pill per active filter — `First name: Sofia ✕` — with the ✕ clearing that\n * filter and a click on the label opening the filter panel on its column.\n *\n * The one grid component that takes the api as a prop instead of reading\n * context, so it can live anywhere: a page header, a card title, a breadcrumb\n * row. Renders nothing while no filter is active.\n *\n * ```tsx\n * const grid = useTMDataGrid({ data, columns });\n *\n * <Group>\n * <Title order={3}>Employees</Title>\n * <TMDataGridFilterPills api={grid} />\n * </Group>\n * ```\n *\n * Half-typed filters are left out: a filter that is not narrowing the rows yet\n * has nothing to report, which is the same rule the funnel indicator uses.\n */\nexport function TMDataGridFilterPills<TData extends RowData>({\n api,\n size = \"sm\",\n showClearAll = true,\n onPillClick,\n className,\n}: TMDataGridFilterPillsProps<TData>) {\n const { table, labels } = api;\n const columnFilters = useSelector(\n table.store,\n (state) => state.columnFilters,\n );\n\n const activeFilters = columnFilters.filter((filter) =>\n isFilterActive(filter.value),\n );\n if (activeFilters.length === 0) return null;\n\n return (\n <div\n role=\"group\"\n aria-label={labels.activeFilters}\n className={[classes.filterPills, className].filter(Boolean).join(\" \")}\n >\n <Pill.Group size={size}>\n {activeFilters.map((filter) => {\n const column = table.getColumn(filter.id);\n const label = column ? getColumnLabel(column) : filter.id;\n const value = filter.value;\n // isFilterActive already vouched for the shape; this narrows it.\n if (!isTMDataGridFilterValue(value)) return null;\n\n return (\n <Pill\n key={filter.id}\n size={size}\n className={classes.pill}\n withRemoveButton\n onRemove={() =>\n table.setColumnFilters(\n columnFilters.filter((other) => other.id !== filter.id),\n )\n }\n // Mantine hides its remove button from assistive tech and from\n // the tab order, because inside a `PillsInput` Backspace is the\n // way out. These pills stand on their own, so the ✕ has to be a\n // real button.\n removeButtonProps={{\n \"aria-label\": labels.clearFilter(label),\n \"aria-hidden\": false,\n tabIndex: 0,\n }}\n >\n <UnstyledButton\n className={classes.pillLabel}\n onClick={() =>\n onPillClick\n ? onPillClick(filter.id)\n : openColumnFilter(api, filter.id)\n }\n >\n {formatFilterLabel({\n label,\n type: column ? getColumnType(column) : \"string\",\n filter: value,\n operatorLabels: labels.operators,\n })}\n </UnstyledButton>\n </Pill>\n );\n })}\n </Pill.Group>\n\n {showClearAll && activeFilters.length > 1 && (\n // Below two pills their own ✕ is the shorter path, so the button would\n // only be a second way to do the same thing.\n <Button\n variant=\"subtle\"\n color=\"gray\"\n size=\"compact-xs\"\n onClick={() => table.setColumnFilters([])}\n >\n {labels.clearAllFilters}\n </Button>\n )}\n </div>\n );\n}\n",".footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--mantine-spacing-lg);\n padding: 4px var(--mantine-spacing-sm);\n min-height: 48px;\n flex-shrink: 0;\n border-top: 1px solid var(--mantine-color-default-border);\n}\n\n/* Grouping suspends paging. The pager stays put and fades rather than\n disappearing, so the footer reads as switched off rather than as having\n vanished — and the row it holds does not change height under the grid. Its\n controls carry their own `disabled`; this is the label half. */\n.footer[data-paging-suspended=\"true\"] {\n opacity: 0.55;\n}\n","import { ActionIcon, Group, Select, Text, Tooltip } from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ReactNode } from \"react\";\nimport classes from \"./TMDataGridFooter.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getGridCapabilities } from \"../core/capabilities\";\nimport { isPagingActive } from \"../core/rowSelection\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"./icons\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/** Distilled pagination state and actions for building a custom pager. */\nexport type TMDataGridPaginationApi = {\n pageIndex: number;\n pageSize: number;\n /** `-1` when a manual grid declares `pageCount: -1` (unknown total). */\n pageCount: number;\n rowCount: number;\n canPreviousPage: boolean;\n canNextPage: boolean;\n setPageIndex: (pageIndex: number) => void;\n setPageSize: (pageSize: number) => void;\n previousPage: () => void;\n nextPage: () => void;\n firstPage: () => void;\n lastPage: () => void;\n};\n\n/**\n * Reads {@link TMDataGridPaginationApi} off a table. The Footer feeds it to the\n * `pagination` render prop; a pager living outside the Footer can call it with\n * the table from `useTMDataGrid` directly.\n */\nexport function getTMDataGridPaginationApi<TData extends RowData>(\n table: TMDataGridTable<TData>,\n): TMDataGridPaginationApi {\n const { pageIndex, pageSize } = table.store.state.pagination;\n return {\n pageIndex,\n pageSize,\n pageCount: table.getPageCount(),\n rowCount: table.getRowCount(),\n canPreviousPage: table.getCanPreviousPage(),\n canNextPage: table.getCanNextPage(),\n setPageIndex: (index) => table.setPageIndex(index),\n setPageSize: (size) => table.setPageSize(size),\n previousPage: () => table.previousPage(),\n nextPage: () => table.nextPage(),\n firstPage: () => table.firstPage(),\n lastPage: () => table.lastPage(),\n };\n}\n\nexport type TMDataGridFooterProps = {\n pageSizeOptions?: ReadonlyArray<number>;\n /** Replaces the built-in pager. Receives the distilled pagination API. */\n pagination?: (api: TMDataGridPaginationApi) => ReactNode;\n};\n\n/**\n * MUI-style pager: \"Rows per page · from–to of total · ‹ ›\".\n *\n * Renders nothing unless pagination is enabled (`enablePagination` or\n * `manualPagination`) — the footer is a pager; extra footer content belongs in\n * your own layout.\n *\n * Row totals come from `table.getRowCount()`, which prefers `options.rowCount`\n * — so a server-paged grid shows the server's total without changes here.\n */\nexport function TMDataGridFooter({\n pageSizeOptions = [10, 25, 50, 100],\n pagination,\n}: TMDataGridFooterProps) {\n const { table, features, labels, controlSize } = useTMDataGridContext();\n useSelector(table.store);\n\n if (!getGridCapabilities(table, features).canPaginate) return null;\n\n if (pagination) {\n return (\n <div className={classes.footer}>\n {pagination(getTMDataGridPaginationApi(table))}\n </div>\n );\n }\n\n // Grouping suspends paging — see isPagingActive. The pager is greyed out\n // rather than dropped, so that a footer going quiet reads as a state the grid\n // is in rather than as something that broke.\n const paging = isPagingActive(table, features);\n const { pageIndex, pageSize } = table.store.state.pagination;\n const total = table.getRowCount();\n const from = total === 0 ? 0 : pageIndex * pageSize + 1;\n const to = Math.min(total, (pageIndex + 1) * pageSize);\n // A page size restored from storage, or set through `initialState`, need not\n // be one of the offered sizes. Without it in the list the Select renders\n // blank, so the current size is folded in rather than shown as nothing.\n const sizeOptions = pageSizeOptions.includes(pageSize)\n ? pageSizeOptions\n : [...pageSizeOptions, pageSize].sort((a, b) => a - b);\n\n return (\n <Tooltip\n label={labels.pagingSuspendedHint}\n disabled={paging}\n withArrow\n multiline\n w={260}\n position=\"top\"\n >\n <div className={classes.footer} data-paging-suspended={!paging}>\n <Group gap=\"xs\" wrap=\"nowrap\">\n <Text size={controlSize} c=\"dimmed\">\n {labels.rowsPerPage}\n </Text>\n <Select\n size={controlSize}\n w={78}\n allowDeselect={false}\n variant=\"unstyled\"\n disabled={!paging}\n data={sizeOptions.map(String)}\n value={String(pageSize)}\n onChange={(value) => {\n table.setPageSize(Number(value) || pageSizeOptions[0]);\n table.setPageIndex(0);\n }}\n />\n </Group>\n\n <Text size={controlSize} c=\"dimmed\">\n {paging\n ? labels.pageRange({ from, to, total })\n : // Not a range: nothing is being sliced, so a range would be a lie.\n // Counted before grouping too — `getRowCount()` would be counting\n // the tree, so a collapsed grid would claim to hold eight rows.\n labels.groupedAllRows(table.getFilteredRowModel().rows.length)}\n </Text>\n\n <Group gap={4} wrap=\"nowrap\">\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n aria-label={labels.previousPage}\n disabled={!paging || !table.getCanPreviousPage()}\n onClick={() => table.previousPage()}\n >\n <ChevronLeftIcon size={18} stroke={1.6} />\n </ActionIcon>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n aria-label={labels.nextPage}\n disabled={!paging || !table.getCanNextPage()}\n onClick={() => table.nextPage()}\n >\n <ChevronRightIcon size={18} stroke={1.6} />\n </ActionIcon>\n </Group>\n </div>\n </Tooltip>\n );\n}\n","import { ActionIcon, TextInput } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getGridCapabilities } from \"../core/capabilities\";\nimport { CloseIcon, SearchIcon } from \"./icons\";\n\nexport type TMDataGridSearchProps = {\n /** Defaults to `labels.searchPlaceholder`. */\n placeholder?: string;\n /**\n * How long typing pauses before the filter is applied, in ms. Defaults to\n * 250. `0` writes on every keystroke — what the tests use, and fine for\n * small client-side data sets.\n */\n debounce?: number;\n /** Width of the input. Defaults to 220. */\n w?: number | string;\n};\n\n/**\n * Quick search over every column — a debounced input writing the table's\n * `globalFilter` state through the `\"includesString\"` filter the grid\n * configures by default.\n *\n * ```tsx\n * <TMDataGrid.Toolbar>\n * <TMDataGrid.Search />\n * <TMDataGrid.Spacer />\n * <TMDataGrid.FilterButton />\n * </TMDataGrid.Toolbar>\n * ```\n *\n * Renders nothing under `enableGlobalFilter: false`. Columns opt out with\n * their own `enableGlobalFilter: false` — the generated lanes already do.\n *\n * The state is TanStack's `globalFilter`, so everything around it comes free:\n * `manualFiltering` grids forward it to the server, and it is one of the\n * persisted `data` slices. A grid that wants its own input entirely writes\n * `table.setGlobalFilter` itself — this component is only the built-in one.\n */\nexport function TMDataGridSearch({\n placeholder,\n debounce = 250,\n w = 220,\n}: TMDataGridSearchProps) {\n const { table, features, labels, controlSize } = useTMDataGridContext();\n\n // A consumer can put anything in `globalFilter`; the input only mirrors the\n // string form and treats the rest as empty.\n const globalFilter = useSelector(table.store, (state) =>\n typeof state.globalFilter === \"string\" ? state.globalFilter : \"\",\n );\n\n const [draft, setDraft] = useState(globalFilter);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n // What this input last wrote, so an echo of its own write is not mistaken\n // for an external change that should overwrite what is being typed.\n const lastWrittenRef = useRef(globalFilter);\n\n // External writes — a consumer's `setGlobalFilter`, a persistence restore —\n // win over the draft; the input is a mirror, not an owner.\n useEffect(() => {\n if (globalFilter === lastWrittenRef.current) return;\n lastWrittenRef.current = globalFilter;\n setDraft(globalFilter);\n }, [globalFilter]);\n\n // An unmount mid-debounce drops the pending write rather than filtering a\n // grid whose input no longer exists.\n useEffect(() => () => clearTimeout(timeoutRef.current), []);\n\n if (!getGridCapabilities(table, features).canSearch) return null;\n\n const commit = (value: string) => {\n lastWrittenRef.current = value;\n // `undefined` rather than `\"\"`: an empty filter is no filter, and this is\n // what keeps the persisted slice and the funnel logic clean.\n table.setGlobalFilter(value === \"\" ? undefined : value);\n };\n\n const handleChange = (value: string) => {\n setDraft(value);\n clearTimeout(timeoutRef.current);\n if (debounce <= 0) {\n commit(value);\n return;\n }\n timeoutRef.current = setTimeout(() => commit(value), debounce);\n };\n\n return (\n <TextInput\n size={controlSize}\n w={w}\n value={draft}\n onChange={(event) => handleChange(event.currentTarget.value)}\n placeholder={placeholder ?? labels.searchPlaceholder}\n aria-label={labels.searchLabel}\n leftSection={<SearchIcon size={16} stroke={1.6} />}\n rightSection={\n draft !== \"\" ? (\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n aria-label={labels.clearSearch}\n onClick={() => {\n clearTimeout(timeoutRef.current);\n setDraft(\"\");\n commit(\"\");\n }}\n >\n <CloseIcon size={14} stroke={1.6} />\n </ActionIcon>\n ) : undefined\n }\n />\n );\n}\n","/* Anchors the filter panel, which floats over the first body rows. */\n.tableWrapper {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n\n.scrollContainer {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: auto;\n}\n\n/* Column tracks are set inline via gridTemplateColumns. */\n.grid {\n display: grid;\n}\n\n/* Rows are real layout boxes (not display: contents) so position: sticky works,\n and subgrid keeps their cells on the parent's column tracks. */\n.headerRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n top: 0;\n z-index: var(--dg-z-header, 6);\n}\n\n.bodyRow {\n --row-bg: var(--mantine-color-body);\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n align-items: stretch;\n}\n\n.bodyRow:hover {\n --row-bg: var(--mantine-color-default-hover);\n}\n\n/* A group row takes no background of its own. Collapsed, every row on screen is\n a group row, so a tint would grey out the whole grid and read as if\n everything were selected. The bold label and the chevron carry the\n distinction instead — and `--dg-row-group-bg` is there for a consumer who\n wants the tint back. Declared before the selection rules, so a selected or\n highlighted group still reads as one. */\n.bodyRow[data-grouped=\"true\"] {\n --row-bg: var(--dg-row-group-bg);\n}\n\n/* The row an open context menu is about. The pointer has usually left it by\n then, so without this the menu would be the only thing saying which row it\n acts on. Declared before the selection rules, which are the stronger\n statement and win at equal specificity. */\n.bodyRow[data-context-menu=\"true\"] {\n --row-bg: var(--mantine-color-default-hover);\n}\n\n/* Being selected and being painted for it are separate: a row is always\n `data-selected`, but only takes the background when `showSelectedBackground`\n is on — the default under `\"row\"`, off with checkboxes. */\n.bodyRow[data-selected-bg=\"true\"] {\n --row-bg: var(--dg-row-selected-bg);\n}\n\n/* The highlighted row wins over the selected background: under\n `\"checkboxAndHighlight\"` the two coexist, and the highlighted row is the one\n the detail panel is about, so it must stay distinguishable inside a\n selection. Declared after, so the later rule takes it at equal specificity. */\n.bodyRow[data-highlighted=\"true\"] {\n --row-bg: var(--dg-row-highlight-bg);\n}\n\n/* Row selection mode: the row is the control, so it takes focus and must not\n start a text selection on the click that toggles it. */\n.bodyRow[data-selects-on-click=\"true\"] {\n user-select: none;\n}\n\n.bodyRow:focus-visible {\n outline: 2px solid var(--mantine-primary-color-filled);\n outline-offset: -2px;\n}\n\n/* Clipping lives on .cellContent, not here — a pinned cell has to let its\n boundary gradient escape past its own right/left edge. */\n.bodyCell {\n display: flex;\n align-items: center;\n padding: 0 var(--dg-padding);\n border-bottom: 1px solid var(--mantine-color-default-border);\n /* Inherited from .bodyRow — sticky cells need an opaque background. */\n background-color: var(--row-bg);\n font-size: var(--dg-font-size);\n}\n\n/* A control lane — the checkbox, the details chevron — is a fixed 36px track\n holding a control of a known width, not text that can ellipsize. Cell padding\n is sized for text and grows with the scale, so at `xl` its 18px a side left\n 12px for a 16px box and the checkbox was clipped. The lane centres its\n control instead. */\n.bodyCell[data-control-column=\"true\"] {\n padding: 0;\n}\n\n/* A drag is laying down a range. Text selection would otherwise follow the\n pointer across every cell it passes. */\n.grid[data-range-dragging] {\n user-select: none;\n}\n\n/* The selected block, under `cellSelection: \"range\"`.\n\n A tint over the row's own background rather than instead of it, so a\n selected cell on a highlighted row still reads as both. `color-mix` keeps\n one declaration for light and dark: it thins the theme's primary colour into\n whatever `--row-bg` the row resolved to. */\n.bodyCell[data-selected=\"true\"] {\n background-color: color-mix(\n in srgb,\n var(--mantine-primary-color-filled) 14%,\n var(--row-bg)\n );\n}\n\n/* The outline around the block, drawn edge by edge: only the cells on a side\n of the rectangle draw that side, so they add up to one border around the\n whole thing however it is shaped. A single overlay box would have to be\n positioned against a scrolling grid with sticky lanes in it.\n\n Four shadows are always laid down and each is transparent until its edge\n says otherwise. `box-shadow` does not accumulate across rules — a second\n declaration replaces the first — so the alternative is one rule per corner\n combination, and a cell can be on any of fifteen of them. */\n.bodyCell[data-selected=\"true\"] {\n --dg-edge-top: transparent;\n --dg-edge-bottom: transparent;\n --dg-edge-left: transparent;\n --dg-edge-right: transparent;\n box-shadow:\n inset 0 1px 0 0 var(--dg-edge-top),\n inset 0 -1px 0 0 var(--dg-edge-bottom),\n inset 1px 0 0 0 var(--dg-edge-left),\n inset -1px 0 0 0 var(--dg-edge-right);\n}\n\n.bodyCell[data-edge-top=\"true\"] {\n --dg-edge-top: var(--mantine-primary-color-filled);\n}\n\n.bodyCell[data-edge-bottom=\"true\"] {\n --dg-edge-bottom: var(--mantine-primary-color-filled);\n}\n\n.bodyCell[data-edge-left=\"true\"] {\n --dg-edge-left: var(--mantine-primary-color-filled);\n}\n\n.bodyCell[data-edge-right=\"true\"] {\n --dg-edge-right: var(--mantine-primary-color-filled);\n}\n\n/* The cell the keyboard is on, under `cellSelection`.\n\n Painted from `data-focused` rather than `:focus-visible`, because the ring\n has to stay while the focus steps into a control inside the cell — that is\n still where the arrow keys resume from. The offset keeps it inside the\n cell's own box, so a pinned neighbour cannot clip it. */\n.bodyCell[data-focused=\"true\"] {\n outline: 2px solid var(--mantine-primary-color-filled);\n outline-offset: -2px;\n}\n\n.cellContent {\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.bodyCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.bodyCell[data-align=\"center\"] {\n justify-content: center;\n}\n\n/* Only stretch to fill when left-aligned, so right/centre stay put. */\n.bodyCell[data-align=\"left\"] .cellContent {\n flex: 1 1 auto;\n}\n\n/* The panel an expanded row opens. Its own grid row inside .bodyRow, spanning\n every column track — so it is measured together with the row above it.\n\n It takes `--row-bg` rather than a colour of its own: the panel belongs to its\n row, and a selected or highlighted row whose panel stayed white would read as\n two separate things. */\n.detailsCell {\n grid-column: 1 / -1;\n border-bottom: 1px solid var(--mantine-color-default-border);\n background-color: var(--row-bg);\n padding: var(--dg-padding);\n /* The row above may be the selection control, which turns text selection off\n for everything inside it. A panel is content, so it takes both back. */\n user-select: text;\n cursor: auto;\n}\n\n.messageRow {\n grid-column: 1 / -1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--mantine-spacing-xs);\n padding: var(--mantine-spacing-xl);\n}\n\n/* The summary row — one sticky row of column footers along the bottom edge,\n rendered only while at least one column defines `footer`. Same subgrid\n placement as the header, so its cells sit exactly on the body's tracks. */\n.summaryRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n bottom: 0;\n z-index: var(--dg-z-summary-row, 4);\n}\n\n.summaryCell {\n display: flex;\n align-items: center;\n padding: 0 var(--dg-padding);\n border-top: 1px solid var(--mantine-color-default-border);\n /* Opaque: the body scrolls underneath it. */\n background-color: var(--mantine-color-body);\n font-size: var(--dg-font-size);\n font-weight: 600;\n}\n\n.summaryCell[data-control-column=\"true\"] {\n padding: 0;\n}\n\n.summaryCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.summaryCell[data-align=\"center\"] {\n justify-content: center;\n}\n","/* Boundary of a pinned column group. Shared, because the edge is cast by both\n the header cell and every body cell in the same column — the two have to draw\n an identical band or the seam shows at the header.\n\n A box-shadow is drawn per cell, and its blur fades in at each cell's own top\n and bottom edge — stacked down a column that reads as banding at every row\n seam. Instead: a gradient pseudo element pinned to `top: 0; bottom: 0` so\n consecutive cells butt together into one unbroken band. Mantine sets\n `color-scheme` on the root, so light-dark() resolves without a second\n selector.\n\n No border. A 1px line the colour of the grid's own borders drew a hard rule\n between the pinned lanes and the data, so the pinned columns read as a\n separate table rather than as part of this one — and at the system lanes,\n which are only a control wide, it framed them like a sidebar. */\n.stickyLeft::after,\n.stickyRight::after {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n width: 8px;\n pointer-events: none;\n}\n\n/* Three stops rather than two. A straight linear ramp to `transparent` fades\n fastest at the start, so its own outer edge stays visible as a faint line —\n the sharpness a hard border was blamed for. Front-loading the falloff puts\n the density against the pinned cell and lets the tail reach zero unnoticed. */\n.stickyLeft::after {\n left: 100%;\n background: linear-gradient(\n to right,\n light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.26)),\n light-dark(rgba(0, 0, 0, 0.025), rgba(0, 0, 0, 0.09)) 45%,\n transparent\n );\n}\n\n.stickyRight::after {\n right: 100%;\n background: linear-gradient(\n to left,\n light-dark(rgba(0, 0, 0, 0.07), rgba(0, 0, 0, 0.26)),\n light-dark(rgba(0, 0, 0, 0.025), rgba(0, 0, 0, 0.09)) 45%,\n transparent\n );\n}\n\n/* The band says \"there is more table under this lane\". So it should only be\n there while that is true: nothing is hidden at either end of the scroll, and\n nothing at all is hidden by a grid narrow enough not to scroll.\n\n Driven by the scroll position itself rather than by a listener writing a\n class. A scroll-driven animation is evaluated on the compositor, so the band\n tracks the scroll frame for frame without a single React render — and the\n body re-renders on every scroll frame already, from virtualization.\n\n `scroll(nearest inline)` resolves to `.scrollContainer`, the one horizontal\n scroller above these cells. An inactive timeline — which is what a container\n with nothing to scroll gives — leaves the base style in place, so `opacity:\n 0` inside this block is also the answer for a grid that does not scroll. */\n@supports (animation-timeline: scroll()) {\n .stickyLeft::after,\n .stickyRight::after {\n /* Distance over which the band arrives. Short enough to read as an edge\n appearing under the lane rather than as a fade. */\n --dg-sticky-edge-range: 20px;\n opacity: 0;\n animation-timeline: scroll(nearest inline);\n animation-timing-function: linear;\n animation-fill-mode: both;\n }\n\n .stickyLeft::after {\n animation-name: stickyEdgeIn;\n animation-range: 0 var(--dg-sticky-edge-range);\n }\n\n /* The mirror: on at rest, gone as the last column arrives. The range is\n measured from the end, and `both` holds the first value everywhere before\n it — so the band stays fully on until the scroller is within 20px of home.\n */\n .stickyRight::after {\n animation-name: stickyEdgeOut;\n animation-range: calc(100% - var(--dg-sticky-edge-range)) 100%;\n }\n}\n\n@keyframes stickyEdgeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes stickyEdgeOut {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n",".headerCell {\n position: relative;\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 var(--dg-padding);\n min-width: 0;\n min-height: var(--dg-header-height);\n font-weight: 600;\n font-size: var(--dg-font-size);\n background-color: var(--mantine-color-body);\n border-bottom: 1px solid var(--mantine-color-default-border);\n user-select: none;\n}\n\n.headerCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.headerCell[data-align=\"center\"] {\n justify-content: center;\n}\n\n/* Same as the body cells: a control lane's header — the select-all box, the\n expand-all chevron — sits in a fixed 36px track, which the text padding would\n squeeze it out of at the larger sizes. */\n.headerCell[data-control-column=\"true\"] {\n padding: 0;\n}\n\n/* Sorted or filtered columns read as active, like the MUI data grid. */\n.headerCell[data-active=\"true\"] .headerTitle {\n color: var(--mantine-primary-color-filled);\n}\n\n.headerTitle {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Right-aligned headers stay text so the ellipsis still works; centered ones\n hold a control (the select-all checkbox), so they become a flex box. */\n.headerCell[data-align=\"right\"] .headerTitle {\n text-align: right;\n}\n\n.headerCell[data-align=\"center\"] .headerTitle {\n display: flex;\n justify-content: center;\n}\n\n.headerActions {\n display: flex;\n align-items: center;\n gap: 0;\n flex-shrink: 0;\n margin-left: auto;\n}\n\n/* Actions always reserve their width. On right-aligned columns they move to the\n leading edge so the header text stays flush with the cell values below it. */\n.headerCell[data-align=\"right\"] .headerActions {\n order: -1;\n margin-left: 0;\n margin-right: auto;\n}\n\n/* Idle actions are removed from layout, not just faded — reserving their width\n would truncate header text that otherwise fits. Indicators that must stay\n visible (active sort, active filter, open menu) set data-pinned-visible. */\n.headerAction {\n display: none;\n}\n\n.headerCell:hover .headerAction,\n.headerCell:focus-within .headerAction,\n.headerAction[data-pinned-visible=\"true\"] {\n display: flex;\n}\n\n.headerCellSortable {\n cursor: pointer;\n}\n\n/* Sort priority under multi-sort — \"1\", \"2\", … beside the arrow. Only rendered\n while more than one column sorts, so a single sort stays as it always was. */\n.sortIndex {\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n color: var(--mantine-color-dimmed);\n min-width: 10px;\n text-align: center;\n}\n\n/* Column reordering. The dragged header stays in place and dims — the browser\n already carries a snapshot of it under the pointer — while the header being\n dragged over draws a bar on the edge the column will land against. */\n.headerCellDragging {\n opacity: 0.4;\n}\n\n.headerCellDropBefore::before,\n.headerCellDropAfter::before {\n content: \"\";\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background-color: var(--mantine-primary-color-filled);\n z-index: 5;\n pointer-events: none;\n}\n\n.headerCellDropBefore::before {\n left: 0;\n}\n\n.headerCellDropAfter::before {\n right: 0;\n}\n\n/* Doubles as the column divider seen between every header cell. */\n.columnSeparator {\n position: absolute;\n top: 25%;\n right: 0;\n height: 50%;\n width: 10px;\n transform: translateX(50%);\n display: flex;\n justify-content: center;\n z-index: 1;\n}\n\n.columnSeparatorResizable {\n cursor: col-resize;\n touch-action: none;\n}\n\n/* The divider is a hover affordance, not permanent chrome — it only appears on\n the header cell you are pointing at, or on the column being resized. */\n.columnSeparator::after {\n content: \"\";\n width: 1px;\n height: 100%;\n background-color: transparent;\n transition:\n background-color 120ms ease,\n width 120ms ease;\n}\n\n.headerCell:hover .columnSeparator::after,\n.headerCell:focus-within .columnSeparator::after {\n background-color: var(--mantine-color-default-border);\n}\n\n.columnSeparatorResizable:hover::after,\n.columnSeparatorActive::after {\n width: 2px;\n background-color: var(--mantine-primary-color-filled);\n}\n\n/* Marks the pin position a column is currently in. */\n.menuItemActive {\n background-color: var(--mantine-color-default-hover);\n font-weight: 600;\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/**\n * Room the header keeps for its hover-revealed actions (sort arrow, menu) and\n * the resize divider, which measure zero while idle. Without it a column sized\n * exactly to its header text puts the actions on top of the title.\n */\nconst HEADER_ACTIONS_ALLOWANCE = 30;\n\n/** Breathing room so the widest value does not touch the next divider. */\nconst CONTENT_ALLOWANCE = 2;\n\n/**\n * What the content inside one cell actually spans, in px.\n *\n * A Range over the children rather than the span's `scrollWidth`, because the\n * two disagree in opposite directions: a left-aligned cell stretches its\n * content span to fill the cell (`flex: 1 1 auto`), so `scrollWidth` reports\n * the stretched box and autosize could never *shrink* a column — while for\n * clipped content both see past the `overflow: hidden`. The Range measures\n * the laid-out text and elements themselves, whatever box they sit in.\n *\n * `scrollWidth` stays as the fallback for environments whose Ranges do not\n * measure (jsdom reports 0 there).\n */\nfunction contentSpanWidth(content: HTMLElement): number {\n const range = document.createRange();\n range.selectNodeContents(content);\n // jsdom's Range has no getBoundingClientRect at all, hence the guard\n // rather than a zero-check alone.\n const width =\n typeof range.getBoundingClientRect === \"function\"\n ? range.getBoundingClientRect().width\n : 0;\n return width > 0 ? width : content.scrollWidth;\n}\n\n/**\n * Widest rendered content of one column, in px, measured from the DOM.\n *\n * Mounted cells only: under virtualization the unmounted rows do not exist to\n * be measured, so this reads the visible window plus overscan — the same\n * trade AG Grid's autosize makes by default.\n */\nexport function measureColumnContentWidth({\n container,\n columnId,\n}: {\n /** The grid's scroll container — anything enclosing the column's cells. */\n container: HTMLElement;\n columnId: string;\n}): number {\n let widest = 0;\n\n const cells = container.querySelectorAll<HTMLElement>(\n `[role=\"cell\"][data-column-id=\"${CSS.escape(columnId)}\"],` +\n `[role=\"gridcell\"][data-column-id=\"${CSS.escape(columnId)}\"]`,\n );\n for (const cell of cells) {\n const content = cell.firstElementChild;\n if (!(content instanceof HTMLElement)) continue;\n const styles = getComputedStyle(cell);\n const padding =\n (Number.parseFloat(styles.paddingLeft) || 0) +\n (Number.parseFloat(styles.paddingRight) || 0);\n widest = Math.max(\n widest,\n contentSpanWidth(content) + padding + CONTENT_ALLOWANCE,\n );\n }\n\n const title = container.querySelector<HTMLElement>(\n `[data-testid=\"dg-header-${CSS.escape(columnId)}\"] [data-dg-header-title]`,\n );\n if (title) {\n const header = title.closest<HTMLElement>('[role=\"columnheader\"]');\n const styles = header ? getComputedStyle(header) : null;\n const padding = styles\n ? (Number.parseFloat(styles.paddingLeft) || 0) +\n (Number.parseFloat(styles.paddingRight) || 0)\n : 0;\n widest = Math.max(\n widest,\n contentSpanWidth(title) + padding + HEADER_ACTIONS_ALLOWANCE,\n );\n }\n\n return widest;\n}\n\n/**\n * Sizes a column to its widest mounted content — what double-clicking the\n * resize divider does, exported so a menu item or consumer code can trigger\n * the same thing.\n *\n * The width lands in `columnSizing`, so it persists with the other widths and\n * a later resize drag takes over from it. Clamped to the column's\n * `minSize`/`maxSize`; a no-op (returning `false`) for a column that cannot\n * be resized or has nothing mounted to measure.\n */\nexport function autosizeColumn<TData extends RowData>({\n table,\n columnId,\n container,\n}: {\n table: TMDataGridTable<TData>;\n columnId: string;\n container: HTMLElement;\n}): boolean {\n const erased = table as unknown as TMDataGridTable<TMDataGridRowData>;\n const column = erased.getColumn(columnId);\n if (!column || !column.getCanResize()) return false;\n\n const measured = measureColumnContentWidth({ container, columnId });\n if (measured <= 0) return false;\n\n const minSize = column.columnDef.minSize ?? 80;\n const maxSize = column.columnDef.maxSize ?? Number.POSITIVE_INFINITY;\n const width = Math.round(Math.min(Math.max(measured, minSize), maxSize));\n\n erased.setColumnSizing((previous) => ({ ...previous, [columnId]: width }));\n return true;\n}\n","import type { Column, ColumnPinningState } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport { isColumnReorderable } from \"./columnUtils\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\ntype GridColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\ntype GridTable = TMDataGridTable<TMDataGridRowData>;\n\n/**\n * The lane a column renders in.\n *\n * Pinning splits the grid into three, and TanStack sequences them from two\n * different state slices: `columnPinning.left` / `.right` order the pinned\n * lanes, `columnOrder` orders the centre. A move therefore always stays inside\n * one lane — moving a column into another one would be a pin, not a reorder.\n */\nexport type TMDataGridColumnRegion = \"left\" | \"center\" | \"right\";\n\n/** Which edge of the column under the pointer a dragged column lands on. */\nexport type TMDataGridDropSide = \"before\" | \"after\";\n\nexport function getColumnRegion(\n columnPinning: ColumnPinningState,\n columnId: string,\n): TMDataGridColumnRegion {\n if (columnPinning.left.includes(columnId)) return \"left\";\n if (columnPinning.right.includes(columnId)) return \"right\";\n return \"center\";\n}\n\n/** Moves one id next to another, leaving every other id in place. */\nfunction moveInList(\n ids: ReadonlyArray<string>,\n movedId: string,\n targetId: string,\n side: TMDataGridDropSide,\n): Array<string> {\n const remaining = ids.filter((id) => id !== movedId);\n const targetIndex = remaining.indexOf(targetId);\n if (targetIndex === -1) return [...ids];\n remaining.splice(side === \"before\" ? targetIndex : targetIndex + 1, 0, movedId);\n return remaining;\n}\n\nexport type MoveColumnArgs = {\n table: GridTable;\n /** Column being moved. */\n columnId: string;\n /** Column it was dropped on. */\n targetId: string;\n side: TMDataGridDropSide;\n};\n\n/**\n * Moves a column next to another one. A no-op when the two are in different\n * pinned regions, or when either id is unknown.\n *\n * `columnOrder` is always written as the full leaf order, including hidden and\n * pinned columns, so a column keeps its place when it is later shown or\n * unpinned. Pinned lanes are read from `columnPinning`, so a move inside one\n * updates that array as well.\n */\nexport function moveColumn({\n table,\n columnId,\n targetId,\n side,\n}: MoveColumnArgs): void {\n if (columnId === targetId) return;\n\n const columnPinning = table.store.state.columnPinning;\n const region = getColumnRegion(columnPinning, columnId);\n if (region !== getColumnRegion(columnPinning, targetId)) return;\n\n const leafIds = table.getAllLeafColumns().map((column) => column.id);\n table.setColumnOrder(moveInList(leafIds, columnId, targetId, side));\n\n if (region !== \"center\") {\n table.setColumnPinning((previous) => ({\n ...previous,\n [region]: moveInList(previous[region], columnId, targetId, side),\n }));\n }\n}\n\n/** Visible leaf columns of one lane, in the order they render. */\nfunction getRegionColumns(\n table: GridTable,\n region: TMDataGridColumnRegion,\n): Array<GridColumn> {\n if (region === \"left\") return table.getLeftVisibleLeafColumns();\n if (region === \"right\") return table.getRightVisibleLeafColumns();\n return table.getCenterVisibleLeafColumns();\n}\n\nexport type ColumnStepArgs = {\n table: GridTable;\n columnId: string;\n /** `-1` moves towards the start of the lane, `1` towards its end. */\n direction: -1 | 1;\n};\n\n/**\n * The column a single step would swap with, or `null` when there is none.\n *\n * A neighbour that cannot be reordered acts as a wall rather than being skipped\n * — that is what keeps the checkbox column anchored at the start of the left\n * lane. Use it to enable or disable a \"move\" control.\n */\nexport function getStepTargetColumn({\n table,\n columnId,\n direction,\n}: ColumnStepArgs): GridColumn | null {\n const region = getColumnRegion(table.store.state.columnPinning, columnId);\n const columns = getRegionColumns(table, region);\n const index = columns.findIndex((column) => column.id === columnId);\n if (index === -1) return null;\n\n const target = columns[index + direction];\n if (!target || !isColumnReorderable(target)) return null;\n return target;\n}\n\n/** Moves a column one position within its lane. Hidden columns are stepped over. */\nexport function moveColumnByStep({\n table,\n columnId,\n direction,\n}: ColumnStepArgs): void {\n const target = getStepTargetColumn({ table, columnId, direction });\n if (!target) return;\n\n moveColumn({\n table,\n columnId,\n targetId: target.id,\n side: direction === -1 ? \"before\" : \"after\",\n });\n}\n","import { ActionIcon, Menu, Tooltip } from \"@mantine/core\";\nimport { flexRender, type Header } from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { shallow } from \"@tanstack/store\";\nimport { type DragEvent, type ReactNode, useRef, useState } from \"react\";\nimport classes from \"./TMDataGridHeaderCell.module.css\";\nimport sticky from \"./sticky.module.css\";\nimport {\n type TMDataGridRowData,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport type { TMDataGridColumnLayout } from \"./TMDataGridTable\";\nimport { getColumnCapabilities, getGridCapabilities } from \"../core/capabilities\";\nimport { autosizeColumn } from \"../core/autosize\";\nimport {\n getColumnRegion,\n getStepTargetColumn,\n moveColumn,\n moveColumnByStep,\n type TMDataGridDropSide,\n} from \"../core/columnOrdering\";\nimport {\n getColumnAlign,\n getColumnLabel,\n isControlColumn,\n} from \"../core/columnUtils\";\nimport { resolveExpandAll } from \"../core/expanding\";\nimport { isFilterActive } from \"../core/filterOperators\";\nimport {\n ArrowDownIcon,\n ArrowUpIcon,\n AutosizeIcon,\n CollapseAllIcon,\n ColumnsIcon,\n DotsVerticalIcon,\n ExpandAllIcon,\n EyeOffIcon,\n FilterIcon,\n GroupIcon,\n MoveLeftIcon,\n MoveRightIcon,\n PinLeftIcon,\n PinOffIcon,\n PinRightIcon,\n UngroupIcon,\n} from \"./icons\";\nimport { GROUP_COLUMN_ID } from \"./TMDataGridGroupColumn\";\nimport { type TMDataGridFeatures, openColumnFilter } from \"../useTMDataGrid\";\n\nexport type TMDataGridHeader = Header<\n TMDataGridFeatures,\n TMDataGridRowData,\n unknown\n>;\n\nexport function TMDataGridHeaderCell({\n header,\n layout,\n}: {\n header: TMDataGridHeader;\n layout: TMDataGridColumnLayout;\n}) {\n const api = useTMDataGridContext();\n const { table, features, labels } = api;\n const column = header.column;\n const [menuOpened, setMenuOpened] = useState(false);\n const [contextMenuOpened, setContextMenuOpened] = useState(false);\n const [dropSide, setDropSide] = useState<TMDataGridDropSide | null>(null);\n const cellRef = useRef<HTMLDivElement>(null);\n // A resize drag ends with a click that bubbles to the header — without this\n // every resize would also toggle the column's sort order.\n const suppressSortRef = useRef(false);\n\n // Subscribing to the slices this cell renders from keeps it live even when the\n // surrounding tree is memoized (React Compiler) or the table lives elsewhere.\n // `columnOrder` is in the list because the move menu items are derived from\n // the column's neighbours, which is exactly what an order change invalidates.\n const { sorting, columnFilters, resizingColumnId, columnPinning, grouping } =\n useSelector(\n table.store,\n (state) => ({\n sorting: state.sorting,\n columnFilters: state.columnFilters,\n resizingColumnId: state.columnResizing.isResizingColumn,\n columnPinning: state.columnPinning,\n columnOrder: state.columnOrder,\n grouping: state.grouping,\n }),\n { compare: shallow },\n );\n const draggedColumnId = useSelector(api.ui, (state) => state.draggedColumnId);\n\n const isLeaf = header.subHeaders.length === 0;\n const label = getColumnLabel(column);\n const align = getColumnAlign(column);\n const sortDirection = sorting.find((sort) => sort.id === column.id)?.desc;\n const isSorted = sortDirection !== undefined;\n // 1-based position in a multi-sort, shown only while more than one column\n // sorts — under a single sort the arrow already says everything.\n const sortIndex =\n isSorted && sorting.length > 1\n ? sorting.findIndex((sort) => sort.id === column.id) + 1\n : null;\n const isFiltered = columnFilters.some(\n (filter) => filter.id === column.id && isFilterActive(filter.value),\n );\n const isResizing = resizingColumnId === column.id;\n const pinnedAt = layout.pinnedAt;\n\n // Every affordance below mirrors a TanStack capability check, so switching a\n // feature off through the table options removes the markup with it.\n const capabilities = getColumnCapabilities(column, features);\n const canSort = isLeaf && capabilities.canSort;\n const canFilter = isLeaf && capabilities.canFilter;\n const canHide = isLeaf && capabilities.canHide;\n const canPin = isLeaf && capabilities.canPin;\n const canResize = capabilities.canResize;\n const canReorder = isLeaf && capabilities.canReorder;\n const canGroup = isLeaf && capabilities.canGroup;\n const canManageColumns =\n isLeaf && getGridCapabilities(table, features).canHideAny;\n\n // Read off the subscribed slice, not from `column.getIsGrouped()`: that is a\n // call on a `column` whose identity survives a grouping change, so the React\n // Compiler would cache the answer and the menu would keep offering to group\n // a column that already is. Same reason the sort and filter flags above are\n // derived from state rather than from `getIsSorted()`.\n const isGrouped = grouping.includes(column.id);\n const isGroupingActive = grouping.length > 0;\n\n // A column only moves inside its own pinned lane, so a header in another one\n // never lights up as a target. See TMDataGridColumnRegion.\n const isDragged = draggedColumnId === column.id;\n const isDropTarget =\n canReorder &&\n draggedColumnId !== null &&\n !isDragged &&\n getColumnRegion(columnPinning, draggedColumnId) ===\n getColumnRegion(columnPinning, column.id);\n\n function handleDragStart(event: DragEvent<HTMLDivElement>) {\n event.dataTransfer.effectAllowed = \"move\";\n // Some browsers refuse to start a drag with an empty payload.\n event.dataTransfer.setData(\"text/plain\", column.id);\n api.ui.actions.startColumnDrag(column.id);\n }\n\n function handleDragOver(event: DragEvent<HTMLDivElement>) {\n if (!isDropTarget) return;\n // Only a prevented dragover marks an element as a drop target.\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n const bounds = cellRef.current?.getBoundingClientRect();\n if (!bounds) return;\n setDropSide(\n event.clientX < bounds.left + bounds.width / 2 ? \"before\" : \"after\",\n );\n }\n\n function handleDragLeave(event: DragEvent<HTMLDivElement>) {\n // dragleave also fires when the pointer crosses into a child element.\n const next = event.relatedTarget;\n if (next instanceof Node && event.currentTarget.contains(next)) return;\n setDropSide(null);\n }\n\n function handleDrop(event: DragEvent<HTMLDivElement>) {\n event.preventDefault();\n setDropSide(null);\n api.ui.actions.endColumnDrag();\n if (!isDropTarget || !dropSide || !draggedColumnId) return;\n moveColumn({\n table,\n columnId: draggedColumnId,\n targetId: column.id,\n side: dropSide,\n });\n }\n\n function handleDragEnd() {\n setDropSide(null);\n api.ui.actions.endColumnDrag();\n }\n\n /**\n * Sizes the column to its widest mounted content. The container is found\n * from the cell rather than passed down — the header always renders inside\n * the grid's scroll container, and that is the subtree autosize measures.\n */\n function autosize() {\n const container = cellRef.current?.closest<HTMLElement>(\n \"[data-dg-scroll-container]\",\n );\n if (container) autosizeColumn({ table, columnId: column.id, container });\n }\n\n /**\n * Pinned columns are positioned with `getStart()` / `getAfter()`, which sum\n * `column.getSize()`. Fluid (`fr`) columns don't report their rendered width\n * there, so freeze the measured width into `columnSizing` as we pin — that\n * keeps the column looking the same and keeps the offsets exact.\n */\n function setPinned(position: \"left\" | \"right\" | false) {\n if (position && !(column.id in table.store.state.columnSizing)) {\n const width = cellRef.current?.getBoundingClientRect().width;\n if (width) {\n table.setColumnSizing((prev) => ({\n ...prev,\n [column.id]: Math.round(width),\n }));\n }\n }\n column.pin(position);\n }\n\n const menuItems: ReactNode[] = [];\n if (canSort) {\n menuItems.push(\n <Menu.Item\n key=\"sort-asc\"\n leftSection={<ArrowUpIcon size={16} stroke={1.6} />}\n onClick={() => column.toggleSorting(false)}\n >\n {labels.sortAsc}\n </Menu.Item>,\n <Menu.Item\n key=\"sort-desc\"\n leftSection={<ArrowDownIcon size={16} stroke={1.6} />}\n onClick={() => column.toggleSorting(true)}\n >\n {labels.sortDesc}\n </Menu.Item>,\n <Menu.Divider key=\"sort-divider\" />,\n );\n }\n if (canFilter) {\n menuItems.push(\n <Menu.Item\n key=\"filter\"\n leftSection={<FilterIcon size={16} stroke={1.6} />}\n onClick={() => openColumnFilter(api, column.id)}\n >\n {labels.filterMenuItem}\n </Menu.Item>,\n <Menu.Divider key=\"filter-divider\" />,\n );\n }\n if (canGroup) {\n menuItems.push(\n <Menu.Item\n key=\"group\"\n className={isGrouped ? classes.menuItemActive : undefined}\n leftSection={\n isGrouped ? (\n <UngroupIcon size={16} stroke={1.6} />\n ) : (\n <GroupIcon size={16} stroke={1.6} />\n )\n }\n onClick={column.getToggleGroupingHandler()}\n >\n {isGrouped ? labels.ungroup(label) : labels.groupBy(label)}\n </Menu.Item>,\n );\n }\n if (isGroupingActive) {\n // Under the default `groupedColumnMode: \"remove\"` a grouped column is taken\n // out of the grid, so its own header — and the Ungroup item on it — is no\n // longer reachable. The tree column that replaced it carries them instead,\n // which is also where someone would look for them.\n if (column.id === GROUP_COLUMN_ID) {\n for (const groupedId of grouping) {\n const groupedColumn = table.getColumn(groupedId);\n if (!groupedColumn) continue;\n menuItems.push(\n <Menu.Item\n key={`ungroup-${groupedId}`}\n leftSection={<UngroupIcon size={16} stroke={1.6} />}\n onClick={() => groupedColumn.toggleGrouping()}\n >\n {labels.ungroup(getColumnLabel(groupedColumn))}\n </Menu.Item>,\n );\n }\n }\n // Groups only, though `expanded` also holds which rows have their detail\n // panel open — `toggleAllRowsExpanded` would open every one of them from an\n // item that says \"groups\". See resolveExpandAll.\n const expandAllGroups = (expand: boolean) =>\n table.setExpanded(\n resolveExpandAll({\n rows: table.getPrePaginatedRowModel().flatRows,\n expanded: table.store.state.expanded,\n target: \"groups\",\n expand,\n }),\n );\n\n menuItems.push(\n <Menu.Item\n key=\"expand-all\"\n leftSection={<ExpandAllIcon size={16} stroke={1.6} />}\n onClick={() => expandAllGroups(true)}\n >\n {labels.expandAllGroups}\n </Menu.Item>,\n <Menu.Item\n key=\"collapse-all\"\n leftSection={<CollapseAllIcon size={16} stroke={1.6} />}\n onClick={() => expandAllGroups(false)}\n >\n {labels.collapseAllGroups}\n </Menu.Item>,\n );\n }\n if (canGroup || isGroupingActive) {\n menuItems.push(<Menu.Divider key=\"group-divider\" />);\n }\n if (canPin) {\n menuItems.push(\n <Menu.Item\n key=\"pin-left\"\n className={pinnedAt === \"left\" ? classes.menuItemActive : undefined}\n leftSection={<PinLeftIcon size={16} stroke={1.6} />}\n onClick={() => setPinned(pinnedAt === \"left\" ? false : \"left\")}\n >\n {labels.pinLeft}\n </Menu.Item>,\n <Menu.Item\n key=\"pin-right\"\n className={pinnedAt === \"right\" ? classes.menuItemActive : undefined}\n leftSection={<PinRightIcon size={16} stroke={1.6} />}\n onClick={() => setPinned(pinnedAt === \"right\" ? false : \"right\")}\n >\n {labels.pinRight}\n </Menu.Item>,\n );\n if (pinnedAt) {\n menuItems.push(\n <Menu.Item\n key=\"unpin\"\n leftSection={<PinOffIcon size={16} stroke={1.6} />}\n onClick={() => setPinned(false)}\n >\n {labels.unpin}\n </Menu.Item>,\n );\n }\n menuItems.push(<Menu.Divider key=\"pin-divider\" />);\n }\n if (canReorder) {\n // The keyboard path to reordering, and the discoverable one — a header you\n // can drag looks no different from one you cannot.\n const previous = getStepTargetColumn({\n table,\n columnId: column.id,\n direction: -1,\n });\n const next = getStepTargetColumn({\n table,\n columnId: column.id,\n direction: 1,\n });\n if (previous || next) {\n menuItems.push(\n <Menu.Item\n key=\"move-left\"\n disabled={!previous}\n leftSection={<MoveLeftIcon size={16} stroke={1.6} />}\n onClick={() =>\n moveColumnByStep({ table, columnId: column.id, direction: -1 })\n }\n >\n {labels.moveLeft}\n </Menu.Item>,\n <Menu.Item\n key=\"move-right\"\n disabled={!next}\n leftSection={<MoveRightIcon size={16} stroke={1.6} />}\n onClick={() =>\n moveColumnByStep({ table, columnId: column.id, direction: 1 })\n }\n >\n {labels.moveRight}\n </Menu.Item>,\n <Menu.Divider key=\"move-divider\" />,\n );\n }\n }\n if (canResize && isLeaf) {\n menuItems.push(\n <Menu.Item\n key=\"autosize\"\n leftSection={<AutosizeIcon size={16} stroke={1.6} />}\n onClick={autosize}\n >\n {labels.autosizeColumn}\n </Menu.Item>,\n <Menu.Divider key=\"autosize-divider\" />,\n );\n }\n if (canHide) {\n menuItems.push(\n <Menu.Item\n key=\"hide\"\n leftSection={<EyeOffIcon size={16} stroke={1.6} />}\n onClick={() => column.toggleVisibility(false)}\n >\n {labels.hideColumn}\n </Menu.Item>,\n );\n }\n if (canManageColumns) {\n menuItems.push(\n <Menu.Item\n key=\"manage\"\n leftSection={<ColumnsIcon size={16} stroke={1.6} />}\n onClick={() => api.ui.actions.setColumnsPanelOpen(true)}\n >\n {labels.manageColumns}\n </Menu.Item>,\n );\n }\n // A trailing divider reads as a dropped item — drop the divider instead.\n while (menuItems.length > 0 && isDivider(menuItems.at(-1))) {\n menuItems.pop();\n }\n\n // One gate for both ways into the menu — the button and the right-click —\n // so the two can never disagree about which headers have one. A control\n // lane's header is itself a control (select-all, expand-all), so it carries\n // no column menu, and a right-click there falls through to the browser's.\n const hasMenu = isLeaf && menuItems.length > 0 && !isControlColumn(column.id);\n\n const cellClass = [\n classes.headerCell,\n canSort ? classes.headerCellSortable : \"\",\n isDragged ? classes.headerCellDragging : \"\",\n dropSide === \"before\" ? classes.headerCellDropBefore : \"\",\n dropSide === \"after\" ? classes.headerCellDropAfter : \"\",\n layout.isBoundary && pinnedAt === \"left\" ? sticky.stickyLeft : \"\",\n layout.isBoundary && pinnedAt === \"right\" ? sticky.stickyRight : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const cell = (\n <div\n ref={cellRef}\n role=\"columnheader\"\n data-testid={`dg-header-${column.id}`}\n data-active={isSorted || isFiltered}\n data-align={align}\n // A control lane is a fixed track, so it cannot take the cell padding the\n // scale grows for text. See isControlColumn.\n data-control-column={isControlColumn(column.id)}\n // Only meaningful on a sortable column: \"none\" advertises that this\n // header sorts, which is a lie on one that doesn't.\n aria-sort={\n canSort\n ? isSorted\n ? sortDirection\n ? \"descending\"\n : \"ascending\"\n : \"none\"\n : undefined\n }\n className={cellClass}\n // Dropped while a resize is running, so that dragging the separator\n // resizes the column instead of starting to move it. The resize handler\n // records the column on mousedown, before the first pointer move.\n draggable={canReorder && !isResizing}\n onDragStart={canReorder ? handleDragStart : undefined}\n onDragEnd={canReorder ? handleDragEnd : undefined}\n onDragOver={isDropTarget ? handleDragOver : undefined}\n onDragLeave={isDropTarget ? handleDragLeave : undefined}\n onDrop={isDropTarget ? handleDrop : undefined}\n style={{\n left: pinnedAt === \"left\" ? layout.offset : undefined,\n right: pinnedAt === \"right\" ? layout.offset : undefined,\n position: pinnedAt ? \"sticky\" : undefined,\n // From the stacking ladder in TMDataGrid.module.css.\n zIndex: pinnedAt ? \"var(--dg-z-header-pinned-cell, 7)\" : undefined,\n }}\n // Shift+click is \"add to sort\", and the browser would smear a text\n // selection across the headers it passes. Stopped at the one gesture,\n // same as the body rows do for shift-select.\n onMouseDown={\n canSort\n ? (event) => {\n if (event.shiftKey) event.preventDefault();\n }\n : undefined\n }\n onClick={\n canSort\n ? (event) => {\n if (suppressSortRef.current) {\n suppressSortRef.current = false;\n return;\n }\n // TanStack's handler reads the modifier itself: a plain click\n // replaces the sort, Shift+click appends (`isMultiSortEvent`).\n column.getToggleSortingHandler()?.(event);\n }\n : undefined\n }\n >\n {header.isPlaceholder ? null : (\n <Tooltip label={label} openDelay={600} withinPortal disabled={!isLeaf}>\n {/* `data-dg-header-title` is how autosize measures the title text. */}\n <span className={classes.headerTitle} data-dg-header-title>\n {flexRender(column.columnDef.header, header.getContext())}\n </span>\n </Tooltip>\n )}\n\n {isLeaf && (\n <div className={classes.headerActions}>\n {isFiltered && (\n <ActionIcon\n className={classes.headerAction}\n data-pinned-visible=\"true\"\n variant=\"subtle\"\n color=\"gray\"\n size=\"xs\"\n aria-label={labels.filterOn(label)}\n onClick={(event) => {\n event.stopPropagation();\n openColumnFilter(api, column.id);\n }}\n >\n <FilterIcon size={14} stroke={1.6} />\n </ActionIcon>\n )}\n\n {canSort && (\n <ActionIcon\n className={classes.headerAction}\n data-pinned-visible={isSorted}\n variant=\"subtle\"\n color=\"gray\"\n size=\"xs\"\n aria-label={labels.sortColumn(label)}\n onClick={column.getToggleSortingHandler()}\n >\n {sortDirection ? (\n <ArrowDownIcon size={14} stroke={1.6} />\n ) : (\n <ArrowUpIcon size={14} stroke={1.6} />\n )}\n </ActionIcon>\n )}\n\n {/* Shift+click adds a column to the sort (TanStack's own\n `isMultiSortEvent`); the number is its priority. Outside the\n hover-revealed action so an active multi-sort stays readable. */}\n {sortIndex !== null && (\n <span className={classes.sortIndex} data-testid=\"dg-sort-index\">\n {sortIndex}\n </span>\n )}\n\n {hasMenu && (\n <Menu\n opened={menuOpened}\n onChange={setMenuOpened}\n position=\"bottom-start\"\n shadow=\"md\"\n width={220}\n withinPortal\n >\n <Menu.Target>\n <ActionIcon\n className={classes.headerAction}\n // Held visible for the right-click menu too: that one opens at\n // the pointer and is portaled, so the hover that revealed the\n // actions is lost the moment the pointer enters the dropdown.\n data-pinned-visible={menuOpened || contextMenuOpened}\n variant=\"subtle\"\n color=\"gray\"\n size=\"xs\"\n aria-label={labels.columnMenu(label)}\n onClick={(event) => {\n event.stopPropagation();\n setMenuOpened((opened) => !opened);\n }}\n >\n <DotsVerticalIcon size={14} stroke={1.6} />\n </ActionIcon>\n </Menu.Target>\n <Menu.Dropdown onClick={(event) => event.stopPropagation()}>\n {menuItems}\n </Menu.Dropdown>\n </Menu>\n )}\n </div>\n )}\n\n {/* A system lane has no separator at all: it cannot be resized, and the\n hover line reads as a handle that does nothing — the one place the\n separator stops being a divider and starts being a lie. */}\n {!isControlColumn(column.id) && (\n <div\n className={[\n classes.columnSeparator,\n canResize ? classes.columnSeparatorResizable : \"\",\n isResizing ? classes.columnSeparatorActive : \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n // Keeps a drag that starts on the separator from being picked up by\n // the draggable header around it.\n draggable={false}\n onMouseDown={\n canResize\n ? (event) => {\n suppressSortRef.current = true;\n header.getResizeHandler()(event);\n }\n : undefined\n }\n onTouchStart={canResize ? header.getResizeHandler() : undefined}\n onClick={(event) => event.stopPropagation()}\n // The spreadsheet gesture: double-click the divider, the column\n // fits its content. Same measurement as the menu item.\n onDoubleClick={\n canResize\n ? (event) => {\n event.stopPropagation();\n autosize();\n }\n : undefined\n }\n />\n )}\n </div>\n );\n\n if (!hasMenu) return cell;\n\n // A second Menu for the same items, rather than one Menu serving both ways\n // in: the button's dropdown hangs off the button, while a context menu\n // belongs at the pointer, and a Mantine Menu has one target. `menuItems` is\n // built once and rendered by whichever dropdown is open — never both — so\n // the two can't drift apart.\n //\n // The per-header Popover this adds is not the cost the body pays for one per\n // row (see TMDataGridBodyRowGroup): there are as many headers as columns, and\n // they don't re-render on every scroll frame.\n return (\n <Menu\n opened={contextMenuOpened}\n onChange={(opened) => {\n setContextMenuOpened(opened);\n // Right-clicking a header whose button menu is still open would\n // otherwise leave two dropdowns of the same items on screen.\n if (opened) setMenuOpened(false);\n }}\n position=\"bottom-start\"\n shadow=\"md\"\n width={220}\n withinPortal\n >\n <Menu.ContextMenu>{cell}</Menu.ContextMenu>\n <Menu.Dropdown onClick={(event) => event.stopPropagation()}>\n {menuItems}\n </Menu.Dropdown>\n </Menu>\n );\n}\n\nfunction isDivider(node: ReactNode): boolean {\n return (\n typeof node === \"object\" &&\n node !== null &&\n \"type\" in node &&\n node.type === Menu.Divider\n );\n}\n","import type { TMDataGridCellPosition } from \"./cellNavigation\";\n\n/**\n * A selected rectangle of cells, held as the two cells that span it.\n *\n * Two corners rather than a list of cells, because a range is a gesture, not a\n * set: dragging over 40 columns of a 100k-row grid would otherwise build — and\n * rebuild, on every mouse move — a list with millions of entries in it. Two\n * positions describe the same thing and cost nothing to extend.\n *\n * `anchor` is where the gesture started and stays put; `focus` is the end that\n * moves. Which of the two is top-left depends on the direction it was dragged,\n * so nothing here assumes an order — see {@link resolveRangeBounds}.\n */\nexport type TMDataGridCellRange = {\n anchor: TMDataGridCellPosition;\n focus: TMDataGridCellPosition;\n};\n\n/** The rectangle a range covers, in row and column indices, both ends included. */\nexport type TMDataGridRangeBounds = {\n top: number;\n bottom: number;\n left: number;\n right: number;\n};\n\nexport type ResolveRangeBoundsArgs = {\n range: TMDataGridCellRange | null;\n /** Index of a row id among the rows on screen, or `-1`. */\n rowIndexOf: (rowId: string) => number;\n columnIndexOf: (columnId: string) => number;\n};\n\n/**\n * Turns a range into the rectangle to paint and copy, or `null` when either\n * corner no longer exists.\n *\n * A corner goes missing whenever a filter drops its row or a column is hidden,\n * and the honest answer then is that there is no rectangle — better than\n * guessing at a replacement corner and quietly copying cells the user never\n * selected. The range itself is left alone: clearing it here would throw away\n * a selection that comes straight back when the filter is lifted.\n */\nexport function resolveRangeBounds({\n range,\n rowIndexOf,\n columnIndexOf,\n}: ResolveRangeBoundsArgs): TMDataGridRangeBounds | null {\n if (range === null) return null;\n\n const anchorRow = rowIndexOf(range.anchor.rowId);\n const focusRow = rowIndexOf(range.focus.rowId);\n const anchorColumn = columnIndexOf(range.anchor.columnId);\n const focusColumn = columnIndexOf(range.focus.columnId);\n if (\n anchorRow < 0 ||\n focusRow < 0 ||\n anchorColumn < 0 ||\n focusColumn < 0\n ) {\n return null;\n }\n\n return {\n top: Math.min(anchorRow, focusRow),\n bottom: Math.max(anchorRow, focusRow),\n left: Math.min(anchorColumn, focusColumn),\n right: Math.max(anchorColumn, focusColumn),\n };\n}\n\n/** Whether a cell is inside the rectangle. */\nexport function isWithinBounds(\n bounds: TMDataGridRangeBounds | null,\n rowIndex: number,\n columnIndex: number,\n): boolean {\n if (bounds === null) return false;\n return (\n rowIndex >= bounds.top &&\n rowIndex <= bounds.bottom &&\n columnIndex >= bounds.left &&\n columnIndex <= bounds.right\n );\n}\n\n/** How many cells the rectangle covers. `0` for no range at all. */\nexport function boundsCellCount(bounds: TMDataGridRangeBounds | null): number {\n if (bounds === null) return 0;\n return (\n (bounds.bottom - bounds.top + 1) * (bounds.right - bounds.left + 1)\n );\n}\n\n/**\n * Which edges of the rectangle a cell sits on, for the outline.\n *\n * The border is drawn per cell rather than as one box over the top, because the\n * body is a scrolling CSS grid with sticky columns in it: an overlay would have\n * to be positioned against a moving target and would still be wrong the moment\n * a pinned lane slid over it. Four booleans per cell need no positioning at all.\n */\nexport function boundsEdges(\n bounds: TMDataGridRangeBounds | null,\n rowIndex: number,\n columnIndex: number,\n): { top: boolean; bottom: boolean; left: boolean; right: boolean } | null {\n if (!isWithinBounds(bounds, rowIndex, columnIndex) || bounds === null) {\n return null;\n }\n return {\n top: rowIndex === bounds.top,\n bottom: rowIndex === bounds.bottom,\n left: columnIndex === bounds.left,\n right: columnIndex === bounds.right,\n };\n}\n","import type { Column, Row, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\nimport type { TMDataGridRangeBounds } from \"./cellRange\";\nimport { getColumnLabel, isControlColumn } from \"./columnUtils\";\n\n/**\n * The byte order mark Excel looks for before it will read a file as UTF-8.\n * Built from its code point rather than pasted in: a literal BOM is invisible\n * in a source file, and an invisible character nobody can see is one somebody\n * eventually deletes.\n */\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\n/** The selected block, flattened to text. One inner array per row. */\nexport type TMDataGridCellMatrix = Array<Array<string>>;\n\n/**\n * How values are written out.\n *\n * The defaults are the Nordic ones, because they are the ones that need\n * choosing: an Excel running a Swedish, Norwegian, Danish or Finnish locale\n * reads `;` as its list separator and `,` as its decimal mark, and a file\n * written the other way opens as one column of text. Both are settable for a\n * grid whose users run something else.\n */\nexport type TMDataGridCellExportOptions = {\n /** CSV field separator. Defaults to `\";\"`. */\n separator?: string;\n /** Write numbers as `1,5` rather than `1.5`. Defaults to `true`. */\n decimalComma?: boolean;\n /** Column labels as the first row. Defaults to `true`. */\n includeHeaders?: boolean;\n /** Without extension. Defaults to `\"export\"`. */\n fileName?: string;\n};\n\ntype ResolvedExportOptions = Required<TMDataGridCellExportOptions>;\n\nexport const DEFAULT_CELL_EXPORT_OPTIONS: ResolvedExportOptions = {\n separator: \";\",\n decimalComma: true,\n includeHeaders: true,\n fileName: \"export\",\n};\n\n/**\n * One value as text.\n *\n * Deliberately not the rendered cell: what a cell renders is React, and often a\n * badge, a link or an icon rather than the value. The value is what a\n * spreadsheet wants, and it is the one thing every column is guaranteed to\n * have.\n */\nexport function formatExportValue(\n value: unknown,\n { decimalComma }: { decimalComma: boolean },\n): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) return \"\";\n const text = String(value);\n return decimalComma ? text.replace(\".\", \",\") : text;\n }\n if (typeof value === \"string\") return value;\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n // A multiSelect cell holds an array of values; a spreadsheet cell holds one\n // string, so the elements are joined the way they read on screen.\n if (Array.isArray(value)) {\n return value\n .map((entry) => formatExportValue(entry, { decimalComma }))\n .join(\", \");\n }\n // `sv-SE` is ISO-shaped — 2026-07-31, 2026-07-31 14:05:00 — which is both the\n // Nordic form and the one Excel parses as a date rather than as text.\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? \"\" : value.toLocaleString(\"sv-SE\");\n }\n // An object in a cell is a shape the grid cannot know. JSON at least keeps\n // what was there, where `String(value)` would write \"[object Object]\".\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value);\n } catch {\n return \"\";\n }\n }\n return String(value);\n}\n\nexport type BuildCellMatrixArgs = {\n rows: ReadonlyArray<Row<TMDataGridFeatures, TMDataGridRowData>>;\n /** Every visible column, in render order — the same list the bounds index into. */\n columns: ReadonlyArray<Column<TMDataGridFeatures, TMDataGridRowData, unknown>>;\n bounds: TMDataGridRangeBounds;\n includeHeaders: boolean;\n decimalComma: boolean;\n};\n\n/**\n * The selected rectangle as rows of text.\n *\n * The generated lanes — the checkbox, the tree chevron, the details chevron —\n * are dropped even when the rectangle covers them. They hold controls rather\n * than data, so a column of empty strings is all they could contribute, and\n * pasting one into a spreadsheet only shifts everything to its right.\n */\nexport function buildCellMatrix({\n rows,\n columns,\n bounds,\n includeHeaders,\n decimalComma,\n}: BuildCellMatrixArgs): TMDataGridCellMatrix {\n const selectedColumns = columns\n .slice(bounds.left, bounds.right + 1)\n .filter((column) => !isControlColumn(column.id));\n if (selectedColumns.length === 0) return [];\n\n const matrix: TMDataGridCellMatrix = [];\n if (includeHeaders) {\n matrix.push(selectedColumns.map((column) => getColumnLabel(column)));\n }\n\n for (let index = bounds.top; index <= bounds.bottom; index += 1) {\n const row = rows[index];\n if (row === undefined) continue;\n matrix.push(\n selectedColumns.map((column) =>\n formatExportValue(row.getValue(column.id), { decimalComma }),\n ),\n );\n }\n return matrix;\n}\n\n/**\n * The whole grid as rows of text: every filtered and sorted data row — all\n * pages, not the one on screen — by every visible non-control column, in\n * render order.\n *\n * The values are the same ones a cell-range export writes; only the bounds\n * differ. Group rows are left out (their records are the rows themselves),\n * and hidden columns are not exported — what you see is what you get, minus\n * paging.\n */\nexport function buildGridCellMatrix<TData extends RowData>({\n table,\n includeHeaders = DEFAULT_CELL_EXPORT_OPTIONS.includeHeaders,\n decimalComma = DEFAULT_CELL_EXPORT_OPTIONS.decimalComma,\n}: {\n table: TMDataGridTable<TData>;\n includeHeaders?: boolean;\n decimalComma?: boolean;\n}): TMDataGridCellMatrix {\n // The same erasure the context provider performs: the matrix only ever reads\n // generic row and column APIs.\n const erased = table as unknown as TMDataGridTable<TMDataGridRowData>;\n const columns = [\n ...erased.getLeftVisibleLeafColumns(),\n ...erased.getCenterVisibleLeafColumns(),\n ...erased.getRightVisibleLeafColumns(),\n ];\n // The sorted model: after filtering, grouping and sorting, before expansion\n // and paging — so a paged grid exports the whole filtered set, and a grouped\n // grid exports the records under every group whether or not it is open.\n //\n // Walked by hand rather than taken from `flatRows`: in table-core\n // 9.0.0-beta.21 the grouped model lists every leaf twice there (once as a\n // leaf row, once re-parented under its group), and its order puts the\n // groups last. Depth-first over `rows` is exactly render order, once each.\n const rows: Array<Row<TMDataGridFeatures, TMDataGridRowData>> = [];\n const walk = (\n list: ReadonlyArray<Row<TMDataGridFeatures, TMDataGridRowData>>,\n ) => {\n for (const row of list) {\n if (row.getIsGrouped()) walk(row.subRows);\n else rows.push(row);\n }\n };\n walk(erased.getSortedRowModel().rows);\n\n return buildCellMatrix({\n rows,\n columns,\n bounds: {\n top: 0,\n bottom: rows.length - 1,\n left: 0,\n right: columns.length - 1,\n },\n includeHeaders,\n decimalComma,\n });\n}\n\n/**\n * Downloads the whole grid as a CSV for Excel — {@link buildGridCellMatrix}\n * through {@link toExcelCsv}, with the same Nordic defaults and overrides as\n * the cell-range export.\n *\n * No built-in button: wire it to your own toolbar.\n *\n * ```tsx\n * <Button onClick={() => exportGridToCsv({ table: grid.table })}>Export</Button>\n * ```\n */\nexport function exportGridToCsv<TData extends RowData>({\n table,\n options,\n}: {\n table: TMDataGridTable<TData>;\n options?: TMDataGridCellExportOptions;\n}): void {\n const resolved = { ...DEFAULT_CELL_EXPORT_OPTIONS, ...options };\n const matrix = buildGridCellMatrix({\n table,\n includeHeaders: resolved.includeHeaders,\n decimalComma: resolved.decimalComma,\n });\n if (matrix.length === 0) return;\n downloadTextFile({\n fileName: `${resolved.fileName}.csv`,\n text: toExcelCsv(matrix, { separator: resolved.separator }),\n });\n}\n\n/**\n * Quotes a field when it holds something that would otherwise end it early.\n * Doubling the quote is how both CSV and Excel's own clipboard format escape\n * one, so the same rule serves both.\n */\nfunction escapeField(value: string, separator: string): string {\n const needsQuotes =\n value.includes(separator) ||\n value.includes('\"') ||\n value.includes(\"\\n\") ||\n value.includes(\"\\r\");\n return needsQuotes ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\n/**\n * The clipboard format spreadsheets read: tab between cells, CRLF between rows.\n *\n * Tabs rather than commas because that is what Excel, Sheets and Numbers all\n * put on the clipboard themselves — paste it and the cells land in cells. A\n * comma-separated string pastes into a single column, which is the thing this\n * exists to avoid.\n */\nexport function toClipboardText(matrix: TMDataGridCellMatrix): string {\n return matrix\n .map((row) => row.map((value) => escapeField(value, \"\\t\")).join(\"\\t\"))\n .join(\"\\r\\n\");\n}\n\n/**\n * A CSV that opens straight into columns in Excel.\n *\n * Three things make that true, and all three are needed:\n *\n * | Part | Why |\n * | ---- | --- |\n * | `sep=;` first line | Excel's own directive — it stops guessing and uses this |\n * | UTF-8 BOM | without it Excel reads the file as ANSI, and å ä ö arrive broken |\n * | CRLF line endings | what Excel writes, and what its importer is happiest with |\n *\n * The `sep=` line is Excel's alone; other readers show it as a first row. That\n * is the trade this makes — the file is for Excel, and \"it just opens\" is worth\n * more than being a well-behaved CSV nobody was going to feed to a parser.\n */\nexport function toExcelCsv(\n matrix: TMDataGridCellMatrix,\n { separator }: { separator: string },\n): string {\n const body = matrix\n .map((row) => row.map((value) => escapeField(value, separator)).join(separator))\n .join(\"\\r\\n\");\n return `${UTF8_BOM}sep=${separator}\\r\\n${body}\\r\\n`;\n}\n\n/**\n * Puts text on the clipboard, reporting whether it landed.\n *\n * The async clipboard API only resolves for a document that has the focus and a\n * user gesture behind it — both true when this runs off Ctrl+C or a menu item.\n * It is still allowed to reject (a permissions policy, a page that lost focus\n * mid-copy), so the result is a boolean rather than a promise nobody checks.\n */\nexport async function writeClipboardText(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Downloads text as a file, through the one mechanism a library can use: an\n * anchor with an object URL behind it, clicked. Revoked on the next frame —\n * immediately would race the browser's own read of it.\n */\nexport function downloadTextFile({\n fileName,\n text,\n mimeType = \"text/csv;charset=utf-8\",\n}: {\n fileName: string;\n text: string;\n mimeType?: string;\n}): void {\n const url = URL.createObjectURL(new Blob([text], { type: mimeType }));\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = \"none\";\n document.body.append(anchor);\n anchor.click();\n anchor.remove();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n","import { Checkbox, Loader, Menu, type MenuProps, Text } from \"@mantine/core\";\nimport {\n type Cell,\n flexRender,\n type Row,\n type RowData,\n type Table,\n} from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport sticky from \"./sticky.module.css\";\nimport { type TMDataGridRowData, useTMDataGridContext } from \"../TMDataGridContext\";\nimport { TMDataGridFilterPanel } from \"./TMDataGridFilterPanel\";\nimport { TMDataGridHeaderCell } from \"./TMDataGridHeaderCell\";\nimport { getColumnAlign, isControlColumn } from \"../core/columnUtils\";\nimport {\n resolveCellMove,\n type TMDataGridCellPosition,\n} from \"../core/cellNavigation\";\nimport {\n boundsCellCount,\n boundsEdges,\n isWithinBounds,\n resolveRangeBounds,\n} from \"../core/cellRange\";\nimport {\n buildCellMatrix,\n DEFAULT_CELL_EXPORT_OPTIONS,\n downloadTextFile,\n toClipboardText,\n toExcelCsv,\n writeClipboardText,\n type TMDataGridCellExportOptions,\n} from \"../core/cellExport\";\nimport { autosizeColumn } from \"../core/autosize\";\nimport {\n getDisplayedRows,\n getSelectableRowIds,\n resolveRowSelectionClick,\n} from \"../core/rowSelection\";\nimport { SearchIcon } from \"./icons\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\n/** Where a column sits relative to the pinned regions, resolved once per render. */\nexport type TMDataGridColumnLayout = {\n pinnedAt: \"left\" | \"right\" | false;\n /** Distance in px from the grid's left or right edge. */\n offset: number;\n /** Last left-pinned / first right-pinned column — the one that casts the edge. */\n isBoundary: boolean;\n};\n\nconst UNPINNED_LAYOUT: TMDataGridColumnLayout = {\n pinnedAt: false,\n offset: 0,\n isBoundary: false,\n};\n\n/**\n * What Enter and F2 step into. Deliberately the plain list rather than a full\n * tabbable audit: a cell holds a control or it doesn't, and anything exotic\n * enough to fool this is exotic enough to handle its own keys.\n */\nconst FOCUSABLE_IN_CELL = [\n \"button:not([disabled])\",\n \"input:not([disabled])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"a[href]\",\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(\",\");\n\n/**\n * The mounted element for a cell position, or `null` when its row is scrolled\n * out — the normal case for a move that has to scroll before it can focus.\n */\nfunction findCellElement(\n container: HTMLElement,\n cell: TMDataGridCellPosition,\n): HTMLElement | null {\n return container.querySelector<HTMLElement>(\n `[data-cell=\"true\"][data-row-id=\"${CSS.escape(cell.rowId)}\"]` +\n `[data-column-id=\"${CSS.escape(cell.columnId)}\"]`,\n );\n}\n\n/**\n * Scrolls sideways far enough to clear the pinned lanes.\n *\n * `scrollIntoView` cannot do this: the pinned columns are `position: sticky`,\n * so as far as the browser is concerned a cell sliding underneath them is\n * still perfectly visible, and it stops scrolling the moment the cell's edge\n * reaches the container's. The visible edge is the inside of the pinned lane,\n * which only this component knows — it laid the lanes out.\n */\nfunction keepColumnInView({\n container,\n cellElement,\n leftPinnedWidth,\n rightPinnedWidth,\n}: {\n container: HTMLElement;\n cellElement: HTMLElement;\n leftPinnedWidth: number;\n rightPinnedWidth: number;\n}): void {\n const cellRect = cellElement.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const leftBound = containerRect.left + leftPinnedWidth;\n const rightBound = containerRect.right - rightPinnedWidth;\n\n if (cellRect.left < leftBound) {\n container.scrollLeft -= leftBound - cellRect.left;\n } else if (cellRect.right > rightBound) {\n container.scrollLeft += cellRect.right - rightBound;\n }\n}\n\n/**\n * What a cell shows once grouping is in play.\n *\n * A group row carries a cell for every column, but only some of them have\n * anything to say:\n *\n * | Cell | Renders |\n * | ---- | ------- |\n * | On a data row | the column's `cell`, as always |\n * | Placeholder — a grouped column other than this row's own | nothing |\n * | Aggregated, column declares `aggregatedCell` | that |\n * | Aggregated, column declares an `aggregationFn` | the column's `cell`, over the aggregate |\n * | Aggregated, column declares neither | nothing |\n *\n * That last row is the one worth spelling out. Without an aggregation function\n * `getValue()` is `undefined` on a group row, so the column's own renderer\n * would be handed nothing — and a renderer that formats what it gets\n * (`value.toFixed(2)`) would throw. Blank is both the safe answer and the right\n * one: a plain \"group by\" is a tree, not a summary, and a column only joins in\n * once it has been told how.\n */\nfunction renderCellContent(\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>,\n) {\n if (cell.getIsPlaceholder()) return null;\n if (!cell.getIsAggregated()) {\n return flexRender(cell.column.columnDef.cell, cell.getContext());\n }\n const { aggregatedCell, aggregationFn } = cell.column.columnDef;\n if (aggregatedCell !== undefined) {\n return flexRender(aggregatedCell, cell.getContext());\n }\n if (aggregationFn === undefined) return null;\n return flexRender(cell.column.columnDef.cell, cell.getContext());\n}\n\n/**\n * What a cell needs to take part in cell selection, or `undefined` while the\n * feature is off — which is what keeps a plain grid's cells exactly as they\n * were: no tab stop, no `gridcell` role, no coordinates in the DOM.\n *\n * The coordinates are there for the delegated key handler, which reads them off\n * `event.target` rather than closing over per-cell state, and for the effect\n * that puts DOM focus where {@link TMDataGridUiState.focusedCell} says.\n */\nexport type TMDataGridCellNav = {\n rowId: string;\n /** 1-based, for `aria-colindex`. */\n columnIndex: number;\n focused: boolean;\n /** The roving tab stop: `0` on exactly one mounted cell, `-1` on the rest. */\n tabIndex: 0 | -1;\n /** Inside the selected rectangle. Always `false` under `\"single\"`. */\n selected: boolean;\n /**\n * Which sides of the rectangle this cell is on, or `null` when it is not in\n * one. The outline is drawn per cell — see {@link boundsEdges}.\n */\n edges: { top: boolean; bottom: boolean; left: boolean; right: boolean } | null;\n};\n\nfunction TMDataGridBodyCell({\n cell,\n rowHeight,\n layout,\n nav,\n onFocus,\n onMouseDown,\n onMouseEnter,\n onContextMenu,\n}: {\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n rowHeight: number;\n layout: TMDataGridColumnLayout;\n nav?: TMDataGridCellNav;\n onFocus?: () => void;\n onMouseDown?: (event: MouseEvent<HTMLDivElement>) => void;\n onMouseEnter?: () => void;\n onContextMenu?: (event: MouseEvent<HTMLDivElement>) => void;\n}) {\n return (\n <div\n // `gridcell` rather than `cell` is the whole promise of cell selection:\n // it is what tells a screen reader the arrow keys move a cursor here, so\n // it is set together with the tab stop rather than always.\n role={nav ? \"gridcell\" : \"cell\"}\n aria-colindex={nav?.columnIndex}\n tabIndex={nav?.tabIndex}\n // The marker the delegated key handler tests: a key event whose target is\n // a cell is the grid's, one from inside a cell belongs to whatever holds\n // the focus in there.\n data-cell={nav ? true : undefined}\n data-row-id={nav?.rowId}\n // Always present, not only under cell selection: autosize finds a\n // column's mounted cells by it. The cell-navigation selectors also\n // require `data-cell`, so they are unaffected.\n data-column-id={cell.column.id}\n data-focused={nav?.focused}\n aria-selected={nav?.selected}\n data-selected={nav?.selected}\n // One attribute per side rather than a class per combination: the\n // stylesheet draws the outline edge by edge, and sixteen classes for the\n // sixteen corners of a rectangle is not a stylesheet anyone can read.\n data-edge-top={nav?.edges?.top}\n data-edge-bottom={nav?.edges?.bottom}\n data-edge-left={nav?.edges?.left}\n data-edge-right={nav?.edges?.right}\n // Bubbles, so focus landing on a control inside the cell counts as\n // landing on the cell — the ring follows the user into the checkbox\n // rather than being left behind on whichever cell they came from.\n onFocus={onFocus}\n onMouseDown={onMouseDown}\n onMouseEnter={onMouseEnter}\n data-align={getColumnAlign(cell.column)}\n // A control lane is a fixed track, so it cannot take the cell padding the\n // scale grows for text. See isControlColumn.\n data-control-column={isControlColumn(cell.column.id)}\n onContextMenu={onContextMenu}\n className={[\n classes.bodyCell,\n layout.isBoundary && layout.pinnedAt === \"left\" ? sticky.stickyLeft : \"\",\n layout.isBoundary && layout.pinnedAt === \"right\"\n ? sticky.stickyRight\n : \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{\n minHeight: rowHeight,\n left: layout.pinnedAt === \"left\" ? layout.offset : undefined,\n right: layout.pinnedAt === \"right\" ? layout.offset : undefined,\n // The focus ring is drawn inside the cell's own box, so the cell has to\n // be able to stack above its neighbours — a plain one to lift the ring\n // over the pinned lane it sits beside, a pinned one to keep the ring\n // whole while the rest of the row slides under it. Values from the\n // stacking ladder in TMDataGrid.module.css.\n position: layout.pinnedAt\n ? \"sticky\"\n : nav?.focused\n ? \"relative\"\n : undefined,\n zIndex: nav?.focused\n ? \"var(--dg-z-focused-cell, 3)\"\n : layout.pinnedAt\n ? \"var(--dg-z-pinned-cell, 2)\"\n : undefined,\n }}\n >\n <span className={classes.cellContent}>{renderCellContent(cell)}</span>\n </div>\n );\n}\n\n/**\n * The virtualized body rows, wrapped in the single Menu that serves all of them\n * when `rowContextMenu` is set.\n *\n * One instance for the whole body rather than one per row. A Mantine `Menu` is\n * a `Popover`, and a closed Popover still runs its hooks on every render — and\n * the body re-renders on every scroll frame, because that is how virtualization\n * works. Wrapping each of ~20 mounted rows measured a fifth onto a body render;\n * wrapping the group is the same behaviour for one instance.\n *\n * `display: contents` keeps the group out of the grid's layout while still\n * taking the right-click, carrying `Menu.ContextMenu`'s handlers, and passing\n * its inherited `user-select: none` down to the rows.\n */\nfunction TMDataGridBodyRowGroup({\n enabled,\n menuContent,\n menuProps,\n onContextMenu,\n onClose,\n children,\n}: {\n enabled: boolean;\n menuContent: ReactNode;\n menuProps?: Omit<MenuProps, \"opened\" | \"onChange\" | \"children\">;\n onContextMenu: () => void;\n onClose: () => void;\n children: ReactNode;\n}) {\n const rowGroup = (\n <div\n role=\"rowgroup\"\n style={{ display: \"contents\" }}\n // Runs before Mantine's own handler, which `Menu.ContextMenu` composes on\n // top of this one — so the row and cell are known by the time the\n // dropdown is built and opened at the pointer.\n onContextMenu={enabled ? onContextMenu : undefined}\n >\n {children}\n </div>\n );\n\n if (!enabled) return rowGroup;\n\n return (\n <Menu\n // Open only once the render prop has returned something: a row it answers\n // `null` for never opens an empty dropdown.\n opened={menuContent !== null}\n onChange={(opened) => {\n if (!opened) onClose();\n }}\n position=\"bottom-start\"\n shadow=\"md\"\n width={220}\n {...menuProps}\n >\n <Menu.ContextMenu>{rowGroup}</Menu.ContextMenu>\n <Menu.Dropdown>{menuContent}</Menu.Dropdown>\n </Menu>\n );\n}\n\n/** What a `rowContextMenu` render prop is handed for the right-clicked row. */\nexport type TMDataGridRowContextMenuArgs<TData extends RowData> = {\n table: Table<TMDataGridFeatures, TData>;\n row: Row<TMDataGridFeatures, TData>;\n /**\n * The cell under the pointer. `null` only when the right-click landed on the\n * row but on no cell — which a custom cell renderer that stops propagation\n * can cause.\n */\n cell: Cell<TMDataGridFeatures, TData, unknown> | null;\n /**\n * Closes the menu. `Menu.Item` already closes on click (Mantine's\n * `closeOnItemClick`), so this is for content that isn't a menu item.\n */\n close: () => void;\n};\n\n/**\n * Builds the contents of a row's context menu — `Menu.Item`, `Menu.Label`,\n * `Menu.Divider`, `Menu.Sub`, or any other node. The grid owns the `Menu` and\n * its `Menu.Dropdown`; this fills the dropdown.\n */\nexport type TMDataGridRowContextMenu<TData extends RowData> = (\n args: TMDataGridRowContextMenuArgs<TData>,\n) => ReactNode;\n\nexport type TMDataGridTableProps<TData extends RowData> = {\n /**\n * Called when a body row is clicked. Runs in addition to row selection under\n * `selectionMode: \"row\"`, not instead of it.\n */\n onRowClick?: (row: Row<TMDataGridFeatures, TData>) => void;\n /**\n * Contents of the menu a right-click on a row opens, at the pointer. Return\n * `null` to leave a row without one — the browser's own menu stays suppressed\n * either way.\n *\n * ```tsx\n * <TMDataGrid.Table<Employee>\n * rowContextMenu={({ row, close }) => (\n * <>\n * <Menu.Label>{row.original.firstName}</Menu.Label>\n * <Menu.Item onClick={() => open(row.original.id)}>Open</Menu.Item>\n * <Menu.Divider />\n * <Menu.Item color=\"red\" onClick={() => remove(row.original.id)}>\n * Delete\n * </Menu.Item>\n * </>\n * )}\n * />\n * ```\n *\n * Called during render, and only for the row whose menu is open — so it stays\n * a pure function of the row, and cost per row does not matter.\n */\n rowContextMenu?: TMDataGridRowContextMenu<TData>;\n /**\n * Passed to the Mantine `Menu` the grid wraps the row in — `width`, `shadow`,\n * `position`, `transitionProps` and the rest. Its open state is the grid's.\n */\n rowContextMenuProps?: Omit<MenuProps, \"opened\" | \"onChange\" | \"children\">;\n /**\n * How Ctrl+C and the export item write values, under\n * `cellSelection: \"range\"`. Defaults to the Nordic Excel conventions — see\n * {@link TMDataGridCellExportOptions}.\n */\n cellExport?: TMDataGridCellExportOptions;\n /**\n * Called when the scroll approaches the last row — the infinite-scroll\n * hook-in. Append the next page to `data` and the virtualizer keeps its\n * position; fires once per row count, so a pending fetch is not asked\n * again until it lands.\n *\n * ```tsx\n * <TMDataGrid.Table onReachEnd={() => query.fetchNextPage()} />\n * ```\n *\n * Sorting and filtering must be server-side (`manual*`) on a grid that\n * loads this way — the client only ever holds a prefix of the data. Not\n * compatible with `enablePagination`, which slices the same scroll.\n */\n onReachEnd?: () => void;\n /**\n * How many rows before the end {@link onReachEnd} fires at. Defaults to 10.\n */\n reachEndThreshold?: number;\n};\n\n/**\n * The scrollable grid surface. Always virtualized: only the rows inside the\n * viewport (plus overscan) are mounted — which is what makes the default\n * no-pagination mode viable at any row count. Pagination is opt-in via\n * `enablePagination` (or implied by `manualPagination`).\n */\nexport function TMDataGridTable<TData extends RowData = TMDataGridRowData>({\n onRowClick,\n rowContextMenu,\n rowContextMenuProps,\n cellExport,\n onReachEnd,\n reachEndThreshold = 10,\n}: TMDataGridTableProps<TData>) {\n const {\n table,\n ui,\n features,\n labels,\n rowHeight,\n controlSize,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n } = useTMDataGridContext();\n\n // The body depends on every state slice (sorting, filters, paging, sizing,\n // visibility, selection), so it subscribes to the whole table store.\n useSelector(table.store);\n // The active row lives in the chrome store, so it needs its own subscription.\n const highlightedRowId = useSelector(ui, (state) => state.highlightedRowId);\n // As does the focused cell. Selected separately from the row above so a grid\n // with cell selection off never re-renders for it.\n const focusedCell = useSelector(ui, (state) => state.focusedCell);\n const cellRange = useSelector(ui, (state) => state.cellRange);\n\n const { loading, noResultsLabel = labels.noResults } =\n table.options.meta ?? {};\n\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n // Pagination off (the default): every filtered+sorted row, virtualized.\n // Pagination on: the current page; under `manualPagination` TanStack returns\n // the rows as delivered, so the same branch serves server paging.\n const rows = getDisplayedRows(table, features);\n\n /**\n * Whether this row opens a detail panel underneath it.\n *\n * Group rows are out: expanding one opens its children, and they share the\n * `expanded` state with details — so a grouped grid with `renderDetails` set\n * would otherwise render a panel about the group's first record.\n */\n const showsDetails = (row: Row<TMDataGridFeatures, TMDataGridRowData>) =>\n renderDetails !== undefined && !row.getIsGrouped() && row.getIsExpanded();\n\n /**\n * `meta.autoSize` columns, sized once after the first rows are in the DOM.\n * A ref rather than an effect dependency: this must run exactly once per\n * mount, and only for columns no persisted or user width already covers —\n * autosizing again on data changes would fight a width the user has since\n * dragged.\n */\n const autoSizedRef = useRef(false);\n useEffect(() => {\n if (autoSizedRef.current) return;\n autoSizedRef.current = true;\n const container = scrollContainerRef.current;\n if (container === null) return;\n for (const column of orderedColumns) {\n if (column.columnDef.meta?.autoSize !== true) continue;\n if (column.id in table.store.state.columnSizing) continue;\n autosizeColumn({ table, columnId: column.id, container });\n }\n });\n\n // A persisted pageIndex can outlive the data that produced it; TanStack only\n // auto-resets on live filter/sort/data changes, not on restored state. The\n // guard makes the dependency-free effect idempotent.\n useEffect(() => {\n if (!features.pagination) return;\n const pageCount = table.getPageCount();\n if (pageCount > 0 && table.store.state.pagination.pageIndex >= pageCount) {\n table.setPageIndex(pageCount - 1);\n }\n });\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getScrollElement: () => scrollContainerRef.current,\n /**\n * Exact for a plain row, which is fixed at `rowHeight`, and a guess for a\n * row showing a detail panel — the panel is as tall as whatever the\n * consumer renders. Rows are measured whenever details are on (see\n * `measureElement` below), so this only has to hold until the row has been\n * on screen once.\n *\n * Not a `useCallback`, unlike `getItemKey` below it: the virtualizer's\n * measurement cache lists `getItemKey` among its dependencies and not this,\n * so a stable identity here would buy nothing — and the closure has to see\n * the current expansion to answer at all.\n */\n estimateSize: (index: number) => {\n const row = rows[index];\n if (row === undefined) return rowHeight;\n return rowHeight + (showsDetails(row) ? renderDetailsEstHeight : 0);\n },\n /**\n * Zero is never a row: every one carries `minHeight: rowHeight`. An element\n * reports it before layout has run — and always under jsdom, which has no\n * layout at all — and a row cached at zero height stays that way until\n * something resizes it. The estimate stands in until there is a real\n * measurement.\n */\n measureElement: (element, _entry, instance) =>\n element.getBoundingClientRect().height ||\n instance.options.estimateSize(instance.indexFromElement(element)),\n getItemKey: useCallback((index: number) => rows[index]?.id ?? index, [rows]),\n overscan,\n initialRect: { height: 600, width: 1200 },\n });\n\n const virtualItems = virtualizer.getVirtualItems();\n const paddingTop = virtualItems[0]?.start ?? 0;\n const paddingBottom =\n virtualizer.getTotalSize() - (virtualItems.at(-1)?.end ?? 0);\n\n /**\n * Infinite scroll. Latched on the row count rather than debounced: one call\n * per count means a pending fetch is never asked twice, and the append that\n * resolves it changes the count, which re-arms the latch. A failed fetch\n * stays quiet until something changes the rows — retrying is the\n * consumer's call, not a scroll side effect.\n *\n * Effect (not render): `onReachEnd` sets consumer state.\n */\n const reachEndFiredForCountRef = useRef<number | null>(null);\n const warnedReachEndPaginationRef = useRef(false);\n const lastMountedIndex = virtualItems.at(-1)?.index ?? -1;\n useEffect(() => {\n if (onReachEnd === undefined || rows.length === 0) return;\n if (features.pagination && !warnedReachEndPaginationRef.current) {\n warnedReachEndPaginationRef.current = true;\n console.warn(\n \"TMDataGrid: onReachEnd and pagination slice the same scroll — the pager caps the rows, so the end it reaches is the page's. Use one or the other.\",\n );\n }\n if (lastMountedIndex < rows.length - 1 - reachEndThreshold) return;\n if (reachEndFiredForCountRef.current === rows.length) return;\n reachEndFiredForCountRef.current = rows.length;\n onReachEnd();\n });\n\n // The *Visible* variants throughout: `getLeftLeafColumns()` and friends\n // include hidden columns, while the cells below come from\n // `row.getLeftVisibleCells()`, which does not. Mixing the two would lay down\n // a grid track for a column that renders no cell, shifting every column after\n // it out of its header. The tree column is hidden exactly this way while\n // nothing is grouped.\n const leftLeafColumns = table.getLeftVisibleLeafColumns();\n const rightLeafColumns = table.getRightVisibleLeafColumns();\n const centerLeafColumns = table.getCenterVisibleLeafColumns();\n\n const orderedColumns = [\n ...leftLeafColumns,\n ...centerLeafColumns,\n ...rightLeafColumns,\n ];\n\n // Headers and cells must follow the same left → center → right order as the\n // column tracks, otherwise pinning a column would shuffle it out of its lane.\n const centerHeaderGroups = table.getCenterHeaderGroups();\n const leftHeaderGroups = table.getLeftHeaderGroups();\n const rightHeaderGroups = table.getRightHeaderGroups();\n const headerGroups = centerHeaderGroups.map((group, index) => ({\n id: group.id,\n headers: [\n ...(leftHeaderGroups[index]?.headers ?? []),\n ...group.headers,\n ...(rightHeaderGroups[index]?.headers ?? []),\n ],\n }));\n // Unresized columns stay fluid (`minmax(min, flex fr)`) so the grid fills the\n // viewport; dragging a resize handle pins that column to an exact pixel width.\n // minWidth is the sum of those floors — anything wider and the grid would\n // force a horizontal scrollbar it doesn't need.\n //\n // Pinned columns are always exact: their sticky offsets come from\n // `getStart()` / `getAfter()`, which sum `getSize()` and cannot see an `fr`.\n const columnSizing = table.store.state.columnSizing;\n const columnTracks = orderedColumns.map((column) => {\n const isFixed = column.columnDef.minSize === column.columnDef.maxSize;\n const isResized = column.id in columnSizing;\n const isPinned = column.getIsPinned() !== false;\n const minWidth = column.columnDef.minSize ?? 80;\n if (isFixed || isResized || isPinned) {\n return { track: `${column.getSize()}px`, minWidth: column.getSize() };\n }\n return {\n track: `minmax(${minWidth}px, ${column.columnDef.meta?.flex ?? 1}fr)`,\n minWidth,\n };\n });\n const gridTemplateColumns = columnTracks.map((c) => c.track).join(\" \");\n const gridMinWidth = columnTracks.reduce((sum, c) => sum + c.minWidth, 0);\n\n /**\n * Sticky offsets are derived here, from state this component subscribes to,\n * and handed down as props.\n *\n * Deriving them inside the cell via `column.getIsPinned()` /\n * `column.getStart()` looks equivalent but isn't: those are plain calls on a\n * `column` object whose identity survives a pin, so the React Compiler caches\n * the result and the cell keeps rendering with stale pinning. Building the\n * offsets from the same widths as the grid tracks also guarantees the two\n * agree to the pixel.\n */\n const columnLayout = new Map<string, TMDataGridColumnLayout>();\n const widthOf = (columnId: string) =>\n columnTracks[orderedColumns.findIndex((c) => c.id === columnId)]?.minWidth ??\n 0;\n\n let leftOffset = 0;\n for (const column of leftLeafColumns) {\n columnLayout.set(column.id, {\n pinnedAt: \"left\",\n offset: leftOffset,\n isBoundary: column.id === leftLeafColumns.at(-1)?.id,\n });\n leftOffset += widthOf(column.id);\n }\n let rightOffset = 0;\n for (const column of [...rightLeafColumns].reverse()) {\n columnLayout.set(column.id, {\n pinnedAt: \"right\",\n offset: rightOffset,\n isBoundary: column.id === rightLeafColumns[0]?.id,\n });\n rightOffset += widthOf(column.id);\n }\n for (const column of centerLeafColumns) {\n columnLayout.set(column.id, {\n pinnedAt: false,\n offset: 0,\n isBoundary: false,\n });\n }\n const layoutFor = (columnId: string) =>\n columnLayout.get(columnId) ?? UNPINNED_LAYOUT;\n\n const isEmpty = rows.length === 0;\n\n /**\n * The summary row exists by declaration, not by flag: it renders exactly\n * when at least one visible leaf column defines a `footer`. Its cells come\n * from the leaf header group, whose headers sit in the same left → centre →\n * right order as `orderedColumns` — so `layoutFor` and the grid tracks\n * apply unchanged.\n */\n const leafHeaders = headerGroups.at(-1)?.headers ?? [];\n const hasSummaryRow = orderedColumns.some(\n (column) => column.columnDef.footer !== undefined,\n );\n\n // \"row\" mode: the row itself is the selection control, with the modifier\n // conventions of any desktop list — see resolveRowSelectionClick.\n const selectsOnRowClick = features.rowClickSelects;\n const rowIsInteractive =\n selectsOnRowClick || features.highlightRow || onRowClick !== undefined;\n\n /**\n * Group rows sit out every row-level gesture.\n *\n * Not squeamishness: TanStack builds a group row on top of its first leaf's\n * record (`constructRow(table, id, leafRows[0].original, …)`), so an\n * `onRowClick` firing here would hand a consumer a real-looking row that is\n * the wrong one — a detail panel would open on an arbitrary child. The same\n * goes for the highlight, which is what a detail panel follows.\n *\n * Selecting a group is still possible, through its checkbox, which resolves\n * to the descendants rather than to the group itself. See\n * getSelectableRowIds.\n */\n const rowGesturesFor = (row: Row<TMDataGridFeatures, TMDataGridRowData>) =>\n row.getIsGrouped() ? false : rowIsInteractive;\n\n const handleRowActivate = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n modifiers: { toggle: boolean; extend: boolean },\n ) => {\n if (selectsOnRowClick && row.getCanSelect()) {\n const resolved = resolveRowSelectionClick({\n rows,\n rowId: row.id,\n anchorRowId: ui.state.selectionAnchorRowId,\n modifiers,\n selection: table.store.state.rowSelection,\n canReplaceSelection: true,\n });\n table.setRowSelection(resolved.selection);\n ui.actions.setSelectionAnchor(resolved.anchorRowId);\n }\n // Set, never toggle: a second click on the highlighted row must not close\n // the detail panel showing it. Clearing is\n // `ui.actions.setHighlightedRow(null)`.\n if (features.highlightRow) ui.actions.setHighlightedRow(row.id);\n onRowClick?.(row as unknown as Row<TMDataGridFeatures, TData>);\n };\n\n // ---------------------------------------------------------------------------\n // Cell selection\n //\n // Three pieces: the tab stop (which cell the browser can reach), the key\n // handler (which cell the state points at), and the effect (which cell the\n // DOM actually focuses). They are separate because under virtualization the\n // three can disagree for a frame — a move to row 4000 names a cell that has\n // no element yet — and the state is the one that is always right.\n // ---------------------------------------------------------------------------\n const cellSelection = features.cellSelection;\n const cellRangeSelection = features.cellRangeSelection;\n\n /**\n * That a move came from inside the grid, and so should take the DOM focus\n * with it.\n *\n * A ref rather than \"is the focus in the grid?\" asked at the time, because by\n * the time the effect runs the cell the key was pressed on may have unmounted\n * — a PageDown scrolls it away — and the focus with it. The intent survives\n * where the evidence does not.\n */\n const wantsCellFocusRef = useRef(false);\n /** The last position the effect acted on, so it can tell a move from a re-render. */\n const appliedCellRef = useRef<TMDataGridCellPosition | null>(null);\n\n // O(n) per keystroke and per render while a cell is focused. Fine at any row\n // count a grid actually holds, and the alternative — an id→index map rebuilt\n // whenever sorting, filtering or grouping changes — costs more than it saves.\n const focusedRowIndex =\n cellSelection && focusedCell !== null\n ? rows.findIndex((row) => row.id === focusedCell.rowId)\n : -1;\n const focusedColumnIndex =\n cellSelection && focusedCell !== null\n ? orderedColumns.findIndex((column) => column.id === focusedCell.columnId)\n : -1;\n const focusedCellIsMounted =\n focusedRowIndex >= 0 &&\n virtualItems.some((item) => item.index === focusedRowIndex);\n\n /**\n * The one cell in the body that Tab can reach.\n *\n * The focused cell when it is on screen. When it is not — the grid has never\n * been entered, or the user scrolled the focus away with the wheel — the\n * first mounted cell stands in, so the body always has exactly one tab stop.\n * Without the fallback, scrolling the focused row out of the DOM would take\n * the grid out of the tab order entirely.\n */\n const firstMountedRow = rows[virtualItems[0]?.index ?? -1];\n const tabStopCell: TMDataGridCellPosition | null = !cellSelection\n ? null\n : focusedCellIsMounted && focusedCell !== null\n ? focusedCell\n : firstMountedRow && orderedColumns[0]\n ? { rowId: firstMountedRow.id, columnId: orderedColumns[0].id }\n : null;\n\n const isCellAt = (\n position: TMDataGridCellPosition | null,\n rowId: string,\n columnId: string,\n ) => position !== null && position.rowId === rowId && position.columnId === columnId;\n\n // The rectangle, resolved from ids to the indices the cells are rendered at.\n // `null` whenever a corner has been filtered or hidden away — the range keeps\n // its ids, so lifting the filter brings the selection back.\n const rangeBounds = resolveRangeBounds({\n range: cellRangeSelection ? cellRange : null,\n rowIndexOf: (rowId) => rows.findIndex((row) => row.id === rowId),\n columnIndexOf: (columnId) =>\n orderedColumns.findIndex((column) => column.id === columnId),\n });\n\n /**\n * Extends the rectangle to a cell, or lays a new one-cell rectangle down.\n *\n * The anchor is what tells the two apart: extending keeps it and moves the\n * far corner, starting drops it on the cell under the pointer. Every gesture\n * that selects cells is one of these two.\n */\n const setRangeTo = (\n cell: TMDataGridCellPosition,\n { extend }: { extend: boolean },\n ) => {\n if (!cellRangeSelection) return;\n const anchor = extend ? (cellRange?.anchor ?? cell) : cell;\n ui.actions.setCellRange({ anchor, focus: cell });\n };\n\n /**\n * What a copy or an export would take.\n *\n * The rectangle when there is one, and the focused cell on its own when there\n * is not — under `\"single\"` there never is one, and under `\"range\"` there is\n * none until the first gesture. Copying the one cell the user is on is what\n * every spreadsheet does, so the two cases collapse into the same block here\n * rather than into two paths through the export code.\n */\n const selectionBounds =\n rangeBounds ??\n (cellSelection && focusedRowIndex >= 0 && focusedColumnIndex >= 0\n ? {\n top: focusedRowIndex,\n bottom: focusedRowIndex,\n left: focusedColumnIndex,\n right: focusedColumnIndex,\n }\n : null);\n const selectedCellCount = boundsCellCount(selectionBounds);\n /**\n * How many of the selected columns have anything to export.\n *\n * The generated lanes are part of the selection — they take the tint and the\n * outline, so the block stays a rectangle and the keyboard still reaches the\n * checkbox — but they hold controls rather than values. A rectangle covering\n * only those has nothing to copy, and the items that would say otherwise are\n * disabled rather than quietly doing nothing.\n */\n const selectedDataColumnCount =\n selectionBounds === null\n ? 0\n : orderedColumns\n .slice(selectionBounds.left, selectionBounds.right + 1)\n .filter((column) => !isControlColumn(column.id)).length;\n\n const exportOptions = { ...DEFAULT_CELL_EXPORT_OPTIONS, ...cellExport };\n // Sticky across menus, the way a checkbox in a dialog is: a user who exports\n // with headers once almost always wants them the next time too.\n const [exportIncludesHeaders, setExportIncludesHeaders] = useState(\n exportOptions.includeHeaders,\n );\n const buildSelectionMatrix = (includeHeaders: boolean) =>\n selectionBounds === null\n ? []\n : buildCellMatrix({\n rows,\n columns: orderedColumns,\n bounds: selectionBounds,\n includeHeaders,\n decimalComma: exportOptions.decimalComma,\n });\n\n /**\n * Ctrl+C. Values only, no header row — Excel's own copy does not include one\n * either, and a header pasted into the middle of a sheet is a row of text\n * where numbers were expected. The export menu is where headers are offered,\n * because a file is a document and a clipboard is a fragment.\n */\n const copySelection = async () => {\n const matrix = buildSelectionMatrix(false);\n if (matrix.length === 0) return;\n await writeClipboardText(toClipboardText(matrix));\n };\n\n /**\n * Whether a drag is laying down a rectangle right now.\n *\n * State rather than a ref, because the cells only listen for `mouseenter`\n * while it is true — one re-render at each end of the gesture buys a body\n * that is not running a handler per cell the rest of the time.\n */\n const [isDraggingRange, setIsDraggingRange] = useState(false);\n\n // The drag ends wherever the button comes up, which is routinely outside the\n // grid — over the scrollbar, or past the window edge. Only the window hears\n // that, so only the window can end it.\n useEffect(() => {\n if (!isDraggingRange) return;\n const stop = () => setIsDraggingRange(false);\n window.addEventListener(\"mouseup\", stop);\n return () => window.removeEventListener(\"mouseup\", stop);\n }, [isDraggingRange]);\n\n const startRangeDrag = (\n position: TMDataGridCellPosition,\n { extend }: { extend: boolean },\n ) => {\n ui.actions.setFocusedCell(position);\n setRangeTo(position, { extend });\n // A Shift+click is a single act, not the start of one — there is nothing\n // left to drag once the far corner has been named.\n if (!extend) setIsDraggingRange(true);\n };\n\n const exportSelectionCsv = (includeHeaders: boolean) => {\n const matrix = buildSelectionMatrix(includeHeaders);\n if (matrix.length === 0) return;\n downloadTextFile({\n fileName: `${exportOptions.fileName}.csv`,\n text: toExcelCsv(matrix, { separator: exportOptions.separator }),\n });\n };\n\n /**\n * Moves the focus, and takes the selection with it.\n *\n * `extend` is the Shift key: held, the rectangle grows from wherever it was\n * anchored; released, it collapses onto the cell just moved to. Collapsing\n * rather than clearing keeps the invariant the copy path relies on — the\n * selection is always the block Ctrl+C would take, even when that block is\n * one cell.\n */\n const moveFocusedCell = (\n coords: { rowIndex: number; columnIndex: number },\n { extend }: { extend: boolean } = { extend: false },\n ) => {\n const row = rows[coords.rowIndex];\n const column = orderedColumns[coords.columnIndex];\n if (!row || !column) return;\n const cell = { rowId: row.id, columnId: column.id };\n // The state moves; the effect below is what makes the DOM follow, because\n // the element for an off-screen row does not exist yet to be focused.\n wantsCellFocusRef.current = true;\n ui.actions.setFocusedCell(cell);\n setRangeTo(cell, { extend });\n };\n\n /**\n * Space, from a cell. Checkbox semantics rather than click semantics: it adds\n * to the selection instead of replacing it, so a keyboard user builds one the\n * way they would by ticking boxes — which is what the key has taken over from.\n *\n * Group rows work because the resolver expands a tick to the descendants they\n * stand for. A grid with no selection at all falls back to the highlight,\n * which is the only thing \"pick this row\" can mean there.\n */\n const selectRowFromCell = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n { extend }: { extend: boolean },\n ) => {\n if (features.rowSelection && getSelectableRowIds(row).length > 0) {\n const resolved = resolveRowSelectionClick({\n rows,\n rowId: row.id,\n anchorRowId: ui.state.selectionAnchorRowId,\n modifiers: { toggle: !extend, extend },\n selection: table.store.state.rowSelection,\n canReplaceSelection: false,\n });\n table.setRowSelection(resolved.selection);\n ui.actions.setSelectionAnchor(resolved.anchorRowId);\n return;\n }\n if (features.highlightRow && !row.getIsGrouped()) {\n ui.actions.setHighlightedRow(row.id);\n }\n };\n\n /**\n * One handler on the grid rather than one per cell: the body mounts a few\n * hundred cells and remounts them on every scroll frame, and this closes over\n * `rows` and `orderedColumns` — which every cell would otherwise have to be\n * handed just in case it is the one that gets a key.\n *\n * The cell it is about comes off `event.target`, which is where the\n * coordinate attributes are for.\n */\n const handleGridKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n\n // Focus is on something inside a cell — a checkbox, a link, an editor. Its\n // keys are its own; the one the grid still answers is the way back out.\n if (target.dataset.cell !== \"true\") {\n if (event.key !== \"Escape\") return;\n const cellElement = target.closest<HTMLElement>('[data-cell=\"true\"]');\n if (cellElement === null) return;\n event.preventDefault();\n cellElement.focus();\n return;\n }\n\n const { rowId, columnId } = target.dataset;\n if (rowId === undefined || columnId === undefined) return;\n const rowIndex = rows.findIndex((row) => row.id === rowId);\n const columnIndex = orderedColumns.findIndex(\n (column) => column.id === columnId,\n );\n if (rowIndex < 0 || columnIndex < 0) return;\n\n // Ctrl+C over the selection. Claimed rather than left to the browser: the\n // native copy of a grid whose rows are mostly not in the DOM would take the\n // twenty that happen to be mounted, in whatever shape the CSS left them.\n if (\n (event.ctrlKey || event.metaKey) &&\n (event.key === \"c\" || event.key === \"C\")\n ) {\n if (selectionBounds === null) return;\n event.preventDefault();\n void copySelection();\n return;\n }\n\n // Step into the cell. The pair Excel and AG Grid both use, and the pair the\n // editor will take over: F2 has never meant anything else, and Enter is\n // what a keyboard user reaches for. Nothing to step into leaves the key\n // alone rather than swallowing it.\n if (event.key === \"Enter\" || event.key === \"F2\") {\n const interactive = target.querySelector<HTMLElement>(FOCUSABLE_IN_CELL);\n if (interactive === null) return;\n event.preventDefault();\n interactive.focus();\n return;\n }\n\n // Escape drops the rectangle back to the one cell, as it drops the marching\n // ants in a spreadsheet. The focus stays where it is — Escape is about the\n // selection, not about leaving the grid.\n if (event.key === \"Escape\") {\n if (cellRange === null) return;\n event.preventDefault();\n setRangeTo({ rowId, columnId }, { extend: false });\n return;\n }\n\n // Space selects the row, from any of its cells.\n //\n // Not routed through `handleRowActivate`, which is the *click* path and only\n // selects in `\"row\"` mode: with the cell cursor on, the checkbox is no\n // longer a tab stop (see useCellControlTabIndex), so this is the keyboard's\n // way to a selection under every mode that has one — checkbox included.\n if (event.key === \" \") {\n event.preventDefault();\n const row = rows[rowIndex];\n if (row) selectRowFromCell(row, { extend: event.shiftKey });\n return;\n }\n\n const next = resolveCellMove({\n key: event.key,\n ctrlKey: event.ctrlKey || event.metaKey,\n from: { rowIndex, columnIndex },\n rowCount: rows.length,\n columnCount: orderedColumns.length,\n pageRows: Math.max(\n 1,\n Math.floor((scrollContainerRef.current?.clientHeight ?? 0) / rowHeight) -\n 1,\n ),\n });\n if (next === null) return;\n // Claimed even when the move was clamped at an edge: letting an arrow\n // through at the last row would scroll the body out from under a focus that\n // did not move.\n event.preventDefault();\n if (next.rowIndex === rowIndex && next.columnIndex === columnIndex) return;\n // Shift extends the rectangle instead of collapsing it — the same key that\n // extends a text selection, a file list and a spreadsheet range.\n moveFocusedCell(next, { extend: event.shiftKey && cellRangeSelection });\n };\n\n /**\n * Puts the DOM where the state says, once the state has moved.\n *\n * No dependency array, like the page-clamp effect above: the interesting\n * moment is not a state change but the render after the virtualizer mounted\n * the row that was scrolled to, and a scroll is not in any dependency list.\n * Every path out of here is a ref comparison, so the cost of running it on\n * each frame is nil.\n */\n useEffect(() => {\n if (!cellSelection) return;\n const container = scrollContainerRef.current;\n if (container === null) return;\n\n if (focusedCell !== appliedCellRef.current) {\n appliedCellRef.current = focusedCell;\n // Bring the row on screen first — this is what makes a cell that is not\n // mounted focusable at all, one frame later.\n if (focusedRowIndex >= 0) {\n virtualizer.scrollToIndex(focusedRowIndex, { align: \"auto\" });\n }\n }\n if (focusedCell === null) {\n wantsCellFocusRef.current = false;\n return;\n }\n\n // Never take the focus from elsewhere on the page. A consumer moving the\n // cell while the user is typing in a form somewhere means \"move the ring\",\n // not \"move the caret\" — the scroll above already did the visible part.\n if (\n !wantsCellFocusRef.current &&\n !container.contains(document.activeElement)\n ) {\n return;\n }\n\n const cellElement = findCellElement(container, focusedCell);\n // Still scrolling. The intent stays up, and the next render tries again.\n if (cellElement === null) return;\n wantsCellFocusRef.current = false;\n // Focus is already inside — on the control Enter stepped into. The cell is\n // where the ring belongs, so there is nothing to move.\n if (cellElement.contains(document.activeElement)) return;\n\n // The vertical half is the virtualizer's, and it has already been asked.\n cellElement.focus({ preventScroll: true });\n if (layoutFor(focusedCell.columnId).pinnedAt === false) {\n keepColumnInView({\n container,\n cellElement,\n leftPinnedWidth: leftOffset,\n rightPinnedWidth: rightOffset,\n });\n }\n });\n\n // Which row's context menu is open, and which cell it was opened from.\n const [contextMenuTarget, setContextMenuTarget] = useState<{\n rowId: string;\n columnId: string | null;\n } | null>(null);\n const closeContextMenu = () => setContextMenuTarget(null);\n\n // Row and cell each record themselves on the way up, so that by the time the\n // rowgroup's handler opens the menu it knows what was hit. Refs rather than\n // state: written and read inside the same event, before the render it causes.\n const contextMenuRowRef = useRef<string | null>(null);\n const contextMenuColumnRef = useRef<string | null>(null);\n\n const handleContextMenu = () => {\n const rowId = contextMenuRowRef.current;\n const columnId = contextMenuColumnRef.current;\n contextMenuRowRef.current = null;\n contextMenuColumnRef.current = null;\n\n // A right-click inside the selection is about the selection and leaves it\n // alone; one outside moves it first, so the menu never offers to copy a\n // block somewhere else on the screen. Spreadsheets and file managers both\n // behave this way, and the alternative — exporting cells the user cannot\n // see the outline of — is the kind of surprise that ends in a support call.\n if (cellSelection && rowId !== null && columnId !== null) {\n const rowIndex = rows.findIndex((row) => row.id === rowId);\n const columnIndex = orderedColumns.findIndex(\n (column) => column.id === columnId,\n );\n if (!isWithinBounds(selectionBounds, rowIndex, columnIndex)) {\n ui.actions.setFocusedCell({ rowId, columnId });\n setRangeTo({ rowId, columnId }, { extend: false });\n }\n }\n\n setContextMenuTarget(rowId === null ? null : { rowId, columnId });\n };\n\n const contextMenuRow =\n contextMenuTarget === null\n ? undefined\n : rows.find((row) => row.id === contextMenuTarget.rowId);\n\n /**\n * Built for the open row only, so a consumer's render prop is called once per\n * opened menu rather than once per mounted row. `null` back from it means\n * this row has no menu, which is also how the menu stays shut.\n *\n * The casts put back the concrete row type the context boundary erased — the\n * same crossing `onRowClick` makes.\n */\n const rowMenuContent =\n rowContextMenu &&\n contextMenuTarget &&\n contextMenuRow &&\n !contextMenuRow.getIsGrouped()\n ? rowContextMenu({\n table: table as unknown as Table<TMDataGridFeatures, TData>,\n row: contextMenuRow as unknown as Row<TMDataGridFeatures, TData>,\n cell: (contextMenuRow\n .getAllCells()\n .find((cell) => cell.column.id === contextMenuTarget.columnId) ??\n null) as unknown as Cell<TMDataGridFeatures, TData, unknown> | null,\n close: closeContextMenu,\n }) ?? null\n : null;\n\n /**\n * The built-in half of the menu: what to do with the cells that are selected.\n *\n * Offered under `\"range\"` only. Under `\"single\"` the selection is always the\n * one cell the user is standing on, and a menu whose every item acts on it\n * would be a menu about nothing much — Ctrl+C still copies it.\n */\n const cellMenuContent =\n cellRangeSelection && contextMenuTarget !== null && selectionBounds !== null ? (\n <>\n <Menu.Label>{labels.cellCount(selectedCellCount)}</Menu.Label>\n <Menu.Item\n disabled={selectedDataColumnCount === 0}\n onClick={() => void copySelection()}\n >\n {labels.copy}\n </Menu.Item>\n <Menu.Item\n disabled={selectedDataColumnCount === 0}\n onClick={() => exportSelectionCsv(exportIncludesHeaders)}\n >\n {labels.exportCsv}\n </Menu.Item>\n {/* Stays open on click: it is the setting the item above reads, and\n reopening the menu to change your mind about headers is a worse\n answer than one that lets you see the box tick. */}\n <Menu.Item\n closeMenuOnClick={false}\n onClick={() => setExportIncludesHeaders((previous) => !previous)}\n >\n <Checkbox\n size=\"xs\"\n checked={exportIncludesHeaders}\n label={labels.includeHeaders}\n // The item owns the click; the box only shows what it did.\n readOnly\n styles={{ input: { cursor: \"pointer\" } }}\n />\n </Menu.Item>\n </>\n ) : null;\n\n /**\n * The two halves, in the order they are about: the cells first, since the\n * right-click landed on one, then whatever the consumer offers for the row.\n */\n const contextMenuContent =\n cellMenuContent === null && rowMenuContent === null ? null : (\n <>\n {cellMenuContent}\n {cellMenuContent !== null && rowMenuContent !== null && <Menu.Divider />}\n {rowMenuContent}\n </>\n );\n\n /**\n * The dropdown is anchored to a fixed viewport point, so it does not travel\n * with the row when the body scrolls — and under virtualization the row it\n * belongs to may unmount entirely. Closing is the honest answer, and matches\n * what every desktop context menu does.\n */\n const handleScroll = contextMenuTarget ? closeContextMenu : undefined;\n\n return (\n <div className={classes.tableWrapper}>\n <div\n ref={scrollContainerRef}\n className={classes.scrollContainer}\n // How autosize finds the measurable subtree from a header cell.\n data-dg-scroll-container\n onScroll={handleScroll}\n >\n <div\n // A `table` is content; a `grid` is a widget with a keyboard cursor\n // in it. Which one this is depends on whether cell selection is on,\n // and saying `grid` without one would promise arrow keys that do\n // nothing.\n role={cellSelection ? \"grid\" : \"table\"}\n aria-multiselectable={\n cellSelection && features.rowSelection && features.multiRowSelection\n ? true\n : undefined\n }\n onKeyDown={cellSelection ? handleGridKeyDown : undefined}\n // A drag across cells is a selection gesture, and the browser's own\n // text selection would follow the pointer through it. Only while the\n // drag runs, so copying a cell value with the mouse still works.\n data-range-dragging={isDraggingRange || undefined}\n className={classes.grid}\n // Virtualization means most rows are not in the DOM, so the counts\n // have to be stated rather than inferred from what is rendered. Every\n // row carries its aria-rowindex for the same reason.\n aria-rowcount={\n rows.length + headerGroups.length + (hasSummaryRow ? 1 : 0)\n }\n aria-colcount={orderedColumns.length}\n style={{ gridTemplateColumns, minWidth: gridMinWidth }}\n >\n <div role=\"rowgroup\" style={{ display: \"contents\" }}>\n {headerGroups.map((headerGroup, groupIndex) => (\n <div\n key={headerGroup.id}\n role=\"row\"\n aria-rowindex={groupIndex + 1}\n className={classes.headerRow}\n >\n {headerGroup.headers.map((header) => (\n <TMDataGridHeaderCell\n key={header.id}\n header={header}\n layout={layoutFor(header.column.id)}\n />\n ))}\n </div>\n ))}\n </div>\n\n {paddingTop > 0 && (\n <div aria-hidden style={{ gridColumn: \"1/-1\", height: paddingTop }} />\n )}\n\n <TMDataGridBodyRowGroup\n // Under `\"range\"` the grid has a menu of its own to offer, so the\n // wrapper goes on even without a consumer's `rowContextMenu`.\n enabled={rowContextMenu !== undefined || cellRangeSelection}\n menuContent={contextMenuContent}\n menuProps={rowContextMenuProps}\n onContextMenu={handleContextMenu}\n onClose={closeContextMenu}\n >\n {virtualItems.map((virtualItem) => {\n const row = rows[virtualItem.index];\n if (!row) return null;\n const isGroupRow = row.getIsGrouped();\n const isInteractive = rowGesturesFor(row);\n // Cell selection takes the body's tab stop off the row and puts\n // it on a cell — two stops per row would make Tab a way of\n // walking the grid, which is what the arrow keys are for. Space\n // on a cell keeps the selection reachable; see handleGridKeyDown.\n const takesKeyboard =\n !isGroupRow &&\n !cellSelection &&\n (selectsOnRowClick || features.highlightRow);\n return (\n <div\n key={virtualItem.key}\n role=\"row\"\n aria-rowindex={virtualItem.index + headerGroups.length + 1}\n data-testid={`dg-row-${row.id}`}\n // Only measured when details are on: without them every row\n // is exactly `rowHeight`, and the estimate above is already\n // the answer — so a plain grid keeps its ResizeObserver-free\n // body. `measureElement` is a stable instance method and\n // returns nothing, so it can be the ref itself.\n //\n // `data-index` is how the virtualizer maps the observed\n // element back to its item. The panel is inside this element,\n // so what gets measured is the row *and* its detail — which\n // is the whole reason no second virtual item is needed.\n data-index={renderDetails ? virtualItem.index : undefined}\n ref={renderDetails ? virtualizer.measureElement : undefined}\n // The tree's own rows. `data-grouped` rather than a class, to\n // match how the rest of the row's state is published — and so\n // a consumer can restyle them without reaching into modules.\n data-grouped={isGroupRow}\n data-depth={row.depth}\n // Gated on the flag, not just on `getIsSelected()`: under\n // `\"highlight\"` there is no selection, but `rowSelection` may\n // still hold ids from before the mode changed — TanStack never\n // prunes it — and a row must not report itself selected in a\n // mode where selecting is not a thing.\n data-selected={features.rowSelection && row.getIsSelected()}\n // Being selected is state; painting it is a display choice, so\n // the two are separate attributes.\n data-selected-bg={\n features.rowSelection &&\n features.showSelectedBackground &&\n row.getIsSelected()\n }\n // The highlighted row is its own concept, so its own attribute\n // pair — `data-highlighted` / `aria-current` against\n // `data-selected` / `aria-selected` for selection. Under\n // `\"checkboxAndHighlight\"` a row can carry both.\n //\n // Not `data-active`: header cells already use that for\n // sorted-or-filtered, and Mantine puts it on its own controls,\n // so a consumer styling or querying rows by it would cast far\n // wider than they meant to.\n data-highlighted={\n features.highlightRow && row.id === highlightedRowId\n }\n // The menu is anchored to the rowgroup, so Mantine's own\n // `data-expanded` lands there rather than on a row. This is\n // what says which row the open menu is about.\n data-context-menu={\n contextMenuContent !== null &&\n contextMenuTarget?.rowId === row.id\n }\n data-selects-on-click={selectsOnRowClick && !isGroupRow}\n aria-selected={\n features.rowSelection ? row.getIsSelected() : undefined\n }\n aria-current={\n features.highlightRow && row.id === highlightedRowId\n ? true\n : undefined\n }\n className={classes.bodyRow}\n style={{\n minHeight: rowHeight,\n cursor: isInteractive ? \"pointer\" : undefined,\n }}\n // Keyboard parity with the checkbox the row replaces.\n tabIndex={takesKeyboard ? 0 : undefined}\n // Shift-click extends the browser's text selection across\n // every row it passes. `user-select: none` would fix it too,\n // but at the cost of ever copying a cell value, so the smear\n // is stopped at the one gesture that causes it.\n onMouseDown={\n selectsOnRowClick && !isGroupRow\n ? (event) => {\n if (event.shiftKey) event.preventDefault();\n }\n : undefined\n }\n onClick={\n isInteractive\n ? (event) =>\n handleRowActivate(row, {\n toggle: event.ctrlKey || event.metaKey,\n extend: event.shiftKey,\n })\n : undefined\n }\n onKeyDown={\n takesKeyboard\n ? (event) => {\n if (event.key !== \" \" && event.key !== \"Enter\") return;\n if (event.target !== event.currentTarget) return;\n event.preventDefault();\n // Space/Enter toggle rather than replace, so a\n // keyboard-only user can still build a selection.\n handleRowActivate(row, {\n toggle: true,\n extend: event.shiftKey,\n });\n }\n : undefined\n }\n // Bubbles to the rowgroup, where the menu opens — so the row\n // is recorded before the dropdown is built.\n //\n // A group row records itself only for the cell menu, which is\n // about the cells it covers. `rowContextMenu` is still never\n // called for one: TanStack builds a group row on its first\n // child's record, so a render prop reaching for `row.original`\n // would be handed a real employee that has nothing to do with\n // the group — see where the content is built. The browser menu\n // stays suppressed over them either way.\n onContextMenu={\n (rowContextMenu && !isGroupRow) || cellRangeSelection\n ? () => {\n contextMenuRowRef.current = row.id;\n }\n : undefined\n }\n >\n {[\n ...row.getLeftVisibleCells(),\n ...row.getCenterVisibleCells(),\n ...row.getRightVisibleCells(),\n ].map((cell, cellIndex) => (\n <TMDataGridBodyCell\n key={cell.id}\n cell={cell}\n rowHeight={rowHeight}\n layout={layoutFor(cell.column.id)}\n // The cells come out in the same left → centre → right\n // order as `orderedColumns`, which is what lets the index\n // here stand for the column index everywhere else.\n nav={\n cellSelection\n ? {\n rowId: row.id,\n columnIndex: cellIndex + 1,\n focused: isCellAt(\n focusedCell,\n row.id,\n cell.column.id,\n ),\n tabIndex: isCellAt(\n tabStopCell,\n row.id,\n cell.column.id,\n )\n ? 0\n : -1,\n // \"Selected\" means \"in the block Ctrl+C would\n // take\" — which under `\"single\"` is the one cell\n // the user is standing on.\n selected: cellRangeSelection\n ? isWithinBounds(\n rangeBounds,\n virtualItem.index,\n cellIndex,\n )\n : isCellAt(focusedCell, row.id, cell.column.id),\n edges: boundsEdges(\n rangeBounds,\n virtualItem.index,\n cellIndex,\n ),\n }\n : undefined\n }\n onFocus={\n cellSelection\n ? () =>\n ui.actions.setFocusedCell({\n rowId: row.id,\n columnId: cell.column.id,\n })\n : undefined\n }\n onMouseDown={\n cellRangeSelection\n ? (event) => {\n // Right-click is the menu's; the middle button is\n // the browser's.\n if (event.button !== 0) return;\n // Shift+click would otherwise smear the browser's\n // own text selection across everything between\n // the two cells.\n if (event.shiftKey) event.preventDefault();\n wantsCellFocusRef.current = true;\n startRangeDrag(\n { rowId: row.id, columnId: cell.column.id },\n { extend: event.shiftKey },\n );\n }\n : undefined\n }\n // Only bound while a drag is running, so the other 99% of\n // the time the body carries no pointer handlers per cell.\n onMouseEnter={\n cellRangeSelection && isDraggingRange\n ? () =>\n setRangeTo(\n { rowId: row.id, columnId: cell.column.id },\n { extend: true },\n )\n : undefined\n }\n onContextMenu={\n rowContextMenu || cellRangeSelection\n ? () => {\n contextMenuColumnRef.current = cell.column.id;\n }\n : undefined\n }\n />\n ))}\n\n {/* A second grid row inside the row element, on the same\n subgrid tracks — which is what lets one measurement cover\n both. A cell spanning every column rather than a row of\n its own, so the row keeps holding exactly one row's worth\n of content and `aria-rowcount` still counts records. */}\n {showsDetails(row) && (\n <div\n role=\"cell\"\n aria-colspan={orderedColumns.length}\n data-testid={`dg-details-${row.id}`}\n className={classes.detailsCell}\n // The row underneath may select, highlight or open a\n // context menu. A panel is content, not part of that\n // gesture surface — and stopping the right-click here is\n // what leaves the browser's own menu working for a link\n // or an input inside it.\n onClick={(event) => event.stopPropagation()}\n onContextMenu={(event) => event.stopPropagation()}\n >\n {/* No cast back to `TData`: the context erased the row\n type, and the renderer reaching this point was typed\n against the consumer's own at the `useTMDataGrid`\n call. */}\n {renderDetails?.({ table, row })}\n </div>\n )}\n </div>\n );\n })}\n </TMDataGridBodyRowGroup>\n\n {isEmpty && loading === true && (\n <div role=\"row\" className={classes.messageRow}>\n <Loader size=\"lg\" aria-label={labels.loading} />\n </div>\n )}\n\n {isEmpty && loading !== true && (\n <div role=\"row\" className={classes.messageRow}>\n <SearchIcon size={40} stroke={1.4} opacity={0.4} />\n <Text size={controlSize} c=\"dimmed\">\n {noResultsLabel}\n </Text>\n </div>\n )}\n\n {paddingBottom > 0 && (\n <div\n aria-hidden\n style={{ gridColumn: \"1/-1\", height: paddingBottom }}\n />\n )}\n\n {/* Sticky along the bottom edge, the way the header is along the\n top. `flexRender` with the header context, which is what a\n TanStack `footer` renderer is written against. */}\n {hasSummaryRow && (\n <div\n role=\"row\"\n aria-rowindex={rows.length + headerGroups.length + 1}\n data-testid=\"dg-summary-row\"\n className={classes.summaryRow}\n >\n {leafHeaders.map((header) => {\n const layout = layoutFor(header.column.id);\n return (\n <div\n key={header.id}\n role=\"cell\"\n data-column-id={header.column.id}\n data-align={getColumnAlign(header.column)}\n data-control-column={isControlColumn(header.column.id)}\n className={[\n classes.summaryCell,\n layout.isBoundary && layout.pinnedAt === \"left\"\n ? sticky.stickyLeft\n : \"\",\n layout.isBoundary && layout.pinnedAt === \"right\"\n ? sticky.stickyRight\n : \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{\n minHeight: rowHeight,\n left:\n layout.pinnedAt === \"left\" ? layout.offset : undefined,\n right:\n layout.pinnedAt === \"right\" ? layout.offset : undefined,\n position: layout.pinnedAt ? \"sticky\" : undefined,\n zIndex: layout.pinnedAt\n ? \"var(--dg-z-summary-pinned-cell, 5)\"\n : undefined,\n }}\n >\n <span className={classes.cellContent}>\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.footer,\n header.getContext(),\n )}\n </span>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n\n <TMDataGridFilterPanel />\n </div>\n );\n}\n",".toolbar {\n display: flex;\n align-items: center;\n gap: var(--mantine-spacing-xs);\n padding: 6px var(--mantine-spacing-xs);\n min-height: 42px;\n flex-shrink: 0;\n}\n\n.toolbarSpacer {\n flex: 1;\n}\n","import { ActionIcon, Loader, Popover, Text, Tooltip } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ReactNode } from \"react\";\nimport classes from \"./TMDataGridToolbar.module.css\";\nimport { TMDataGridColumnsPanel } from \"./TMDataGridColumnsPanel\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getGridCapabilities } from \"../core/capabilities\";\nimport { isFilterActive } from \"../core/filterOperators\";\nimport { BurgerIcon, FilterIcon } from \"./icons\";\nimport { openColumnFilter } from \"../useTMDataGrid\";\n\n/** Row above the grid. Compose it from the pieces below, or anything else. */\nexport function TMDataGridToolbar({ children }: { children?: ReactNode }) {\n return <div className={classes.toolbar}>{children}</div>;\n}\n\n/** Pushes the following toolbar items to the right. */\nexport function TMDataGridToolbarSpacer() {\n return <div className={classes.toolbarSpacer} />;\n}\n\n/**\n * A small spinner shown while `meta.loading` is true, and nothing otherwise.\n *\n * The body only shows its loading state while the grid is *empty* — a\n * server-driven grid refetching with rows on screen keeps showing them, which\n * is right, but leaves nothing saying a fetch is running. This is that signal,\n * and the consumer decides where it sits by placing it in the toolbar:\n *\n * ```tsx\n * <TMDataGrid.Toolbar>\n * <TMDataGrid.SummaryCount />\n * <TMDataGrid.Spacer />\n * <TMDataGrid.LoadingIndicator />\n * <TMDataGrid.FilterButton />\n * </TMDataGrid.Toolbar>\n * ```\n */\nexport function TMDataGridLoadingIndicator() {\n const { table, labels } = useTMDataGridContext();\n if (table.options.meta?.loading !== true) return null;\n return <Loader size=\"xs\" aria-label={labels.loading} />;\n}\n\n/**\n * Visible rows over total rows. On a server-driven grid, set\n * `meta.totalRowCount` for the denominator — the client never sees every row.\n */\nexport function TMDataGridSummaryCount({ children }: { children?: ReactNode }) {\n const { table, controlSize } = useTMDataGridContext();\n useSelector(table.store);\n\n if (children !== undefined) {\n return (\n <Text size={controlSize} c=\"dimmed\">\n {children}\n </Text>\n );\n }\n\n const shown = table.getRowCount();\n const total =\n table.options.meta?.totalRowCount ??\n table.getPreFilteredRowModel().rows.length;\n\n return (\n <Text size={controlSize} c=\"dimmed\">\n {shown} / {total}\n </Text>\n );\n}\n\n/**\n * Burger menu in the grid's top-right corner — opens \"Manage columns\".\n * Renders nothing when no column can be hidden (`enableHiding: false`).\n */\nexport function TMDataGridColumnsButton() {\n const { table, ui, features, labels, controlSize } = useTMDataGridContext();\n const opened = useSelector(ui, (state) => state.columnsPanelOpen);\n\n if (!getGridCapabilities(table, features).canHideAny) return null;\n\n return (\n <Popover\n opened={opened}\n onChange={ui.actions.setColumnsPanelOpen}\n position=\"bottom-end\"\n shadow=\"md\"\n radius=\"md\"\n withinPortal\n trapFocus\n >\n <Popover.Target>\n <Tooltip label={labels.manageColumns} openDelay={400}>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size={controlSize}\n aria-label={labels.manageColumns}\n onClick={ui.actions.toggleColumnsPanel}\n >\n <BurgerIcon size={18} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Popover.Target>\n <Popover.Dropdown p={0}>\n <TMDataGridColumnsPanel />\n </Popover.Dropdown>\n </Popover>\n );\n}\n\n/**\n * Toggles the filter panel, seeding a filter row on the first filterable column.\n * Renders nothing when no column can be filtered (`enableColumnFilters: false`).\n */\nexport function TMDataGridFilterButton() {\n const api = useTMDataGridContext();\n const { table, ui, features, labels, controlSize } = api;\n const opened = useSelector(ui, (state) => state.filterPanelOpen);\n const columnFilters = useSelector(\n table.store,\n (state) => state.columnFilters,\n );\n const activeCount = columnFilters.filter((filter) =>\n isFilterActive(filter.value),\n ).length;\n\n if (!getGridCapabilities(table, features).canFilterAny) return null;\n\n return (\n <Tooltip label={labels.filters} openDelay={400}>\n <ActionIcon\n variant={opened || activeCount > 0 ? \"light\" : \"subtle\"}\n color={activeCount > 0 ? undefined : \"gray\"}\n size={controlSize}\n aria-label={labels.filters}\n // Marks this as the panel's own toggle, so the panel's click-away\n // handler leaves it alone and the button stays a toggle.\n data-dg-filter-toggle\n onClick={() => {\n if (opened) {\n ui.actions.closeFilterPanel();\n return;\n }\n const firstFilterable = table\n .getAllLeafColumns()\n .find((column) => column.getCanFilter());\n if (firstFilterable) openColumnFilter(api, firstFilterable.id);\n else ui.actions.openFilterPanel();\n }}\n >\n <FilterIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n );\n}\n","import type { MantineSize } from \"@mantine/core\";\n\nexport type TMDataGridSize = MantineSize;\n\nexport const DEFAULT_TMDATAGRID_SIZE: TMDataGridSize = \"md\";\n\n/**\n * Row height per size, in px.\n *\n * The virtualizer needs this as a number — it cannot read the CSS variable —\n * so the scale lives here and `TMDataGrid.module.css` mirrors it. `meta.rowHeight`\n * overrides it when a grid needs a height the scale doesn't offer.\n */\nexport const SIZE_ROW_HEIGHT: Record<TMDataGridSize, number> = {\n xs: 34,\n sm: 42,\n md: 52,\n lg: 62,\n xl: 72,\n};\n\n/** Size of the Mantine controls rendered inside the grid chrome. */\nexport const SIZE_CONTROL_SIZE: Record<TMDataGridSize, MantineSize> = {\n xs: \"xs\",\n sm: \"xs\",\n md: \"sm\",\n lg: \"sm\",\n xl: \"md\",\n};\n","import type { RowData } from \"@tanstack/react-table\";\nimport { type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport classes from \"./TMDataGrid.module.css\";\nimport { TMDataGridColumnsPanel } from \"./TMDataGridColumnsPanel\";\nimport { TMDataGridContextProvider } from \"../TMDataGridContext\";\nimport { TMDataGridFilterPanel } from \"./TMDataGridFilterPanel\";\nimport { TMDataGridFilterPills } from \"./TMDataGridFilterPills\";\nimport { TMDataGridFooter } from \"./TMDataGridFooter\";\nimport { TMDataGridSearch } from \"./TMDataGridSearch\";\nimport { TMDataGridTable } from \"./TMDataGridTable\";\nimport {\n TMDataGridColumnsButton,\n TMDataGridFilterButton,\n TMDataGridLoadingIndicator,\n TMDataGridSummaryCount,\n TMDataGridToolbar,\n TMDataGridToolbarSpacer,\n} from \"./TMDataGridToolbar\";\nimport {\n DEFAULT_TMDATAGRID_SIZE,\n SIZE_CONTROL_SIZE,\n SIZE_ROW_HEIGHT,\n type TMDataGridSize,\n} from \"../core/sizes\";\nimport type { TMDataGridApi } from \"../useTMDataGrid\";\n\nexport type TMDataGridProps<TData extends RowData> = TMDataGridApi<TData> & {\n children: ReactNode;\n /**\n * Mantine size scale. Drives row height, font size, cell padding and the\n * size of the controls in the chrome. `meta.rowHeight` still wins if set.\n */\n size?: TMDataGridSize;\n className?: string;\n /**\n * Inline styles. Widened to accept CSS variables, which is how the grid's\n * colours are themed — `--dg-row-selected-bg` for the selected row\n * background. Plain `CSSProperties` rejects `--*` keys.\n */\n style?: CSSProperties & Record<`--${string}`, string | number>;\n};\n\n/**\n * Root of the grid. Takes the object returned by `useTMDataGrid` — spread it —\n * and publishes it to the compound components below it:\n *\n * ```tsx\n * const grid = useTMDataGrid({ data, columns });\n *\n * <TMDataGrid {...grid}>\n * <TMDataGrid.Toolbar>\n * <TMDataGrid.SummaryCount />\n * <TMDataGrid.Spacer />\n * <TMDataGrid.ColumnsButton />\n * </TMDataGrid.Toolbar>\n * <TMDataGrid.Table />\n * <TMDataGrid.Footer />\n * </TMDataGrid>\n * ```\n */\nfunction TMDataGridRoot<TData extends RowData>({\n table,\n ui,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n size = DEFAULT_TMDATAGRID_SIZE,\n children,\n className,\n style,\n}: TMDataGridProps<TData>) {\n const rowHeight = table.options.meta?.rowHeight ?? SIZE_ROW_HEIGHT[size];\n\n const api = useMemo(\n () => ({\n table,\n ui,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n size,\n rowHeight,\n controlSize: SIZE_CONTROL_SIZE[size],\n }),\n [\n table,\n ui,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n size,\n rowHeight,\n ],\n );\n\n return (\n <TMDataGridContextProvider value={api}>\n <div\n data-size={size}\n className={[classes.root, className].filter(Boolean).join(\" \")}\n style={style}\n >\n {children}\n </div>\n </TMDataGridContextProvider>\n );\n}\n\nexport const TMDataGrid = Object.assign(TMDataGridRoot, {\n Toolbar: TMDataGridToolbar,\n Spacer: TMDataGridToolbarSpacer,\n SummaryCount: TMDataGridSummaryCount,\n LoadingIndicator: TMDataGridLoadingIndicator,\n Search: TMDataGridSearch,\n ColumnsButton: TMDataGridColumnsButton,\n FilterButton: TMDataGridFilterButton,\n Table: TMDataGridTable,\n Footer: TMDataGridFooter,\n /** Rendered by `TMDataGrid.Table`; exported for custom layouts. */\n FilterPanel: TMDataGridFilterPanel,\n /**\n * Takes the grid as an `api` prop rather than from context, so it can be\n * rendered outside `<TMDataGrid>` — a page header, for instance.\n */\n FilterPills: TMDataGridFilterPills,\n /** Rendered by `TMDataGrid.ColumnsButton`; exported for custom layouts. */\n ColumnsPanel: TMDataGridColumnsPanel,\n});\n","import type { TMDataGridLabels } from \"./labels\";\n\n/**\n * The complete Swedish dictionary. Typed as {@link TMDataGridLabels} rather\n * than as an override, so a label added to the grid without a Swedish\n * translation is a compile error here instead of English quietly leaking\n * through.\n *\n * ```tsx\n * useTMDataGrid({ data, columns, labels: TMDATAGRID_LABELS_SV });\n * ```\n */\nexport const TMDATAGRID_LABELS_SV: TMDataGridLabels = {\n operators: {\n contains: \"innehåller\",\n equals: \"är lika med\",\n notEquals: \"är inte lika med\",\n startsWith: \"börjar med\",\n endsWith: \"slutar med\",\n greaterThan: \"är större än\",\n greaterThanOrEqual: \"är större än eller lika med\",\n lessThan: \"är mindre än\",\n lessThanOrEqual: \"är mindre än eller lika med\",\n before: \"är före\",\n after: \"är efter\",\n onOrBefore: \"är på eller före\",\n onOrAfter: \"är på eller efter\",\n isAnyOf: \"är någon av\",\n isNoneOf: \"är ingen av\",\n isEmpty: \"är tom\",\n isNotEmpty: \"är inte tom\",\n },\n\n manageColumns: \"Hantera kolumner\",\n filters: \"Filter\",\n searchPlaceholder: \"Sök\",\n searchLabel: \"Sök rader\",\n clearSearch: \"Rensa sökningen\",\n\n columnsSearchPlaceholder: \"Sök\",\n columnsNoMatch: (search) => `Inga kolumner matchar ”${search}”`,\n columnsShowHideAll: \"Visa/dölj alla\",\n columnsReset: \"ÅTERSTÄLL\",\n\n filterColumn: \"Kolumn\",\n filterOperator: \"Operator\",\n filterValue: \"Värde\",\n filterValuePlaceholder: \"Filtervärde\",\n booleanTrue: \"Ja\",\n booleanFalse: \"Nej\",\n addFilter: \"Lägg till filter\",\n clearAllFilters: \"Rensa alla\",\n closeFilters: \"Stäng filter\",\n removeFilter: \"Ta bort filter\",\n\n activeFilters: \"Aktiva filter\",\n clearFilter: (column) => `Rensa filtret för ${column}`,\n\n sortAsc: \"Sortera stigande\",\n sortDesc: \"Sortera fallande\",\n filterMenuItem: \"Filtrera\",\n groupBy: (column) => `Gruppera på ${column}`,\n ungroup: (column) => `Avgruppera ${column}`,\n expandAllGroups: \"Expandera alla grupper\",\n collapseAllGroups: \"Fäll ihop alla grupper\",\n pinLeft: \"Fäst till vänster\",\n pinRight: \"Fäst till höger\",\n unpin: \"Lossa\",\n moveLeft: \"Flytta åt vänster\",\n moveRight: \"Flytta åt höger\",\n autosizeColumn: \"Anpassa kolumnbredd\",\n hideColumn: \"Dölj kolumn\",\n filterOn: (column) => `Filtrera på ${column}`,\n sortColumn: (column) => `Sortera ${column}`,\n columnMenu: (column) => `Kolumnmeny för ${column}`,\n\n rowsPerPage: \"Rader per sida:\",\n pageRange: ({ from, to, total }) => `${from}–${to} av ${total}`,\n groupedAllRows: (total) => `Grupperad · alla ${total} rader`,\n pagingSuspendedHint:\n \"Sidindelningen är avstängd medan raderna är grupperade: hela trädet renderas och virtualiseras. Avgruppera för att bläddra igen.\",\n previousPage: \"Föregående sida\",\n nextPage: \"Nästa sida\",\n\n noResults: \"Inga rader matchar dina filter\",\n loading: \"Laddar\",\n\n cellCount: (count) => (count === 1 ? \"1 cell\" : `${count} celler`),\n copy: \"Kopiera\",\n exportCsv: \"Exportera som CSV för Excel\",\n includeHeaders: \"Inkludera rubriker\",\n\n selectColumnLabel: \"Kryssrutemarkering\",\n selectAllRows: \"Markera alla rader\",\n selectRow: \"Markera rad\",\n selectGroup: \"Markera grupp\",\n\n detailsColumnLabel: \"Detaljer\",\n showDetails: \"Visa detaljer\",\n hideDetails: \"Dölj detaljer\",\n expandAllDetails: \"Expandera alla detaljer\",\n collapseAllDetails: \"Fäll ihop alla detaljer\",\n\n groupColumnLabel: \"Grupp\",\n blankGroupValue: \"(Tom)\",\n expandGroup: (label) => `Expandera ${label}`,\n collapseGroup: (label) => `Fäll ihop ${label}`,\n};\n","import { aggregationFns, type RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/** The registered aggregation names — the same set `aggregationFn` accepts. */\nexport type TMDataGridAggregationName = keyof typeof aggregationFns;\n\n/**\n * One column aggregated over every filtered row — the number a summary-row\n * `footer` wants:\n *\n * ```tsx\n * columnHelper.accessor(\"salary\", {\n * footer: ({ table }) => sek(Number(aggregateColumn({ table, columnId: \"salary\" }))),\n * });\n * ```\n *\n * Filtered rather than paginated rows, so the total covers everything the\n * filters left — all pages — and follows the filters as they change. Reuses\n * TanStack's registered aggregation functions; `fn` defaults to `\"sum\"`.\n */\nexport function aggregateColumn<TData extends RowData>({\n table,\n columnId,\n fn = \"sum\",\n}: {\n table: TMDataGridTable<TData>;\n columnId: string;\n fn?: TMDataGridAggregationName;\n}): unknown {\n const erased = table as unknown as TMDataGridTable<TMDataGridRowData>;\n const rows = erased.getFilteredRowModel().rows;\n // Leaf and child rows are the same set here: the filtered model is flat.\n return aggregationFns[fn](columnId, rows, rows);\n}\n"],"mappings":"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"}