@jielga/tmdatagrid 2.0.0-beta.7 → 2.0.0-beta.8
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.
- package/dist/index.js +1093 -1007
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -1
- package/skills/appearance/SKILL.md +1 -1
- package/skills/cell-selection/SKILL.md +1 -1
- package/skills/columns/SKILL.md +1 -1
- package/skills/data/SKILL.md +1 -1
- package/skills/editing/SKILL.md +1 -1
- package/skills/filtering/SKILL.md +1 -1
- package/skills/getting-started/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +1 -1
- package/skills/options/SKILL.md +1 -1
- package/skills/rows/SKILL.md +1 -1
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +1 -1
- package/src/tmdatagrid/components/TMDataGridEntryRows.tsx +4 -3
- package/src/tmdatagrid/components/TMDataGridFooter.tsx +5 -5
- package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +59 -14
- package/src/tmdatagrid/components/TMDataGridTable.module.css +3 -3
- package/src/tmdatagrid/components/TMDataGridTable.tsx +88 -16
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +2 -1
- package/src/tmdatagrid/core/resizePreview.ts +141 -0
- package/src/tmdatagrid/core/useSettledTableState.ts +36 -0
- package/src/tmdatagrid/useTMDataGrid.tsx +43 -6
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","useCellControlTabIndex","features","cellSelection","Row","RowData","TableFeatures","TMDataGridFilterValue","operator","TMDataGridFilterOperator","value","ReadonlyArray","TMDataGridColumnType","FILTER_OPERATOR_LABELS","Record","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","between","before","after","onOrBefore","onOrAfter","isAnyOf","isNoneOf","isEmpty","isNotEmpty","STRING_OPERATORS","NUMBER_OPERATORS","DATE_OPERATORS","BOOLEAN_OPERATORS","SELECT_OPERATORS","VALUELESS_OPERATORS","ARRAY_OPERATORS","RANGE_OPERATORS","OPERATORS_BY_TYPE","string","number","boolean","date","select","multiSelect","DEFAULT_OPERATOR_BY_TYPE","getOperatorsForType","type","getDefaultOperator","operatorNeedsValue","includes","operatorTakesArrayValue","operatorTakesRangeValue","emptyValueForOperator","isTMDataGridFilterValue","isFilterActive","Array","isArray","some","entry","String","trim","formatFilterLabel","label","filter","operatorLabels","text","map","join","toIsoDay","Date","Number","isNaN","getTime","toLocaleDateString","match","exec","boundHolds","cellValue","bound","end","boundText","numericCell","NaN","numericBound","cellDay","boundDay","isEmptyCell","undefined","length","matchesFilter","set","toLowerCase","cellEntries","hit","min","max","filterText","filterDay","numericFilter","compareNumeric","cellText","needle","tmDataGridFilterFn","row","TFeatures","TData","columnId","filterValue","getValue","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","id","detailsToggle","DetailsHeader","getPrePaginatedRowModel","flatRows","detailRows","state","rows","target","allExpanded","collapseAllDetails","expandAllDetails","setExpanded","expand","t7","createDetailsColumn","label","TData","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","header","cell","FormApi","getBy","AnyFieldApi","AnyFormApi","StandardSchemaV1","batch","Store","Cell","Column","Row","RowData","ComponentType","TMDataGridRowData","TMDataGridFeatures","TMDataGridTable","isColumnEditableForRow","isColumnEditSwitchedOff","isControlColumn","TMDataGridColumnType","TMDataGridSize","TMDataGridEditMode","TMDataGridRowEditForm","TMDataGridEditField","TMDataGridValidator","args","value","fieldApi","TMDataGridFieldValidate","onMount","onChange","onChangeAsync","onChangeAsyncDebounceMs","onBlur","onBlurAsync","onSubmit","onSubmitAsync","TMDataGridRowValidators","onSubmitAsyncDebounceMs","TMDataGridTableValidateArgs","TData","rowId","isNew","rows","ReadonlyArray","TMDataGridTableValidators","Promise","TMDataGridEditChange","columnId","field","previous","next","TMDataGridEditCommitArgs","original","changes","Array","source","TMDataGridEditRowProjection","dirtyFields","errorFields","errorMessages","message","hasRowError","isSubmitting","values","TMDataGridEditState","active","openRowIds","Record","committedRowIds","newRows","tempId","committed","deletedRowIds","EMPTY_EDIT_STATE","getOpenRowIds","state","filter","includes","some","newRow","length","ErasedRow","ErasedColumn","TMDataGridEditorArgs","form","cell","row","column","table","commit","cancel","size","seedText","TMDataGridEditorComponent","TMDataGridEditValueMapArgs","TMDataGridEditValueMap","TMDataGridColumnEditOptions","enabled","editor","validate","mapValue","TMDataGridRowAddArgs","TMDataGridRowDeleteArgs","TMDataGridSaveDraftsArgs","updated","created","deleted","added","TMDataGridSaveOutcomes","TMDataGridSaveDraftsResult","isSaved","outcomes","id","undefined","TMDataGridEditCommitDraftsArgs","TMDataGridEditEngineContext","editMode","draft","rowValidators","tableValidators","editableColumnIds","isRowEditable","onEditCommit","onSaveDrafts","newRowDefaults","onRowAdd","onRowDelete","getEditFieldName","columnDef","meta","edit","fromMeta","accessorKey","clearedValueForType","type","TMDataGridAddRowsOptions","TMDataGridAddRowsResult","open","TMDataGridEditApi","store","getForm","canEditCell","canEditRow","isColumnEditable","begin","target","deactivate","cancelAll","commitAll","saveDrafts","submitAll","clearCell","setCellValue","setRowValues","addRow","Partial","addRows","options","deleteRow","canDeleteRows","clearFormSourcedFieldErrors","fieldMeta","errorSourceMap","name","Object","entries","staleKeys","map","key","setFieldMeta","errorMap","fromEntries","sameValue","a","b","is","isArray","every","entry","i","Date","getTime","hasAnyError","errors","error","firstErrorText","text","SUBMIT_VALIDATE_TRIGGERS","const","isValidationError","result","runFieldValidator","validator","schema","issues","createEditEngine","getContext","FormEntry","lastSubmitOk","submitErrors","parkOnly","pendingCommit","unsubscribe","unmount","forms","Map","newRowCounter","savingDrafts","draftCollector","draftAddCollector","allowed","editableColumns","getAllLeafColumns","validateColumnFields","getRow","fields","normalized","normalizeFieldValidate","trigger","keys","mergedRows","Set","getCoreRowModel","flatRows","has","push","held","get","runTableValidators","validators","sync","mergeSubmitResults","results","only","shape","mergedFields","merged","composeValidators","consumerAsync","fromConsumer","fromTable","diff","project","live","flatMap","kept","current","change","publishRow","setState","prev","setActive","setNewRowCommitted","find","setCommitted","drop","delete","createForm","defaultValues","addArgs","setErrorMap","Error","String","mount","subscription","subscribe","set","getIsGrouped","context","takeFieldErrors","handleSubmit","beginOn","entryForm","getColumn","openElsewhere","other","then","ok","seedNewRow","defaults","tempIds","takeDeletedRowIds","committedFormIds","openIds","all","Boolean","saveInFlight","saveDraftsInner","finally","committedIds","deletedIds","collected","allValid","savedAll","savedDeletions","committedOk","savedOk","writeFields","writes","setFieldValue","writableField","ActionIcon","Group","Loader","Tooltip","useSelector","ColumnDef","Row","RowData","classes","useCellControlTabIndex","useTMDataGridContext","TMDataGridFeatures","firstErrorText","CheckIcon","CloseIcon","PencilIcon","PlusIcon","RestoreIcon","TrashIcon","EDIT_COLUMN_ID","RowStateIndicator","t0","$","_c","state","rowId","label","error","Icon","t1","t2","undefined","t3","t4","rowStateIndicator","t5","EditLaneCell","row","edit","features","labels","tabIndex","id","openRowIds","includes","isOpen","store","state_0","rows","projection","state_1","newRows","some","newRow","tempId","isNew","state_2","find","newRow_0","committed","isConfirmedNew","state_3","committedRowIds","isCommitted","t6","state_4","deletedRowIds","isMarkedDeleted","getIsGrouped","hasErrors","hasRowError","errorFields","length","t7","getForm","errors","errorMessages","message","editRowErrors","rowError","t8","canDeleteRows","deleteRow","event","stopPropagation","trash","t9","rowStateNew","t10","event_0","begin","columnId","t11","Symbol","for","t12","editRow","t13","t14","cancel","t15","t16","discardNewRow","t17","t18","commit","confirmNewRow","rowStateDeleted","event_1","restoreRow","canEditRow","isSubmitting","loading","rowStateEdited","event_2","revertRow","editMode","event_3","event_4","saveRow","save","event_5","cancelRowEdit","createEditColumn","wide","TData","width","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","header","cell","aggregatedCell","Row","RowData","TMDataGridFeatures","getGroupDataRows","row","TData","Array","subRows","length","getLeafRows","filter","leaf","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","id","t8","event","stopPropagation","toggleExpanded","t9","Symbol","for","t10","chevron","t11","groupLabel","t12","t13","length","groupCount","t14","GroupHeader","compare","grouping","_temp","groupColumnLabel","columnId","column","getColumn","map","join","state","createGroupColumn","TData","meta","enableOrdering","size","minSize","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","cell","aggregatedCell","header","ColumnDef","RowData","TMDataGridFeatures","ROW_NUMBER_COLUMN_ID","createRowNumberColumn","label","TData","id","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enablePinning","enableHiding","header","cell","Row","RowData","RowSelectionState","TMDataGridFeatureFlags","getGroupDataRows","TMDataGridFeatures","TMDataGridTable","getDisplayedRows","table","TData","features","Array","rows","isPagingActive","getPaginatedRowModel","getPrePaginatedRowModel","rowPinning","top","bottom","store","state","length","pinned","Set","filter","row","has","id","pagination","grouping","TMDataGridRowClickModifiers","toggle","extend","ResolveRowSelectionClickArgs","ReadonlyArray","rowId","anchorRowId","modifiers","selection","canReplaceSelection","ResolvedRowSelection","getSelectableRowIds","dataRow","getCanSelect","map","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","enableHiding","enablePinning","header","cell","aggregatedCell","Row","getDefaultOperator","TMDataGridColumnType","TMDataGridFilterOperator","DETAILS_COLUMN_ID","EDIT_COLUMN_ID","GROUP_COLUMN_ID","ROW_NUMBER_COLUMN_ID","SELECT_COLUMN_ID","TMDataGridRowData","TMDataGridColumnMeta","TMDataGridFeatures","TMDataGridFilterControlComponent","ColumnLike","id","columnDef","header","meta","parent","getColumnLabel","column","label","getColumnType","type","getColumnDefaultOperator","filter","defaultOperator","getColumnFilterControl","control","isColumnEditSwitchedOff","edit","enabled","isColumnEditableForRow","row","getColumnAlign","align","isControlColumn","columnId","isGeneratedColumn","isColumnReorderable","enableOrdering","undefined","Button","Checkbox","ScrollArea","Text","TextInput","Tooltip","useSelector","useState","classes","useTMDataGridContext","getColumnLabel","SearchIcon","TMDataGridColumnsPanel","$","_c","table","labels","controlSize","resetSettings","search","setSearch","columnVisibility","store","_temp","T0","columns","setAllVisible","shownCount","t0","t1","t2","t3","t4","t5","t6","visibleInPanel","columnsSearchPlaceholder","getAllLeafColumns","filter","_temp2","needle","trim","toLowerCase","column_0","column","includes","t7","column_1","id","length","visible","setColumnVisibility","previous","next","column_2","columnsPanel","t8","Symbol","for","event","currentTarget","value","t9","columnsPanelSearch","Autosize","columnsPanelList","t10","column_3","event_0","toggleVisibility","checked","map","columnsNoMatch","t11","t12","event_1","t13","columnsShowHideAll","t14","t15","columnsReset","t16","columnsResetHint","t17","columnsPanelFooter","t18","getCanHide","state","Button","Group","Text","useSelector","shallow","ReactNode","useTMDataGridContext","getOpenRowIds","getDisplayedRows","TMDataGridScrollAlign","TMDataGridScrollToRowArgs","useDraftCount","edit","store","_temp2","state","committedRowIds","length","newRows","filter","_temp","deletedRowIds","newRow","committed","useOpenCount","_temp3","useOpenRowIds","$","_c","t0","Symbol","for","compare","EditSaveButton","labels","draftCount","isSubmitting","_temp4","t1","saveDrafts","t2","saveAllEdits","t3","openRowIds","some","rowId","rows","EditOpenRowsNote","openCount","editRowsStillOpen","EditDiscardButton","pendingCount","cancelAll","discardAllEdits","EDIT_ACTIONS_CONTROLS","TMDataGridDraftActionsControls","Save","Discard","OpenRowsNote","TMDataGridDraftActionsState","ReadonlyArray","TMDataGridDraftActionsActions","save","Promise","commitAll","discard","scrollToRow","args","scrollToFirstOpenRow","align","TMDataGridDraftActionsSlotArgs","actions","Controls","TMDataGridDraftActionsProps","renderActions","TMDataGridDraftActions","undefined","features","table","_temp5","editing","t4","state_0","openIds","open","Set","first","find","row","has","id","rowId_0","tempId","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","Group","MultiSelect","Select","TextInput","optionsToComboboxData","getColumnType","TMDataGridFilterControlArgs","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","TMDataGridFilterValueInput","t0","$","_c","column","operator","value","onChange","options","size","labels","type","t1","needsValue","scalarValue","inputType","t2","Array","isArray","String","rangeValue","t3","event","currentTarget","t4","filterFrom","t5","event_0","t6","filterTo","t7","filterValue","Symbol","for","withinPortal","filterValuePlaceholder","booleanTrue","label","booleanFalse","t8","t9","next","t10","event_1","ActionIcon","Button","Select","Stack","Text","TextInput","useSelector","useEffect","useRef","classes","useTMDataGridContext","resolveColumnOptions","getColumnDefaultOperator","getColumnFilterControl","getColumnLabel","getColumnType","TMDataGridFilterOperator","TMDataGridFilterValue","emptyValueForOperator","getDefaultOperator","getOperatorsForType","isTMDataGridFilterValue","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","CloseIcon","TMDataGridFilterValueInput","FALLBACK_FILTER","operator","value","asFilterValue","valueShape","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","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","operator_1","t6","column_2","filter_6","canAddFilter","filters","event_0","key","stopPropagation","Symbol","for","t7","closeFilters","t8","filterPanelHeader","t9","t10","filter_7","column_3","value_1","type","needsValue","scalarValue","options","columnDef","meta","undefined","fallback","ValueControl","filterRow","filterColumn","withinPortal","next","filterOperator","operator_2","label","operators","next_0","next_1","filterValue","filterValuePlaceholder","event_1","currentTarget","t11","t12","t13","t14","filterPanelFooter","t15","t16","filterPanel","column_0","getCanFilter","state_0","state","filterPanelOpen","compareItems","rankItem","RankingInfo","createSortedRowModel","Row","RowData","RowModel","Table","TableFeatures","TMDataGridQuickSearchMode","FUZZY_FILTER_FN_NAME","FuzzyFilterMeta","fuzzyRank","isFuzzyFilterMeta","value","rank","fuzzyGlobalFilterFn","row","TFeatures","TData","columnId","filterValue","addMeta","meta","String","getValue","passed","bestRank","best","columnFiltersMeta","Record","Object","values","isRankingActive","table","globalFilterFn","options","state","store","sorting","Array","grouping","globalFilter","length","trim","createFuzzyRankedSortedRowModel","base","getSorted","lastModel","ranked","model","rows","sort","a","b","rankA","rankB","flatRows","rowsById","FILTER_OPERATOR_LABELS","TMDataGridFilterOperator","TMDataGridLabels","operators","Record","manageColumns","filters","searchPlaceholder","searchLabel","clearSearch","columnsSearchPlaceholder","columnsNoMatch","search","columnsShowHideAll","columnsReset","columnsResetHint","rowNumberColumnLabel","noRows","filterColumn","filterOperator","filterValue","filterValuePlaceholder","filterFrom","filterTo","filterAll","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","editCell","confirmEdit","cancelEdit","editColumnLabel","editRow","saveRow","cancelRowEdit","editRowErrors","saveAllEdits","rows","discardAllEdits","editRowsStillOpen","confirmNewRow","discardNewRow","deleteRow","restoreRow","revertRow","rowStateNew","rowStateEdited","rowStateDeleted","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","PERSIST_PAYLOAD_VERSION","VERSION_FIELD","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","collectLeafColumnIds","defs","into","def","columns","length","accessorKey","id","replaceAll","header","push","realignToColumns","known","ReadonlySet","has","keepIds","filter","keepKeys","T","fromEntries","entries","keepEntries","realigned","left","right","readPersistedState","knownColumnIds","Set","writePersistedState","Column","RowData","TMDataGridRowData","isColumnReorderable","TMDataGridEditMode","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","editing","editMode","editDraft","editNewRowsSticky","rowNumbers","rowPinning","matchHighlighting","readFeatureFlags","options","Pick","TData","undefined","enableRowSelection","enableSorting","enableColumnFilters","enableGlobalFilter","enableHiding","enableColumnPinning","enableColumnResizing","enableColumnOrdering","enableMultiRowSelection","enablePagination","manualPagination","enableGrouping","mode","draft","newRowsSticky","enableRowNumbers","enableRowPinning","enableMatchHighlighting","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","NextEditableCellArgs","direction","isEditable","coords","getNextEditableCell","total","start","step","index","floor","isSameCell","a","b","TableState","TMDataGridFeatures","GridState","CONTROLLED_SLICE_HANDLERS","columnFilters","columnOrder","columnPinning","columnResizing","columnSizing","columnVisibility","expanded","globalFilter","grouping","pagination","rowPinning","rowSelection","sorting","const","Partial","Record","TMDataGridControlledSlice","ControlledOptions","state","atoms","hasOwn","value","key","Object","prototype","hasOwnProperty","call","isDataObject","proto","getPrototypeOf","sameStateValue","a","b","is","Date","getTime","Array","isArray","length","every","item","index","keys","withoutUndefinedSlices","undefined","values","includes","compacted","entries","stabilizeControlledState","next","previous","stabilized","changed","nextValue","previousValue","findFrozenStateSlices","options","slice","handler","filter","map","useCreateStore","aggregationFns","ColumnDef","columnFacetingFeature","columnFilteringFeature","columnGroupingFeature","columnOrderingFeature","columnPinningFeature","columnResizingFeature","columnSizingFeature","columnVisibilityFeature","createColumnHelper","createExpandedRowModel","createFacetedMinMaxValues","createFacetedRowModel","createFacetedUniqueValues","createFilteredRowModel","createGroupedRowModel","createPaginatedRowModel","filterFns","globalFilteringFeature","metaHelper","Row","RowData","rowExpandingFeature","rowPaginationFeature","rowPinningFeature","rowSelectionFeature","rowSortingFeature","sortFns","Table","tableFeatures","TableOptions","TableState","useTable","Store","MutableRefObject","ReactNode","useCallback","useEffect","useMemo","useRef","useState","TMDataGridRowData","TMDataGridOptionsSource","createEditEngine","TMDataGridEditApi","TMDataGridEditCommitArgs","TMDataGridSaveDraftsArgs","TMDataGridSaveDraftsResult","TMDataGridEditEngineContext","TMDataGridColumnEditOptions","TMDataGridEditMode","TMDataGridRowAddArgs","TMDataGridRowDeleteArgs","TMDataGridRowValidators","TMDataGridTableValidators","emptyValueForOperator","TMDataGridColumnType","tmDataGridFilterFn","getColumnDefaultOperator","isControlColumn","TMDataGridColumnFilterOptions","createFuzzyRankedSortedRowModel","fuzzyGlobalFilterFn","TMDataGridQuickSearchMode","mergeLabels","TMDataGridLabels","TMDataGridLabelsOverride","collectLeafColumnIds","hasPersistenceKeys","readPersistedState","TMDataGridPersistence","writePersistedState","readFeatureFlags","TMDataGridCellSelectionMode","TMDataGridFeatureFlags","TMDataGridSelectionMode","isSameCell","TMDataGridCellPosition","findFrozenStateSlices","stabilizeControlledState","withoutUndefinedSlices","TMDataGridCellRange","createSelectColumn","SELECT_COLUMN_ID","createGroupColumn","GROUP_COLUMN_ID","createDetailsColumn","DETAILS_COLUMN_ID","createEditColumn","EDIT_COLUMN_ID","createRowNumberColumn","ROW_NUMBER_COLUMN_ID","PERSIST_DEBOUNCE_MS","TMDataGridColumnMeta","label","type","options","flex","align","autoSize","enableOrdering","filter","edit","TMDataGridTableMeta","loading","noResultsLabel","rowHeight","totalRowCount","tmDataGridFeatures","filteredRowModel","groupedRowModel","sortedRowModel","expandedRowModel","paginatedRowModel","facetedRowModel","facetedMinMaxValues","facetedUniqueValues","tmDataGrid","tmDataGridFuzzy","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","TMDataGridScrollAlign","TMDataGridScrollToRowArgs","TMDataGridScroller","TMDataGridApi","ui","features","labels","renderDetails","renderDetailsEstHeight","overscan","resetSettings","scrollToRow","scrollerRef","TMDataGridEditingCallbacks","rowValidators","tableValidators","isRowEditable","onCommit","Promise","newRowDefaults","onRowAdd","onRowDelete","TMDataGridEditingOptions","mode","columns","ReadonlyArray","draft","onSaveDrafts","onCommitDrafts","newRowsSticky","UseTMDataGridOptions","Omit","editing","getRowId","NonNullable","persist","enableColumnOrdering","enablePagination","enableRowNumbers","quickSearchMode","enableMatchHighlighting","selectionMode","showSelectedBackground","defaultHighlightedRowId","onHighlightedRowChange","cellSelection","onFocusedCellChange","TMDataGridColumnDef","withoutControlColumnVisibility","visibility","Record","scrubbed","id","Object","keys","withTMDataGridDefaults","Array","map","column","isArray","filterFn","aggregationFn","undefined","aggregatedCell","useTMDataGrid","labelsOverride","editMode","editDraft","pinningEnabled","enableColumnPinning","selectColumnEnabled","selectColumn","groupColumnEnabled","grouping","detailsColumnEnabled","editColumnEnabled","selectColumnLabel","groupColumnLabel","detailsColumnLabel","editColumnLabel","rowNumberColumnLabel","rowNumbersEnabled","rowNumbers","editWideLane","base","persistedState","initialGrouping","initialState","groupingActiveRef","state","length","consumerState","controlledColumnVisibility","columnVisibility","requestedState","current","controlledStateRef","Partial","republishControlledStateRef","controlledState","columnResizeMode","enableSorting","enableColumnResizing","globalFilterFn","groupedColumnMode","getRowCanExpand","enableRowPinning","getIsGrouped","columnPinning","left","right","pagination","pageIndex","pageSize","editContextRef","editableColumnIds","onEditCommit","previousEditPolicyRef","previous","cancelAll","console","error","slice","handler","warn","previousGrouping","store","setColumnVisibility","old","subscription","subscribe","setColumnOrder","unsubscribe","timeout","ReturnType","setTimeout","pending","flush","clearTimeout","setState","prev","anchor","focus","onHighlightedRowChangeRef","onFocusedCellChangeRef","resetSettingsRef","initial","setGrouping","setColumnSizing","columnSizing","columnOrder","setColumnPinning","openColumnFilter","api","getColumn","getFilterValue","operator","setFilterValue","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","t9","Symbol","for","bb0","filter","_temp2","length","t10","filterPills","Boolean","join","Group","t11","filter_0","column","getColumn","id","label","value","pill","setColumnFilters","other","clearFilter","tabIndex","pillLabel","type","operatorLabels","operators","map","clearAllFilters","t12","state","ActionIcon","Group","Select","Text","Tooltip","RowData","useSelector","useMemo","ReactNode","classes","useTMDataGridContext","getGridCapabilities","isPagingActive","ChevronLeftIcon","ChevronRightIcon","TMDataGridTable","TMDataGridPaginationState","pageIndex","pageSize","pageCount","rowCount","canPreviousPage","canNextPage","from","to","TMDataGridPaginationActions","setPageIndex","setPageSize","previousPage","nextPage","firstPage","lastPage","TMDataGridPaginationApi","state","actions","TMDataGridPaginationControls","PageSize","Range","Pager","TMDataGridPaginationSlotArgs","Controls","getTMDataGridPaginationApi","table","TData","isPaging","store","pagination","getRowCount","getPageCount","getCanPreviousPage","getCanNextPage","Math","min","index","size","PaginationPageSize","t0","$","_c","pageSizeOptions","features","labels","controlSize","t1","paging","t2","includes","sort","_temp","sizeOptions","t3","rowsPerPage","t4","t5","map","String","t6","t7","value","Number","t8","t9","a","b","PaginationRange","T0","total","pageRange","groupedAllRows","getFilteredRowModel","rows","length","PaginationPager","Symbol","for","TMDataGridFooterProps","ReadonlyArray","renderPagination","args","DEFAULT_PAGE_SIZE_OPTIONS","TMDataGridFooter","undefined","canPaginate","bb0","footer","pagingSuspendedHint","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","mountedCells","container","columnId","NodeListOf","id","CSS","escape","querySelectorAll","hasMountedCells","length","measureColumnContentWidth","widest","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","isGeneratedColumn","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","keepGeneratedColumnsOutermost","pinning","generated","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","keepGeneratedColumnsOutermost","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","TMDataGridTableInstance","ReturnType","TMDataGridHeader","TMDataGridColumnMenuItemsArgs","column","table","internalItems","Array","TMDataGridColumnMenuItemsRenderer","args","TMDataGridHeaderCell","t0","$","_c","header","layout","renderColumnMenuItems","api","features","labels","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","finalItems","handleDragEnd","handleDragLeave","handleDragOver","handleDragStart","handleDrop","isDragged","isDropTarget","isFiltered","isResizing","isSorted","label","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","setColumnPinning","menuItems","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","headerCellFiltered","headerCellDragging","headerCellDropBefore","headerCellDropAfter","isBoundary","stickyLeft","stickyRight","headerCell","Boolean","cellClass","join","offset","right","zIndex","_temp3","t27","event_4","getToggleSortingHandler","t28","columnDef","isPlaceholder","headerTitle","getContext","t29","headerActions","headerAction","filterOn","event_5","stopPropagation","sortAction","sortColumn","columnMenu","event_6","_temp4","_temp5","t30","columnSeparator","columnSeparatorResizable","columnSeparatorActive","event_8","getResizeHandler","_temp6","event_10","t31","cell","t32","opened_0","opened","t33","t34","_temp7","t35","event_11","event_9","event_7","event_3","shiftKey","state_0","columnResizing","isResizingColumn","columnOrder","node","type","Divider","useStore","useLayoutEffect","useRef","RefObject","firstErrorText","TMDataGridEditField","useFieldValue","field","store","_temp","state","value","useFieldError","_temp2","meta","errors","ReadonlyArray","selectAllOnFocus","event","currentTarget","target","HTMLInputElement","select","useCaretKeeper","$","_c","inputRef","caret","t0","Symbol","for","pending","current","input","shift","length","next","Math","max","min","position","setSelectionRange","t1","remember","input_0","selectionStart","Checkbox","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridBooleanEditor","t0","$","_c","field","column","size","labels","value","error","t1","editCell","t2","t3","event","handleChange","currentTarget","checked","t4","handleBlur","TextInput","useRef","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridDateEditor","t0","$","_c","field","column","size","labels","value","error","writesDates","Date","t1","toLocaleDateString","slice","text","t2","editCell","t3","event","next","currentTarget","handleChange","current","t4","handleBlur","MultiSelect","TMDataGridEditorArgs","optionsToComboboxData","resolveColumnOptions","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridMultiSelectEditor","t0","$","_c","field","column","row","table","size","labels","value","error","t1","Symbol","for","withinPortal","t2","editCell","t3","fallback","t4","Array","isArray","map","String","t5","next","handleChange","t6","handleBlur","NumberInput","useState","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","selectAllOnFocus","useCaretKeeper","useFieldError","useFieldValue","TMDataGridNumberEditor","t0","$","_c","field","column","size","labels","value","error","inputRef","remember","typed","setTyped","parsedTyped","Number","textDescribesField","isFinite","t1","editCell","t2","t3","next","current","handleChange","parsed","t4","handleBlur","Select","TMDataGridEditorArgs","optionsToComboboxData","resolveColumnOptions","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridSelectEditor","t0","$","_c","field","column","row","table","size","commit","labels","features","value","error","t1","Symbol","for","withinPortal","t2","editCell","t3","fallback","t4","t5","next","handleChange","editMode","t6","handleBlur","TextInput","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","selectAllOnFocus","useCaretKeeper","useFieldError","useFieldValue","TMDataGridStringEditor","t0","$","_c","field","column","size","labels","value","error","inputRef","remember","t1","editCell","t2","t3","event","currentTarget","handleChange","t4","handleBlur","ActionIcon","FieldApi","Cell","Row","ComponentType","FocusEvent","KeyboardEvent","useEffect","useRef","useState","classes","TMDataGridRowData","useTMDataGridContext","getEditFieldName","normalizeFieldValidate","TMDataGridEditField","TMDataGridEditorArgs","TMDataGridEditValueMap","TMDataGridFeatures","CheckIcon","CloseIcon","TMDataGridBooleanEditor","TMDataGridDateEditor","TMDataGridMultiSelectEditor","TMDataGridNumberEditor","TMDataGridSelectEditor","TMDataGridStringEditor","BUILT_IN_EDITORS","Record","string","number","boolean","date","select","multiSelect","TMDataGridCellEditorClose","committed","via","TMDataGridCellEditor","cell","row","takeSeedText","onClose","inEntryBlock","args","table","edit","features","labels","controlSize","isRowShaped","editMode","column","form","getForm","id","fieldName","seedText","mapValueRef","undefined","current","columnDef","meta","mapValue","field","created","name","validators","validate","write","handleChange","bind","updater","map","previous","state","value","prev","mount","type","seeded","Number","isFinite","closingRef","commitAndClose","Promise","ok","commit","cancelAndClose","cancel","deferAndClose","deactivate","handleKeyDown","event","HTMLDivElement","key","preventDefault","stopPropagation","shiftKey","handleBlur","next","relatedTarget","Node","currentTarget","contains","then","size","Editor","editor","cellEditor","cellEditorActions","confirmEdit","cancelEdit","FOCUSABLE_IN_CELL","join","focusEditorContent","editor","HTMLElement","target","querySelector","focus","flexRender","useTable","Column","Row","useSelector","useLayoutEffect","useMemo","useRef","classes","sticky","TMDataGridRowData","useTMDataGridContext","getColumnAlign","isColumnEditableForRow","isControlColumn","TMDataGridEditApi","focusEditorContent","tmDataGridFeatures","TMDataGridFeatures","TMDataGridCellEditor","EDIT_COLUMN_ID","TMDataGridColumnLayout","ErasedColumn","isEntryCellEditable","row","column","edit","isColumnEditable","TMDataGridEntryRows","t0","$","_c","orderedColumns","layoutFor","rowHeight","table","features","newRows","store","_temp","activeEntry","_temp2","blockRef","focusedTempIdRef","focusedActiveRef","t1","newest","at","tempId","undefined","current","block","editor","querySelector","CSS","escape","t2","key","rowId","columnId","block_0","editor_0","t3","t4","t5","committed","getForm","state","values","options","defaultValues","map","data","_row","index","String","columns","getRowId","entryTable","length","t6","t7","editNewRowsSticky","entryRows","getCoreRowModel","rows","t8","Map","_temp3","committedById","t9","entryRow","get","id","stickyRows","filter","flowRows","entryRow_0","t10","entryRow_1","pinnedZ","cellsById","getAllCells","_temp4","committed_0","cell_0","layout","editable","cell","begin","entryCell","isBoundary","pinnedAt","stickyLeft","stickyRight","Boolean","join","minHeight","left","offset","right","position","zIndex","columnDef","getContext","cellContent","_temp5","_temp6","renderEntryRow","entryBlock","entryRow_2","entryFlowBlock","entryRow_3","newRow_0","newRow","state_0","active","some","Cell","CellContext","Row","TMDataGridRowData","TMDataGridFeatures","ErasedCell","ErasedRow","ErasedCellContext","RowInternals","original","_valuesCache","Record","_uniqueValuesCache","draftCellContext","cell","draftValues","draftRow","Object","create","row","internals","draftCell","table","column","getValue","id","renderValue","options","renderFallbackValue","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","Row","RowData","TMDataGridFeatures","TMDataGridTable","readPinnedRows","table","TData","position","Array","ids","store","state","rowPinning","length","visible","getPrePaginatedRowModel","rowsById","all","getCoreRowModel","rows","id","row","undefined","getIsAllParentsExpanded","push","RowData","isTMDataGridFilterValue","TMDataGridFilterOperator","TMDataGridTable","TMDataGridMatchRange","start","end","HIGHLIGHTABLE_OPERATORS","ReadonlyArray","buildMatchNeedles","table","TData","Map","state","store","global","globalFilter","trim","byColumn","Array","filter","columnFilters","value","operator","includes","needles","get","id","push","set","size","map","column","getAllLeafColumns","getCanGlobalFilter","own","undefined","length","findMatchRanges","text","haystack","toLowerCase","found","needle","lowered","index","indexOf","sort","a","b","merged","range","last","at","Math","max","Checkbox","Loader","Menu","MenuProps","Text","Cell","Column","flexRender","Row","RowData","Table","useSelector","useVirtualizer","CSSProperties","KeyboardEvent","MouseEvent","ReactNode","UIEvent","useCallback","useEffect","useLayoutEffect","useRef","useState","classes","sticky","TMDataGridRowData","useTMDataGridContext","TMDataGridFilterPanel","TMDataGridHeaderCell","TMDataGridColumnMenuItemsRenderer","TMDataGridCellEditor","TMDataGridCellEditorClose","TMDataGridEntryRows","getColumnAlign","isControlColumn","draftCellContext","getEditFieldName","TMDataGridEditState","getNextEditableCell","resolveCellMove","TMDataGridCellPosition","FOCUSABLE_IN_CELL","focusEditorContent","boundsCellCount","boundsEdges","isWithinBounds","resolveRangeBounds","buildCellMatrix","DEFAULT_CELL_EXPORT_OPTIONS","downloadTextFile","toClipboardText","toExcelCsv","writeClipboardText","TMDataGridCellExportOptions","autosizeColumn","hasMountedCells","getDisplayedRows","getSelectableRowIds","isPagingActive","resolveRowSelectionClick","readPinnedRows","buildMatchNeedles","findMatchRanges","ROW_NUMBER_COLUMN_ID","SearchIcon","TMDataGridFeatures","TMDataGridColumnLayout","pinnedAt","offset","isBoundary","UNPINNED_LAYOUT","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","withMatchHighlights","text","needles","ReadonlyArray","ranges","parts","Array","cursor","range","start","push","slice","matchHighlight","end","length","TMDataGridBodyCell","t0","$","_c","rowHeight","layout","nav","editor","contentOverride","highlightNeedles","onFocus","onClick","onMouseDown","onMouseEnter","onDoubleClick","onContextMenu","table","edit","t1","fieldName","cellRowId","row","id","t2","isControl","t3","state","projection","rows","dirtyFields","includes","isDirty","store","t4","state_0","projection_0","errorFields","isInvalid","t5","state_1","values","draftValues","t6","t7","t8","t9","t10","t11","t12","t13","t14","t15","t16","t17","t18","t19","t20","t21","t22","t23","stickyLeft","t24","stickyRight","t25","bodyCell","filter","Boolean","t26","join","t27","t28","t29","t30","t31","minHeight","position","zIndex","t32","cellContent","draftContext","getDefaultColumnDef","value","renderValue","String","t33","TMDataGridBodyRowGroup","enabled","menuContent","menuProps","onClose","children","Symbol","for","display","rowGroup","opened","TMDataGridRowContextMenuArgs","TData","close","internalItems","TMDataGridRowContextMenuRenderer","args","TMDataGridCellEventArgs","event","TMDataGridRowStyle","Record","TMDataGridTableProps","onRowClick","onCellClick","onCellDoubleClick","onCellContextMenu","rowClassName","rowStyle","striped","onScrollToTop","onScrollToBottom","onScrollToLeft","onScrollToRight","renderEmptyState","hasActiveFilters","renderRowContextMenu","renderColumnMenuItems","rowContextMenuProps","Omit","cellExport","onReachEnd","reachEndThreshold","TMDataGridTable","ariaLabel","ariaLabelledBy","ui","features","labels","controlSize","renderDetails","renderDetailsEstHeight","overscan","scrollerRef","highlightedRowId","focusedCell","cellRange","editActive","active","editOpenRowIds","openRowIds","newRowCount","newRows","deletedRowIds","editDirtyRowIds","editDraftRowIds","committedRowIds","loading","noResultsLabel","noResults","options","meta","scrollContainerRef","HTMLDivElement","matchNeedles","matchHighlighting","pinnedTopRows","rowPinning","pinnedBottomRows","pinnedRowCount","rowNumberById","Map","rowNumbers","n","pagination","pageIndex","pageSize","viewRow","getIsGrouped","set","showsDetails","getIsExpanded","pendingAutoSizeRef","Set","current","getAllLeafColumns","autoSize","map","pending","size","columnSizing","delete","gridElementRef","grid","headerRows","querySelectorAll","measure","total","headerRow","offsetHeight","style","setProperty","observer","ResizeObserver","observe","disconnect","entryBlock","removeProperty","summaryRow","pageCount","getPageCount","setPageIndex","virtualizer","count","getScrollElement","estimateSize","index","measureElement","element","_entry","instance","height","indexFromElement","getItemKey","initialRect","width","prevRowHeightRef","virtualItems","getVirtualItems","paddingTop","paddingBottom","getTotalSize","at","align","some","findIndex","scrollToIndex","reachEndFiredForCountRef","warnedReachEndPaginationRef","lastMountedIndex","console","warn","leftLeafColumns","getLeftVisibleLeafColumns","rightLeafColumns","getRightVisibleLeafColumns","centerLeafColumns","getCenterVisibleLeafColumns","orderedColumns","centerHeaderGroups","getCenterHeaderGroups","leftHeaderGroups","getLeftHeaderGroups","rightHeaderGroups","getRightHeaderGroups","headerGroups","group","headers","columnTracks","isFixed","minSize","maxSize","isResized","isPinned","getIsPinned","minWidth","track","getSize","flex","gridTemplateColumns","c","gridMinWidth","reduce","sum","columnLayout","widthOf","leftOffset","rightOffset","reverse","layoutFor","get","isEmpty","emptyGlobalFilter","globalFilter","columnFilters","trim","leafHeaders","hasSummaryRow","footer","selectsOnRowClick","rowClickSelects","rowIsInteractive","highlightRow","rowGesturesFor","handleRowActivate","modifiers","toggle","extend","getCanSelect","resolved","anchorRowId","selectionAnchorRowId","selection","rowSelection","canReplaceSelection","setRowSelection","actions","setSelectionAnchor","setHighlightedRow","rowClassNameFor","rowStyleFor","cellEventArgs","cellSelection","cellRangeSelection","wantsCellFocusRef","appliedCellRef","focusedRowIndex","focusedColumnIndex","focusedCellIsMounted","item","firstMountedRow","tabStopCell","isCellAt","rangeBounds","rowIndexOf","columnIndexOf","setRangeTo","anchor","setCellRange","focus","selectionBounds","selectedCellCount","selectedDataColumnCount","exportOptions","exportIncludesHeaders","setExportIncludesHeaders","includeHeaders","buildSelectionMatrix","columns","bounds","decimalComma","copySelection","matrix","isDraggingRange","setIsDraggingRange","stop","window","addEventListener","removeEventListener","startRangeDrag","setFocusedCell","exportSelectionCsv","fileName","separator","moveFocusedCell","coords","rowIndex","editSeedRef","takeEditSeed","seed","firstEditableColumnId","find","candidate","cells","getLeftVisibleCells","getCenterVisibleCells","getRightVisibleCells","canEditCell","placedEditCaretRef","refocusCell","openEditor","begin","handleEditorClose","move","via","editMode","next","from","direction","rowCount","columnCount","isEditable","selectRowFromCell","handleGridKeyDown","target","dataset","key","closest","preventDefault","ctrlKey","metaKey","keyRow","keyColumn","editing","clearCell","then","altKey","interactive","shiftKey","pageRows","Math","max","floor","clientHeight","contains","document","activeElement","Element","preventScroll","contextMenuTarget","setContextMenuTarget","closeContextMenu","contextMenuRowRef","contextMenuColumnRef","handleContextMenu","contextMenuRow","canRenderRowMenu","cellMenuContent","cellCount","copy","exportCsv","previous","input","tookOverMenu","rowMenuContent","getAllCells","contextMenuContent","scrollEdgesRef","hasEdgeCallbacks","handleScroll","el","currentTarget","scrollTop","scrollHeight","clientWidth","scrollWidth","tableWrapper","scrollContainer","multiRowSelection","headerGroup","groupIndex","header","renderBodyRow","viewIndex","ariaRowIndex","isGroupRow","isInteractive","rowCells","rowEditing","takesKeyboard","depth","getIsSelected","showSelectedBackground","bodyRow","cellIndex","isEditingCell","button","detailsCell","stopPropagation","pinnedTopBlock","gridColumn","virtualItem","pinnedBottomBlock","messageRow","noRows","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","getRowCount","shown","t2","totalRowCount","getPreFilteredRowModel","rows","length","total","t3","undefined","t4","summaryCount","TMDataGridColumnsButton","ui","features","opened","_temp","canHideAny","manageColumns","actions","toggleColumnsPanel","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","TMDataGridDraftActions","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","id","TMDataGridRoot","t0","$","_c","table","ui","edit","features","labels","renderDetails","renderDetailsEstHeight","overscan","resetSettings","scrollToRow","scrollerRef","t1","testId","undefined","rowHeight","options","meta","t2","t3","controlSize","api","t4","root","filter","Boolean","t5","join","t6","t7","TMDataGrid","Object","assign","Toolbar","Spacer","SummaryCount","LoadingIndicator","Search","DraftActions","ColumnsButton","FilterButton","Table","Footer","FilterPanel","FilterPills","ColumnsPanel","Input","RangeSlider","TMDataGridFilterControlArgs","operatorTakesRangeValue","TMDataGridFilterValueInput","DgRangeSliderFilter","args","$","_c","column","operator","value","onChange","size","labels","t0","numbers","key","getFacetedUniqueValues","keys","numeric","Number","isFinite","push","min","length","Math","max","Array","isArray","pair","lower","undefined","upper","t1","filterValue","t2","t3","t4","t5","t6","nextLower","nextUpper","String","filterFrom","filterTo","t7","Group","TextInput","TMDataGridFilterControlArgs","operatorTakesRangeValue","TMDataGridFilterValueInput","DgDateRangeFilter","args","$","_c","operator","value","onChange","size","labels","t0","Array","isArray","String","pair","t1","event","currentTarget","t2","filterFrom","t3","event_0","t4","filterTo","t5","Autocomplete","resolveColumnOptions","TMDataGridFilterControlArgs","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","TMDataGridFilterValueInput","DgAutocompleteFilter","args","$","_c","column","table","operator","value","onChange","options","size","labels","t0","needsValue","t1","length","fallback","suggestions","t2","filterValue","t3","Symbol","for","withinPortal","t4","t5","filterValuePlaceholder","t6","map","_temp","t7","t8","option","Input","SegmentedControl","TMDataGridFilterControlArgs","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","TMDataGridFilterValueInput","DgTriStateFilter","args","$","_c","operator","value","onChange","size","labels","t0","needsValue","scalar","t1","t2","filterAll","label","t3","booleanTrue","t4","booleanFalse","t5","t6","t7","next","t8","t9","filterValue","TMDataGridLabels","TMDATAGRID_LABELS_SV","operators","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","between","before","after","onOrBefore","onOrAfter","isAnyOf","isNoneOf","isEmpty","isNotEmpty","manageColumns","filters","searchPlaceholder","searchLabel","clearSearch","columnsSearchPlaceholder","columnsNoMatch","search","columnsShowHideAll","columnsReset","columnsResetHint","rowNumberColumnLabel","noRows","filterColumn","filterOperator","filterValue","filterValuePlaceholder","filterFrom","filterTo","filterAll","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","editCell","confirmEdit","cancelEdit","editColumnLabel","editRow","saveRow","cancelRowEdit","editRowErrors","saveAllEdits","rows","discardAllEdits","editRowsStillOpen","confirmNewRow","discardNewRow","deleteRow","restoreRow","revertRow","rowStateNew","rowStateEdited","rowStateDeleted","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","flatRows"],"sources":["../src/tmdatagrid/components/TMDataGrid.module.css","../src/tmdatagrid/components/TMDataGridColumnsPanel.module.css","../src/tmdatagrid/TMDataGridContext.ts","../src/tmdatagrid/core/filterOperators.ts","../src/tmdatagrid/components/TMDataGridDetailsColumn.module.css","../src/tmdatagrid/core/expanding.ts","../src/tmdatagrid/components/TMDataGridDetailsColumn.tsx","../src/tmdatagrid/components/TMDataGridTable.module.css","../src/tmdatagrid/core/editEngine.ts","../src/tmdatagrid/components/TMDataGridEditColumn.tsx","../src/tmdatagrid/components/TMDataGridGroupColumn.module.css","../src/tmdatagrid/core/grouping.ts","../src/tmdatagrid/components/TMDataGridGroupColumn.tsx","../src/tmdatagrid/components/TMDataGridRowNumberColumn.tsx","../src/tmdatagrid/core/rowSelection.ts","../src/tmdatagrid/components/TMDataGridSelectColumn.tsx","../src/tmdatagrid/core/columnUtils.ts","../src/tmdatagrid/components/TMDataGridColumnsPanel.tsx","../src/tmdatagrid/components/TMDataGridDraftActions.tsx","../src/tmdatagrid/components/TMDataGridFilterPanel.module.css","../src/tmdatagrid/core/columnOptions.ts","../src/tmdatagrid/components/filters/TMDataGridFilterValueInput.tsx","../src/tmdatagrid/components/TMDataGridFilterPanel.tsx","../src/tmdatagrid/components/TMDataGridFilterPills.module.css","../src/tmdatagrid/core/quickSearch.ts","../src/tmdatagrid/core/labels.ts","../src/tmdatagrid/core/persistence.ts","../src/tmdatagrid/core/capabilities.ts","../src/tmdatagrid/core/cellNavigation.ts","../src/tmdatagrid/core/controlledState.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/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/components/editors/editorShared.ts","../src/tmdatagrid/components/editors/TMDataGridBooleanEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridDateEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridMultiSelectEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridSelectEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridStringEditor.tsx","../src/tmdatagrid/components/TMDataGridCellEditor.tsx","../src/tmdatagrid/core/editorFocus.ts","../src/tmdatagrid/components/TMDataGridEntryRows.tsx","../src/tmdatagrid/core/draftCellContext.ts","../src/tmdatagrid/core/cellRange.ts","../src/tmdatagrid/core/cellExport.ts","../src/tmdatagrid/core/rowPinning.ts","../src/tmdatagrid/core/matchHighlight.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/components/filters/DgRangeSliderFilter.tsx","../src/tmdatagrid/components/filters/DgDateRangeFilter.tsx","../src/tmdatagrid/components/filters/DgAutocompleteFilter.tsx","../src/tmdatagrid/components/filters/DgTriStateFilter.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 /* The frame's corner radius. Any length or Mantine radius token; `0` squares\n the grid off against a card or a full-bleed page. Override it on the grid:\n <TMDataGrid style={{ \"--dg-radius\": 0 }} />\n The root clips its overflow, so the header and the last row follow it. */\n --dg-radius: var(--mantine-radius-md);\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 /* Every second row under `striped`. A whisper of the text colour over the\n body, so one declaration is right in both themes. */\n --dg-row-striped-bg: color-mix(\n in srgb,\n var(--mantine-color-text) 3.5%,\n var(--mantine-color-body)\n );\n /* A confirmed entry row under draft mode - entered, awaiting Save all. A\n whisper of green over the body, one declaration for both themes. */\n --dg-row-new-bg: color-mix(\n in srgb,\n var(--mantine-color-green-6) 8%,\n var(--mantine-color-body)\n );\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 /* The pinned-row slot serves both sticky rows: the summary along the\n bottom and the entry block under the header. */\n --dg-z-pinned-row: 4;\n --dg-z-pinned-row-pinned-cell: 5;\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(--dg-radius);\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","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 filter model plain,\n * serialisable JSON, so a server-side `manualFiltering` table can forward\n * `columnFilters` to the API unchanged.\n *\n * `value` is a string array under `isAnyOf` / `isNoneOf` (the set the cell is\n * tested against), a `[min, max]` pair under `between` (an empty string means\n * that end is open), and a single string everywhere else - dates travel as\n * ISO `YYYY-MM-DD` strings, booleans as `\"true\"` / `\"false\"`. Still plain\n * 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 | \"between\"\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 between: \"is between\",\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 \"between\",\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 \"between\",\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\n/** Operators whose value is a `[min, max]` pair. */\nconst RANGE_OPERATORS: readonly TMDataGridFilterOperator[] = [\"between\"];\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\n/** Whether the operator's value is a `[min, max]` pair - `between`. */\nexport function operatorTakesRangeValue(\n operator: TMDataGridFilterOperator,\n): boolean {\n return RANGE_OPERATORS.includes(operator);\n}\n\n/** The untouched value a fresh filter starts with - the operator's shape, empty. */\nexport function emptyValueForOperator(\n operator: TMDataGridFilterOperator,\n): string | ReadonlyArray<string> {\n if (operatorTakesArrayValue(operator)) return [];\n if (operatorTakesRangeValue(operator)) return [\"\", \"\"];\n return \"\";\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 // A `between` pair is `[\"\", \"\"]` while untouched, so an array is active\n // once some entry says something, not merely by existing.\n return Array.isArray(value.value)\n ? value.value.some((entry) => String(entry).trim() !== \"\")\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 =\n operator === \"between\" && Array.isArray(value)\n ? value.map((entry) => String(entry).trim()).join(\"–\")\n : Array.isArray(value)\n ? value.join(\", \")\n : 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\n/** One end of a `between` interval. An empty bound is an open end. */\nfunction boundHolds(\n cellValue: unknown,\n bound: string,\n end: \"min\" | \"max\",\n): boolean {\n const boundText = bound.trim();\n if (boundText === \"\") return true;\n\n const numericCell = typeof cellValue === \"number\" ? cellValue : Number.NaN;\n const numericBound = Number(boundText);\n if (!Number.isNaN(numericCell) && !Number.isNaN(numericBound)) {\n return end === \"min\"\n ? numericCell >= numericBound\n : numericCell <= numericBound;\n }\n\n const cellDay = toIsoDay(cellValue);\n const boundDay = toIsoDay(boundText);\n if (cellDay === null || boundDay === null) return false;\n return end === \"min\" ? cellDay >= boundDay : cellDay <= boundDay;\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 // A closed or half-open interval. Each present end must hold; an empty end\n // is open - and a fully empty pair matches everything, the same way a blank\n // needle does. Ends compare the way the single-ended operators would:\n // numerically when both sides are numbers, by calendar day otherwise.\n if (operator === \"between\") {\n const [min, max] = Array.isArray(value)\n ? [String(value[0] ?? \"\"), String(value[1] ?? \"\")]\n : [String(value), \"\"];\n return (\n boundHolds(cellValue, min, \"min\") && boundHolds(cellValue, max, \"max\")\n );\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, so `equals` on a date column means\n // \"is this day\" rather than a string comparison against the Date's default\n // 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","/* 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 data-dg-part=\"details-toggle\"\n data-row-id={row.id}\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 data-dg-part=\"details-toggle-all\"\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. Moving\n * or hiding the toggle would leave rows with panels that cannot be opened.\n *\n * Last of the three because it acts on a single record.\n *\n * A second toggle elsewhere is supported: `row.toggleExpanded()` is the entire\n * interface, and this lane is only the control 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","/* 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 /* Lets .messageRow size itself to the scrollport (100cqi) instead of the\n full column-track width, so its content centres in the visible window. */\n container-type: inline-size;\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/* The scrolled-under shadow: a soft band under the header, only while body\n rows are actually beneath it. On the last header row - the header/body\n boundary - not on every stacked group row. A scroll-driven animation, like\n the pinned-lane gradients: the shadow tracks the scroll on the compositor\n with no listener and no render, and an inactive timeline (nothing to\n scroll) leaves `opacity: 0` standing, so a grid that fits shows nothing.\n Where unsupported there is simply no shadow - the header's border already\n draws the boundary. */\n.headerRow[data-dg-header-last]::after {\n content: \"\";\n position: absolute;\n inset: 100% 0 auto 0;\n height: 6px;\n pointer-events: none;\n background: linear-gradient(\n to bottom,\n var(--dg-header-shadow-color, rgba(0, 0, 0, 0.14)),\n transparent\n );\n opacity: 0;\n}\n\n@supports (animation-timeline: scroll()) {\n .headerRow[data-dg-header-last]::after {\n animation: dg-header-shadow linear both;\n animation-timeline: scroll(nearest block);\n /* Arrives over the first rows leaving, reads as depth not as a fade. */\n animation-range: 0px 24px;\n }\n}\n\n@keyframes dg-header-shadow {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\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/* Every second row, under the Table's `striped` prop. Painted from the row's\n own position (`data-striped`), never `:nth-child`: virtualization mounts a\n moving window of rows, so document position says nothing about data\n position. Declared before the hover rule, which is the stronger statement\n and wins at equal specificity. */\n.bodyRow[data-striped=\"true\"] {\n --row-bg: var(--dg-row-striped-bg);\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/* The editing cell hands its box to the editor: the text padding comes off so\n the input can fill the track, and the input's own chrome takes over. */\n.bodyCell[data-editing] {\n padding: 0 calc(var(--dg-padding) / 2);\n}\n\n.cellEditor {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n gap: 2px;\n}\n\n/* cellConfirm's ✓ / ✕ pair, beside the input. */\n.cellEditorActions {\n display: flex;\n align-items: center;\n flex: 0 0 auto;\n}\n\n/* Corner triangles for a cell's edit state, drawn like a spreadsheet's: a\n draft not yet saved is blue, a value failing validation is red. The cell\n needs a positioning context; pinned and focused cells set their own inline\n `position`, which wins over this. */\n.bodyCell[data-dirty],\n.bodyCell[data-invalid] {\n position: relative;\n}\n\n.bodyCell[data-dirty]::after,\n.bodyCell[data-invalid]::after {\n content: \"\";\n position: absolute;\n top: 0;\n right: 0;\n border: 5px solid transparent;\n border-top-color: var(--mantine-primary-color-filled);\n border-right-color: var(--mantine-primary-color-filled);\n}\n\n/* Invalid wins over dirty - a cell is usually both. */\n.bodyCell[data-invalid]::after {\n border-top-color: var(--mantine-color-error);\n border-right-color: var(--mantine-color-error);\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/* Spans every column track, but the rendered box is pinned to the scrollport:\n sticky at the left edge and exactly one container-width wide, so the\n centred content stays in the middle of the window however far the grid is\n scrolled horizontally. */\n.messageRow {\n grid-column: 1 / -1;\n position: sticky;\n left: 0;\n width: 100cqi;\n justify-self: start;\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/* Marked deleted under draft: struck through and inert until submitAll\n reports it - a row about to go away must not keep taking edits. Interaction\n comes off the data cells, not the row: `pointer-events: none` on the row\n would also kill the edit lane's Restore, which is the one control the row\n still needs (jsdom does not enforce pointer-events, so only a real browser\n ever saw that bug). */\n.bodyRow[data-deleted=\"true\"] {\n text-decoration: line-through;\n opacity: 0.55;\n}\n\n.bodyRow[data-deleted=\"true\"] .bodyCell:not([data-control-column=\"true\"]) {\n pointer-events: none;\n}\n\n/* The entry block - one row per edit.addRow(), under the header on the same\n subgrid tracks as everything else. The *block* is the sticky element, not\n the rows: sticky siblings would all compete for the same `top` and stack\n onto one spot, while a single sticky wrapper lets its rows flow normally\n inside it. Subgrid twice over keeps the cells on the outer tracks.\n `--dg-header-height` is measured only while the block exists. */\n.entryBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n top: var(--dg-header-height, 0px);\n z-index: var(--dg-z-pinned-row, 4);\n}\n\n.entryRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n}\n\n/* Confirmed entry rows in the scrolling flow (the default; `newRowsSticky`\n keeps them in the sticky block instead). Same tracks, no stickiness - they\n sit above the body rows and scroll with them. */\n.entryFlowBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n}\n\n/* The pinned edge blocks - user-pinned rows held at the top or bottom of the\n body, on the entry block's sticky mechanics: the block is the sticky\n element, its rows flow normally inside it. The top block stacks under the\n entry block when both exist; `--dg-entry-height` is measured only then, so\n the offset is otherwise the header alone. The bottom block stacks above the\n summary row the same way. Rows are opaque already (`--row-bg` paints the\n body colour), so the blocks only add the edge borders. */\n.pinnedTopBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n top: calc(var(--dg-header-height, 0px) + var(--dg-entry-height, 0px));\n z-index: var(--dg-z-pinned-row, 4);\n}\n\n.pinnedTopBlock > :last-child > [role=\"cell\"] {\n border-bottom: 2px solid var(--mantine-color-default-border);\n}\n\n.pinnedBottomBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n bottom: var(--dg-summary-height, 0px);\n z-index: var(--dg-z-pinned-row, 4);\n}\n\n.pinnedBottomBlock > :first-child > [role=\"cell\"] {\n border-top: 2px solid var(--mantine-color-default-border);\n}\n\n.entryCell {\n display: flex;\n align-items: center;\n padding: 0 calc(var(--dg-padding) / 2);\n border-bottom: 2px solid var(--mantine-primary-color-filled);\n /* Opaque: the body scrolls underneath it. */\n background-color: var(--mantine-color-body);\n font-size: var(--dg-font-size);\n}\n\n.entryCell[data-control-column=\"true\"] {\n padding: 0;\n justify-content: center;\n}\n\n/* A confirmed entry row - entered, awaiting Save all. It reads as a value\n row: text padding, the body's border weight, and the \"new\" tint instead of\n the editing underline. */\n.entryRow[data-confirmed=\"true\"] .entryCell {\n padding: 0 var(--dg-padding);\n border-bottom: 1px solid var(--mantine-color-default-border);\n background-color: var(--dg-row-new-bg, var(--mantine-color-body));\n}\n\n.entryRow[data-confirmed=\"true\"] .entryCell[data-control-column=\"true\"] {\n padding: 0;\n}\n\n/* Draft mode's change marker in the edit lane - dimmed beside the buttons\n that act, red when validation blocks the row. */\n.rowStateIndicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n flex: 0 0 auto;\n color: var(--mantine-color-dimmed);\n}\n\n.rowStateIndicator[data-error] {\n color: var(--mantine-color-error);\n}\n\n.entryCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.entryCell[data-align=\"center\"] {\n justify-content: center;\n}\n\n/* The matched slice of a cell's text, while `enableMatchHighlighting` is on\n and a contains-family filter or the quick search is active. `mark` resets\n the browser's default so the colour is the grid's to state - override with\n `--dg-match-highlight-bg` on the grid. */\n.matchHighlight {\n background-color: var(\n --dg-match-highlight-bg,\n light-dark(var(--mantine-color-yellow-2), rgba(250, 176, 5, 0.35))\n );\n color: inherit;\n border-radius: 2px;\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","import {\n FormApi,\n getBy,\n type AnyFieldApi,\n type AnyFormApi,\n type StandardSchemaV1,\n} from \"@tanstack/react-form\";\nimport { batch, Store } from \"@tanstack/store\";\nimport type { Cell, Column, Row, RowData } from \"@tanstack/react-table\";\nimport type { ComponentType } from \"react\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\nimport {\n isColumnEditableForRow,\n isColumnEditSwitchedOff,\n isControlColumn,\n} from \"./columnUtils\";\nimport type { TMDataGridColumnType } from \"./filterOperators\";\nimport type { TMDataGridSize } from \"./sizes\";\n\n/**\n * What counts as a commit - one axis, each mode a thin policy over the same\n * engine. Where a commit *goes* is the other axis, `editing.draft`: out to\n * the consumer, or into the draft store. See `editing` on\n * `UseTMDataGridOptions`.\n *\n * | Mode | Enter | Tab | Focus leaves | Escape |\n * | ---- | ----- | --- | ------------ | ------ |\n * | `\"cell\"` | commits | commits, caret moves on | commits | cancels |\n * | `\"cellConfirm\"` | commits | keeps the draft, caret moves on | keeps the draft | cancels |\n * | `\"row\"` | commits the row | the browser's, along the row | nothing | cancels the row |\n *\n * An entry row is row-shaped in every mode - every editable cell open at\n * once, the browser's Tab between them, and an explicit ✓.\n */\nexport type TMDataGridEditMode = \"cell\" | \"cellConfirm\" | \"row\";\n\n/**\n * One editing row's live form. TanStack Form's `FormApi`, not a wrapper: the\n * engine is a form library, and everything mid-edit - values, dirty state,\n * errors, async validation, submit lifecycle - is form state, read off\n * `form.store` with the same selector idiom as the rest of the grid.\n *\n * The alias erases Form's validator generics the way `TMDataGridRowData`\n * erases the row type: the concrete types lived at the `useTMDataGrid` call.\n */\nexport type TMDataGridRowEditForm = AnyFormApi;\n\n/** The live field a cell editor binds to - TanStack Form's own `FieldApi`. */\nexport type TMDataGridEditField = AnyFieldApi;\n\n/**\n * A validator as TanStack Form takes it: a Standard Schema (Zod, Valibot,\n * ArkType…) or a plain function returning an error or nothing. Forwarded\n * untouched - the vocabulary is Form's, not a grid re-implementation.\n */\nexport type TMDataGridValidator =\n | StandardSchemaV1<unknown, unknown>\n | ((args: { value: never; fieldApi: never }) => unknown);\n\n/**\n * `meta.edit.validate` - per-column field validators. A bare schema or function is\n * shorthand for `{ onChange: it }`; the object form takes every trigger\n * TanStack Form defines, `Async` variants and debounce included.\n */\nexport type TMDataGridFieldValidate =\n | TMDataGridValidator\n | {\n onMount?: TMDataGridValidator;\n onChange?: TMDataGridValidator;\n onChangeAsync?: TMDataGridValidator;\n onChangeAsyncDebounceMs?: number;\n onBlur?: TMDataGridValidator;\n onBlurAsync?: TMDataGridValidator;\n onSubmit?: TMDataGridValidator;\n onSubmitAsync?: TMDataGridValidator;\n };\n\n/**\n * `rowValidators` - form-level validators for the whole row, where\n * cross-field rules live. Passed into each row form's `validators` untouched;\n * pathed issues land on the matching fields, pathless ones on the row.\n */\nexport type TMDataGridRowValidators = {\n onMount?: TMDataGridValidator;\n onChange?: TMDataGridValidator;\n onChangeAsync?: TMDataGridValidator;\n onChangeAsyncDebounceMs?: number;\n onBlur?: TMDataGridValidator;\n onBlurAsync?: TMDataGridValidator;\n onSubmit?: TMDataGridValidator;\n onSubmitAsync?: TMDataGridValidator;\n onSubmitAsyncDebounceMs?: number;\n};\n\n/** What `editing.tableValidators` is handed for one commit. */\nexport type TMDataGridTableValidateArgs<\n TData extends RowData = TMDataGridRowData,\n> = {\n /** The committing row, as drafted. */\n value: TData;\n /** Its id - `addRow`'s temp id for an entry row. */\n rowId: string;\n /** Whether the row is an entry row, not yet in `data`. */\n isNew: boolean;\n /**\n * The collection as it would stand if this commit landed: every data row\n * overlaid with its draft where one is held (this row's `value` included),\n * entry rows appended, deletion-marked rows removed. Unfiltered - a rule\n * sees the whole collection whatever the view shows.\n */\n rows: ReadonlyArray<{ rowId: string; value: TData }>;\n};\n\n/**\n * `editing.tableValidators` - rules that need the other rows: no duplicate\n * keys, no overlapping ranges, allocations summing to a total. Run at every\n * commit, after the row's own validators, and again per parked row during\n * `saveDrafts` - so a draft invalidated by a later edit blocks the save.\n *\n * Return nothing to pass, a message, or Form's `{ form, fields }` shape;\n * pathed issues land on the committing row's cells, pathless ones on the row.\n * `onSubmit` runs first, and its failure stands without `onSubmitAsync`\n * running.\n */\nexport type TMDataGridTableValidators<\n TData extends RowData = TMDataGridRowData,\n> = {\n onSubmit?: (args: TMDataGridTableValidateArgs<TData>) => unknown;\n onSubmitAsync?: (\n args: TMDataGridTableValidateArgs<TData>,\n ) => unknown | Promise<unknown>;\n};\n\n/** One field's before/after across a commit. */\nexport type TMDataGridEditChange = {\n /** Column the field maps back to, for consumers thinking in columns. */\n columnId: string;\n /** The data path - `getEditFieldName` of the column. */\n field: string;\n previous: unknown;\n next: unknown;\n};\n\nexport type TMDataGridEditCommitArgs<TData extends RowData> = {\n rowId: string;\n /** The whole row as edited - for the consumer who saves records. */\n value: TData;\n /** The row as it was when editing began. */\n original: TData;\n /** Per-field diff - for the consumer who PATCHes. One entry in cell mode. */\n changes: Array<TMDataGridEditChange>;\n /** Which policy committed. */\n source: TMDataGridEditMode;\n};\n\n/** What one open row's form looks like from outside - the cell markers. */\nexport type TMDataGridEditRowProjection = {\n /** Field names whose value differs from the original. */\n dirtyFields: ReadonlyArray<string>;\n /** Field names carrying a validation error, live or from a failed commit. */\n errorFields: ReadonlyArray<string>;\n /**\n * Those errors as text: what each cell editor is showing, plus what the\n * row's last failed commit found. The second half is the reason this\n * exists - Form clears a field's errors when its editor unmounts, so a row\n * left invalid would go back to looking like an ordinary edited row. Such\n * a message is dropped as soon as its field's value moves: the fix is what\n * clears the mark.\n */\n errorMessages: ReadonlyArray<{ field: string; message: string }>;\n /** A row-level error - a pathless `.refine()`, or a rejected commit. */\n hasRowError: boolean;\n isSubmitting: boolean;\n /**\n * The row as drafted - the form's `state.values`. Reference-stable while no\n * value changes, so a cell may subscribe to it and repaint only when its\n * row's draft actually moves.\n */\n values: TMDataGridRowData;\n};\n\n/**\n * The grid-facing index of everything mid-edit. A projection synced from the\n * open forms' stores, so body cells subscribe to this one store for their\n * dirty/error markers instead of one store per form. Only the editor host\n * reads a form's store directly - it is mounted for one cell at a time.\n */\nexport type TMDataGridEditState = {\n /**\n * The cell the last open gesture named - where the caret goes. In row mode\n * the whole row is editing whatever this says, so there it is only the\n * caret's cell, and `null` for the lane's pencil, which names no column.\n */\n active: { rowId: string; columnId: string | null } | null;\n /**\n * Rows with a live form, committed or not - every row the grid is holding\n * work for. A row is *open* (undecided form state) when it is in here and\n * not in {@link committedRowIds}.\n */\n openRowIds: ReadonlyArray<string>;\n rows: Record<string, TMDataGridEditRowProjection>;\n /**\n * The draft store's edit slice: existing rows whose form passed its submit\n * and is parked, waiting for `saveDrafts`. A subset of `openRowIds` - the\n * values stay in the row's form, this records which side of the line the\n * row is on. `begin` on one of these takes it back out, into form state.\n *\n * Only `editing.draft` parks. Without it a commit goes straight to the\n * consumer and the form is dropped, so this stays empty.\n */\n committedRowIds: ReadonlyArray<string>;\n /**\n * Rows being created, not yet in `data`. `committed` is the draft store's\n * add slice: the entry row passed its submit and renders as a value row\n * until `begin` re-opens it. Without `editing.draft` a commit adds through\n * `onRowAdd` and the entry is dropped, so it never turns `true`.\n */\n newRows: ReadonlyArray<{ tempId: string; committed: boolean }>;\n /** The draft store's delete slice: rows marked deleted, awaiting the save. */\n deletedRowIds: ReadonlyArray<string>;\n};\n\nconst EMPTY_EDIT_STATE: TMDataGridEditState = {\n active: null,\n openRowIds: [],\n rows: {},\n committedRowIds: [],\n newRows: [],\n deletedRowIds: [],\n};\n\n/**\n * The rows still *open*: holding a live form nobody has decided yet.\n *\n * Narrower than {@link TMDataGridEditState.openRowIds}, which is every row\n * with a form, the parked ones included. A row qualifies here when it is not\n * parked in the draft store and there is something to lose - an entered row\n * always counts, an existing one only once a value has moved.\n *\n * The order is the engine's: the order the forms were opened.\n */\nexport function getOpenRowIds(\n state: TMDataGridEditState,\n): ReadonlyArray<string> {\n return state.openRowIds.filter(\n (rowId) =>\n !state.committedRowIds.includes(rowId) &&\n !state.newRows.some(\n (newRow) => newRow.tempId === rowId && newRow.committed,\n ) &&\n (state.newRows.some((newRow) => newRow.tempId === rowId) ||\n (state.rows[rowId]?.dirtyFields.length ?? 0) > 0),\n );\n}\n\ntype ErasedRow = Row<TMDataGridFeatures, TMDataGridRowData>;\ntype ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\n\n/**\n * What a cell editor is handed - deliberately both vocabularies at once. The\n * form side is TanStack Form's real `field` API (`field.state.value`,\n * `field.state.meta.errors`, `field.handleChange`, `field.handleBlur`), so a\n * custom calendar, slider or async combobox binds to it exactly as it would\n * inside any TanStack Form. The table side is where the editor is standing.\n *\n * The built-ins are implemented against this same contract, so\n * `meta.edit.editor` is not a special case - it is the slot the defaults\n * fill, and the exported built-ins can be wrapped instead of replaced.\n */\nexport type TMDataGridEditorArgs = {\n /** The live TanStack Form field for this cell. */\n field: TMDataGridEditField;\n /** The whole row form, for the rare editor that reads sibling fields. */\n form: TMDataGridRowEditForm;\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n row: ErasedRow;\n column: ErasedColumn;\n table: TMDataGridTable<TMDataGridRowData>;\n /** What Enter would do - commit the edit. For the editor's own UI. */\n commit: () => Promise<boolean>;\n /** What Escape would do - drop the draft. */\n cancel: () => void;\n size: TMDataGridSize;\n /**\n * Set when typing opened the editor (the Sheets gesture) - the built-ins\n * replace the value with it and keep typing. A custom editor may ignore it.\n */\n seedText?: string;\n};\n\n/**\n * `meta.edit.editor` - replaces the built-in editor for this column. Rendered\n * as JSX, never invoked as a bare function, so hooks are legal inside. Define\n * it at module scope: a new identity per render remounts the editor mid-edit.\n */\nexport type TMDataGridEditorComponent = ComponentType<TMDataGridEditorArgs>;\n\n/** What `meta.edit.mapValue` is handed for one write. */\nexport type TMDataGridEditValueMapArgs = {\n /** The value the editor just wrote. */\n value: unknown;\n /** What the field held before this write - for length-aware masks. */\n previous: unknown;\n row: ErasedRow;\n column: ErasedColumn;\n table: TMDataGridTable<TMDataGridRowData>;\n};\n\n/**\n * `meta.edit.mapValue` - the value on its way into the draft, mapped.\n *\n * Runs on every write an editor makes, which for a text input is every\n * keystroke and for a select is every pick, so the mapped value is what the\n * user sees, what validators judge and what commits.\n */\nexport type TMDataGridEditValueMap = (\n args: TMDataGridEditValueMapArgs,\n) => unknown;\n\n/**\n * `meta.edit` - everything about how this column is edited, in one place,\n * mirroring the `edit.*` engine the grid exposes at runtime.\n *\n * ```tsx\n * meta: {\n * type: \"string\",\n * edit: {\n * enabled: (row) => row.original.status !== \"Locked\",\n * validate: z.string().min(2, \"Too short\"),\n * mapValue: ({ value }) =>\n * typeof value === \"string\" ? value.toUpperCase() : value,\n * },\n * }\n * ```\n *\n * `meta.type` and `meta.options` stay outside this namespace on purpose: one\n * declaration of each feeds the cell editor and the filter panel alike.\n */\nexport type TMDataGridColumnEditOptions = {\n /**\n * Whether this column's cells take edits, once `editMode` is on. `false`\n * switches the column off outright; a predicate decides per row. Defaults\n * to editable for any column that maps to a field - see {@link field}.\n */\n enabled?:\n | boolean\n | ((row: Row<TMDataGridFeatures, TMDataGridRowData>) => boolean);\n /**\n * The data path this column edits, when it is not the `accessorKey` - the\n * only way a column built on `accessorFn` becomes editable. Dot paths reach\n * into nested records: `\"address.city\"`.\n */\n field?: string;\n /**\n * Replaces the built-in editor for this column. See\n * {@link TMDataGridEditorComponent}.\n */\n editor?: TMDataGridEditorComponent;\n /**\n * Field-level validators, in TanStack Form's own vocabulary. A bare Zod\n * schema (or any Standard Schema, or a plain function) means\n * `{ onChange: it }`; the object form takes every trigger Form defines.\n */\n validate?: TMDataGridFieldValidate;\n /**\n * Maps every value an editor writes before it reaches the draft - uppercase\n * a code, strip spaces from an IBAN, clamp a number into range. See\n * {@link TMDataGridEditValueMap}.\n */\n mapValue?: TMDataGridEditValueMap;\n};\n\n/** A new row being committed - `onRowAdd`, and `saveDrafts`'s `created`. */\nexport type TMDataGridRowAddArgs<TData extends RowData> = {\n /** The engine's placeholder id; the real id is the consumer's to mint. */\n tempId: string;\n value: TData;\n};\n\n/** A deletion - `onRowDelete`. */\nexport type TMDataGridRowDeleteArgs<TData extends RowData> = {\n rowId: string;\n row: Row<TMDataGridFeatures, TData>;\n};\n\n/**\n * The draft store, flushed - what `saveDrafts` hands `onSaveDrafts`. Every\n * committed change at once, so a server can apply it as one transaction.\n * Rows still open (undecided form state) are not in here and stay open.\n */\nexport type TMDataGridSaveDraftsArgs<TData extends RowData> = {\n /** Committed edits to existing rows; each entry carries its `rowId`. */\n updated: Array<TMDataGridEditCommitArgs<TData>>;\n /** Committed new rows from the entry block; each entry carries its `tempId`. */\n created: Array<TMDataGridRowAddArgs<TData>>;\n /** Ids marked deleted while the drafts accumulated. */\n deleted: Array<string>;\n /** @deprecated Renamed to {@link updated}. Removed in a later beta. */\n rows: Array<TMDataGridEditCommitArgs<TData>>;\n /** @deprecated Renamed to {@link created}. Removed in a later beta. */\n added: Array<TMDataGridRowAddArgs<TData>>;\n};\n\n/**\n * Which entries of one bucket saved. `true`, or an id the map does not name,\n * saved and is dropped from the draft store; `false` failed and keeps its\n * draft. A bare boolean answers for the whole bucket.\n */\nexport type TMDataGridSaveOutcomes = boolean | Record<string, boolean>;\n\n/**\n * What `onSaveDrafts` may return to save part of the store.\n *\n * Returning nothing saves everything, and throwing saves nothing. Between\n * those, name the ids that failed: they keep their drafts, committed and\n * ready for the next save, while the rest are dropped. The grid marks them\n * with nothing beyond the state itself - a failed edit keeps `data-draft`,\n * a failed deletion keeps `data-deleted` - so the display is the consumer's.\n */\nexport type TMDataGridSaveDraftsResult = {\n /** Keyed by `rowId`. */\n updated?: TMDataGridSaveOutcomes;\n /** Keyed by `tempId`. */\n created?: TMDataGridSaveOutcomes;\n /** Keyed by `rowId`. */\n deleted?: TMDataGridSaveOutcomes;\n};\n\n/** Whether one id of a bucket saved. Unnamed ids saved. */\nfunction isSaved(\n outcomes: TMDataGridSaveOutcomes | undefined,\n id: string,\n): boolean {\n if (outcomes === undefined) return true;\n if (typeof outcomes === \"boolean\") return outcomes;\n return outcomes[id] !== false;\n}\n\n/**\n * @deprecated Renamed to {@link TMDataGridSaveDraftsArgs} - the payload is\n * the draft store being saved, not a commit. Removed in a later beta.\n */\nexport type TMDataGridEditCommitDraftsArgs<TData extends RowData> =\n TMDataGridSaveDraftsArgs<TData>;\n\n/** What the engine reads fresh on every call - see `createEditEngine`. */\nexport type TMDataGridEditEngineContext = {\n table: TMDataGridTable<TMDataGridRowData>;\n editMode: TMDataGridEditMode;\n /** `editing.draft` - whether a commit parks instead of reaching out. */\n draft: boolean;\n rowValidators?: TMDataGridRowValidators;\n tableValidators?: TMDataGridTableValidators;\n /**\n * `editing.columns` - the allowlist, or `undefined` for \"every column that\n * maps to a field\".\n */\n editableColumnIds?: ReadonlyArray<string>;\n isRowEditable?: (row: ErasedRow) => boolean;\n onEditCommit?: (\n args: TMDataGridEditCommitArgs<TMDataGridRowData>,\n ) => void | Promise<void>;\n onSaveDrafts?: (\n args: TMDataGridSaveDraftsArgs<TMDataGridRowData>,\n ) =>\n | void\n | TMDataGridSaveDraftsResult\n | Promise<void | TMDataGridSaveDraftsResult>;\n /**\n * Seed values for `addRow`, under the values it is called with. A function\n * is called per added row.\n */\n newRowDefaults?: TMDataGridRowData | (() => TMDataGridRowData);\n onRowAdd?: (\n args: TMDataGridRowAddArgs<TMDataGridRowData>,\n ) => void | Promise<void>;\n onRowDelete?: (\n args: TMDataGridRowDeleteArgs<TMDataGridRowData>,\n ) => void | Promise<void>;\n};\n\n/**\n * The data path a column edits, or `null` for a column that has none.\n *\n * `accessorKey` is the true path and Form addresses fields by dot-path, so\n * nested rows need no extra handling: `accessorKey: \"address.city\"` edits\n * `values.address.city`. A column built on `accessorFn` has no path and is not\n * editable unless `meta.edit.field` names one. TanStack's default column id\n * turns dots into underscores, which is why this starts from `accessorKey` and\n * never from `id`.\n */\nexport function getEditFieldName(column: {\n columnDef: { meta?: { edit?: { field?: string } } };\n}): string | null {\n const fromMeta = column.columnDef.meta?.edit?.field;\n if (fromMeta) return fromMeta;\n const accessorKey = (column.columnDef as Record<string, unknown>)[\n \"accessorKey\"\n ];\n return typeof accessorKey === \"string\" ? accessorKey : null;\n}\n\n/** What Delete writes into a cell - the type's honest empty value. */\nexport function clearedValueForType(type: TMDataGridColumnType): unknown {\n switch (type) {\n case \"string\":\n return \"\";\n case \"multiSelect\":\n return [];\n case \"boolean\":\n return false;\n default:\n return null;\n }\n}\n\n/** `edit.addRows` options. */\nexport type TMDataGridAddRowsOptions = {\n /**\n * Submit each row as it is added instead of leaving it open. Defaults to\n * `false` - the rows open as editable entry rows, as `addRow` does.\n */\n commit?: boolean;\n};\n\n/** What `edit.addRows` reports back. Every added row is in exactly one list. */\nexport type TMDataGridAddRowsResult = {\n /** Temp ids that committed - parked as drafts, or added outright. */\n committed: Array<string>;\n /**\n * Temp ids still open in the entry block: everything, when `commit` was\n * not asked for; the rows that failed validation, when it was.\n */\n open: Array<string>;\n};\n\n/**\n * The engine plus its store - `api.edit`.\n *\n * \"One row, one form\": `getForm` hands out the same `FormApi` the inline\n * editors write through, so a consumer can render it in a drawer or a detail\n * panel and share values, dirty state and errors with the cells.\n */\nexport type TMDataGridEditApi<\n TData extends RowData = TMDataGridRowData,\n> = {\n /** The projection store - subscribe with `useSelector(edit.store, …)`. */\n store: Store<TMDataGridEditState>;\n /** Current snapshot, for reads outside React. */\n readonly state: TMDataGridEditState;\n /** rowId → live form. The source of truth for everything mid-edit. */\n getForm: (rowId: string) => TMDataGridRowEditForm | undefined;\n /**\n * Whether this cell may open an editor: the column maps to a field, nothing\n * switched it off, and the row takes edits at all.\n */\n canEditCell: (row: ErasedRow, column: ErasedColumn) => boolean;\n /** Whether the row takes edits at all - the edit lane's pencil gate. */\n canEditRow: (row: ErasedRow) => boolean;\n /**\n * Whether the column takes edits at all, with no row in hand: it maps to a\n * field, `editing.columns` lists it if that option is set, and\n * `meta.edit.enabled` is not `false`. A per-row `enabled` predicate is the\n * row's half of the question - `canEditCell` asks both.\n */\n isColumnEditable: (column: ErasedColumn) => boolean;\n /**\n * Opens an editor. In row mode the whole row opens either way and `columnId`\n * only says which cell takes the caret; `null` (the lane's pencil) leaves it\n * to the row's first editable cell.\n */\n begin: (target: { rowId: string; columnId: string | null }) => void;\n /**\n * Commits one row - `form.handleSubmit` under the hood. Resolves `true`\n * when the form is gone: validation passed and `onEditCommit` resolved, or\n * there was nothing to save. `false` keeps the form open with its errors.\n */\n commit: (rowId: string) => Promise<boolean>;\n /** Drops one row's draft. */\n cancel: (rowId: string) => void;\n /**\n * Closes the editor without touching the draft - what blur does under\n * `\"cellConfirm\"`, where the dirty cell keeps waiting for its ✓.\n */\n deactivate: () => void;\n /** Drops every draft - open form state and the draft store alike. */\n cancelAll: () => void;\n /**\n * Submits every open row, as if each had been OK'd: a row that validates\n * commits (into the draft store with `editing.draft` on, straight to the\n * consumer without it), a row that fails stays open with its errors.\n * `true` when every row committed. Under `editing.draft` it sends nothing\n * to the consumer by itself - that is `saveDrafts`.\n */\n commitAll: () => Promise<boolean>;\n /**\n * Flushes the draft store: every committed edit, added row and deletion\n * mark reaches the consumer, through `onSaveDrafts` in one call when it is\n * set, or row by row through `onCommit` / `onRowAdd` / `onRowDelete`.\n *\n * Rows still open are left alone - they keep their form state and stay\n * open. `true` when everything landed; a rejected save keeps every draft.\n */\n saveDrafts: () => Promise<boolean>;\n /**\n * @deprecated Split into {@link commitAll} and {@link saveDrafts}, which is\n * exactly what this now does. Removed in a later beta.\n */\n submitAll: () => Promise<boolean>;\n /** Writes the type's empty value into a cell and commits it - Delete. */\n clearCell: (rowId: string, columnId: string) => Promise<boolean>;\n /**\n * Writes one cell and commits the row - a typed edit without the typing,\n * for toolbar actions and bulk fills. Under `editing.draft` the row parks\n * in the draft store exactly as a hand-made edit does, so it carries the\n * same change markers and the same per-row revert.\n *\n * The row need not be mounted; a row inside a collapsed group takes the\n * write. Resolves `false` when the cell takes no edit - no such row or\n * column, `editing.columns` excludes it, `meta.edit.enabled` is off, or the\n * row is not editable - and when validation refuses the value, which leaves\n * the row open carrying its errors.\n *\n * `value` is the stored value: no editor runs, so `meta.edit.mapValue`\n * does not either. `meta.edit.validate` does.\n */\n setCellValue: (\n rowId: string,\n columnId: string,\n value: unknown,\n ) => Promise<boolean>;\n /**\n * {@link setCellValue} for several cells of one row, in a single commit -\n * one consumer call and one draft entry rather than one per column. Keys\n * are column ids.\n *\n * All or nothing: if any named cell takes no edit, nothing is written and\n * this resolves `false`.\n */\n setRowValues: (\n rowId: string,\n values: Record<string, unknown>,\n ) => Promise<boolean>;\n /**\n * Opens a new entry row (the sticky block under the header) seeded from\n * `newRowDefaults`. `values` overrides that seed key by key, so\n * `addRow()` opens a blank row and `addRow({ status: \"draft\" })` opens one\n * that starts filled in. Returns its temporary id - a form with no backing\n * row yet. Committing it calls `onRowAdd`, or parks it for `saveDrafts`\n * under `editing.draft`.\n */\n addRow: (values?: Partial<TData>) => string;\n /**\n * Opens entry rows for a list of records at once - one state write for the\n * batch, where a loop over `addRow` is one per row. Each row is seeded over\n * `newRowDefaults` exactly as `addRow` does.\n *\n * `commit: true` submits each row as it lands, which is what an import\n * wants: rows that validate commit (parked in the draft store under\n * `editing.draft`, added through `onRowAdd` without it - once per row),\n * and rows that fail stay open in the entry block carrying their errors,\n * for the user to fix. The result says which went which way.\n */\n addRows: (\n rows: ReadonlyArray<Partial<TData>>,\n options?: TMDataGridAddRowsOptions,\n ) => Promise<TMDataGridAddRowsResult>;\n /**\n * Deletes a row: `onRowDelete` straight away, or under `editing.draft` a\n * toggle of the id in `deletedRowIds` - the row renders struck through\n * until `saveDrafts` reports it. On an uncommitted entry row it just\n * discards the entry.\n */\n deleteRow: (rowId: string) => void;\n /** Whether delete chrome makes sense - the lane's trash gate. */\n canDeleteRows: () => boolean;\n};\n\nfunction clearFormSourcedFieldErrors(form: TMDataGridRowEditForm): void {\n const fieldMeta = form.state.fieldMeta as Record<\n string,\n { errorSourceMap?: Record<string, unknown> }\n >;\n for (const [name, meta] of Object.entries(fieldMeta)) {\n const staleKeys = Object.entries(meta.errorSourceMap ?? {})\n .filter(([, source]) => source === \"form\")\n .map(([key]) => key);\n if (staleKeys.length === 0) continue;\n form.setFieldMeta(name as never, (previous) => ({\n ...previous,\n errorMap: {\n ...previous.errorMap,\n ...Object.fromEntries(staleKeys.map((key) => [key, undefined])),\n },\n }));\n }\n}\n\n/** Arrays compare by element so a multiSelect edit-back-to-same is clean. */\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((entry, i) => Object.is(entry, b[i]));\n }\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n return false;\n}\n\nfunction hasAnyError(errors: ReadonlyArray<unknown>): boolean {\n return errors.some((error) => error !== undefined && error !== null);\n}\n\n/**\n * The first error as text, whatever shape the validator produced - TanStack\n * Form keeps errors verbatim, so a Zod issue arrives as `{ message }`, a\n * plain function's return arrives as it was, and a form-level schema's\n * pathless issues arrive keyed under an empty path (`{ \"\": [issues] }`).\n * This digs until it finds a message.\n */\nexport function firstErrorText(error: unknown): string | undefined {\n if (error === null || error === undefined) return undefined;\n if (typeof error === \"string\") return error;\n if (Array.isArray(error)) {\n for (const entry of error) {\n const text = firstErrorText(entry);\n if (text !== undefined) return text;\n }\n return undefined;\n }\n if (typeof error === \"object\") {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\") return message;\n for (const value of Object.values(error)) {\n const text = firstErrorText(value);\n if (text !== undefined) return text;\n }\n }\n return undefined;\n}\n\n/**\n * The triggers a submit runs, in the order Form would: a value that fails its\n * column's `onChange` rule fails the submit too.\n */\nconst SUBMIT_VALIDATE_TRIGGERS = [\n \"onChange\",\n \"onChangeAsync\",\n \"onSubmit\",\n \"onSubmitAsync\",\n] as const;\n\n/** Whether a validator's return counts as an error. */\nfunction isValidationError(result: unknown): boolean {\n return result !== undefined && result !== null && result !== false;\n}\n\n/**\n * Runs one field validator the way TanStack Form would - a Standard Schema\n * (Zod, Valibot…) or a plain function - and returns its error, or undefined.\n */\nasync function runFieldValidator(\n validator: unknown,\n value: unknown,\n): Promise<unknown> {\n if (typeof validator === \"function\") {\n return await (\n validator as (args: { value: unknown; fieldApi: unknown }) => unknown\n )({ value, fieldApi: undefined });\n }\n if (\n typeof validator === \"object\" &&\n validator !== null &&\n \"~standard\" in validator\n ) {\n const schema = validator as StandardSchemaV1<unknown, unknown>;\n const result = await schema[\"~standard\"].validate(value);\n const { issues } = result as {\n issues?: ReadonlyArray<{ message: string }>;\n };\n if (issues === undefined || issues.length === 0) return undefined;\n return issues[0]?.message ?? \"Invalid\";\n }\n return undefined;\n}\n\n/**\n * Builds the edit engine. A factory over React so it is headless-testable;\n * `getContext` is read fresh on every call, which is how the engine always\n * sees the latest table, mode and consumer callbacks without being rebuilt.\n *\n * Virtualization, per the plan: nothing here is DOM. A form is a plain object\n * in a map keyed by rowId - scroll its row away and the editor unmounts, the\n * form keeps its values, meta and errors; scroll back and the editor\n * re-mounts over the same form.\n */\nexport function createEditEngine(\n getContext: () => TMDataGridEditEngineContext,\n): TMDataGridEditApi {\n const store = new Store<TMDataGridEditState>(EMPTY_EDIT_STATE);\n\n type FormEntry = {\n form: TMDataGridRowEditForm;\n original: TMDataGridRowData;\n /** An entry-block row - a form with no backing row yet. */\n isNew: boolean;\n /**\n * In the draft store: this row's form passed its submit and is parked,\n * waiting for `saveDrafts`. Mirrored into the state's `committedRowIds`\n * (existing rows) or `newRows[].committed` (entry rows).\n */\n committed: boolean;\n /** Set by the wrapped onSubmit when the consumer's commit resolved. */\n lastSubmitOk: boolean;\n /**\n * What the last failed commit found, field by field, with the value it\n * found it on. Form clears a field's errors when its editor unmounts, so\n * without this a row that failed on the way out would keep its draft and\n * lose the reason. `project` drops an entry once its value has moved.\n */\n submitErrors: Array<{ field: string; value: unknown; message: string }>;\n /**\n * The park: this submit validates and puts the row in the draft store\n * instead of calling the consumer. Set by `commit` per attempt - `true`\n * only while `editing.draft` is on and outside `saveDrafts`, which is\n * what closes the per-row escape hatches (the lane's ✓,\n * Delete-to-clear) at the engine.\n */\n parkOnly: boolean;\n /** A commit already running - Enter and blur race on the same edit. */\n pendingCommit: Promise<boolean> | null;\n unsubscribe: () => void;\n unmount: () => void;\n };\n const forms = new Map<string, FormEntry>();\n let newRowCounter = 0;\n /** Lets `commit` tell a `saveDrafts` flush apart from a lone commit. */\n let savingDrafts = false;\n\n /**\n * While `saveDrafts` runs with an `onSaveDrafts`, each row's wrapped\n * onSubmit contributes its args here instead of calling `onEditCommit` -\n * validation stays per row (Form's), the consumer call becomes one.\n */\n let draftCollector: Array<TMDataGridEditCommitArgs<TMDataGridRowData>> | null =\n null;\n let draftAddCollector: Array<TMDataGridRowAddArgs<TMDataGridRowData>> | null =\n null;\n\n /**\n * The column's half of the rule, with no row in hand: it is a consumer\n * column mapping to a field, `editing.columns` lists it if that is set, and\n * `meta.edit.enabled` has not switched it off outright. A per-row predicate\n * on `enabled` is the row's half and is not asked here.\n */\n const isColumnEditable = (column: ErasedColumn): boolean => {\n if (isControlColumn(column.id)) return false;\n if (getEditFieldName(column) === null) return false;\n const allowed = getContext().editableColumnIds;\n if (allowed !== undefined && !allowed.includes(column.id)) return false;\n return !isColumnEditSwitchedOff(column);\n };\n\n const editableColumns = (): Array<ErasedColumn> =>\n getContext().table.getAllLeafColumns().filter(isColumnEditable);\n\n /**\n * Every column's `meta.edit.validate`, run against a row's values.\n *\n * Field validators belong to the mounted editor, so a row committed with\n * no editors on screen - an import, a programmatic commit, a row whose\n * cells are scrolled out - would otherwise submit without them ever\n * running. This is the engine running the same rules itself, so a commit\n * validates the same wherever it comes from. The result is Form's\n * `{ fields }` shape, which plants each error on its own field.\n */\n const validateColumnFields = async (\n values: TMDataGridRowData,\n rowId: string,\n isNew: boolean,\n ): Promise<Record<string, unknown> | undefined> => {\n const row = isNew ? undefined : getRow(rowId);\n const fields: Record<string, unknown> = {};\n for (const column of editableColumns()) {\n // A column switched off for this row has no editor and takes no edit,\n // so its rule is not this row's to satisfy.\n if (row !== undefined && !isColumnEditableForRow(column, row)) continue;\n const field = getEditFieldName(column);\n if (field === null) continue;\n const normalized = normalizeFieldValidate(\n column.columnDef.meta?.edit?.validate,\n );\n if (normalized === undefined) continue;\n const value = getBy(values, field);\n for (const trigger of SUBMIT_VALIDATE_TRIGGERS) {\n const validator = normalized[trigger];\n if (validator === undefined) continue;\n const error = await runFieldValidator(validator, value);\n if (isValidationError(error)) {\n fields[field] = error;\n break;\n }\n }\n }\n return Object.keys(fields).length > 0 ? fields : undefined;\n };\n\n /**\n * The collection as a table validator sees it: every data row overlaid\n * with its draft where a form holds one, entry rows appended, and rows\n * marked deleted removed. The committing row contributes the values being\n * submitted, not what `data` still says. Built from the core row model, so\n * it is unfiltered and never contains group rows.\n */\n const mergedRows = (\n rowId: string,\n value: TMDataGridRowData,\n isNew: boolean,\n ): Array<{ rowId: string; value: TMDataGridRowData }> => {\n const deleted = new Set(store.state.deletedRowIds);\n const rows: Array<{ rowId: string; value: TMDataGridRowData }> = [];\n for (const row of getContext().table.getCoreRowModel().flatRows) {\n if (deleted.has(row.id)) continue;\n if (row.id === rowId) {\n rows.push({ rowId, value });\n continue;\n }\n const held = forms.get(row.id);\n rows.push({\n rowId: row.id,\n value:\n held === undefined\n ? (row.original as TMDataGridRowData)\n : (held.form.state.values as TMDataGridRowData),\n });\n }\n for (const newRow of store.state.newRows) {\n if (newRow.tempId === rowId) continue;\n const held = forms.get(newRow.tempId);\n if (held === undefined || deleted.has(newRow.tempId)) continue;\n rows.push({\n rowId: newRow.tempId,\n value: held.form.state.values as TMDataGridRowData,\n });\n }\n if (isNew) rows.push({ rowId, value });\n return rows;\n };\n\n /**\n * Runs `editing.tableValidators` for one commit. `onSubmit` first; its\n * failure stands and `onSubmitAsync` is not consulted, mirroring how the\n * column triggers short-circuit.\n */\n const runTableValidators = async (\n value: TMDataGridRowData,\n rowId: string,\n isNew: boolean,\n ): Promise<unknown> => {\n const validators = getContext().tableValidators;\n if (\n validators?.onSubmit === undefined &&\n validators?.onSubmitAsync === undefined\n ) {\n return undefined;\n }\n const args: TMDataGridTableValidateArgs = {\n value,\n rowId,\n isNew,\n rows: mergedRows(rowId, value, isNew),\n };\n const sync = validators.onSubmit?.(args);\n if (isValidationError(sync)) return sync;\n return await validators.onSubmitAsync?.(args);\n };\n\n /**\n * One submit pass's results folded into Form's error shape. A single\n * source passes through untouched (its own shape preserved); several merge\n * into `{ form, fields }`, the later source winning a field collision and\n * the form slot alike.\n */\n const mergeSubmitResults = (\n results: ReadonlyArray<unknown>,\n fields: Record<string, unknown> | undefined,\n ): unknown => {\n const errors = results.filter(isValidationError);\n if (errors.length === 0) {\n return fields === undefined ? undefined : { fields };\n }\n if (errors.length === 1) {\n const only = errors[0];\n if (fields === undefined) return only;\n if (typeof only === \"object\" && only !== null) {\n const shape = only as { fields?: Record<string, unknown> };\n return { ...shape, fields: { ...fields, ...(shape.fields ?? {}) } };\n }\n return { form: only, fields };\n }\n let form: unknown;\n let mergedFields: Record<string, unknown> = { ...(fields ?? {}) };\n for (const error of errors) {\n if (typeof error === \"object\" && error !== null) {\n const shape = error as {\n form?: unknown;\n fields?: Record<string, unknown>;\n };\n if (isValidationError(shape.form)) form = shape.form;\n mergedFields = { ...mergedFields, ...(shape.fields ?? {}) };\n } else {\n form = error;\n }\n }\n const merged: { form?: unknown; fields?: Record<string, unknown> } = {};\n if (form !== undefined) merged.form = form;\n if (Object.keys(mergedFields).length > 0) merged.fields = mergedFields;\n return merged;\n };\n\n /**\n * The row's `validators`, with column validation and the table rules folded\n * into the submit pass. The consumer's own `rowValidators` are passed\n * through untouched except for `onSubmitAsync`, which now also carries the\n * column rules and `editing.tableValidators` - later sources win a merge,\n * so the order is columns, then the table rules, then the row's own.\n */\n const composeValidators = (\n rowId: string,\n isNew: boolean,\n ): Record<string, unknown> => {\n const rowValidators = (getContext().rowValidators ?? {}) as Record<\n string,\n unknown\n >;\n const consumerAsync = rowValidators[\"onSubmitAsync\"];\n return {\n ...rowValidators,\n onSubmitAsync: async (args: { value: unknown }) => {\n const value = args.value as TMDataGridRowData;\n const fromConsumer =\n consumerAsync === undefined\n ? undefined\n : await (consumerAsync as (a: unknown) => unknown)(args);\n const fromTable = await runTableValidators(value, rowId, isNew);\n const fields = await validateColumnFields(value, rowId, isNew);\n return mergeSubmitResults([fromTable, fromConsumer], fields);\n },\n };\n };\n\n const diff = (\n entry: FormEntry,\n values: TMDataGridRowData,\n ): Array<TMDataGridEditChange> => {\n const changes: Array<TMDataGridEditChange> = [];\n for (const column of editableColumns()) {\n const field = getEditFieldName(column);\n if (field === null) continue;\n const previous: unknown = getBy(entry.original, field);\n const next: unknown = getBy(values, field);\n if (!sameValue(previous, next)) {\n changes.push({ columnId: column.id, field, previous, next });\n }\n }\n return changes;\n };\n\n const project = (entry: FormEntry): TMDataGridEditRowProjection => {\n const state = entry.form.state;\n const values = state.values as TMDataGridRowData;\n const live = Object.entries(state.fieldMeta).flatMap(([name, meta]) => {\n // The empty path is a pathless (row-level) issue's landing spot - it\n // belongs to `hasRowError`, not to any cell's marker.\n if (name === \"\") return [];\n const errors = (meta as { errors: ReadonlyArray<unknown> }).errors;\n if (!hasAnyError(errors)) return [];\n return [{ field: name, message: firstErrorText(errors) ?? \"\" }];\n });\n // What a closed editor left behind, minus everything the user has since\n // changed - editing the field is the answer to its message.\n const kept = entry.submitErrors.filter(\n (error) =>\n !live.some((current) => current.field === error.field) &&\n sameValue(getBy(values, error.field), error.value),\n );\n const errorMessages = [\n ...live,\n ...kept.map(({ field, message }) => ({ field, message })),\n ];\n return {\n dirtyFields: diff(entry, values).map((change) => change.field),\n errorFields: errorMessages.map((error) => error.field),\n errorMessages,\n hasRowError: hasAnyError(state.errors),\n isSubmitting: state.isSubmitting,\n values,\n };\n };\n\n const publishRow = (rowId: string) => {\n const entry = forms.get(rowId);\n store.setState((prev) => {\n const rows = { ...prev.rows };\n if (entry === undefined) delete rows[rowId];\n else rows[rowId] = project(entry);\n return { ...prev, rows, openRowIds: [...forms.keys()] };\n });\n };\n\n const setActive = (active: TMDataGridEditState[\"active\"]) => {\n store.setState((prev) => ({ ...prev, active }));\n };\n\n const setNewRowCommitted = (tempId: string, committed: boolean) => {\n store.setState((prev) => {\n const target = prev.newRows.find((newRow) => newRow.tempId === tempId);\n if (target === undefined || target.committed === committed) return prev;\n return {\n ...prev,\n newRows: prev.newRows.map((newRow) =>\n newRow.tempId === tempId ? { ...newRow, committed } : newRow,\n ),\n };\n });\n };\n\n /**\n * Moves an existing row across the line between form state and the draft\n * store. The values never move - they stay in the row's form; this records\n * which side the row is on, and the entry's flag keeps the two in step.\n */\n const setCommitted = (rowId: string, committed: boolean) => {\n const entry = forms.get(rowId);\n if (entry !== undefined) entry.committed = committed;\n store.setState((prev) => {\n const has = prev.committedRowIds.includes(rowId);\n if (has === committed) return prev;\n return {\n ...prev,\n committedRowIds: committed\n ? [...prev.committedRowIds, rowId]\n : prev.committedRowIds.filter((id) => id !== rowId),\n };\n });\n };\n\n const drop = (rowId: string) => {\n const entry = forms.get(rowId);\n if (entry === undefined) return;\n entry.unsubscribe();\n entry.unmount();\n forms.delete(rowId);\n store.setState((prev) => {\n const rows = { ...prev.rows };\n delete rows[rowId];\n return {\n ...prev,\n rows,\n openRowIds: [...forms.keys()],\n committedRowIds: prev.committedRowIds.filter((id) => id !== rowId),\n newRows: entry.isNew\n ? prev.newRows.filter((newRow) => newRow.tempId !== rowId)\n : prev.newRows,\n active: prev.active?.rowId === rowId ? null : prev.active,\n };\n });\n };\n\n const createForm = (\n rowId: string,\n original: TMDataGridRowData,\n isNew: boolean,\n ): FormEntry => {\n const entry: FormEntry = {\n original,\n isNew,\n committed: false,\n lastSubmitOk: false,\n submitErrors: [],\n parkOnly: false,\n pendingCommit: null,\n unsubscribe: () => {},\n unmount: () => {},\n form: new FormApi({\n defaultValues: original,\n // The consumer's vocabulary is Form's own; the cast erases the\n // validator generics the same way the row type is erased. The column\n // rules ride along in the submit pass - see `composeValidators`.\n validators: composeValidators(rowId, isNew) as never,\n onSubmit: async ({ value }) => {\n // A new row commits whole: it is an add, not a diff against\n // anything that exists.\n if (entry.isNew) {\n const addArgs: TMDataGridRowAddArgs<TMDataGridRowData> = {\n tempId: rowId,\n value: value as TMDataGridRowData,\n };\n if (draftAddCollector !== null) {\n draftAddCollector.push(addArgs);\n entry.lastSubmitOk = true;\n return;\n }\n // Parked: validated and held for Save all - no consumer call.\n if (entry.parkOnly) {\n entry.lastSubmitOk = true;\n return;\n }\n try {\n await getContext().onRowAdd?.(addArgs);\n entry.lastSubmitOk = true;\n } catch (error) {\n entry.form.setErrorMap({\n onSubmit:\n error instanceof Error ? error.message : String(error),\n } as never);\n }\n return;\n }\n const changes = diff(entry, value as TMDataGridRowData);\n const args: TMDataGridEditCommitArgs<TMDataGridRowData> = {\n rowId,\n value: value as TMDataGridRowData,\n original,\n changes,\n source: getContext().editMode,\n };\n if (draftCollector !== null) {\n draftCollector.push(args);\n entry.lastSubmitOk = true;\n return;\n }\n // Parked: validated and held for Save all - no consumer call.\n if (entry.parkOnly) {\n entry.lastSubmitOk = true;\n return;\n }\n try {\n await getContext().onEditCommit?.(args);\n entry.lastSubmitOk = true;\n } catch (error) {\n // A rejected save keeps the form open, the message on the row.\n entry.form.setErrorMap({\n onSubmit:\n error instanceof Error ? error.message : String(error),\n } as never);\n }\n },\n }) as TMDataGridRowEditForm,\n };\n entry.unmount = entry.form.mount();\n const subscription = entry.form.store.subscribe(() => publishRow(rowId));\n entry.unsubscribe = () => subscription.unsubscribe();\n forms.set(rowId, entry);\n publishRow(rowId);\n return entry;\n };\n\n const canEditRow = (row: ErasedRow): boolean => {\n if (row.getIsGrouped()) return false;\n return getContext().isRowEditable?.(row) !== false;\n };\n\n const canEditCell = (row: ErasedRow, column: ErasedColumn): boolean => {\n const context = getContext();\n if (row.getIsGrouped()) return false;\n if (!isColumnEditable(column)) return false;\n if (!isColumnEditableForRow(column, row)) return false;\n if (context.isRowEditable !== undefined && !context.isRowEditable(row)) {\n return false;\n }\n return true;\n };\n\n const getRow = (rowId: string): ErasedRow | undefined => {\n try {\n return getContext().table.getRow(rowId);\n } catch {\n // TanStack throws for an id that is not in the current row model.\n return undefined;\n }\n };\n\n /**\n * The row's field errors as they stand, with the value each was found on.\n * Read straight after a failed submit, while every editor is still mounted\n * and Form still holds what its validators said.\n */\n const takeFieldErrors = (\n entry: FormEntry,\n ): Array<{ field: string; value: unknown; message: string }> => {\n const values = entry.form.state.values as TMDataGridRowData;\n return Object.entries(entry.form.state.fieldMeta).flatMap(\n ([field, meta]) => {\n if (field === \"\") return [];\n const errors = (meta as { errors: ReadonlyArray<unknown> }).errors;\n const message = hasAnyError(errors) ? firstErrorText(errors) : undefined;\n if (message === undefined) return [];\n return [{ field, value: getBy(values, field), message }];\n },\n );\n };\n\n const commit = async (rowId: string): Promise<boolean> => {\n const entry = forms.get(rowId);\n if (entry === undefined) return true;\n // Enter and blur race on the same edit; the second caller joins the\n // first's commit instead of submitting the row twice.\n if (entry.pendingCommit !== null) return entry.pendingCommit;\n // A pristine form has nothing to say - drop it without a consumer call.\n // Not for a new row: adding an untouched entry is still an add.\n if (\n !entry.isNew &&\n diff(entry, entry.form.state.values as TMDataGridRowData).length === 0\n ) {\n drop(rowId);\n return true;\n }\n // Field errors the *form's* validator planted are cleared before the\n // submit re-runs it: a field with no mounted editor is never revalidated\n // by Form itself, so a pathed issue would otherwise outlive its fix and\n // block `canSubmit` forever. The validator puts back whatever still holds.\n clearFormSourcedFieldErrors(entry.form);\n entry.lastSubmitOk = false;\n entry.submitErrors = [];\n entry.parkOnly = getContext().draft && !savingDrafts;\n entry.pendingCommit = (async () => {\n try {\n await entry.form.handleSubmit();\n } finally {\n entry.pendingCommit = null;\n }\n if (!entry.lastSubmitOk) {\n // Snapshot before the caller closes the editor: the field errors go\n // with it, and the row is about to be left carrying them.\n entry.submitErrors = takeFieldErrors(entry);\n publishRow(rowId);\n return false;\n }\n if (entry.parkOnly) {\n // Into the draft store: the row's values stay in its form, and the\n // grid records that they are decided. An entry row renders as a\n // value row, an edited row as its draft - both until `begin` takes\n // the row back out into form state, or `saveDrafts` flushes it.\n entry.committed = true;\n if (entry.isNew) setNewRowCommitted(rowId, true);\n else setCommitted(rowId, true);\n store.setState((prev) =>\n prev.active?.rowId === rowId ? { ...prev, active: null } : prev,\n );\n return true;\n }\n drop(rowId);\n return true;\n })();\n return entry.pendingCommit;\n };\n\n const beginOn = (rowId: string, columnId: string | null) => {\n // An entry row has no backing row in the table; opening one re-arms its\n // editors - with `editing.draft` on, that is how a parked row is edited\n // again.\n const entryForm = forms.get(rowId);\n if (entryForm?.isNew === true) {\n entryForm.committed = false;\n setNewRowCommitted(rowId, false);\n setActive({ rowId, columnId });\n return;\n }\n const row = getRow(rowId);\n if (row === undefined) return;\n if (columnId !== null) {\n const column = getContext().table.getColumn(columnId);\n if (column === undefined || !canEditCell(row, column)) return;\n } else if (getContext().isRowEditable?.(row) === false) {\n return;\n }\n if (!forms.has(rowId)) createForm(rowId, row.original, false);\n // Reopening a committed row takes it back out of the draft store: what\n // the user is now editing is undecided again, and `saveDrafts` must not\n // send it until it is committed afresh.\n else if (forms.get(rowId)?.committed === true) setCommitted(rowId, false);\n setActive({ rowId, columnId });\n };\n\n const begin: TMDataGridEditApi[\"begin\"] = ({ rowId, columnId }) => {\n const { editMode } = getContext();\n // Each mode's policy about a row already open elsewhere:\n //\n // | Mode | Another row open |\n // | ---- | ---------------- |\n // | cell | committed - Sheets; a failed commit keeps holding the edit |\n // | row, cellConfirm | accumulates. Every draft waits for its own save,\n // so a second row opening can neither discard the first nor be refused\n // by it - nothing about one row's form bears on another's |\n //\n // A parked row is not \"open\": it has had its submit and is waiting for\n // the save, so it is skipped rather than put through a second one. An\n // entry row is skipped too - it is row-shaped in every mode, and its ✓\n // is the decision, so the sweep must not add a half-typed row.\n if (editMode === \"cell\") {\n const openElsewhere = [...forms.keys()].find((id) => {\n const other = forms.get(id);\n return id !== rowId && other?.committed !== true && other?.isNew !== true;\n });\n if (openElsewhere !== undefined) {\n void commit(openElsewhere).then((ok) => {\n if (ok) beginOn(rowId, columnId);\n });\n return;\n }\n }\n beginOn(rowId, columnId);\n };\n\n const cancel = (rowId: string) => {\n drop(rowId);\n };\n\n const deactivate = () => {\n setActive(null);\n };\n\n const cancelAll = () => {\n for (const rowId of [...forms.keys()]) drop(rowId);\n store.setState((prev) => ({\n ...prev,\n active: null,\n committedRowIds: [],\n deletedRowIds: [],\n }));\n };\n\n const addRow = (values?: TMDataGridRowData): string => {\n newRowCounter += 1;\n const tempId = `__new__${newRowCounter}`;\n createForm(tempId, seedNewRow(values), true);\n store.setState((prev) => ({\n ...prev,\n newRows: [...prev.newRows, { tempId, committed: false }],\n }));\n return tempId;\n };\n\n /** Seeds one entry row's values - `newRowDefaults` under `values`. */\n const seedNewRow = (values?: TMDataGridRowData): TMDataGridRowData => {\n const { newRowDefaults } = getContext();\n const defaults =\n typeof newRowDefaults === \"function\"\n ? newRowDefaults()\n : (newRowDefaults ?? {});\n // The argument wins over the defaults key by key, so a caller can seed\n // one field and leave the rest of `newRowDefaults` standing.\n return { ...defaults, ...values };\n };\n\n const addRows = async (\n rows: ReadonlyArray<TMDataGridRowData>,\n options?: TMDataGridAddRowsOptions,\n ): Promise<TMDataGridAddRowsResult> => {\n const tempIds: Array<string> = [];\n // One notification for the batch: `createForm` publishes its row as it\n // mounts, so an import of hundreds would otherwise wake every subscriber\n // once per row before the entry block has even been told they exist.\n batch(() => {\n for (const values of rows) {\n newRowCounter += 1;\n const tempId = `__new__${newRowCounter}`;\n createForm(tempId, seedNewRow(values), true);\n tempIds.push(tempId);\n }\n store.setState((prev) => ({\n ...prev,\n newRows: [\n ...prev.newRows,\n ...tempIds.map((tempId) => ({ tempId, committed: false })),\n ],\n }));\n });\n\n if (options?.commit !== true) return { committed: [], open: tempIds };\n\n // In order, so a consumer's `onRowAdd` sees the rows as the file had\n // them. A row that fails validation stays open carrying its errors.\n const committed: Array<string> = [];\n const open: Array<string> = [];\n for (const tempId of tempIds) {\n const ok = await commit(tempId);\n (ok ? committed : open).push(tempId);\n }\n return { committed, open };\n };\n\n const deleteRow = (rowId: string) => {\n const entry = forms.get(rowId);\n // Deleting an unsaved entry row is just discarding the entry.\n if (entry?.isNew === true) {\n drop(rowId);\n return;\n }\n const context = getContext();\n if (context.draft) {\n // A toggle: the second press unmarks - the mark is a draft too.\n store.setState((prev) => ({\n ...prev,\n deletedRowIds: prev.deletedRowIds.includes(rowId)\n ? prev.deletedRowIds.filter((id) => id !== rowId)\n : [...prev.deletedRowIds, rowId],\n }));\n return;\n }\n const row = getRow(rowId);\n if (row === undefined) return;\n // Confirmation is the consumer's business, in their onRowDelete.\n void context.onRowDelete?.({ rowId, row });\n };\n\n const canDeleteRows = (): boolean => {\n const context = getContext();\n if (context.draft) {\n return (\n context.onRowDelete !== undefined ||\n context.onSaveDrafts !== undefined\n );\n }\n return context.onRowDelete !== undefined;\n };\n\n /** The pending deletions, reported and cleared by `saveDrafts`. */\n const takeDeletedRowIds = (): Array<string> => {\n const deleted = [...store.state.deletedRowIds];\n if (deleted.length > 0) {\n store.setState((prev) => ({ ...prev, deletedRowIds: [] }));\n }\n return deleted;\n };\n\n /** The draft store's rows: committed forms, in the order they landed. */\n const committedFormIds = (): Array<string> =>\n [...forms.keys()].filter((rowId) => forms.get(rowId)?.committed === true);\n\n const commitAll = async (): Promise<boolean> => {\n // Only the open ones - a row already in the draft store has had its\n // submit and must not be put through a second one here.\n const openIds = [...forms.keys()].filter(\n (rowId) => forms.get(rowId)?.committed !== true,\n );\n const results = await Promise.all(openIds.map((rowId) => commit(rowId)));\n return results.every(Boolean);\n };\n\n /**\n * The in-flight save. A second call while `onSaveDrafts` awaits would\n * re-collect the same payload and send it again - a double-clicked Save\n * would create every pending entry row twice - so concurrent calls join\n * this promise instead of starting a save of their own.\n */\n let saveInFlight: Promise<boolean> | null = null;\n\n const saveDrafts = (): Promise<boolean> => {\n if (saveInFlight !== null) return saveInFlight;\n // While this runs, `commit` really commits - `editing.draft` parks\n // otherwise. Single-threaded flag, same idiom as the collectors.\n savingDrafts = true;\n saveInFlight = saveDraftsInner().finally(() => {\n savingDrafts = false;\n saveInFlight = null;\n });\n return saveInFlight;\n };\n\n const saveDraftsInner = async (): Promise<boolean> => {\n const committedIds = committedFormIds();\n const deletedIds = [...store.state.deletedRowIds];\n // Nothing decided: open rows are not this verb's business, so a grid\n // mid-edit with an empty draft store saves cleanly and stays as it is.\n if (committedIds.length === 0 && deletedIds.length === 0) return true;\n\n if (getContext().onSaveDrafts === undefined) {\n // The default: the per-row loop - edits through `onEditCommit`, entry\n // rows through `onRowAdd`, marked deletions through `onRowDelete`.\n const results = await Promise.all(\n committedIds.map((rowId) => commit(rowId)),\n );\n for (const rowId of takeDeletedRowIds()) {\n const row = getRow(rowId);\n if (row !== undefined) {\n await getContext().onRowDelete?.({ rowId, row });\n }\n }\n return results.every(Boolean);\n }\n\n // One consumer call for the lot. Validation stays Form's, per row: rows\n // that fail keep their forms and markers; the valid ones travel\n // together, and only a resolved save drops them - a rejected save keeps\n // every draft, deletions included.\n const collected: Array<TMDataGridEditCommitArgs<TMDataGridRowData>> = [];\n const added: Array<TMDataGridRowAddArgs<TMDataGridRowData>> = [];\n draftCollector = collected;\n draftAddCollector = added;\n let allValid = true;\n try {\n for (const rowId of committedIds) {\n const entry = forms.get(rowId);\n if (entry === undefined) continue;\n entry.lastSubmitOk = false;\n await entry.form.handleSubmit();\n if (!entry.lastSubmitOk) allValid = false;\n }\n } finally {\n draftCollector = null;\n draftAddCollector = null;\n }\n const deleted = deletedIds;\n if (collected.length > 0 || added.length > 0 || deleted.length > 0) {\n let result: void | TMDataGridSaveDraftsResult;\n try {\n result = await getContext().onSaveDrafts?.({\n updated: collected,\n created: added,\n deleted,\n // The pre-2.0 names, still filled - see TMDataGridSaveDraftsArgs.\n rows: collected,\n added,\n });\n } catch {\n return false;\n }\n\n // Nothing returned saves the lot. A result names what failed; those\n // keep their drafts, committed, so the next save retries them.\n const outcomes = result ?? {};\n let savedAll = true;\n\n for (const args of collected) {\n if (isSaved(outcomes.updated, args.rowId)) drop(args.rowId);\n else savedAll = false;\n }\n for (const args of added) {\n if (isSaved(outcomes.created, args.tempId)) drop(args.tempId);\n else savedAll = false;\n }\n const savedDeletions = deleted.filter((id) =>\n isSaved(outcomes.deleted, id),\n );\n if (savedDeletions.length > 0) {\n store.setState((prev) => ({\n ...prev,\n deletedRowIds: prev.deletedRowIds.filter(\n (id) => !savedDeletions.includes(id),\n ),\n }));\n }\n if (savedDeletions.length < deleted.length) savedAll = false;\n\n if (!savedAll) return false;\n }\n return allValid;\n };\n\n /** @deprecated The old one-shot save - `commitAll` then `saveDrafts`. */\n const submitAll = async (): Promise<boolean> => {\n const committedOk = await commitAll();\n const savedOk = await saveDrafts();\n return committedOk && savedOk;\n };\n\n /**\n * The write path behind `clearCell`, `setCellValue` and `setRowValues`:\n * fill the row's own form and commit it, exactly as a ✓ on an open editor\n * would. Uses the form already open on the row when there is one, so a\n * programmatic write joins an edit in progress rather than discarding it.\n *\n * No editor is involved, so `meta.edit.mapValue` does not run - the caller\n * writes the stored value itself. Validation is untouched: this is the same\n * `commit`, so `meta.edit.validate` and `editing.rowValidators` still decide\n * whether the row lands, and a failure leaves the row open carrying its\n * errors.\n */\n const writeFields = async (\n rowId: string,\n writes: ReadonlyArray<{ field: string; value: unknown }>,\n ): Promise<boolean> => {\n const row = getRow(rowId);\n if (row === undefined) return false;\n if (writes.length === 0) return true;\n const entry = forms.get(rowId) ?? createForm(rowId, row.original, false);\n for (const { field, value } of writes) {\n entry.form.setFieldValue(field as never, value as never);\n }\n return commit(rowId);\n };\n\n /** The field a cell writes to, or `null` when that cell takes no edit. */\n const writableField = (rowId: string, columnId: string): string | null => {\n const row = getRow(rowId);\n const column = getContext().table.getColumn(columnId);\n if (row === undefined || column === undefined) return null;\n if (!canEditCell(row, column)) return null;\n return getEditFieldName(column);\n };\n\n const clearCell = async (\n rowId: string,\n columnId: string,\n ): Promise<boolean> => {\n const column = getContext().table.getColumn(columnId);\n const field = writableField(rowId, columnId);\n if (field === null || column === undefined) return false;\n return writeFields(rowId, [\n {\n field,\n value: clearedValueForType(column.columnDef.meta?.type ?? \"string\"),\n },\n ]);\n };\n\n const setCellValue = async (\n rowId: string,\n columnId: string,\n value: unknown,\n ): Promise<boolean> => {\n const field = writableField(rowId, columnId);\n if (field === null) return false;\n return writeFields(rowId, [{ field, value }]);\n };\n\n const setRowValues = async (\n rowId: string,\n values: Record<string, unknown>,\n ): Promise<boolean> => {\n const writes: Array<{ field: string; value: unknown }> = [];\n for (const [columnId, value] of Object.entries(values)) {\n const field = writableField(rowId, columnId);\n // All or nothing: one cell that takes no edit fails the call before\n // anything is written, so a bulk action cannot half-apply unnoticed.\n if (field === null) return false;\n writes.push({ field, value });\n }\n return writeFields(rowId, writes);\n };\n\n return {\n store,\n get state() {\n return store.state;\n },\n getForm: (rowId) => forms.get(rowId)?.form,\n canEditCell,\n canEditRow,\n isColumnEditable,\n begin,\n commit,\n cancel,\n deactivate,\n cancelAll,\n commitAll,\n saveDrafts,\n submitAll,\n clearCell,\n setCellValue,\n setRowValues,\n addRow,\n addRows,\n deleteRow,\n canDeleteRows,\n };\n}\n\n/**\n * `meta.edit.validate` normalised to the object TanStack Form's `validators`\n * option takes - a bare schema or function is shorthand for `{ onChange }`.\n */\nexport function normalizeFieldValidate(\n validate: TMDataGridFieldValidate | undefined,\n): Record<string, unknown> | undefined {\n if (validate === undefined) return undefined;\n if (typeof validate === \"function\" || \"~standard\" in validate) {\n return { onChange: validate };\n }\n return validate as Record<string, unknown>;\n}\n","import { ActionIcon, Group, Loader, Tooltip } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ColumnDef, Row, RowData } from \"@tanstack/react-table\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport {\n useCellControlTabIndex,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\nimport { firstErrorText } from \"../core/editEngine\";\nimport {\n CheckIcon,\n CloseIcon,\n PencilIcon,\n PlusIcon,\n RestoreIcon,\n TrashIcon,\n} from \"./icons\";\n\nexport const EDIT_COLUMN_ID = \"__edit__\";\n\n/**\n * The draft store's change marker in the lane - what kind of change the row\n * is holding for the save. Non-interactive; the buttons beside it act.\n * `data-state` is the styling hook, `data-error` flips it red and puts the\n * message in the tooltip in place of the state's name.\n */\nfunction RowStateIndicator({\n state,\n rowId,\n label,\n error,\n}: {\n state: \"new\" | \"edited\" | \"deleted\";\n rowId: string;\n label: string;\n error: string | null;\n}) {\n const Icon =\n state === \"new\" ? PlusIcon : state === \"edited\" ? PencilIcon : TrashIcon;\n return (\n <Tooltip label={error ?? label} withArrow>\n <span\n role=\"img\"\n aria-label={label}\n data-dg-part=\"row-state\"\n data-state={state}\n data-row-id={rowId}\n data-error={error !== null || undefined}\n className={classes.rowStateIndicator}\n >\n <Icon size={16} stroke={1.6} />\n </span>\n </Tooltip>\n );\n}\n\n/**\n * One row's slot in the edit lane, driven off the edit store. Two things\n * decide what it holds, and they are the two axes of `editing`:\n *\n * | Row is | Lane holds | From |\n * | ------ | ---------- | ---- |\n * | parked in the draft store | the change marker and the way back out - revert, discard or restore | `editing.draft` |\n * | open | the mode's own controls: Save and Cancel | `editing.mode` |\n * | neither | the pencil (row mode) and the trash | `editing.mode` |\n *\n * A row error turns the Save red with the message in its tooltip - a\n * pathless `.refine()` has nowhere else to land, and a field error outlives\n * the editor that found it. A parked row never offers a save: it has had its\n * submit, and `TMDataGrid.DraftActions` is what sends it.\n */\nfunction EditLaneCell<TData extends RowData>({\n row,\n}: {\n row: Row<TMDataGridFeatures, TData>;\n}) {\n const { edit, features, labels } = useTMDataGridContext();\n const tabIndex = useCellControlTabIndex();\n const rowId = row.id;\n const isOpen = useSelector(edit.store, (state) =>\n state.openRowIds.includes(rowId),\n );\n const projection = useSelector(edit.store, (state) => state.rows[rowId]);\n const isNew = useSelector(edit.store, (state) =>\n state.newRows.some((newRow) => newRow.tempId === rowId),\n );\n const isConfirmedNew = useSelector(\n edit.store,\n (state) =>\n state.newRows.find((newRow) => newRow.tempId === rowId)?.committed ===\n true,\n );\n // Parked: the row passed its submit and is waiting for the save. A subset\n // of the open rows, so it is asked about first - the two overlap.\n const isCommitted = useSelector(edit.store, (state) =>\n state.committedRowIds.includes(rowId),\n );\n const isMarkedDeleted = useSelector(edit.store, (state) =>\n state.deletedRowIds.includes(rowId),\n );\n\n if (row.getIsGrouped()) return null;\n\n const hasErrors =\n projection !== undefined &&\n (projection.hasRowError || projection.errorFields.length > 0);\n // The row's own message first - a pathless issue is about the row - then\n // the first field's, which is what a failed commit left behind.\n const rowError = hasErrors\n ? (firstErrorText(edit.getForm(rowId)?.state.errors ?? []) ??\n projection.errorMessages[0]?.message ??\n labels.editRowErrors)\n : null;\n\n const trash = edit.canDeleteRows() ? (\n <Tooltip label={labels.deleteRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.deleteRow}\n data-dg-part=\"delete-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.deleteRow(rowId);\n }}\n >\n <TrashIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n ) : null;\n\n // An entry row: ✓ enters it - an add, or a park under `editing.draft` -\n // and ✕ discards the entry. A parked entry waits for the save as a value\n // row: marked new, re-openable, still discardable.\n if (isNew) {\n if (isConfirmedNew) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n <RowStateIndicator\n state=\"new\"\n rowId={rowId}\n label={labels.rowStateNew}\n error={rowError}\n />\n <Tooltip label={labels.editRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.editRow}\n data-dg-part=\"edit-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.begin({ rowId, columnId: null });\n }}\n >\n <PencilIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n <Tooltip label={labels.discardNewRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.discardNewRow}\n data-dg-part=\"discard-new-row\"\n data-row-id={rowId}\n onClick={() => edit.cancel(rowId)}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n return (\n <Group gap={0} wrap=\"nowrap\">\n <Tooltip label={labels.confirmNewRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"green\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.confirmNewRow}\n data-dg-part=\"confirm-new-row\"\n data-row-id={rowId}\n onClick={() => void edit.commit(rowId)}\n >\n <CheckIcon size={16} stroke={2} />\n </ActionIcon>\n </Tooltip>\n <Tooltip label={labels.discardNewRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.discardNewRow}\n data-dg-part=\"discard-new-row\"\n data-row-id={rowId}\n onClick={() => edit.cancel(rowId)}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n\n // A deletion mark is a draft like any other - restorable in place.\n if (isMarkedDeleted) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n <RowStateIndicator\n state=\"deleted\"\n rowId={rowId}\n label={labels.rowStateDeleted}\n error={null}\n />\n <Tooltip label={labels.restoreRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.restoreRow}\n data-dg-part=\"restore-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.deleteRow(rowId);\n }}\n >\n <RestoreIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n\n // The pencil means \"this row edits\"; a row that does not gets nothing.\n if (!edit.canEditRow(row as never)) return null;\n\n if (projection?.isSubmitting) {\n return <Loader size=\"xs\" aria-label={labels.loading} />;\n }\n\n // Parked in the draft store: the mark, and the way back out. No trash\n // beside the revert - the two undo-shaped icons were too easy to mistake\n // for one another, so a drafted row reverts first, then deletes.\n if (isCommitted) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n <RowStateIndicator\n state=\"edited\"\n rowId={rowId}\n label={labels.rowStateEdited}\n error={rowError}\n />\n <Tooltip label={labels.revertRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.revertRow}\n data-dg-part=\"revert-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.cancel(rowId);\n }}\n >\n <RestoreIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n\n if (!isOpen) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n {features.editMode === \"row\" && (\n <Tooltip label={labels.editRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.editRow}\n data-dg-part=\"edit-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.begin({ rowId, columnId: null });\n }}\n >\n <PencilIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n )}\n {trash}\n </Group>\n );\n }\n\n const save = (\n <ActionIcon\n variant=\"subtle\"\n color={hasErrors ? \"red\" : \"green\"}\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.saveRow}\n data-dg-part=\"save-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n void edit.commit(rowId);\n }}\n >\n <CheckIcon size={16} stroke={2} />\n </ActionIcon>\n );\n\n return (\n <Group gap={0} wrap=\"nowrap\">\n {rowError === null ? (\n <Tooltip label={labels.saveRow} withArrow>\n {save}\n </Tooltip>\n ) : (\n <Tooltip label={rowError} withArrow>\n {save}\n </Tooltip>\n )}\n <Tooltip label={labels.cancelRowEdit} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.cancelRowEdit}\n data-dg-part=\"cancel-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.cancel(rowId);\n }}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n}\n\n/**\n * The generated edit lane, appended and pinned right - the row's Save at the\n * end of the row under `mode: \"row\"`, the state marker and revert under\n * `editing.draft`, mirroring the checkbox lane's build on the left.\n */\nexport function createEditColumn<TData extends RowData>(\n label = \"Edit\",\n /** A draft lane holds three controls where the rest hold two. */\n wide = false,\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n const width = wide ? 88 : 64;\n return {\n id: EDIT_COLUMN_ID,\n meta: {\n label,\n align: \"center\",\n enableOrdering: false,\n },\n // Wide enough for the pair (or draft's trio) it holds while editing.\n size: width,\n minSize: width,\n maxSize: width,\n enableResizing: false,\n enableSorting: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n // The row's Save, Cancel and Delete live here, so hiding the lane would\n // strand an open row with no way to commit or discard it. Same rule as the\n // checkbox lane: chrome the grid generates is not a user setting.\n enableHiding: false,\n // Structurally pinned to the right; not movable.\n enablePinning: false,\n header: () => null,\n cell: ({ row }) => <EditLaneCell row={row} />,\n // Group rows: same reasoning as the checkbox lane - without this the\n // cell renders blank on aggregated rows, but here blank is also correct,\n // so the aggregated cell renders the same (null for groups).\n aggregatedCell: ({ row }) => <EditLaneCell row={row} />,\n };\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 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 { 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 data-dg-part=\"group-toggle\"\n data-row-id={row.id}\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 type { ColumnDef, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\nexport const ROW_NUMBER_COLUMN_ID = \"__rowNumber__\";\n\n/**\n * The generated row-number gutter, prepended under `enableRowNumbers` -\n * outermost left, before even the checkbox lane, the way a spreadsheet keeps\n * its gutter outside everything.\n *\n * The def renders nothing itself: a cell cannot know its display position,\n * so the body computes the numbers - one pass over the view, group rows\n * skipped (they are headings over the rows being counted), continuing across\n * pages - and substitutes them in. See `TMDataGridTable`.\n *\n * A system lane: fixed width, no menu, no resize, never exported, and its\n * visibility follows the option rather than the columns panel.\n */\nexport function createRowNumberColumn<TData extends RowData>(\n label = \"Row number\",\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n return {\n id: ROW_NUMBER_COLUMN_ID,\n meta: {\n label,\n align: \"center\",\n // Anchors the left edge with the checkbox lane; nothing moves past 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 enablePinning: false,\n enableHiding: false,\n header: () => \"#\",\n // The body substitutes the number; a row without one - a group row -\n // falls through to this.\n cell: () => null,\n };\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 *\n * Rows pinned to an edge leave this list - they render in their own sticky\n * blocks, outside the scrolling order a shift-click range or the virtualizer\n * walks. See `readPinnedRows`.\n */\nexport function getDisplayedRows<TData extends RowData>(\n table: TMDataGridTable<TData>,\n features: TMDataGridFeatureFlags,\n): Array<Row<TMDataGridFeatures, TData>> {\n const rows = isPagingActive(table, features)\n ? table.getPaginatedRowModel().rows\n : table.getPrePaginatedRowModel().rows;\n if (!features.rowPinning) return rows;\n const { top, bottom } = table.store.state.rowPinning;\n if (top.length === 0 && bottom.length === 0) return rows;\n const pinned = new Set([...top, ...bottom]);\n return rows.filter((row) => !pinned.has(row.id));\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, which replaces the selection. `false` for a\n * checkbox, which is only ever additive: ticking one box does not clear the\n * others, and shift-clicking one adds the range rather than replacing 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 data-dg-part=\"select-all\"\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 holds the leaves,\n // and TanStack's `getIsSelected()` is a plain lookup in that map. A group\n // therefore asks about its descendants instead, so the box means \"all of\n // these\" and goes indeterminate as soon 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 data-dg-part=\"select-row\"\n data-row-id={row.id}\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 // Not a column the user chose, so not one they can switch off: hiding the\n // lane would take the grid's only way to select a row with it, with the\n // row-selection state left behind and no way back to it. Keeping it out of\n // \"Manage columns\" follows from this - the panel lists what can be hidden.\n enableHiding: 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 { Row } from \"@tanstack/react-table\";\nimport {\n getDefaultOperator,\n type TMDataGridColumnType,\n type TMDataGridFilterOperator,\n} from \"./filterOperators\";\nimport { DETAILS_COLUMN_ID } from \"../components/TMDataGridDetailsColumn\";\nimport { EDIT_COLUMN_ID } from \"../components/TMDataGridEditColumn\";\nimport { GROUP_COLUMN_ID } from \"../components/TMDataGridGroupColumn\";\nimport { ROW_NUMBER_COLUMN_ID } from \"../components/TMDataGridRowNumberColumn\";\nimport { SELECT_COLUMN_ID } from \"../components/TMDataGridSelectColumn\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridColumnMeta, TMDataGridFeatures } from \"../useTMDataGrid\";\nimport type { TMDataGridFilterControlComponent } from \"./filterControls\";\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\n/**\n * The operator a fresh filter on this column starts with -\n * `meta.filter.defaultOperator`, else the type's default.\n */\nexport function getColumnDefaultOperator(\n column: ColumnLike,\n): TMDataGridFilterOperator {\n return (\n column.columnDef.meta?.filter?.defaultOperator ??\n getDefaultOperator(getColumnType(column))\n );\n}\n\n/**\n * This column's filter-panel value control - `meta.filter.control`, or\n * `undefined` for the built-in shape-by-operator input.\n */\nexport function getColumnFilterControl(\n column: ColumnLike,\n): TMDataGridFilterControlComponent | undefined {\n return column.columnDef.meta?.filter?.control;\n}\n\n/**\n * Whether `meta.edit.enabled` switches this column off outright, ignoring any\n * per-row predicate. For the passes that have no row in hand - listing which\n * columns a row form covers, finding the first cell an opened row should put\n * the caret in.\n */\nexport function isColumnEditSwitchedOff(column: ColumnLike): boolean {\n return column.columnDef.meta?.edit?.enabled === false;\n}\n\n/**\n * Whether `meta.edit.enabled` lets this column's cell on this row be edited -\n * the switch, then the predicate.\n *\n * This is only the column's half of the rule. A cell also needs the column to\n * map to a field (`getEditFieldName`) and the row to take edits at all\n * (`isRowEditable`); `edit.canEditCell` is the whole question.\n */\nexport function isColumnEditableForRow(\n column: ColumnLike,\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n): boolean {\n const enabled = column.columnDef.meta?.edit?.enabled;\n if (enabled === false) return false;\n if (typeof enabled === \"function\") return enabled(row);\n return true;\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 fixed-width thing - the checkbox, the details\n * chevron, the row number.\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 content in an unpadded cell.\n * Their headers carry no column menu, and none of them is ever exported -\n * they hold chrome, not values.\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 (\n columnId === SELECT_COLUMN_ID ||\n columnId === DETAILS_COLUMN_ID ||\n columnId === EDIT_COLUMN_ID ||\n columnId === ROW_NUMBER_COLUMN_ID\n );\n}\n\n/**\n * Whether the grid generated this column rather than the consumer declaring it\n * - the four control lanes plus the tree column.\n *\n * These hold the grid's own chrome, and they keep the edges of the row: the\n * generated left lanes before every consumer column, the edit lane after all of\n * them. `isControlColumn` answers a narrower question about layout, and leaves\n * the tree column out because it is padded like a data column.\n */\nexport function isGeneratedColumn(columnId: string): boolean {\n return isControlColumn(columnId) || columnId === GROUP_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","import {\n Button,\n Checkbox,\n ScrollArea,\n Text,\n TextInput,\n Tooltip,\n} 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, labels, controlSize, resetSettings } = useTMDataGridContext();\n const [search, setSearch] = useState(\"\");\n\n const columnVisibility = useSelector(\n table.store,\n (state) => state.columnVisibility,\n );\n\n // Only what can actually be hidden. A column with `enableHiding: false` is\n // left out rather than listed and disabled: a box that cannot be ticked only\n // invites the question, and every generated lane is one - the checkbox and\n // edit lanes hold the controls the grid needs, the tree column follows the\n // grouping state, the row-number gutter follows `enableRowNumbers`. None of\n // them is a setting.\n const columns = table\n .getAllLeafColumns()\n .filter((column) => column.getCanHide());\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 shownCount = columns.filter(\n (column) => columnVisibility[column.id] !== false,\n ).length;\n\n /**\n * Show or hide every listed column.\n *\n * Not `table.toggleAllColumnsVisible`, which writes a visibility entry for\n * *every* leaf column: showing all would publish the tree column - hidden\n * because nothing is grouped, not because the user hid it - and hiding all\n * would force the same column visible, since it writes `!getCanHide()` for\n * the columns it will not touch. Either way a lane the panel never listed\n * changes state, and persistence then keeps it that way.\n */\n const setAllVisible = (visible: boolean) => {\n table.setColumnVisibility((previous) => {\n const next = { ...previous };\n for (const column of columns) next[column.id] = visible;\n return next;\n });\n };\n\n return (\n <div data-dg-part=\"columns-panel\" 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-dg-part=\"columns-search\"\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 data-dg-part=\"columns-toggle\"\n data-column-id={column.id}\n checked={columnVisibility[column.id] !== false}\n onChange={(event) =>\n column.toggleVisibility(event.currentTarget.checked)\n }\n />\n ))}\n {visibleInPanel.length === 0 && (\n <Text span 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 data-dg-part=\"columns-toggle-all\"\n checked={shownCount === columns.length}\n indeterminate={shownCount > 0 && shownCount < columns.length}\n onChange={(event) => setAllVisible(event.currentTarget.checked)}\n />\n {/* The whole layout, not only visibility: one reset with an honest\n scope, stated in the tooltip. `table.resetColumnVisibility()` would\n also be wrong under persistence - it resets to `initialState`,\n which the mount built *from* the persisted payload. */}\n <Tooltip label={labels.columnsResetHint} withArrow>\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n data-dg-part=\"columns-reset\"\n onClick={() => resetSettings()}\n >\n {labels.columnsReset}\n </Button>\n </Tooltip>\n </div>\n </div>\n );\n}\n","import { Button, Group, Text } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { shallow } from \"@tanstack/store\";\nimport type { ReactNode } from \"react\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getOpenRowIds } from \"../core/editEngine\";\nimport { getDisplayedRows } from \"../core/rowSelection\";\nimport type {\n TMDataGridScrollAlign,\n TMDataGridScrollToRowArgs,\n} from \"../useTMDataGrid\";\n\n/**\n * How many rows the draft store holds - parked edits, parked entry rows and\n * deletion marks. This is what Save sends, so it is what Save counts: a row\n * the user is still typing into is not in here.\n */\nfunction useDraftCount(): number {\n const { edit } = useTMDataGridContext();\n return useSelector(\n edit.store,\n (state) =>\n state.committedRowIds.length +\n state.newRows.filter((newRow) => newRow.committed).length +\n state.deletedRowIds.length,\n );\n}\n\n/**\n * How many rows are still open - edited or entered but not parked, so not\n * part of the save. Surfaced beside Save so an undecided row is visible\n * rather than silently left behind.\n */\nfunction useOpenCount(): number {\n const { edit } = useTMDataGridContext();\n return useSelector(edit.store, (state) => getOpenRowIds(state).length);\n}\n\n/**\n * The ids behind {@link useOpenCount}. Shallow-compared: the array would\n * otherwise be a new one on every edit-store publish, and it is handed to\n * `renderActions`, where it may well end up in a dependency array.\n */\nfunction useOpenRowIds(): ReadonlyArray<string> {\n const { edit } = useTMDataGridContext();\n return useSelector(edit.store, getOpenRowIds, { compare: shallow });\n}\n\n/*\n * Module scope, like the pagination controls and for the same reason: a\n * component defined inside the render body is a new type every render, so\n * React would remount the buttons underneath an interaction.\n */\n\nfunction EditSaveButton() {\n const { edit, labels } = useTMDataGridContext();\n const draftCount = useDraftCount();\n const isSubmitting = useSelector(edit.store, (state) =>\n state.openRowIds.some((rowId) => state.rows[rowId]?.isSubmitting === true),\n );\n\n return (\n <Button\n size=\"compact-sm\"\n disabled={draftCount === 0}\n loading={isSubmitting}\n data-dg-part=\"save-all\"\n data-draft-count={draftCount}\n onClick={() => void edit.saveDrafts()}\n >\n {labels.saveAllEdits(draftCount)}\n </Button>\n );\n}\n\n/** The count of rows left open, or nothing while every row is decided. */\nfunction EditOpenRowsNote() {\n const { labels } = useTMDataGridContext();\n const openCount = useOpenCount();\n if (openCount === 0) return null;\n return (\n <Text\n size=\"xs\"\n c=\"dimmed\"\n data-dg-part=\"open-rows-note\"\n data-open-count={openCount}\n >\n {labels.editRowsStillOpen(openCount)}\n </Text>\n );\n}\n\nfunction EditDiscardButton() {\n const { edit, labels } = useTMDataGridContext();\n // Discard drops everything the grid is holding, open rows included, so it\n // stays live while anything is uncommitted.\n const pendingCount = useDraftCount() + useOpenCount();\n\n return (\n <Button\n variant=\"subtle\"\n color=\"gray\"\n size=\"compact-sm\"\n disabled={pendingCount === 0}\n data-dg-part=\"discard-all\"\n onClick={() => edit.cancelAll()}\n >\n {labels.discardAllEdits}\n </Button>\n );\n}\n\nconst EDIT_ACTIONS_CONTROLS: TMDataGridDraftActionsControls = {\n Save: EditSaveButton,\n Discard: EditDiscardButton,\n OpenRowsNote: EditOpenRowsNote,\n};\n\n/** What the edit chrome is showing. */\nexport type TMDataGridDraftActionsState = {\n /**\n * Rows in the draft store, which is what Save sends: committed edits,\n * committed entry rows and deletion marks.\n */\n draftCount: number;\n /**\n * Rows still open - edited or entered but not committed, so not part of\n * the save. They stay open across a save.\n */\n openCount: number;\n /**\n * The ids behind {@link openCount}, in the order the grid opened them - a\n * sort, a filter or a page never moves this list. An entered row appears as\n * its `tempId`.\n *\n * Narrower than `edit.state.openRowIds`, which is every row holding a form,\n * the parked ones included. And note the ordering:\n * {@link TMDataGridDraftActionsActions.scrollToFirstOpenRow} takes \"first\"\n * in display order, so it need not be `openRowIds[0]`.\n */\n openRowIds: ReadonlyArray<string>;\n /**\n * @deprecated Was \"everything uncommitted\", which Save no longer sends.\n * Reads as `draftCount + openCount`; use whichever you meant.\n */\n pendingCount: number;\n /** Whether a submit is in flight. */\n isSubmitting: boolean;\n};\n\n/** What the edit chrome can do. */\nexport type TMDataGridDraftActionsActions = {\n /** Saves the draft store. Open rows are left alone. */\n save: () => Promise<boolean>;\n /** Submits every open row, committing the ones that validate. */\n commitAll: () => Promise<boolean>;\n /** Drops everything - open form state and the draft store alike. */\n discard: () => void;\n /**\n * `grid.scrollToRow`, so a control in here can take the user to a row\n * without the grid being threaded down to it.\n */\n scrollToRow: (args: TMDataGridScrollToRowArgs) => boolean;\n /**\n * Scrolls to the first row still open, taking \"first\" in display order: the\n * topmost open row under the current sort, filter and page. That need not\n * be {@link TMDataGridDraftActionsState.openRowIds}`[0]`, which is the\n * order the grid opened them in.\n *\n * Answers whether an open row could be reached. `false` when nothing is\n * open, and when every open row is filtered out, on another page or\n * collapsed inside a group. An open entry row answers `true` without\n * scrolling - it is sticky under the header, so it is on screen already -\n * and so does an open row pinned to an edge. The scroll goes through\n * `scrollToRow`, so before `TMDataGrid.Table` has mounted there is nothing\n * to scroll and the answer is `false`.\n */\n scrollToFirstOpenRow: (align?: TMDataGridScrollAlign) => boolean;\n};\n\n/** The pre-bound pieces of the built-in edit chrome. */\nexport type TMDataGridDraftActionsControls = {\n /** Save, with the draft count, disabled while the draft store is empty. */\n Save: () => ReactNode;\n /** Discard, disabled while nothing is pending. */\n Discard: () => ReactNode;\n /** The \"N rows still being edited\" note, or nothing while there are none. */\n OpenRowsNote: () => ReactNode;\n};\n\n/** What {@link TMDataGridDraftActionsProps.renderActions} is handed. */\nexport type TMDataGridDraftActionsSlotArgs = {\n state: TMDataGridDraftActionsState;\n actions: TMDataGridDraftActionsActions;\n Controls: TMDataGridDraftActionsControls;\n};\n\nexport type TMDataGridDraftActionsProps = {\n /**\n * Replaces the built-in Save/Discard pair, and is handed the pieces of it.\n *\n * ```tsx\n * <TMDataGrid.DraftActions\n * renderActions={({ state, Controls }) => (\n * <Group>\n * {state.draftCount > 0 && <Badge>{state.draftCount}</Badge>}\n * <Controls.OpenRowsNote />\n * <Controls.Save />\n * <Controls.Discard />\n * </Group>\n * )}\n * />\n * ```\n */\n renderActions?: (args: TMDataGridDraftActionsSlotArgs) => ReactNode;\n};\n\n/**\n * The draft store's toolbar chrome: Save with the store's count, Discard, and\n * a note counting the rows still open. Save sends the store and leaves open\n * rows alone, so it greys out while nothing is parked however much is being\n * typed - the note is what makes those rows visible.\n *\n * Works under any `editing.mode`. The toolbar is declarative: the grid does\n * not decide for you, so include this only when the grid runs a draft store -\n * without `editing.draft` there is nothing to save and Save stays disabled.\n *\n * ```tsx\n * <TMDataGrid.Toolbar>\n * <TMDataGrid.SummaryCount />\n * <TMDataGrid.Spacer />\n * <TMDataGrid.DraftActions />\n * </TMDataGrid.Toolbar>\n * ```\n */\nexport function TMDataGridDraftActions({\n renderActions,\n}: TMDataGridDraftActionsProps = {}) {\n const { edit, features, table, scrollToRow } = useTMDataGridContext();\n const draftCount = useDraftCount();\n const openRowIds = useOpenRowIds();\n const isSubmitting = useSelector(edit.store, (state) =>\n state.openRowIds.some((rowId) => state.rows[rowId]?.isSubmitting === true),\n );\n\n if (!features.editing) return null;\n\n if (renderActions) {\n return renderActions({\n state: {\n draftCount,\n openCount: openRowIds.length,\n openRowIds,\n pendingCount: draftCount + openRowIds.length,\n isSubmitting,\n },\n actions: {\n save: () => edit.saveDrafts(),\n commitAll: () => edit.commitAll(),\n discard: () => edit.cancelAll(),\n scrollToRow,\n scrollToFirstOpenRow: (align) => {\n // Read through the store rather than closing over this render's\n // arrays: display order is only decided here, at the click.\n const state = edit.state;\n const openIds = getOpenRowIds(state);\n if (openIds.length === 0) return false;\n const open = new Set(openIds);\n const first = getDisplayedRows(table, features).find((row) =>\n open.has(row.id),\n );\n if (first !== undefined) {\n return scrollToRow({ rowId: first.id, align });\n }\n // Nothing left in the scrolling order, which does not mean nothing\n // is visible: an entry row is sticky under the header, and a pinned\n // row is parked at an edge - `scrollToRow` answers for that one.\n return openIds.some(\n (rowId) =>\n state.newRows.some((newRow) => newRow.tempId === rowId) ||\n scrollToRow({ rowId, align }),\n );\n },\n },\n Controls: EDIT_ACTIONS_CONTROLS,\n });\n }\n\n return (\n <Group gap=\"xs\" wrap=\"nowrap\">\n <EditOpenRowsNote />\n <EditSaveButton />\n <EditDiscardButton />\n </Group>\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 { Group, MultiSelect, Select, TextInput } from \"@mantine/core\";\nimport { optionsToComboboxData } from \"../../core/columnOptions\";\nimport { getColumnType } from \"../../core/columnUtils\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport {\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../../core/filterOperators\";\n\n/**\n * The built-in value control of a filter-panel row - what renders when a\n * column declares no `meta.filter.control`. Shaped by the operator: a\n * multi-select for the set operators, a From/To pair for `between`, a Yes/No\n * dropdown for booleans, a typed input otherwise.\n *\n * Exported so a custom control can fall back to it for the operators it does\n * not care about, instead of rebuilding them.\n */\nexport function TMDataGridFilterValueInput({\n column,\n operator,\n value,\n onChange,\n options,\n size,\n labels,\n}: TMDataGridFilterControlArgs) {\n const type = getColumnType(column);\n const needsValue = operatorNeedsValue(operator);\n const scalarValue = typeof value === \"string\" ? value : \"\";\n const inputType =\n type === \"number\" ? \"number\" : type === \"date\" ? \"date\" : \"text\";\n\n if (operatorTakesRangeValue(operator)) {\n const rangeValue: [string, string] = Array.isArray(value)\n ? [String(value[0] ?? \"\"), String(value[1] ?? \"\")]\n : [\"\", \"\"];\n return (\n // The interval's two ends. Either may stay empty (an open end), and\n // each writes its slot of the `[min, max]` pair.\n <Group gap={4} wrap=\"nowrap\" align=\"flex-start\">\n <TextInput\n label={labels.filterFrom}\n size={size}\n w={88}\n type={inputType}\n data-dg-part=\"filter-value-from\"\n value={rangeValue[0]}\n onChange={(event) =>\n onChange([event.currentTarget.value, rangeValue[1]])\n }\n />\n <TextInput\n label={labels.filterTo}\n size={size}\n w={88}\n type={inputType}\n data-dg-part=\"filter-value-to\"\n value={rangeValue[1]}\n onChange={(event) =>\n onChange([rangeValue[0], event.currentTarget.value])\n }\n />\n </Group>\n );\n }\n\n if (operatorTakesArrayValue(operator)) {\n // The set the cell is tested against. Options come from `meta.options`;\n // a select column that declares none still gets the values present in\n // the data, via the faceted index.\n return (\n <MultiSelect\n label={labels.filterValue}\n size={size}\n w={180}\n comboboxProps={{ withinPortal: false }}\n searchable\n data-dg-part=\"filter-value\"\n data={optionsToComboboxData(options)}\n value={Array.isArray(value) ? [...value] : []}\n onChange={onChange}\n />\n );\n }\n\n if (type === \"boolean\") {\n return (\n <Select\n label={labels.filterValue}\n size={size}\n w={180}\n comboboxProps={{ withinPortal: false }}\n data-dg-part=\"filter-value\"\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) => onChange(next ?? \"\")}\n />\n );\n }\n\n return (\n <TextInput\n label={labels.filterValue}\n size={size}\n w={180}\n type={needsValue ? inputType : \"text\"}\n data-dg-part=\"filter-value\"\n disabled={!needsValue}\n placeholder={needsValue ? labels.filterValuePlaceholder : \"\"}\n value={needsValue ? scalarValue : \"\"}\n onChange={(event) => onChange(event.currentTarget.value)}\n />\n );\n}\n","import {\n ActionIcon,\n Button,\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 { resolveColumnOptions } from \"../core/columnOptions\";\nimport {\n getColumnDefaultOperator,\n getColumnFilterControl,\n getColumnLabel,\n getColumnType,\n} from \"../core/columnUtils\";\nimport {\n type TMDataGridFilterOperator,\n type TMDataGridFilterValue,\n emptyValueForOperator,\n getDefaultOperator,\n getOperatorsForType,\n isTMDataGridFilterValue,\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../core/filterOperators\";\nimport { CloseIcon } from \"./icons\";\nimport { TMDataGridFilterValueInput } from \"./filters/TMDataGridFilterValueInput\";\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 three value shapes an operator can take. A typed value survives an\n * operator or column change only within its shape - a set is not a range,\n * even though both are arrays.\n */\nfunction valueShape(\n operator: TMDataGridFilterOperator,\n): \"scalar\" | \"set\" | \"range\" {\n if (operatorTakesArrayValue(operator)) return \"set\";\n if (operatorTakesRangeValue(operator)) return \"range\";\n return \"scalar\";\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-part=\"filter-button\"]')) 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 = target\n ? getColumnDefaultOperator(target)\n : getDefaultOperator(\"string\");\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 valueShape(operator) === valueShape(current.operator)\n ? current.value\n : emptyValueForOperator(operator);\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 any shape boundary.\n const value =\n valueShape(operator) === valueShape(current.operator)\n ? current.value\n : emptyValueForOperator(operator);\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 const operator = getColumnDefaultOperator(nextColumn);\n table.setColumnFilters([\n ...columnFilters,\n {\n id: nextColumn.id,\n value: {\n operator,\n value: emptyValueForOperator(operator),\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 data-dg-part=\"filter-panel\"\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 span 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 data-dg-part=\"filter-panel-close\"\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 scalarValue = typeof value.value === \"string\" ? value.value : \"\";\n // Pre-resolved only where options mean something out of the box -\n // a declared set, or a select-shaped column's faceted values. A\n // custom control wanting faceted values elsewhere resolves them\n // itself; resolving here would build the faceted index for every\n // filtered column.\n const options =\n column &&\n (column.columnDef.meta?.options !== undefined ||\n type === \"select\" ||\n type === \"multiSelect\")\n ? resolveColumnOptions({ table, column, fallback: \"faceted\" })\n : [];\n const ValueControl =\n (column === undefined ? undefined : getColumnFilterControl(column)) ??\n TMDataGridFilterValueInput;\n\n return (\n <div\n key={filter.id}\n // The row is the handle: a `meta.filter.control` renders whatever\n // it likes in the value slot, so the one thing a test can always\n // count on is which row it is in.\n data-dg-part=\"filter-row\"\n data-column-id={filter.id}\n className={classes.filterRow}\n >\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"lg\"\n aria-label={labels.removeFilter}\n data-dg-part=\"filter-remove\"\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-dg-part=\"filter-column\"\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-dg-part=\"filter-operator\"\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 {column ? (\n // The value slot: `meta.filter.control` if the column declares\n // one, the built-in shape-by-operator input otherwise - both\n // through the same value-only contract.\n <ValueControl\n column={column}\n table={table}\n operator={value.operator}\n value={value.value}\n onChange={(next) => patchFilter(filter.id, { value: next })}\n options={options}\n size={controlSize}\n labels={labels}\n />\n ) : (\n // The column is gone from the definition; the row survives\n // only to be re-pointed or removed.\n <TextInput\n label={labels.filterValue}\n size={controlSize}\n w={180}\n data-dg-part=\"filter-value\"\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 data-dg-part=\"filter-add\"\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 data-dg-part=\"filter-clear-all\"\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 compareItems,\n rankItem,\n type RankingInfo,\n} from \"@tanstack/match-sorter-utils\";\nimport {\n createSortedRowModel,\n type Row,\n type RowData,\n type RowModel,\n type Table,\n type TableFeatures,\n} from \"@tanstack/react-table\";\n\n/** How the quick search matches - see `quickSearchMode` on the hook options. */\nexport type TMDataGridQuickSearchMode = \"fuzzy\" | \"contains\";\n\n/**\n * The fuzzy filter's registry name - what `globalFilterFn` resolves to while\n * `quickSearchMode` is `\"fuzzy\"`. The rank ordering keys off this name, so an\n * explicit `globalFilterFn` override switches the ordering off with it.\n */\nexport const FUZZY_FILTER_FN_NAME = \"tmDataGridFuzzy\";\n\n/** What {@link fuzzyGlobalFilterFn} records per column via `addMeta`. */\ntype FuzzyFilterMeta = { fuzzyRank: RankingInfo };\n\nfunction isFuzzyFilterMeta(value: unknown): value is FuzzyFilterMeta {\n if (typeof value !== \"object\" || value === null) return false;\n const rank = (value as { fuzzyRank?: unknown }).fuzzyRank;\n return (\n typeof rank === \"object\" &&\n rank !== null &&\n typeof (rank as { rank?: unknown }).rank === \"number\"\n );\n}\n\n/**\n * Match-sorter ranking as the global filter: a row passes when a globally\n * filterable column ranks above match-sorter's threshold - typos and skipped\n * characters forgiven - and the rank is recorded for the ordering to read.\n *\n * TanStack stops probing a row's columns at the first passing one, so the\n * recorded ranks cover the columns up to and including it; the best of those\n * stands for the row. Good enough for a quick search: the first passing\n * column is almost always the one the user is looking at.\n */\nexport function fuzzyGlobalFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n addMeta?: (meta: FuzzyFilterMeta) => void,\n): boolean {\n const rank = rankItem(\n String(row.getValue(columnId) ?? \"\"),\n String(filterValue),\n );\n addMeta?.({ fuzzyRank: rank });\n return rank.passed;\n}\n\n/** The best fuzzy rank any column recorded for this row, or `null`. */\nfunction bestRank<TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n): RankingInfo | null {\n let best: RankingInfo | null = null;\n // As a plain record, for the same generic-features reason as the options\n // read in isRankingActive.\n const { columnFiltersMeta } = row as {\n columnFiltersMeta?: Record<string, unknown>;\n };\n for (const meta of Object.values(columnFiltersMeta ?? {})) {\n if (!isFuzzyFilterMeta(meta)) continue;\n if (best === null || meta.fuzzyRank.rank > best.rank) best = meta.fuzzyRank;\n }\n return best;\n}\n\n/**\n * Whether the ranked ordering applies: the fuzzy quick search is narrowing\n * the grid, and nothing else claims an order - no sort, no grouping.\n */\nfunction isRankingActive<TFeatures extends TableFeatures, TData extends RowData>(\n table: Table<TFeatures, TData>,\n): boolean {\n // Off the options as a plain record: a generic `TFeatures` does not carry\n // the global-filtering feature's option types, and this file stays generic\n // to avoid a cycle with useTMDataGrid.\n const { globalFilterFn } = table.options as { globalFilterFn?: unknown };\n if (globalFilterFn !== FUZZY_FILTER_FN_NAME) return false;\n const state = table.store.state as {\n sorting?: Array<unknown>;\n grouping?: Array<unknown>;\n globalFilter?: unknown;\n };\n return (\n (state.sorting?.length ?? 0) === 0 &&\n (state.grouping?.length ?? 0) === 0 &&\n typeof state.globalFilter === \"string\" &&\n state.globalFilter.trim() !== \"\"\n );\n}\n\n/**\n * The sorted row model, with one addition: while {@link isRankingActive},\n * rows order by match quality, best first. Declarative - the ordering is\n * derived from filter state, never written into `sorting`, so no column\n * claims `aria-sort`, the persisted slice stays untouched, and the user's\n * next sort click suspends it just by existing.\n *\n * Sits upstream of pagination, so a ranked first page really is the best\n * matches of the whole set.\n */\nexport function createFuzzyRankedSortedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n const base = createSortedRowModel<TFeatures, TData>();\n return (table) => {\n const getSorted = base(table);\n // One-slot memo: every input of the ordering - filter text, data, the\n // sorting and grouping states - changes the sorted model's identity, so\n // the model alone is the cache key.\n let lastModel: RowModel<TFeatures, TData> | null = null;\n let ranked: RowModel<TFeatures, TData> | null = null;\n return () => {\n const model = getSorted();\n if (!isRankingActive(table)) return model;\n if (model === lastModel && ranked !== null) return ranked;\n const rows = [...model.rows].sort((a, b) => {\n const rankA = bestRank(a);\n const rankB = bestRank(b);\n if (rankA !== null && rankB !== null) return compareItems(rankA, rankB);\n return rankA !== null ? -1 : rankB !== null ? 1 : 0;\n });\n ranked = { rows, flatRows: model.flatRows, rowsById: model.rowsById };\n lastModel = model;\n return ranked;\n };\n };\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 /** Tooltip on the reset button, stating everything the reset covers. */\n columnsResetHint: string;\n /** Menu/panel name of the generated row-number gutter. */\n rowNumberColumnLabel: string;\n /**\n * The truly-empty message - no data and no filters. Filtered-empty says\n * {@link noResults} instead; only one of the two is the user's own doing.\n */\n noRows: string;\n\n // Filter panel\n filterColumn: string;\n filterOperator: string;\n filterValue: string;\n filterValuePlaceholder: string;\n /** The lower bound of a `between` filter. */\n filterFrom: string;\n /** The upper bound of a `between` filter. */\n filterTo: string;\n /** `DgTriStateFilter`'s no-filter segment. */\n filterAll: 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 editing\n /** `aria-label` of an open cell editor's input. */\n editCell: (column: string) => string;\n /** cellConfirm's ✓ beside the input. */\n confirmEdit: string;\n /** cellConfirm's ✕ beside the input. */\n cancelEdit: string;\n /** The generated edit lane's name in the column manager. */\n editColumnLabel: string;\n /** The lane's pencil. */\n editRow: string;\n /** The lane's ✓ while a row edit is open. */\n saveRow: string;\n /** The lane's ✕ while a row edit is open. */\n cancelRowEdit: string;\n /** Save tooltip when field errors block the row, with no row message. */\n editRowErrors: string;\n /** `DraftActions`' Save, with the count of rows in the draft store. */\n saveAllEdits: (rows: number) => string;\n /** `DraftActions`' Discard. */\n discardAllEdits: string;\n /**\n * `DraftActions`' note about rows still open - edited but not committed, so\n * not part of the save. Shown only while there are any.\n */\n editRowsStillOpen: (rows: number) => string;\n /** The entry row's ✓ - commit the add. */\n confirmNewRow: string;\n /** The entry row's ✕ - drop the entry. */\n discardNewRow: string;\n /** The lane's trash can. */\n deleteRow: string;\n /** The lane's undo on a row marked deleted (draft). */\n restoreRow: string;\n /** The lane's undo on a row with a dirty draft (draft) - drops it. */\n revertRow: string;\n /** The lane's state icon on a confirmed entry row (draft). */\n rowStateNew: string;\n /** The lane's state icon on a row with a dirty draft (draft). */\n rowStateEdited: string;\n /** The lane's state icon on a row marked deleted (draft). */\n rowStateDeleted: 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 LAYOUT\",\n columnsResetHint:\n \"Resets column visibility, order, widths, pinning and grouping\",\n rowNumberColumnLabel: \"Row number\",\n noRows: \"No rows to show\",\n\n filterColumn: \"Column\",\n filterOperator: \"Operator\",\n filterValue: \"Value\",\n filterValuePlaceholder: \"Filter value\",\n filterFrom: \"From\",\n filterTo: \"To\",\n filterAll: \"All\",\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 editCell: (column) => `Edit ${column}`,\n confirmEdit: \"Save\",\n cancelEdit: \"Cancel\",\n editColumnLabel: \"Edit\",\n editRow: \"Edit row\",\n saveRow: \"Save row\",\n cancelRowEdit: \"Cancel edit\",\n editRowErrors: \"Fix the marked cells\",\n saveAllEdits: (rows) => (rows === 1 ? \"Save 1 row\" : `Save ${rows} rows`),\n discardAllEdits: \"Discard\",\n editRowsStillOpen: (rows) =>\n rows === 1 ? \"1 row still being edited\" : `${rows} rows still being edited`,\n confirmNewRow: \"Add row\",\n discardNewRow: \"Discard new row\",\n deleteRow: \"Delete row\",\n restoreRow: \"Restore row\",\n revertRow: \"Revert changes\",\n rowStateNew: \"New row\",\n rowStateEdited: \"Edited row\",\n rowStateDeleted: \"Marked for deletion\",\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 holds a piece of state and returns `[value, setValue]`. Here the\n * table already holds 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 conflict with 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\n/**\n * Version stamped into every stored payload, under a key no state slice can\n * collide with. A payload whose version does not match is dropped whole: a\n * migration would be guessing at a shape this code no longer knows, and the\n * cost of dropping is one lost layout. Payloads written before versioning\n * existed (≤0.4.0) have no stamp and are dropped the same way - the 1.0\n * wave's one-time break, named in its changeset.\n */\nexport const PERSIST_PAYLOAD_VERSION = 1;\nconst VERSION_FIELD = \"__v\";\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 if (record[VERSION_FIELD] !== PERSIST_PAYLOAD_VERSION) return {};\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> = { [VERSION_FIELD]: PERSIST_PAYLOAD_VERSION };\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/**\n * The leaf column ids a set of column defs will produce, by TanStack's own\n * derivation: `id`, else `accessorKey` with dots replaced by underscores,\n * else a string `header`. Mirrored here so restored state can be realigned\n * against the columns that will actually exist - deriving ids any other way\n * would realign against names the table never uses.\n */\nexport function collectLeafColumnIds(\n defs: ReadonlyArray<unknown>,\n into: string[] = [],\n): string[] {\n for (const def of defs) {\n if (typeof def !== \"object\" || def === null) continue;\n const record = def as Record<string, unknown>;\n if (Array.isArray(record.columns) && record.columns.length > 0) {\n collectLeafColumnIds(record.columns, into);\n continue;\n }\n const accessorKey =\n typeof record.accessorKey === \"string\" ? record.accessorKey : undefined;\n const id =\n (typeof record.id === \"string\" ? record.id : undefined) ??\n accessorKey?.replaceAll(\".\", \"_\") ??\n (typeof record.header === \"string\" ? record.header : undefined);\n if (id !== undefined) into.push(id);\n }\n return into;\n}\n\n/**\n * Drops restored entries that name columns the grid no longer has.\n *\n * A stored layout outlives the column set: a column removed between deploys\n * would otherwise linger forever - a ghost id in the order, a width for\n * nothing, and worse, a *filter or sort that is active but has no column to\n * show for itself*. New columns need no counterpart here: TanStack appends\n * columns missing from `columnOrder` on its own, in definition order.\n */\nfunction realignToColumns(\n restored: Partial<GridState>,\n known: ReadonlySet<string>,\n): Partial<GridState> {\n const has = (id: unknown): boolean =>\n typeof id === \"string\" && known.has(id);\n const keepIds = (values: ReadonlyArray<string>) => values.filter(has);\n const keepKeys = <T,>(record: Record<string, T>) =>\n Object.fromEntries(Object.entries(record).filter(([id]) => has(id)));\n const keepEntries = <T extends { id: string }>(entries: ReadonlyArray<T>) =>\n entries.filter((entry) => has(entry.id));\n\n const realigned: Partial<GridState> = { ...restored };\n if (restored.columnOrder) realigned.columnOrder = keepIds(restored.columnOrder);\n if (restored.grouping) realigned.grouping = keepIds(restored.grouping);\n if (restored.columnVisibility) {\n realigned.columnVisibility = keepKeys(restored.columnVisibility);\n }\n if (restored.columnSizing) {\n realigned.columnSizing = keepKeys(restored.columnSizing);\n }\n if (restored.columnPinning) {\n realigned.columnPinning = {\n left: keepIds(restored.columnPinning.left ?? []),\n right: keepIds(restored.columnPinning.right ?? []),\n };\n }\n if (restored.sorting) realigned.sorting = keepEntries(restored.sorting);\n if (restored.columnFilters) {\n realigned.columnFilters = keepEntries(restored.columnFilters);\n }\n return realigned;\n}\n\n/**\n * State to merge into `initialState`, read once on mount.\n *\n * With `knownColumnIds` - every id the grid is about to construct, generated\n * lanes included - the column-shaped slices are realigned first; see\n * {@link realignToColumns}. Without it the payload is returned as stored.\n */\nexport function readPersistedState(\n persistence?: TMDataGridPersistence,\n knownColumnIds?: ReadonlyArray<string>,\n): Partial<GridState> {\n const storage = resolveStorage(persistence);\n const { data, settings } = resolveKeys(persistence);\n const deserialize = persistence?.deserialize ?? defaultDeserialize;\n const restored = {\n ...readSlices(storage, settings, deserialize),\n ...readSlices(storage, data, deserialize),\n };\n return knownColumnIds === undefined\n ? restored\n : realignToColumns(restored, new Set(knownColumnIds));\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 { TMDataGridEditMode } from \"./editEngine\";\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 /** Whether cells can be edited at all - the `editing` option was set. */\n editing: boolean;\n /** What counts as a commit, or `null` while editing is off. */\n editMode: TMDataGridEditMode | null;\n /**\n * Where a commit goes - `editing.draft`. On, commits park in the grid's\n * draft store and leave through `edit.saveDrafts()`; off, each one reaches\n * the consumer as it happens.\n */\n editDraft: boolean;\n /**\n * Whether a parked entry row stays pinned in the sticky entry block until\n * the draft store is saved - `editing.newRowsSticky`, which needs\n * `editing.draft`. Off by default: a parked row joins the scrolling flow\n * instead, so entering many rows cannot fill the viewport with sticky\n * chrome.\n */\n editNewRowsSticky: boolean;\n /** The generated row-number gutter - `enableRowNumbers`. Off by default. */\n rowNumbers: boolean;\n /**\n * Whether rows can be pinned to the top or bottom edge - `enableRowPinning`,\n * boolean or per-row predicate. Off by default: pinning has no built-in\n * gesture, so a grid that never calls `row.pin()` has nothing to gain from\n * the body watching the state.\n */\n rowPinning: boolean;\n /**\n * Whether cells highlight the matched text while a contains-family filter\n * or the quick search is active - `enableMatchHighlighting`. Off by\n * default, so a grid that has not asked pays nothing per cell.\n */\n matchHighlighting: 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 | \"editing\"\n | \"enableRowNumbers\"\n | \"enableRowPinning\"\n | \"enableMatchHighlighting\"\n >,\n): TMDataGridFeatureFlags {\n const selectionMode = options.selectionMode ?? \"checkbox\";\n // Editing brings the cell cursor with it: Enter, F2 and type-to-edit all\n // address \"the focused cell\", which only exists under cell selection. An\n // explicit `cellSelection` still wins, `\"range\"` included.\n const cellSelectionMode =\n options.cellSelection ?? (options.editing !== undefined ? \"single\" : \"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 editing: options.editing !== undefined,\n editMode: options.editing?.mode ?? null,\n editDraft: options.editing?.draft === true,\n editNewRowsSticky:\n options.editing?.draft === true &&\n options.editing.newRowsSticky === true,\n rowNumbers: options.enableRowNumbers === true,\n // A predicate counts as on - some rows may still pin.\n rowPinning:\n options.enableRowPinning === true ||\n typeof options.enableRowPinning === \"function\",\n matchHighlighting: options.enableMatchHighlighting === 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 the grid handles \"does not resolve\" explicitly.\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\nexport type NextEditableCellArgs = {\n from: TMDataGridCellCoords;\n /** `1` is Tab, `-1` is Shift+Tab. */\n direction: 1 | -1;\n rowCount: number;\n columnCount: number;\n /** Whether the cell at these coordinates takes edits. */\n isEditable: (coords: TMDataGridCellCoords) => boolean;\n};\n\n/**\n * The next editable cell in reading order, wrapping to the next row - and\n * from the last cell of the grid back to the first. `null` when no other\n * cell is editable.\n *\n * Deliberately wrapping where {@link resolveCellMove} deliberately clamps:\n * arrows are a coordinate space and clamp so the destination is predictable,\n * but Tab mid-edit is the spreadsheet's \"next field\" - at the end of a row\n * the next field is on the next row, which is a convention, not a surprise.\n */\nexport function getNextEditableCell({\n from,\n direction,\n rowCount,\n columnCount,\n isEditable,\n}: NextEditableCellArgs): TMDataGridCellCoords | null {\n const total = rowCount * columnCount;\n if (total === 0) return null;\n const start = from.rowIndex * columnCount + from.columnIndex;\n for (let step = 1; step < total; step += 1) {\n const index = (start + direction * step + total * step) % total;\n const coords = {\n rowIndex: Math.floor(index / columnCount),\n columnIndex: index % columnCount,\n };\n if (isEditable(coords)) return coords;\n }\n return null;\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 type { TableState } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\ntype GridState = TableState<TMDataGridFeatures>;\n\n/**\n * Support for TanStack's `state` option (controlled state).\n *\n * table-core re-reads `options.state` on every render (`useTable` calls\n * `setOptions` while rendering) and writes any slice whose value is not\n * identical to the table's current value into the table's atom. The write\n * publishes the store and re-renders the consumer, so a slice object built in\n * the render body causes an infinite render loop.\n *\n * {@link stabilizeControlledState} prevents the loop by forwarding the\n * previous render's value for a slice whose contents are unchanged.\n * {@link findFrozenStateSlices} detects a controlled slice without its\n * `onXChange` callback, which the grid cannot write to.\n */\n\n/**\n * The `onXChange` option that owns each controlled slice - every slice v9\n * defines. `globalFilterFn` is not among them: in this beta it is a table\n * option, not state.\n */\nexport const CONTROLLED_SLICE_HANDLERS = {\n columnFilters: \"onColumnFiltersChange\",\n columnOrder: \"onColumnOrderChange\",\n columnPinning: \"onColumnPinningChange\",\n columnResizing: \"onColumnResizingChange\",\n columnSizing: \"onColumnSizingChange\",\n columnVisibility: \"onColumnVisibilityChange\",\n expanded: \"onExpandedChange\",\n globalFilter: \"onGlobalFilterChange\",\n grouping: \"onGroupingChange\",\n pagination: \"onPaginationChange\",\n rowPinning: \"onRowPinningChange\",\n rowSelection: \"onRowSelectionChange\",\n sorting: \"onSortingChange\",\n} as const satisfies Partial<Record<keyof GridState, string>>;\n\nexport type TMDataGridControlledSlice = keyof typeof CONTROLLED_SLICE_HANDLERS;\n\n/** The options {@link findFrozenStateSlices} reads - a subset of `TableOptions`. */\ntype ControlledOptions = {\n state?: Partial<GridState>;\n /**\n * The v9 way of owning a slice: an atom the table writes through directly.\n * It outranks `state`, so a slice backed by one is never frozen.\n */\n atoms?: Record<string, unknown>;\n} & Partial<\n Record<(typeof CONTROLLED_SLICE_HANDLERS)[TMDataGridControlledSlice], unknown>\n>;\n\nconst hasOwn = (value: object, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\n/**\n * A plain data object: `Object.prototype` or null prototype. table-core builds\n * its state maps with `Object.create(null)`, so null prototypes must compare\n * as plain objects.\n */\nfunction isDataObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Structural equality for state values.\n *\n * `Date`s compare by time; the built-in date filters hold them in filter\n * values. `Map`s and class instances compare by identity, so a controlled\n * slice containing one rebuilt each render reads as changed on every render\n * and re-renders the table. Use primitives, plain objects, arrays or `Date`s\n * in controlled state.\n */\nexport function sameStateValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (a instanceof Date || b instanceof Date) {\n return (\n a instanceof Date && b instanceof Date && a.getTime() === b.getTime()\n );\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b)) return false;\n return (\n a.length === b.length &&\n a.every((item, index) => sameStateValue(item, b[index]))\n );\n }\n if (!isDataObject(a) || !isDataObject(b)) return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n return keys.every((key) => hasOwn(b, key) && sameStateValue(a[key], b[key]));\n}\n\n/**\n * Removes keys whose value is `undefined`, as in\n * `state: { sorting: cond ? sorting : undefined }`.\n *\n * TanStack's sync writes every present key into the slice's atom, `undefined`\n * included, which breaks everything that reads the slice. A key set to\n * `undefined` is treated as not controlled: the key is removed and the slice\n * falls back to the table's own state. Identity is preserved when there is\n * nothing to remove; the stabilizer compares by it.\n */\nexport function withoutUndefinedSlices(\n state: Partial<GridState> | undefined,\n): Partial<GridState> | undefined {\n if (state === undefined) return state;\n if (!Object.values(state).includes(undefined)) return state;\n const compacted: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(state)) {\n if (value !== undefined) compacted[key] = value;\n }\n return compacted as Partial<GridState>;\n}\n\n/**\n * Returns `next` with every slice that structurally equals its counterpart in\n * `previous` replaced by the previous object, so table-core's identity-based\n * sync finds nothing to write. Returns `previous` when nothing changed.\n */\nexport function stabilizeControlledState(\n next: Partial<GridState> | undefined,\n previous: Partial<GridState> | undefined,\n): Partial<GridState> | undefined {\n if (next === undefined || previous === undefined || next === previous) {\n return next;\n }\n\n const keys = Object.keys(next);\n const stabilized: Record<string, unknown> = {};\n let changed = keys.length !== Object.keys(previous).length;\n\n for (const key of keys) {\n const nextValue = (next as Record<string, unknown>)[key];\n const previousValue = (previous as Record<string, unknown>)[key];\n if (hasOwn(previous, key) && sameStateValue(nextValue, previousValue)) {\n // Unchanged contents: keep the object the table already holds.\n stabilized[key] = previousValue;\n } else {\n stabilized[key] = nextValue;\n changed = true;\n }\n }\n\n return changed ? (stabilized as Partial<GridState>) : previous;\n}\n\n/**\n * Controlled slices without a write path: `state.x` is set but no `onXChange`\n * was passed and no external atom owns the slice. TanStack routes every write\n * through the callback, so such a slice cannot change. Reported so the hook\n * can warn in development; `initialState` is the option for a starting value.\n */\nexport function findFrozenStateSlices(\n options: ControlledOptions,\n): Array<{ slice: TMDataGridControlledSlice; handler: string }> {\n const state = options.state;\n if (state === undefined) return [];\n\n return (\n Object.entries(CONTROLLED_SLICE_HANDLERS) as Array<\n [TMDataGridControlledSlice, string]\n >\n )\n .filter(\n ([slice, handler]) =>\n // Undefined-valued keys are removed before the table sees them; the\n // slice is not controlled.\n (state as Record<string, unknown>)[slice] !== undefined &&\n (options as Record<string, unknown>)[handler] === undefined &&\n options.atoms?.[slice] === undefined,\n )\n .map(([slice, handler]) => ({ slice, handler }));\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 filterFns,\n globalFilteringFeature,\n metaHelper,\n type Row,\n type RowData,\n rowExpandingFeature,\n rowPaginationFeature,\n rowPinningFeature,\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 {\n type MutableRefObject,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { TMDataGridRowData } from \"./TMDataGridContext\";\nimport type { TMDataGridOptionsSource } from \"./core/columnOptions\";\nimport {\n createEditEngine,\n type TMDataGridEditApi,\n type TMDataGridEditCommitArgs,\n type TMDataGridSaveDraftsArgs,\n type TMDataGridSaveDraftsResult,\n type TMDataGridEditEngineContext,\n type TMDataGridColumnEditOptions,\n type TMDataGridEditMode,\n type TMDataGridRowAddArgs,\n type TMDataGridRowDeleteArgs,\n type TMDataGridRowValidators,\n type TMDataGridTableValidators,\n} from \"./core/editEngine\";\nimport {\n emptyValueForOperator,\n type TMDataGridColumnType,\n tmDataGridFilterFn,\n} from \"./core/filterOperators\";\nimport { getColumnDefaultOperator, isControlColumn } from \"./core/columnUtils\";\nimport type { TMDataGridColumnFilterOptions } from \"./core/filterControls\";\nimport {\n createFuzzyRankedSortedRowModel,\n fuzzyGlobalFilterFn,\n type TMDataGridQuickSearchMode,\n} from \"./core/quickSearch\";\nimport {\n mergeLabels,\n type TMDataGridLabels,\n type TMDataGridLabelsOverride,\n} from \"./core/labels\";\nimport {\n collectLeafColumnIds,\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 {\n findFrozenStateSlices,\n stabilizeControlledState,\n withoutUndefinedSlices,\n} from \"./core/controlledState\";\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\";\nimport {\n createEditColumn,\n EDIT_COLUMN_ID,\n} from \"./components/TMDataGridEditColumn\";\nimport {\n createRowNumberColumn,\n ROW_NUMBER_COLUMN_ID,\n} from \"./components/TMDataGridRowNumberColumn\";\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/**\n * Per-column configuration the grid's own components read.\n *\n * The filter and edit stages each get a namespace, `filter` and `edit`,\n * mirroring the feature's runtime API. What the column *is* stays flat:\n * `label`, `type`, `options`, `align`, `flex`, `autoSize`, `enableOrdering`.\n * `type` and `options` are read by both stages, so one declaration of each\n * feeds the filter panel and the cell editor, which is why they sit outside\n * both namespaces.\n */\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 * How this column filters: the operator a fresh filter starts with, and the\n * value control the filter panel renders for it.\n *\n * ```tsx\n * meta: {\n * type: \"number\",\n * filter: { defaultOperator: \"between\", control: DgRangeSliderFilter },\n * }\n * ```\n *\n * See {@link TMDataGridColumnFilterOptions}.\n */\n filter?: TMDataGridColumnFilterOptions;\n /**\n * How this column is edited: whether it takes edits, which field they write\n * to, which editor opens, what validates the field and what maps the value\n * on its way in.\n *\n * ```tsx\n * meta: {\n * type: \"string\",\n * edit: { validate: z.string().min(2, \"Too short\") },\n * }\n * ```\n *\n * See {@link TMDataGridColumnEditOptions}.\n */\n edit?: TMDataGridColumnEditOptions;\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 rowPinningFeature,\n\n filteredRowModel: createFilteredRowModel(),\n groupedRowModel: createGroupedRowModel(),\n // The sorted model plus the fuzzy quick search's rank ordering - see\n // core/quickSearch.ts for when the ordering applies.\n sortedRowModel: createFuzzyRankedSortedRowModel(),\n expandedRowModel: createExpandedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n facetedRowModel: createFacetedRowModel(),\n facetedMinMaxValues: createFacetedMinMaxValues(),\n facetedUniqueValues: createFacetedUniqueValues(),\n\n filterFns: {\n ...filterFns,\n tmDataGrid: tmDataGridFilterFn,\n tmDataGridFuzzy: fuzzyGlobalFilterFn,\n },\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/** Where a scrolled-to row lands in the viewport. TanStack's own alignments. */\nexport type TMDataGridScrollAlign = \"auto\" | \"start\" | \"center\" | \"end\";\n\nexport type TMDataGridScrollToRowArgs = {\n /** The row's id, as `getRowId` produced it. */\n rowId: string;\n /** Defaults to `\"auto\"` - the nearest edge, leaving a visible row alone. */\n align?: TMDataGridScrollAlign;\n};\n\n/** @internal The body's scroll implementation. See `scrollToRow`. */\nexport type TMDataGridScroller = (args: TMDataGridScrollToRowArgs) => boolean;\n\n/** What `useTMDataGrid` returns - spread straight onto `<TMDataGrid />`. */\nexport type TMDataGridApi<TData extends RowData> = {\n table: TMDataGridTable<TData>;\n ui: TMDataGridUiStore;\n /**\n * The edit engine - open forms, dirty/error projections, and the verbs\n * (`begin`, `commit`, `cancel`, `submitAll`). `edit.getForm(rowId)` hands\n * out the same TanStack Form the inline editors write through, so a drawer\n * or detail panel can share a row's draft. Inert until `editing` is set.\n */\n edit: TMDataGridEditApi<TData>;\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 * Puts the settings state - visibility, order, widths, pinning, grouping -\n * back to what a first visit with clean storage would have shown: the\n * consumer's `initialState` plus the structural lanes. With persistence\n * configured the reset writes through to storage like any other change.\n *\n * This, not TanStack's `resetColumnX()` family, is the reset for a\n * persisted grid: those reset to `initialState`, and the grid bakes the\n * restored payload into `initialState` at mount - they would \"reset\" to\n * the very layout being discarded.\n */\n resetSettings: () => void;\n /**\n * Scrolls a row into view. The grid is always virtualized, so a row far down\n * the list has no element to scroll to - this moves the virtualizer instead,\n * which is the only thing that can put one there.\n *\n * ```ts\n * grid.scrollToRow({ rowId: \"42\", align: \"center\" });\n * ```\n *\n * Answers whether the row could be reached. `false` means it is not in the\n * current view at all - filtered out, on another page, or an id that matches\n * no row - and nothing scrolled. A pinned row answers `true` without\n * scrolling: it is already parked at an edge.\n *\n * Identity is stable, so it is safe in a dependency array.\n */\n scrollToRow: (args: TMDataGridScrollToRowArgs) => boolean;\n /**\n * @internal Wiring for `TMDataGrid.Table`, which holds the virtualizer and\n * fills this in. Not part of the public API.\n */\n scrollerRef: MutableRefObject<TMDataGridScroller>;\n};\n\n/** The editing members every mode shares. See {@link TMDataGridEditingOptions}. */\ntype TMDataGridEditingCallbacks<TData extends RowData> = {\n /**\n * Form-level validators for the whole editing row - where cross-field\n * rules live. TanStack Form's own vocabulary, Standard Schema included:\n *\n * ```tsx\n * rowValidators: {\n * onSubmit: z.object({ salary: z.number().positive() })\n * .refine((r) => r.status !== \"Terminated\" || r.salary === 0, {\n * message: \"A terminated employee has no salary\",\n * }),\n * }\n * ```\n *\n * Pathed issues land on the matching columns; pathless ones on the row.\n */\n rowValidators?: TMDataGridRowValidators;\n /**\n * Rules that need the other rows - no duplicate keys, no overlapping\n * ranges, allocations summing to a total. Handed the committing row and\n * `rows`, the collection as it would stand if the commit landed: every\n * draft overlaid, entry rows appended, deletion-marked rows removed.\n *\n * ```tsx\n * tableValidators: {\n * onSubmit: ({ value, rowId, rows }) =>\n * rows.some((r) => r.rowId !== rowId && r.value.code === value.code)\n * ? { fields: { code: \"Duplicate code\" } }\n * : undefined,\n * }\n * ```\n *\n * Runs at every commit, after the row's own validators, and again per\n * parked row during `saveDrafts` - a draft another edit has invalidated\n * blocks the save. Pathed issues land on the committing row's cells,\n * pathless ones on the row.\n */\n tableValidators?: TMDataGridTableValidators<TData>;\n /** Rows the pencil skips - `false` keeps a row read-only in every mode. */\n isRowEditable?: (row: Row<TMDataGridFeatures, TData>) => boolean;\n /**\n * Called when an edit commits. The grid never mutates `data`: apply the\n * change and let the new data arrive back through `data` as always. The\n * engine drops the draft only when this resolves - a slow save keeps the\n * draft visible with a busy marker - and a rejection keeps the form open\n * with the error on the row.\n *\n * `changes` is the per-field diff (one entry in cell mode), for a PATCH.\n * `value` is the entire edited row, for saving a record.\n */\n onCommit?: (args: TMDataGridEditCommitArgs<TData>) => void | Promise<void>;\n /**\n * Seed values for `edit.addRow()` - the entry row's starting point. A\n * function is called per added row (fresh timestamps, empty arrays).\n * `edit.addRow(values)` overrides this key by key for that one row.\n */\n newRowDefaults?: TData | (() => TData);\n /**\n * Called when an entry row commits: `Enter` or the lane's ✓, or\n * `saveDrafts` under `editing.draft`. Create the record and let it arrive\n * back through `data`; the engine's `tempId` never leaves the grid.\n */\n onRowAdd?: (args: TMDataGridRowAddArgs<TData>) => void | Promise<void>;\n /**\n * Called by `edit.deleteRow` - confirmation, if any, belongs in here. Under\n * `editing.draft` deletions accumulate in `edit.state.deletedRowIds`\n * instead and are reported by `saveDrafts`. Setting this also puts the\n * trash can in the edit lane.\n */\n onRowDelete?: (args: TMDataGridRowDeleteArgs<TData>) => void | Promise<void>;\n};\n\n/**\n * The `editing` option: one object that turns editing on and holds\n * everything about it. Two axes, and they are independent: `mode` picks what\n * counts as a commit, `draft` picks where that commit goes.\n *\n * | Mode | Commit | Cancel | Controls |\n * | ---- | ------ | ------ | -------- |\n * | `\"cell\"` | Enter, Tab, blur - Sheets | Escape | none |\n * | `\"cellConfirm\"` | ✓ or Enter; Tab and blur keep the draft | ✕ or Escape | ✓ / ✕ beside the input |\n * | `\"row\"` | Save in the edit lane, or Enter | Cancel, or Escape | generated edit lane |\n *\n * | `draft` | Where a commit goes |\n * | ------- | ------------------- |\n * | `false` (default) | Out as it happens - `onCommit`, `onRowAdd`, `onRowDelete` |\n * | `true` | Into the grid's draft store; `edit.saveDrafts()` sends the lot |\n *\n * So `{ mode: \"row\", draft: true }` is \"edit a row, the lane's ✓ parks it,\n * the toolbar's Save sends every parked row at once\", and\n * `{ mode: \"cell\", draft: true }` is the same store filled cell by cell.\n *\n * Setting `editing` makes `getRowId` required - drafts are keyed by row id,\n * and the index fallback would name a different record after any sort - and\n * `onSaveDrafts` exists only under `draft: true`, the one configuration with\n * a draft store to save.\n *\n * The object may be written inline: the callbacks are read through a ref\n * every render, so its identity does not matter.\n *\n * One TanStack Form per editing row; drafts survive scrolling because the\n * forms live outside the DOM, keyed by row id. Which columns edit, and with\n * what, is declared per column under `meta.edit`: `meta.type` picks the\n * built-in editor, and `enabled`, `field`, `editor`, `validate` and `mapValue`\n * override the rest.\n */\nexport type TMDataGridEditingOptions<TData extends RowData> =\n TMDataGridEditingCallbacks<TData> & {\n /** What counts as a commit. See the table above. */\n mode: TMDataGridEditMode;\n /**\n * The column ids that take edits, by id. Unset - the default - every\n * column mapping to a data path is editable, which is what a grid whose\n * columns are mostly the record itself wants.\n *\n * Set it for the other shape: a grid of reference data with one or two\n * columns the user maintains, where naming those is shorter and harder to\n * get wrong than switching every other column off one by one.\n *\n * This gates before `meta.edit`, never past it: a column left out takes no\n * edits whatever its own meta says, and a column listed here still answers\n * to its `meta.edit.enabled`.\n */\n columns?: ReadonlyArray<string>;\n } & (\n | {\n /**\n * Commits park in the grid's draft store instead of reaching the\n * consumer, and leave together through `edit.saveDrafts()`. The\n * edit lane gains the change markers and the per-row revert, the\n * trash marks a row for deletion rather than deleting it, and\n * `TMDataGrid.DraftActions` gets something to save.\n */\n draft: true;\n /**\n * The bulk save: called once by `edit.saveDrafts()` with the\n * whole draft store - committed edits, added rows and deletion\n * marks - so a server can apply it as one transaction. Without it,\n * `saveDrafts` falls back to the per-row\n * {@link TMDataGridEditingCallbacks.onCommit} loop.\n *\n * Rows still open are not in the payload and stay open. Returning\n * nothing saves the whole store and throwing saves none of it;\n * return a {@link TMDataGridSaveDraftsResult} to save part of it.\n */\n onSaveDrafts?: (\n args: TMDataGridSaveDraftsArgs<TData>,\n ) =>\n | void\n | TMDataGridSaveDraftsResult\n | Promise<void | TMDataGridSaveDraftsResult>;\n /**\n * @deprecated Renamed to {@link onSaveDrafts} - it fires when the\n * draft store is saved, not when a row commits into it. Still\n * honoured; removed in a later beta.\n */\n onCommitDrafts?: (\n args: TMDataGridSaveDraftsArgs<TData>,\n ) =>\n | void\n | TMDataGridSaveDraftsResult\n | Promise<void | TMDataGridSaveDraftsResult>;\n /**\n * Keep parked entry rows pinned in the sticky entry block until\n * the draft store is saved. Off by default: a parked row joins the\n * scrolling flow above the body rows instead - the block a row is\n * *typed* into is always sticky, but parked rows scroll, so\n * entering many cannot fill the viewport with sticky chrome.\n */\n newRowsSticky?: boolean;\n }\n | {\n /** Every commit reaches the consumer as it happens. The default. */\n draft?: false;\n /** Only `draft: true` has a store to save - see the other branch. */\n onSaveDrafts?: never;\n /** @deprecated See {@link onSaveDrafts}. */\n onCommitDrafts?: never;\n /** Parked entry rows exist only under `draft: true` - see there. */\n newRowsSticky?: never;\n }\n );\n\nexport type UseTMDataGridOptions<TData extends RowData> = Omit<\n TableOptions<TMDataGridFeatures, TData>,\n \"features\"\n> &\n (\n | { editing?: undefined }\n | {\n /** Turns editing on. See {@link TMDataGridEditingOptions}. */\n editing: TMDataGridEditingOptions<TData>;\n /**\n * Required once `editing` is set: the forms are keyed by row id and\n * live outside the DOM, and the index fallback points at a different\n * record after any sort.\n */\n getRowId: NonNullable<\n TableOptions<TMDataGridFeatures, TData>[\"getRowId\"]\n >;\n }\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 * The row-number gutter: a generated lane, outermost left, numbering the\n * rows of the current view - sorted, filtered, continuing across pages,\n * with group rows unnumbered. Off by default.\n */\n enableRowNumbers?: boolean;\n /**\n * How the quick search (`TMDataGrid.Search`) matches. `\"fuzzy\"` - the\n * default - forgives typos and skipped characters, and while it is the\n * only thing narrowing the grid (no sort, no grouping) the rows order by\n * match quality, best first. `\"contains\"` is plain substring matching.\n * An explicit `globalFilterFn` overrides both.\n */\n quickSearchMode?: TMDataGridQuickSearchMode;\n /**\n * Highlights the matched text in cells while a contains-family column\n * filter or the quick search is active. Default-rendered cells only - a\n * column with its own `cell` renderer opts out by existing; a fuzzy\n * typo-match with no contiguous occurrence shows no highlight. Off by\n * default.\n */\n enableMatchHighlighting?: 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\n * accurate for panels that open off screen, such as restored `expanded`\n * state. An approximate value 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 */\n/**\n * Drops the control lanes' entries from a visibility map.\n *\n * They are all `enableHiding: false`, but TanStack applies `columnVisibility`\n * regardless - the option only gates `toggleVisibility` - so a stale `false`\n * would hide a lane nothing in the grid can bring back: restored from storage\n * written before 2.1 (when the checkbox lane was still hideable), or passed in\n * `initialState`. The tree column is not scrubbed; its entry is the grid's own,\n * written after this.\n */\nfunction withoutControlColumnVisibility(\n visibility: Record<string, boolean>,\n): Record<string, boolean> {\n const scrubbed = { ...visibility };\n for (const id of Object.keys(scrubbed)) {\n if (isControlColumn(id)) delete scrubbed[id];\n }\n return scrubbed;\n}\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 enableRowNumbers,\n selectionMode,\n showSelectedBackground,\n defaultHighlightedRowId,\n onHighlightedRowChange,\n cellSelection,\n onFocusedCellChange,\n editing,\n renderDetails,\n renderDetailsEstHeight = DEFAULT_DETAILS_EST_HEIGHT,\n overscan = DEFAULT_OVERSCAN,\n ...options\n}: UseTMDataGridOptions<TData>): TMDataGridApi<TData> {\n // The one place `editing` is unpacked - the engine and the flags keep their\n // own vocabulary (`editMode`, `onEditCommit`), so the mapping lives here.\n const editMode = editing?.mode;\n const editDraft = editing?.draft === true;\n\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 enableRowNumbers,\n selectionMode,\n showSelectedBackground,\n cellSelection,\n editing,\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 // Row mode's Save sits at the end of the row - the lane is its chrome. It\n // also appears wherever the trash can has somewhere to report to, and\n // always under `draft`, where it is the change marker and the per-row\n // revert - with or without `onSaveDrafts`, since the per-row fallback is a\n // first-class configuration.\n const editColumnEnabled =\n editing !== undefined &&\n (editing.mode === \"row\" || editDraft || editing.onRowDelete !== undefined);\n\n // The generated lanes bake `meta.label` into their definitions, so the memo\n // depends on the 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 const editColumnLabel = labels.editColumnLabel;\n const rowNumberColumnLabel = labels.rowNumberColumnLabel;\n const rowNumbersEnabled = features.rowNumbers;\n // A draft lane holds three controls (state icon, undo, trash) where the\n // rest hold two - it gets the wider track.\n const editWideLane = editDraft;\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 // The gutter sits outside everything, the way a spreadsheet's does.\n ...(rowNumbersEnabled\n ? [createRowNumberColumn<TData>(rowNumberColumnLabel)]\n : []),\n ...(selectColumnEnabled\n ? [createSelectColumn<TData>(selectColumnLabel)]\n : []),\n ...(groupColumnEnabled ? [createGroupColumn<TData>(groupColumnLabel)] : []),\n ...(detailsColumnEnabled\n ? [createDetailsColumn<TData>(detailsColumnLabel)]\n : []),\n ...base,\n // Last and pinned right - the row's Save belongs at the end of the row.\n ...(editColumnEnabled\n ? [createEditColumn<TData>(editColumnLabel, editWideLane)]\n : []),\n ];\n }, [\n options.columns,\n rowNumbersEnabled,\n selectColumnEnabled,\n detailsColumnEnabled,\n groupColumnEnabled,\n editColumnEnabled,\n editWideLane,\n rowNumberColumnLabel,\n selectColumnLabel,\n groupColumnLabel,\n detailsColumnLabel,\n editColumnLabel,\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 // Realigned against the ids this render is about to construct - lanes\n // included - so a column removed between deploys does not leave a ghost\n // sort, filter or width behind.\n const [persistedState] = useState(() =>\n readPersistedState(persist, collectLeafColumnIds(columns)),\n );\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 // Current grouping state, feeding the tree column's entry in a controlled\n // `columnVisibility` (below). A ref, not state: it is only read while\n // building the options, and the store change that updates it re-renders the\n // hook anyway. A controlled `grouping` takes precedence over the persisted\n // one; grouping held in an external atom is not readable here and is\n // corrected by the effect below with one extra write on mount.\n const groupingActiveRef = useRef(\n (options.state?.grouping ?? initialGrouping).length > 0,\n );\n\n // Removes keys set to `undefined` before TanStack writes them into the\n // slice atoms; such a key means the slice is not controlled.\n const consumerState = withoutUndefinedSlices(options.state);\n\n // A controlled `columnVisibility` replaces the whole map on every options\n // sync, including the grid's own entries, so the tree column's entry must be\n // re-applied here. Entries for the control columns are removed, as they are\n // for `initialState`: their visibility follows the feature options, not the\n // visibility map.\n const controlledColumnVisibility = consumerState?.columnVisibility;\n const requestedState =\n consumerState !== undefined && controlledColumnVisibility !== undefined\n ? {\n ...consumerState,\n columnVisibility: {\n ...withoutControlColumnVisibility(controlledColumnVisibility),\n ...(groupColumnEnabled\n ? { [GROUP_COLUMN_ID]: groupingActiveRef.current }\n : {}),\n },\n }\n : consumerState;\n\n // Controlled state is synced to the table on every render and compared by\n // identity, so a `state` object built in the consumer's render body would\n // cause an infinite render loop. Unchanged slices are forwarded with the\n // previous render's identity instead - see controlledState.ts.\n const controlledStateRef = useRef<Partial<TableState<TMDataGridFeatures>>>(\n undefined,\n );\n // Exception: the grouping workaround below republishes `columnOrder` and\n // `columnVisibility` with unchanged contents and a new identity to repair\n // table-core's missing memo deps - the exact write stabilization cancels.\n // After it runs, one render forwards the controlled state unstabilized so\n // the new identities reach the atoms. A single render cannot loop.\n const republishControlledStateRef = useRef(false);\n const controlledState = republishControlledStateRef.current\n ? requestedState\n : stabilizeControlledState(requestedState, controlledStateRef.current);\n republishControlledStateRef.current = false;\n controlledStateRef.current = controlledState;\n\n const table = useTable({\n columnResizeMode: \"onChange\",\n enableSorting: true,\n enableColumnResizing: true,\n // The quick search's matcher. Fuzzy by default (Q4); `\"contains\"` keeps\n // plain substring matching, and an explicit `globalFilterFn` in the\n // options below overrides both - which also switches the rank ordering\n // off, since it keys off this exact name.\n globalFilterFn:\n options.quickSearchMode === \"contains\"\n ? \"includesString\"\n : \"tmDataGridFuzzy\",\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 // Always a predicate, never the passthrough: TanStack defaults the option\n // to `true` once the feature is registered, and the grid's default is off.\n // Group rows never pin - TanStack builds one on its first child's record,\n // so a pinned group would drag an arbitrary data row's identity to the\n // edge. The consumer's own predicate still decides the data rows.\n enableRowPinning: (row: Row<TMDataGridFeatures, TData>) =>\n !row.getIsGrouped() &&\n (typeof options.enableRowPinning === \"function\"\n ? options.enableRowPinning(row)\n : options.enableRowPinning === true),\n features: tmDataGridFeatures,\n columns: columns as TableOptions<TMDataGridFeatures, TData>[\"columns\"],\n // The stabilized controlled state; `undefined` when nothing is controlled.\n state: controlledState,\n initialState: {\n ...options.initialState,\n ...persistedState,\n columnVisibility: {\n ...withoutControlColumnVisibility({\n ...options.initialState?.columnVisibility,\n ...persistedState.columnVisibility,\n }),\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 ...(rowNumbersEnabled && pinningEnabled ? [ROW_NUMBER_COLUMN_ID] : []),\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 !== ROW_NUMBER_COLUMN_ID &&\n id !== SELECT_COLUMN_ID &&\n id !== DETAILS_COLUMN_ID &&\n id !== GROUP_COLUMN_ID,\n ),\n ],\n // The edit lane mirrors the generated columns on the left: structurally\n // pinned, outermost, re-applied over anything restored.\n right: [\n ...(\n persistedState.columnPinning?.right ??\n options.initialState?.columnPinning?.right ??\n []\n ).filter((id) => id !== EDIT_COLUMN_ID),\n ...(editColumnEnabled && pinningEnabled ? [EDIT_COLUMN_ID] : []),\n ],\n },\n pagination: {\n pageIndex: 0,\n pageSize: 25,\n ...options.initialState?.pagination,\n ...persistedState.pagination,\n },\n },\n });\n\n // The edit engine. Built once per mount; everything it needs later - the\n // table, the mode, the consumer's callbacks - is read through a ref updated\n // every render, so forms created at `begin()` always call the latest\n // `onEditCommit` (the onHighlightedRowChangeRef pattern, applied wholesale).\n const editContextRef = useRef<TMDataGridEditEngineContext>(null as never);\n editContextRef.current = {\n table: table as unknown as TMDataGridTable<TMDataGridRowData>,\n editMode: editMode ?? \"cell\",\n draft: editDraft,\n rowValidators: editing?.rowValidators,\n tableValidators: editing?.tableValidators as\n TMDataGridEditEngineContext[\"tableValidators\"],\n editableColumnIds: editing?.columns,\n isRowEditable:\n editing?.isRowEditable as TMDataGridEditEngineContext[\"isRowEditable\"],\n onEditCommit:\n editing?.onCommit as TMDataGridEditEngineContext[\"onEditCommit\"],\n // The deprecated name still works; the new one wins if both are set.\n onSaveDrafts: (editing?.onSaveDrafts ??\n editing?.onCommitDrafts) as TMDataGridEditEngineContext[\"onSaveDrafts\"],\n newRowDefaults:\n editing?.newRowDefaults as TMDataGridEditEngineContext[\"newRowDefaults\"],\n onRowAdd: editing?.onRowAdd as TMDataGridEditEngineContext[\"onRowAdd\"],\n onRowDelete:\n editing?.onRowDelete as TMDataGridEditEngineContext[\"onRowDelete\"],\n };\n // The engine is erased; the row type comes back on the way out, which is\n // what makes `edit.addRow(values)` check against `TData`.\n const [edit] = useState(\n () =>\n createEditEngine(\n () => editContextRef.current,\n ) as unknown as TMDataGridEditApi<TData>,\n );\n\n // Switching either axis mid-flight drops every draft: the policies disagree\n // about what an open form means, and carrying one across is how a row\n // parked for `saveDrafts` silently commits to the consumer instead.\n const previousEditPolicyRef = useRef({ editMode, editDraft });\n useEffect(() => {\n const previous = previousEditPolicyRef.current;\n if (previous.editMode === editMode && previous.editDraft === editDraft) {\n return;\n }\n previousEditPolicyRef.current = { editMode, editDraft };\n edit.cancelAll();\n }, [editMode, editDraft, edit]);\n\n // Editing without stable ids points every draft at whatever record slides\n // into that index after a sort. Loud, once, in development.\n useEffect(() => {\n if (editing !== undefined && options.getRowId === undefined) {\n console.error(\n \"TMDataGrid: editing requires getRowId - drafts are keyed by row id, and the index fallback names a different record after any sort or filter.\",\n );\n }\n // The check is a mount-time contract, not something to re-run per render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // A controlled slice without its `onXChange` cannot change: TanStack routes\n // every write through the callback, and the next options sync restores the\n // consumer's value. Warned once in development; `initialState` is the option\n // for a starting value.\n useEffect(() => {\n for (const { slice, handler } of findFrozenStateSlices(options)) {\n console.warn(\n `TMDataGrid: state.${slice} is controlled but no ${handler} was passed - the slice cannot change. Add ${handler}, or use initialState.${slice} for a starting value.`,\n );\n }\n // A mount-time contract, like the check above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\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 // Update the ref before any write: it feeds the visibility injection\n // above, and a write below re-renders the hook. With a stale ref the\n // injection would restore the old value on every render. This also\n // corrects the mount value when an external atom owns `grouping`, which\n // the ref's initializer cannot read.\n groupingActiveRef.current = previousGrouping.length > 0;\n\n // The tree column's entry in `initialState` only reaches a slice the\n // table owns. With `columnVisibility` in an external atom the entry is\n // missing, and a missing entry means visible: the tree column would\n // render in an ungrouped grid. The entry is seeded here through the table\n // API instead, so the write reaches whichever store owns the slice. No-op\n // when the entry is already correct. `?.`: an external atom can hold\n // `undefined`.\n if (\n table.store.state.columnVisibility?.[GROUP_COLUMN_ID] !==\n (previousGrouping.length > 0)\n ) {\n table.setColumnVisibility((old) => ({\n ...old,\n [GROUP_COLUMN_ID]: previousGrouping.length > 0,\n }));\n }\n\n const subscription = table.store.subscribe((state) => {\n if (state.grouping === previousGrouping) return;\n previousGrouping = state.grouping;\n // Keeps the entry injected into a controlled `columnVisibility` (see\n // requestedState) in sync with grouping.\n groupingActiveRef.current = state.grouping.length > 0;\n // On a controlled slice the writes below round-trip through the\n // consumer's handler; the next render must forward them unstabilized.\n // See republishControlledStateRef.\n republishControlledStateRef.current = true;\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 matters more here: a drag publishes a\n // new corner on every mouse move, and most of those land on the cell\n // the 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 // The same recipe the mount uses for `initialState`, minus the persisted\n // layer - see the api's JSDoc for why TanStack's own resets cannot do this.\n // Ref-and-stable-wrapper, like the edit engine's context: the recipe reads\n // this render's flags, the callback identity never changes.\n const resetSettingsRef = useRef<() => void>(() => {});\n resetSettingsRef.current = () => {\n const initial = options.initialState;\n const grouping = [...(initial?.grouping ?? [])];\n table.setGrouping(grouping);\n table.setColumnVisibility({\n ...withoutControlColumnVisibility({ ...initial?.columnVisibility }),\n // The tree lane's visibility tracks the grouping, never the user.\n ...(groupColumnEnabled ? { [GROUP_COLUMN_ID]: grouping.length > 0 } : {}),\n });\n table.setColumnSizing({ ...initial?.columnSizing });\n table.setColumnOrder([...(initial?.columnOrder ?? [])]);\n table.setColumnPinning({\n left: [\n ...(rowNumbersEnabled && pinningEnabled ? [ROW_NUMBER_COLUMN_ID] : []),\n ...(selectColumnEnabled && pinningEnabled ? [SELECT_COLUMN_ID] : []),\n ...(groupColumnEnabled && pinningEnabled ? [GROUP_COLUMN_ID] : []),\n ...(detailsColumnEnabled && pinningEnabled ? [DETAILS_COLUMN_ID] : []),\n ...(initial?.columnPinning?.left ?? []).filter(\n (id) =>\n id !== ROW_NUMBER_COLUMN_ID &&\n id !== SELECT_COLUMN_ID &&\n id !== DETAILS_COLUMN_ID &&\n id !== GROUP_COLUMN_ID,\n ),\n ],\n right: [\n ...(initial?.columnPinning?.right ?? []).filter(\n (id) => id !== EDIT_COLUMN_ID,\n ),\n ...(editColumnEnabled && pinningEnabled ? [EDIT_COLUMN_ID] : []),\n ],\n });\n };\n const resetSettings = useCallback(() => resetSettingsRef.current(), []);\n\n // Filled in by `TMDataGrid.Table` on every render, because only the body\n // holds the virtualizer and the current view. Returns `false` until one is\n // mounted, since there is nothing to scroll before then.\n const scrollerRef = useRef<TMDataGridScroller>(() => false);\n const scrollToRow = useCallback(\n (args: TMDataGridScrollToRowArgs) => scrollerRef.current(args),\n [],\n );\n\n return {\n table,\n ui,\n edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\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 const operator = getColumnDefaultOperator(column);\n column.setFilterValue({\n operator,\n value: emptyValueForOperator(operator),\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 data-dg-part=\"filter-pills\"\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 data-dg-part=\"filter-pill\"\n data-column-id={filter.id}\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 // No test id of its own: Mantine types these props as\n // `CloseButtonProps`, which has no room for `data-*`. The pill\n // carries one, and the ✕ is the only button inside it.\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 { useMemo, 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/** What the pager is showing. The read half of {@link TMDataGridPaginationApi}. */\nexport type TMDataGridPaginationState = {\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 /**\n * Whether the pager is slicing anything right now. `false` while a grouping\n * is active, which suspends paging - see `isPagingActive`.\n */\n isPagingActive: boolean;\n /** First and last row number on this page, 1-based, for a range label. */\n from: number;\n to: number;\n};\n\n/** What the pager can do. The write half of {@link TMDataGridPaginationApi}. */\nexport type TMDataGridPaginationActions = {\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 * Pagination state and actions, split into the half you read and the half you\n * call.\n *\n * The split is what makes a partial override possible: a consumer replacing\n * only the range label reads `state` and never touches `actions`, and one\n * replacing only the buttons does the opposite.\n */\nexport type TMDataGridPaginationApi = {\n state: TMDataGridPaginationState;\n actions: TMDataGridPaginationActions;\n};\n\n/**\n * The pre-bound pieces of the built-in pager.\n *\n * Each renders exactly what the default footer renders, already wired to the\n * table and already respecting the suspended-paging state - so a custom layout\n * keeps the parts it likes rather than rebuilding them to look the same.\n */\nexport type TMDataGridPaginationControls = {\n /** \"Rows per page\" and its select. */\n PageSize: () => ReactNode;\n /** The \"1–25 of 300\" range label. */\n Range: () => ReactNode;\n /** The previous/next buttons. */\n Pager: () => ReactNode;\n};\n\n/** What {@link TMDataGridFooterProps.renderPagination} is handed. */\nexport type TMDataGridPaginationSlotArgs = TMDataGridPaginationApi & {\n Controls: TMDataGridPaginationControls;\n};\n\n/**\n * Reads {@link TMDataGridPaginationApi} off a table. The Footer feeds it to the\n * `renderPagination` slot; a pager living outside the Footer can call it with\n * the table from `useTMDataGrid` directly.\n *\n * `Controls` are not here: they are components bound to the grid context, and\n * this function takes only a table.\n */\nexport function getTMDataGridPaginationApi<TData extends RowData>(\n table: TMDataGridTable<TData>,\n isPaging = true,\n): TMDataGridPaginationApi {\n const { pageIndex, pageSize } = table.store.state.pagination;\n const rowCount = table.getRowCount();\n return {\n state: {\n pageIndex,\n pageSize,\n pageCount: table.getPageCount(),\n rowCount,\n canPreviousPage: table.getCanPreviousPage(),\n canNextPage: table.getCanNextPage(),\n isPagingActive: isPaging,\n from: rowCount === 0 ? 0 : pageIndex * pageSize + 1,\n to: Math.min(rowCount, (pageIndex + 1) * pageSize),\n },\n actions: {\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}\n\n/*\n * The three controls are module-scope components on purpose. Defined inside\n * the Footer they would be a new component type on every render, so React\n * would unmount and remount the pager between one render and the next - which\n * detaches the button a click is landing on mid-interaction.\n */\n\nfunction PaginationPageSize({\n pageSizeOptions,\n}: {\n pageSizeOptions: ReadonlyArray<number>;\n}) {\n const { table, features, labels, controlSize } = useTMDataGridContext();\n useSelector(table.store);\n const paging = isPagingActive(table, features);\n const { pageSize } = table.store.state.pagination;\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 <Group gap=\"xs\" wrap=\"nowrap\">\n {/* `span`, here and in every other label the grid renders: Mantine's\n Text is a `<p>` by default, and a grid dropped into prose - a docs\n page, a CMS body, Mantine's own Typography - picks up that context's\n `p` margins. A bottom margin on a flex item shifts its border box up\n off centre, which is how the pager came to sit a half-line below its\n own label. Chrome labels are not prose. */}\n <Text span 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-dg-part=\"page-size\"\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}\n\nfunction PaginationRange() {\n const { table, features, labels, controlSize } = useTMDataGridContext();\n useSelector(table.store);\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\n return (\n <Text span size={controlSize} c=\"dimmed\" data-dg-part=\"page-range\">\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}\n\nfunction PaginationPager() {\n const { table, features, labels } = useTMDataGridContext();\n useSelector(table.store);\n const paging = isPagingActive(table, features);\n\n return (\n <Group gap={4} wrap=\"nowrap\">\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n aria-label={labels.previousPage}\n data-dg-part=\"page-prev\"\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 data-dg-part=\"page-next\"\n disabled={!paging || !table.getCanNextPage()}\n onClick={() => table.nextPage()}\n >\n <ChevronRightIcon size={18} stroke={1.6} />\n </ActionIcon>\n </Group>\n );\n}\n\nexport type TMDataGridFooterProps = {\n pageSizeOptions?: ReadonlyArray<number>;\n /**\n * Replaces the built-in pager, and is handed the pieces of it.\n *\n * ```tsx\n * <TMDataGrid.Footer\n * renderPagination={({ state, actions, Controls }) => (\n * <Group>\n * <Controls.PageSize />\n * <MyJumpToPage page={state.pageIndex} onJump={actions.setPageIndex} />\n * <Controls.Pager />\n * </Group>\n * )}\n * />\n * ```\n */\n renderPagination?: (args: TMDataGridPaginationSlotArgs) => ReactNode;\n};\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\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 = DEFAULT_PAGE_SIZE_OPTIONS,\n renderPagination,\n}: TMDataGridFooterProps) {\n const { table, features, labels } = useTMDataGridContext();\n useSelector(table.store);\n\n // Bound once per option list rather than per render, so the controls keep\n // their identity and the elements they render keep theirs.\n const Controls = useMemo<TMDataGridPaginationControls>(\n () => ({\n PageSize: () => <PaginationPageSize pageSizeOptions={pageSizeOptions} />,\n Range: PaginationRange,\n Pager: PaginationPager,\n }),\n [pageSizeOptions],\n );\n\n if (!getGridCapabilities(table, features).canPaginate) return null;\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\n if (renderPagination) {\n const { state, actions } = getTMDataGridPaginationApi(table, paging);\n return (\n <div data-dg-part=\"footer\" className={classes.footer}>\n {renderPagination({ state, actions, Controls })}\n </div>\n );\n }\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\n data-dg-part=\"footer\"\n className={classes.footer}\n data-paging-suspended={!paging}\n >\n {/* The default render is the controls in order - which is what makes\n `renderPagination` a rearrangement rather than a rebuild. */}\n <Controls.PageSize />\n <Controls.Range />\n <Controls.Pager />\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 data-dg-part=\"search\"\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 data-dg-part=\"search-clear\"\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","/* 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/* A filtered column reads as active: its rows are a subset, and nothing else in\n the header says so once the filter panel is closed. A sorted one is not\n tinted - the arrow, pinned visible for as long as the sort lasts, already\n says which column sorts and which way. */\n.headerCellFiltered .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/* See the sort ActionIcon: an unsorted column's arrow is an invitation, not a\n state, so it sits back until the pointer is on it. */\n.sortAction[data-sorted=\"false\"] {\n opacity: 0.55;\n}\n\n.sortAction[data-sorted=\"false\"]:hover {\n opacity: 1;\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/** One column's body cells that are currently in the DOM. */\nfunction mountedCells(\n container: HTMLElement,\n columnId: string,\n): NodeListOf<HTMLElement> {\n const id = CSS.escape(columnId);\n return container.querySelectorAll<HTMLElement>(\n `[role=\"cell\"][data-column-id=\"${id}\"],` +\n `[role=\"gridcell\"][data-column-id=\"${id}\"]`,\n );\n}\n\n/**\n * Whether this column has any body cell in the DOM to measure.\n *\n * A caller sizing a column on its own schedule rather than from a gesture has\n * to ask: the virtualizer mounts its first rows a render *after* the grid\n * itself mounts, and a measurement taken before that fits the header alone.\n */\nexport function hasMountedCells(\n container: HTMLElement,\n columnId: string,\n): boolean {\n return mountedCells(container, columnId).length > 0;\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. With no rows mounted at all the\n * header is the only thing left to measure, which is a width that fits the\n * title and nothing else - see `hasMountedCells`.\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 for (const cell of mountedCells(container, columnId)) {\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-column-id=\"${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, isGeneratedColumn } 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/**\n * Puts the generated lanes back on the outside of both pinned lanes: the ones\n * on the left before every consumer column, the edit lane after all of them.\n *\n * `column.pin(\"right\")` appends, so pinning a column right would otherwise drop\n * it outside the edit lane, so the row's Save and Delete would no longer be\n * last in the row. Pinning left appends too, which is already correct there,\n * but the same pass keeps both lanes in place whatever a consumer writes into\n * `columnPinning` directly.\n *\n * Relative order is preserved inside each part, so a user's own arrangement of\n * the pinned columns survives.\n */\nexport function keepGeneratedColumnsOutermost(\n pinning: ColumnPinningState,\n): ColumnPinningState {\n const generated = (id: string) => isGeneratedColumn(id);\n return {\n left: [\n ...pinning.left.filter(generated),\n ...pinning.left.filter((id) => !generated(id)),\n ],\n right: [\n ...pinning.right.filter((id) => !generated(id)),\n ...pinning.right.filter(generated),\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 keepGeneratedColumnsOutermost,\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\n/** The table as the header cell sees it, after the context type erasure. */\ntype TMDataGridTableInstance = ReturnType<\n typeof useTMDataGridContext\n>[\"table\"];\n\nexport type TMDataGridHeader = Header<\n TMDataGridFeatures,\n TMDataGridRowData,\n unknown\n>;\n\n/** What {@link TMDataGridColumnMenuItemsRenderer} is handed. */\nexport type TMDataGridColumnMenuItemsArgs = {\n column: TMDataGridHeader[\"column\"];\n table: TMDataGridTableInstance;\n /**\n * The items the grid would have rendered, in order, dividers included.\n * Return them to keep the built-in menu, splice around them to extend it,\n * or drop them to replace it.\n */\n internalItems: Array<ReactNode>;\n};\n\n/**\n * Replaces a column's menu contents. Returning an empty list leaves the column\n * with no menu button at all, the same as a column whose every feature is off.\n */\nexport type TMDataGridColumnMenuItemsRenderer = (\n args: TMDataGridColumnMenuItemsArgs,\n) => Array<ReactNode>;\n\nexport function TMDataGridHeaderCell({\n header,\n layout,\n renderColumnMenuItems,\n}: {\n header: TMDataGridHeader;\n layout: TMDataGridColumnLayout;\n renderColumnMenuItems?: TMDataGridColumnMenuItemsRenderer;\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 // `pin(\"right\")` appends, which would leave the column outside the edit\n // lane. Normalising after the pin rather than writing the lane by hand\n // keeps TanStack's own handling of a header group's leaves.\n table.setColumnPinning(keepGeneratedColumnsOutermost);\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 // The handback: the consumer is given what the grid would have rendered and\n // returns what should be. Trimmed again afterwards, because a consumer that\n // drops the last group can leave a divider stranded the same way.\n const finalItems = renderColumnMenuItems\n ? [...renderColumnMenuItems({ column, table, internalItems: menuItems })]\n : menuItems;\n while (finalItems.length > 0 && isDivider(finalItems.at(-1))) {\n finalItems.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 && finalItems.length > 0 && !isControlColumn(column.id);\n\n const cellClass = [\n classes.headerCell,\n canSort ? classes.headerCellSortable : \"\",\n // Only the filter tints the title. `data-active` below stays\n // sorted-or-filtered - it is the queryable state, not the styling hook.\n isFiltered ? classes.headerCellFiltered : \"\",\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-dg-part=\"header\"\n // The same coordinate the body, summary and entry cells carry, so one\n // selector reaches a column's header and its cells alike.\n data-column-id={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\" announces that this\n // header sorts, which is wrong on one that does not.\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 data-dg-part=\"header-filter\"\n data-column-id={column.id}\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} ${classes.sortAction}`}\n data-pinned-visible={isSorted}\n // The arrow is the only sort indicator now that the title no\n // longer tints, so it takes the colour while the sort holds. On\n // an unsorted column it is only the hover affordance, and stays a\n // faded grey so the two are not confused.\n data-sorted={isSorted}\n variant=\"subtle\"\n color={isSorted ? undefined : \"gray\"}\n size=\"xs\"\n aria-label={labels.sortColumn(label)}\n data-dg-part=\"header-sort\"\n data-column-id={column.id}\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-dg-part=\"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 data-dg-part=\"header-menu\"\n data-column-id={column.id}\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 {finalItems}\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. `finalItems` 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 {finalItems}\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 { useStore } from \"@tanstack/react-form\";\nimport { useLayoutEffect, useRef, type RefObject } from \"react\";\nimport { firstErrorText, type TMDataGridEditField } from \"../../core/editEngine\";\n\n/** The field's live value - one subscription, on the field's own store. */\nexport function useFieldValue(field: TMDataGridEditField): unknown {\n return useStore(field.store, (state) => state.value as unknown);\n}\n\n/** The field's first error, for the Mantine input's `error` prop. */\nexport function useFieldError(field: TMDataGridEditField): string | undefined {\n return useStore(field.store, (state) =>\n firstErrorText(state.meta.errors as ReadonlyArray<unknown>),\n );\n}\n\n/** Select-all on focus - F2/Enter open with the value ready to replace. */\nexport function selectAllOnFocus(event: { currentTarget: unknown }): void {\n const target = event.currentTarget;\n if (target instanceof HTMLInputElement) target.select();\n}\n\n/**\n * Keeps the caret where it was typed when the value comes back changed.\n *\n * A column with `meta.edit.mapValue` writes something other than what the\n * input holds, so React reassigns `input.value` - and the browser collapses\n * the selection to the end of the field. Typing into the middle of a value\n * then jumped to the end on every keystroke.\n *\n * `remember` records the caret as the change is handed over; the effect puts\n * it back once the mapped value has rendered, shifted by however much the map\n * changed the length so a mask that inserts or strips characters keeps the\n * caret beside the same text. Without a map nothing is recorded twice and the\n * restore is a no-op, so an unmapped column is untouched.\n */\nexport function useCaretKeeper(): {\n inputRef: RefObject<HTMLInputElement | null>;\n remember: (input: HTMLInputElement) => void;\n} {\n const inputRef = useRef<HTMLInputElement | null>(null);\n const caret = useRef<{ position: number; length: number } | null>(null);\n\n useLayoutEffect(() => {\n const pending = caret.current;\n const input = inputRef.current;\n caret.current = null;\n if (pending === null || input === null) return;\n const shift = input.value.length - pending.length;\n const next = Math.max(\n 0,\n Math.min(pending.position + shift, input.value.length),\n );\n input.setSelectionRange(next, next);\n });\n\n return {\n inputRef,\n remember: (input) => {\n if (input.selectionStart === null) return;\n caret.current = {\n position: input.selectionStart,\n length: input.value.length,\n };\n },\n };\n}\n","import { Checkbox } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/** The built-in editor for `meta.type: \"boolean\"` - a focused checkbox. */\nexport function TMDataGridBooleanEditor({\n field,\n column,\n size,\n}: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n return (\n <Checkbox\n size={size}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n checked={value === true}\n onChange={(event) => field.handleChange(event.currentTarget.checked)}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { TextInput } from \"@mantine/core\";\nimport { useRef } from \"react\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/**\n * The built-in editor for `meta.type: \"date\"` - the native\n * `<input type=\"date\">` styled by Mantine, no `@mantine/dates` involved. A\n * consumer wanting a real picker plugs one in through `meta.edit.editor`.\n */\nexport function TMDataGridDateEditor({\n field,\n column,\n size,\n}: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n // The cell's original shape decides what the editor writes back: a `Date`\n // cell keeps getting Dates, an ISO-string cell keeps getting strings -\n // decided once at open, so clearing and retyping cannot flip the type.\n const writesDates = useRef(value instanceof Date);\n\n const text =\n value instanceof Date\n ? value.toLocaleDateString(\"sv-SE\")\n : typeof value === \"string\"\n ? value.slice(0, 10)\n : \"\";\n\n return (\n <TextInput\n size={size}\n w=\"100%\"\n type=\"date\"\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n value={text}\n onChange={(event) => {\n const next = event.currentTarget.value;\n if (next === \"\") {\n field.handleChange(null);\n return;\n }\n field.handleChange(\n writesDates.current ? new Date(`${next}T00:00:00`) : next,\n );\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { MultiSelect } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport {\n optionsToComboboxData,\n resolveColumnOptions,\n} from \"../../core/columnOptions\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/**\n * The built-in editor for `meta.type: \"multiSelect\"` - cells holding string\n * arrays. Never commits on pick: building a set takes several, so the commit\n * stays on Enter/blur like a text edit.\n */\nexport function TMDataGridMultiSelectEditor({\n field,\n column,\n row,\n table,\n size,\n}: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n return (\n <MultiSelect\n size={size}\n w=\"100%\"\n searchable\n comboboxProps={{ withinPortal: false }}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n data={optionsToComboboxData(\n resolveColumnOptions({ table, column, row, fallback: \"faceted\" }),\n )}\n value={Array.isArray(value) ? value.map(String) : []}\n onChange={(next) => field.handleChange(next)}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { NumberInput } from \"@mantine/core\";\nimport { useState } from \"react\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport {\n selectAllOnFocus,\n useCaretKeeper,\n useFieldError,\n useFieldValue,\n} from \"./editorShared\";\n\n/** The built-in editor for `meta.type: \"number\"`. */\nexport function TMDataGridNumberEditor({ field, column, size }: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n const { inputRef, remember } = useCaretKeeper();\n /**\n * The last text Mantine reported instead of a number - \"-\" or \"1e\" on the\n * way to one. Held so a half-typed number stays on screen while the field\n * itself holds no value.\n */\n const [typed, setTyped] = useState<string | null>(null);\n // The field is the source of truth: the text survives only while it still\n // describes what the field holds, so a write from outside the editor -\n // `edit.setCellValue`, a revert - replaces it rather than being masked.\n const parsedTyped = typed === null || typed === \"\" ? null : Number(typed);\n const textDescribesField = Number.isFinite(parsedTyped)\n ? parsedTyped === value\n : value === null;\n return (\n <NumberInput\n ref={inputRef}\n size={size}\n w=\"100%\"\n onFocus={selectAllOnFocus}\n hideControls\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n value={\n typed !== null && textDescribesField\n ? typed\n : typeof value === \"number\"\n ? value\n : \"\"\n }\n onChange={(next) => {\n if (inputRef.current !== null) remember(inputRef.current);\n if (typeof next === \"number\") {\n setTyped(null);\n field.handleChange(next);\n return;\n }\n // Mantine reports a number once one can be parsed and a string while\n // it cannot: \"\" for an empty cell, partial input on the way to a\n // number. Anything that does not parse leaves the field empty rather\n // than `NaN` - which is a number to every validator and would commit\n // as one, with no message a user could act on.\n setTyped(next);\n const parsed = Number(next);\n field.handleChange(\n next !== \"\" && Number.isFinite(parsed) ? parsed : null,\n );\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { Select } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport {\n optionsToComboboxData,\n resolveColumnOptions,\n} from \"../../core/columnOptions\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/**\n * The built-in editor for `meta.type: \"select\"`. Options come from the same\n * `meta.options` the filter panel reads - with the row in hand, so a\n * function source can depend on the record being edited.\n */\nexport function TMDataGridSelectEditor({\n field,\n column,\n row,\n table,\n size,\n commit,\n}: TMDataGridEditorArgs) {\n const { labels, features } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n return (\n <Select\n size={size}\n w=\"100%\"\n searchable\n // Inside the cell, so picking an option is not a click-away - the same\n // reason the filter panel keeps its dropdowns unportalled.\n comboboxProps={{ withinPortal: false }}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n data={optionsToComboboxData(\n resolveColumnOptions({ table, column, row, fallback: \"faceted\" }),\n )}\n value={typeof value === \"string\" ? value : null}\n onChange={(next) => {\n field.handleChange(next);\n // Sheets semantics under `\"cell\"`: a pick is the edit, so it commits.\n // The confirming modes leave the draft for their explicit commit.\n if (next !== null && features.editMode === \"cell\") void commit();\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { TextInput } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport {\n selectAllOnFocus,\n useCaretKeeper,\n useFieldError,\n useFieldValue,\n} from \"./editorShared\";\n\n/** The built-in editor for `meta.type: \"string\"` (and the default). */\nexport function TMDataGridStringEditor({ field, column, size }: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n const { inputRef, remember } = useCaretKeeper();\n return (\n <TextInput\n ref={inputRef}\n size={size}\n w=\"100%\"\n onFocus={selectAllOnFocus}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(event) => {\n remember(event.currentTarget);\n field.handleChange(event.currentTarget.value);\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { ActionIcon } from \"@mantine/core\";\nimport { FieldApi } from \"@tanstack/react-form\";\nimport type { Cell, Row } from \"@tanstack/react-table\";\nimport {\n type ComponentType,\n type FocusEvent,\n type KeyboardEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport { type TMDataGridRowData, useTMDataGridContext } from \"../TMDataGridContext\";\nimport {\n getEditFieldName,\n normalizeFieldValidate,\n type TMDataGridEditField,\n type TMDataGridEditorArgs,\n type TMDataGridEditValueMap,\n} from \"../core/editEngine\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\nimport { CheckIcon, CloseIcon } from \"./icons\";\nimport { TMDataGridBooleanEditor } from \"./editors/TMDataGridBooleanEditor\";\nimport { TMDataGridDateEditor } from \"./editors/TMDataGridDateEditor\";\nimport { TMDataGridMultiSelectEditor } from \"./editors/TMDataGridMultiSelectEditor\";\nimport { TMDataGridNumberEditor } from \"./editors/TMDataGridNumberEditor\";\nimport { TMDataGridSelectEditor } from \"./editors/TMDataGridSelectEditor\";\nimport { TMDataGridStringEditor } from \"./editors/TMDataGridStringEditor\";\n\nconst BUILT_IN_EDITORS: Record<\n string,\n ComponentType<TMDataGridEditorArgs>\n> = {\n string: TMDataGridStringEditor,\n number: TMDataGridNumberEditor,\n boolean: TMDataGridBooleanEditor,\n date: TMDataGridDateEditor,\n select: TMDataGridSelectEditor,\n multiSelect: TMDataGridMultiSelectEditor,\n};\n\n/** How an editor closed, for the table to decide where the focus goes. */\nexport type TMDataGridCellEditorClose =\n | { committed: true; via: \"enter\" | \"tab\" | \"shift-tab\" | \"pick\" }\n | { committed: false; via: \"escape\" }\n /** `cellConfirm`: the editor closed, the draft stays, waiting for its ✓. */\n | { committed: false; via: \"defer-tab\" | \"defer-shift-tab\" };\n\n/**\n * The host an editing cell mounts - it owns the field, the keys and the blur\n * policy; the editor inside it (a built-in picked by `meta.type`, or the\n * column's `meta.edit.editor`) owns the input.\n *\n * The form outlives this component by design: scrolling the row away\n * unmounts the host, and the form in the engine's map keeps the draft.\n */\nexport function TMDataGridCellEditor({\n cell,\n row,\n takeSeedText,\n onClose,\n inEntryBlock = false,\n}: {\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n row: Row<TMDataGridFeatures, TMDataGridRowData>;\n /** Consumes the pending type-to-edit seed, when typing opened this editor. */\n takeSeedText: () => string | undefined;\n /** After the editor closed itself - the table moves the focus. */\n onClose: (args: TMDataGridCellEditorClose) => void;\n /**\n * Hosted by the entry block rather than a body cell. An entry row is\n * row-shaped in every mode: Enter enters the whole row, Tab stays the\n * browser's - walking the row's own inputs the way row mode's do - and\n * focus leaving decides nothing, because the ✓ is the decision.\n */\n inEntryBlock?: boolean;\n}) {\n const { table, edit, features, labels, controlSize } = useTMDataGridContext();\n // Row mode mounts one host per editable cell of the row; every key that\n // commits or cancels acts on the whole row's form either way, but Tab must\n // stay the browser's (it walks the row's inputs) and blur must do nothing\n // (focus moves between this row's own editors). The entry block is built\n // the same way, in every mode, so it follows the same two rules.\n const isRowShaped = features.editMode === \"row\" || inEntryBlock;\n const column = cell.column;\n const form = edit.getForm(row.id);\n const fieldName = getEditFieldName(column);\n const [seedText] = useState(() => takeSeedText());\n\n /**\n * The column's current `mapValue`, for the field below to read at write\n * time. No dependency array, so it re-registers every render: the field is\n * created once and kept, and a map redeclared per render would otherwise be\n * frozen at the one this editor opened with. Declared above the seed effect,\n * which writes through the same field.\n */\n const mapValueRef = useRef<TMDataGridEditValueMap | undefined>(undefined);\n useEffect(() => {\n mapValueRef.current = column.columnDef.meta?.edit?.mapValue;\n });\n\n // One FieldApi per open editor, over the row's long-lived form. Created\n // imperatively (the documented core usage) because the form was too.\n const [field] = useState<TMDataGridEditField>(() => {\n const created = new FieldApi({\n form: form as never,\n name: fieldName as never,\n validators: normalizeFieldValidate(\n column.columnDef.meta?.edit?.validate,\n ) as never,\n }) as unknown as TMDataGridEditField;\n\n // `meta.edit.mapValue` lives here rather than in each editor, so one\n // implementation covers the six built-ins, any `meta.edit.editor` and the\n // type-to-edit seed below - everything that writes through this field.\n // Form's own paths (validation, reset, `form.setFieldValue`) hold the\n // form, not this field, so a cleared cell and a rolled-back draft stay\n // exactly what the engine wrote.\n const write = created.handleChange.bind(created);\n created.handleChange = ((updater: unknown) => {\n const map = mapValueRef.current;\n const previous = created.state.value as unknown;\n // Form takes a value or an updater; resolve one so `mapValue` is only\n // ever handed the value itself.\n const value =\n typeof updater === \"function\"\n ? (updater as (prev: unknown) => unknown)(previous)\n : updater;\n write(\n (map === undefined\n ? value\n : map({ value, previous, row, column, table })) as never,\n );\n }) as typeof created.handleChange;\n\n return created;\n });\n useEffect(() => field.mount(), [field]);\n\n // Type-to-edit: the seed replaces the value, as it does in a spreadsheet.\n // Only for the types where keystrokes are the input.\n useEffect(() => {\n if (seedText === undefined) return;\n const type = column.columnDef.meta?.type ?? \"string\";\n if (type === \"string\") {\n field.handleChange(seedText as never);\n } else if (type === \"number\") {\n const seeded = Number(seedText);\n if (Number.isFinite(seeded)) field.handleChange(seeded as never);\n }\n // Once, at open.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const closingRef = useRef(false);\n\n const commitAndClose = async (\n via: \"enter\" | \"tab\" | \"shift-tab\" | \"pick\",\n ): Promise<boolean> => {\n if (closingRef.current) return false;\n const ok = await edit.commit(row.id);\n if (ok && !closingRef.current) {\n closingRef.current = true;\n onClose({ committed: true, via });\n }\n return ok;\n };\n\n const cancelAndClose = () => {\n if (closingRef.current) return;\n closingRef.current = true;\n edit.cancel(row.id);\n onClose({ committed: false, via: \"escape\" });\n };\n\n /**\n * `cellConfirm`: the key closes the editor and leaves the draft where it\n * is, waiting for the ✓. Moving along the row is not a decision about it;\n * Enter is, and commits instead.\n */\n const deferAndClose = (via: \"defer-tab\" | \"defer-shift-tab\") => {\n if (closingRef.current) return;\n closingRef.current = true;\n edit.deactivate();\n onClose({ committed: false, via });\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n // Enter is OK, in every mode: the row's form submits and has to pass\n // validation. Where a commit *goes* is `editing.draft`'s business, not\n // this key's - out to the consumer, or into the draft store.\n void commitAndClose(\"enter\");\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancelAndClose();\n } else if (event.key === \"Tab\" && !isRowShaped) {\n event.preventDefault();\n event.stopPropagation();\n // `cellConfirm` is the one mode where leaving a cell decides nothing:\n // the caret moves on and the draft waits for its ✓.\n if (features.editMode === \"cellConfirm\") {\n deferAndClose(event.shiftKey ? \"defer-shift-tab\" : \"defer-tab\");\n } else {\n void commitAndClose(event.shiftKey ? \"shift-tab\" : \"tab\");\n }\n }\n };\n\n /**\n * Focus left the editor entirely - a click somewhere else. Under `\"cell\"`\n * that commits (Sheets): a row the user has walked away from is a row they\n * are done typing into, and where the commit lands is `editing.draft`'s\n * business. A commit blocked by validation keeps the form and its invalid\n * marker, with the editor closed.\n */\n const handleBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (closingRef.current) return;\n // Row mode and the entry block: the row's other editors are outside this\n // host, and focus moving between them is not leaving the edit. Blur means\n // nothing there; the lane's buttons and the keys end the edit.\n if (isRowShaped) return;\n const next = event.relatedTarget;\n if (next instanceof Node && event.currentTarget.contains(next)) return;\n closingRef.current = true;\n if (features.editMode === \"cellConfirm\") {\n // The draft stays, dirty-marked, waiting for its ✓.\n edit.deactivate();\n return;\n }\n void edit.commit(row.id).then((ok) => {\n if (!ok) edit.deactivate();\n });\n };\n\n if (form === undefined || fieldName === null) return null;\n\n const args: TMDataGridEditorArgs = {\n field,\n form,\n cell,\n row,\n column,\n table,\n commit: () => commitAndClose(\"pick\"),\n cancel: cancelAndClose,\n size: controlSize,\n seedText,\n };\n\n const Editor =\n column.columnDef.meta?.edit?.editor ??\n BUILT_IN_EDITORS[column.columnDef.meta?.type ?? \"string\"] ??\n TMDataGridStringEditor;\n\n return (\n <div\n className={classes.cellEditor}\n data-dg-part=\"editor\"\n data-row-id={row.id}\n data-column-id={column.id}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n // The cell underneath listens for selection gestures; a click inside\n // the editor is about the editor.\n onMouseDown={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n >\n <Editor {...args} />\n {/* cellConfirm's chrome: the draft only commits through the ✓ (or\n Enter), so the pair sits right beside the input. */}\n {features.editMode === \"cellConfirm\" && (\n <div className={classes.cellEditorActions}>\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"green\"\n aria-label={labels.confirmEdit}\n data-dg-part=\"editor-confirm\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => void commitAndClose(\"pick\")}\n >\n <CheckIcon size={14} stroke={2} />\n </ActionIcon>\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"gray\"\n aria-label={labels.cancelEdit}\n data-dg-part=\"editor-cancel\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={cancelAndClose}\n >\n <CloseIcon size={14} stroke={2} />\n </ActionIcon>\n </div>\n )}\n </div>\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 */\nexport const 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 * Puts the caret inside a mounted editor host.\n *\n * `editor-input` is the part a built-in publishes for exactly this, and the\n * first focusable descendant is the fallback that makes a custom editor work\n * without publishing anything. The grid places the caret this way rather than\n * leaving it to the editor, because an editor is free not to bother - and then\n * the cell opened with the caret still outside it.\n */\nexport function focusEditorContent(editor: HTMLElement): void {\n const target =\n editor.querySelector<HTMLElement>('[data-dg-part=\"editor-input\"]') ??\n editor.querySelector<HTMLElement>(FOCUSABLE_IN_CELL);\n target?.focus();\n}\n","import {\n flexRender,\n useTable,\n type Column,\n type Row,\n} from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useLayoutEffect, useMemo, useRef } from \"react\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport sticky from \"./sticky.module.css\";\nimport { type TMDataGridRowData, useTMDataGridContext } from \"../TMDataGridContext\";\nimport {\n getColumnAlign,\n isColumnEditableForRow,\n isControlColumn,\n} from \"../core/columnUtils\";\nimport type { TMDataGridEditApi } from \"../core/editEngine\";\nimport { focusEditorContent } from \"../core/editorFocus\";\nimport {\n tmDataGridFeatures,\n type TMDataGridFeatures,\n} from \"../useTMDataGrid\";\nimport { TMDataGridCellEditor } from \"./TMDataGridCellEditor\";\nimport { EDIT_COLUMN_ID } from \"./TMDataGridEditColumn\";\nimport type { TMDataGridColumnLayout } from \"./TMDataGridTable\";\n\ntype ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\n\n/**\n * Whether an entry cell edits. `edit.canEditCell` asks the main table for\n * the row, and an entry row is precisely not there yet - so the structural\n * half of the same rule is applied to the entry table's own row.\n */\nfunction isEntryCellEditable(\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n column: ErasedColumn,\n edit: TMDataGridEditApi,\n): boolean {\n if (!edit.isColumnEditable(column)) return false;\n return isColumnEditableForRow(column, row);\n}\n\n/**\n * The sticky entry block - one row of open editors per `edit.addRow()`,\n * pinned under the header. The one place stickiness is genuinely required:\n * an existing row that scrolls away has a place to scroll back to, a row\n * being typed into does not exist anywhere else.\n *\n * A second, tiny table instance over the new rows' seed values - same\n * columns, its own `useTable`, no sorting or filtering ever exercised - so\n * these are real `Cell`s and the editor host, the typed editors and the\n * validators all apply unchanged. The forms live in the same engine map as\n * every other draft, keyed by their temporary ids.\n *\n * Enter commits the entry - `onRowAdd`, or a park under `editing.draft`,\n * where `saveDrafts` reports it in `created`; Escape discards it. The edit\n * lane, when present, offers the same pair as buttons.\n */\nexport function TMDataGridEntryRows({\n orderedColumns,\n layoutFor,\n rowHeight,\n}: {\n orderedColumns: ReadonlyArray<ErasedColumn>;\n layoutFor: (columnId: string) => TMDataGridColumnLayout;\n rowHeight: number;\n}) {\n const { table, edit, features } = useTMDataGridContext();\n const newRows = useSelector(edit.store, (state) => state.newRows);\n // The reopen gesture: `begin` on a committed entry row flips it back to\n // editors and names the cell double-clicked - where the caret goes.\n const activeEntry = useSelector(edit.store, (state) =>\n state.active !== null &&\n state.newRows.some(\n (newRow) => newRow.tempId === state.active?.rowId && !newRow.committed,\n )\n ? state.active\n : null,\n );\n const blockRef = useRef<HTMLDivElement>(null);\n /** The entry row the caret has already been placed in. */\n const focusedTempIdRef = useRef<string | null>(null);\n /** The reopen target (`rowId:columnId`) the caret has already landed in. */\n const focusedActiveRef = useRef<string | null>(null);\n\n /**\n * The caret goes into a row the moment `edit.addRow()` opens it, landing in\n * its first editable cell - the same placement the main table makes for a\n * row opened by a gesture, and made here for the same reason: an editor is\n * free not to focus itself, and then a new row appeared with the caret\n * still outside it.\n */\n useLayoutEffect(() => {\n const newest = newRows.at(-1)?.tempId;\n if (newest === undefined) {\n focusedTempIdRef.current = null;\n return;\n }\n if (focusedTempIdRef.current === newest) return;\n const block = blockRef.current;\n if (block === null) return;\n const editor = block.querySelector<HTMLElement>(\n `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(newest)}\"]`,\n );\n // Not mounted yet; the next render tries again, as the table's does.\n if (editor === null) return;\n focusedTempIdRef.current = newest;\n focusEditorContent(editor);\n });\n\n /**\n * The caret for a reopen: `begin` on a committed row re-arms its editors\n * and the double-clicked cell's editor should hold the caret, not the\n * row's first. Keyed separately from the add effect above - the row was\n * already focused once when it was added.\n */\n useLayoutEffect(() => {\n if (activeEntry === null) {\n focusedActiveRef.current = null;\n return;\n }\n const key = `${activeEntry.rowId}:${activeEntry.columnId ?? \"\"}`;\n if (focusedActiveRef.current === key) return;\n const block = blockRef.current;\n if (block === null) return;\n const editor = block.querySelector<HTMLElement>(\n activeEntry.columnId !== null\n ? `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(activeEntry.rowId)}\"][data-column-id=\"${CSS.escape(activeEntry.columnId)}\"]`\n : `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(activeEntry.rowId)}\"]`,\n );\n // Not mounted yet; the next render tries again, as the add effect does.\n if (editor === null) return;\n focusedActiveRef.current = key;\n focusEditorContent(editor);\n });\n\n // Open (uncommitted) rows keep the seed values frozen at addRow - the live values\n // belong to the forms, which the editors read directly, and this table only\n // provides row and cell identity. A committed row's cells render values, so\n // there the draft itself is the row; the memo recomputes on every\n // commit/reopen because either flips `newRows`' identity.\n const data = useMemo(\n () =>\n newRows.map(\n ({ tempId, committed }) =>\n ((committed\n ? edit.getForm(tempId)?.state.values\n : edit.getForm(tempId)?.options.defaultValues) ??\n {}) as TMDataGridRowData,\n ),\n [newRows, edit],\n );\n\n const entryTable = useTable({\n features: tmDataGridFeatures,\n columns: table.options.columns,\n data,\n getRowId: (_row, index) => newRows[index]?.tempId ?? String(index),\n });\n\n if (newRows.length === 0) return null;\n\n const entryRows = entryTable.getCoreRowModel().rows;\n const committedById = new Map(\n newRows.map((newRow) => [newRow.tempId, newRow.committed]),\n );\n // A row being *typed* into is always sticky - it exists nowhere else to\n // scroll back to. A committed row joins the scrolling flow unless\n // `newRowsSticky` keeps it pinned, so entering many rows cannot fill the\n // viewport with sticky chrome.\n const stickyRows = entryRows.filter(\n (entryRow) =>\n features.editNewRowsSticky || committedById.get(entryRow.id) !== true,\n );\n const flowRows = features.editNewRowsSticky\n ? []\n : entryRows.filter((entryRow) => committedById.get(entryRow.id) === true);\n\n const renderEntryRow = (\n entryRow: (typeof entryRows)[number],\n pinnedZ: string,\n ) => {\n const cellsById = new Map(\n entryRow.getAllCells().map((cell) => [cell.column.id, cell]),\n );\n const committed = committedById.get(entryRow.id) === true;\n return (\n <div\n key={entryRow.id}\n role=\"row\"\n data-dg-part=\"entry-row\"\n data-row-id={entryRow.id}\n data-new\n data-committed={committed}\n // The same marker body rows carry once committed, so one selector\n // reaches everything parked in the draft store.\n data-draft={committed}\n className={classes.entryRow}\n >\n {orderedColumns.map((column) => {\n const cell = cellsById.get(column.id);\n const layout = layoutFor(column.id);\n const editable =\n cell !== undefined && isEntryCellEditable(entryRow, column, edit);\n return (\n <div\n key={column.id}\n role=\"cell\"\n data-column-id={column.id}\n data-align={getColumnAlign(column)}\n data-control-column={isControlColumn(column.id)}\n // A committed row re-opens where it is double-clicked, the\n // same gesture a body cell answers.\n onDoubleClick={\n committed && !isControlColumn(column.id)\n ? () =>\n edit.begin({\n rowId: entryRow.id,\n columnId: editable ? column.id : null,\n })\n : undefined\n }\n className={[\n classes.entryCell,\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: layout.pinnedAt === \"left\" ? layout.offset : undefined,\n right: layout.pinnedAt === \"right\" ? layout.offset : undefined,\n position: layout.pinnedAt ? \"sticky\" : undefined,\n zIndex: layout.pinnedAt ? pinnedZ : undefined,\n }}\n >\n {cell !== undefined && column.id === EDIT_COLUMN_ID ? (\n // The lane's cell - the entry row's controls.\n flexRender(cell.column.columnDef.cell, cell.getContext())\n ) : committed && cell !== undefined ? (\n // Entered, awaiting Save all: a value row through the\n // columns' own renderers, over the draft the memo above\n // fed this table.\n <span className={classes.cellContent}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </span>\n ) : editable && cell !== undefined ? (\n <TMDataGridCellEditor\n cell={cell}\n row={entryRow}\n takeSeedText={() => undefined}\n onClose={() => {}}\n inEntryBlock\n />\n ) : null}\n </div>\n );\n })}\n </div>\n );\n };\n\n return (\n <>\n {stickyRows.length > 0 && (\n <div\n ref={blockRef}\n role=\"rowgroup\"\n data-dg-entry-block\n className={classes.entryBlock}\n >\n {stickyRows.map((entryRow) =>\n renderEntryRow(entryRow, \"var(--dg-z-pinned-row-pinned-cell, 5)\"),\n )}\n </div>\n )}\n {flowRows.length > 0 && (\n <div\n role=\"rowgroup\"\n data-dg-entry-flow-block\n className={classes.entryFlowBlock}\n >\n {/* In flow, so a pinned cell stacks like a body row's, under the\n sticky blocks it scrolls past. */}\n {flowRows.map((entryRow) =>\n renderEntryRow(entryRow, \"var(--dg-z-pinned-cell, 2)\"),\n )}\n </div>\n )}\n </>\n );\n}\n","import type { Cell, CellContext, Row } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\ntype ErasedCell = Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\ntype ErasedRow = Row<TMDataGridFeatures, TMDataGridRowData>;\ntype ErasedCellContext = CellContext<\n TMDataGridFeatures,\n TMDataGridRowData,\n unknown\n>;\n\n/**\n * The row internals the draft wrapper overrides. Private to table-core, but\n * load-bearing for it: `row.getValue` reads `_valuesCache` before running\n * `column.accessorFn(row.original, row.index)`, so owning fresh caches and a\n * draft `original` is what makes every accessor - key, function, dot path -\n * re-derive from the draft. Pinned by draftCellContext.test.ts, which is the\n * tripwire for a beta bump moving these.\n */\ntype RowInternals = {\n original: TMDataGridRowData;\n _valuesCache: Record<string, unknown>;\n _uniqueValuesCache: Record<string, unknown>;\n};\n\n/**\n * A cell render context whose values come from a row's edit draft instead of\n * `data` - how a parked draft is shown through the column's own `cell`\n * renderer.\n *\n * v9 constructs rows and cells as `Object.create(prototype)` instances whose\n * API methods dispatch on `this`, so a wrapper inheriting the real object but\n * owning `original` and empty value caches serves draft values from the same\n * code paths the real row uses. The context is hand-built rather than taken\n * from the wrapper's `getContext()`, which is memoized per instance and would\n * be inherited from the real cell.\n *\n * Limitation, accepted: instance-memoized traversals (`row.getAllCells()` and\n * friends) are inherited already-bound to the real row, so a renderer walking\n * `ctx.row` beyond `original` / `getValue()` / `renderValue()` sees committed\n * values. The documented renderer surface sees the draft.\n */\nexport function draftCellContext(\n cell: ErasedCell,\n draftValues: TMDataGridRowData,\n): ErasedCellContext {\n const draftRow = Object.create(cell.row) as ErasedRow;\n const internals = draftRow as unknown as RowInternals;\n internals.original = draftValues;\n internals._valuesCache = Object.create(null) as Record<string, unknown>;\n internals._uniqueValuesCache = Object.create(null) as Record<string, unknown>;\n\n const draftCell = Object.create(cell) as ErasedCell;\n (draftCell as { row: ErasedRow }).row = draftRow;\n\n return {\n table: cell.table,\n column: cell.column,\n row: draftRow,\n cell: draftCell,\n getValue: () => draftRow.getValue(cell.column.id),\n renderValue: () =>\n draftRow.getValue(cell.column.id) ??\n cell.table.options.renderFallbackValue ??\n null,\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 * There is then no rectangle, rather than a guessed replacement corner that\n * would copy cells the user never selected. The range itself is left alone:\n * clearing it here would discard a selection that returns as soon as the filter\n * is cleared.\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 lies 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, because a literal BOM is\n * invisible in a source file and easily deleted by accident.\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. This\n * export targets Excel, so opening correctly there takes priority over strict\n * CSV.\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 the caller can act on.\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 type { Row, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\n/**\n * The rows pinned to one edge, resolved safely and in pin order.\n *\n * Not TanStack's `getTopRows()`: that resolves each pinned id with\n * `getRow(id, true)`, which throws once the row's data is gone - and pinned\n * ids outlive data. A delete, a server-side page swap, a refetch that comes\n * back without the row: any of these would take the whole grid down. Here a\n * stale id is skipped instead; it stays in state, harmless, and the row\n * returns to its edge if its data comes back.\n *\n * The semantics are TanStack's `keepPinnedRows: true`: a pinned row stays at\n * its edge even when a filter or the pager would have dropped it from the\n * body. Ids resolve against the pre-pagination model first - those rows carry\n * the live sort and filter context - with the core model as the fallback for\n * rows the filters removed. A leaf whose group is collapsed stays hidden,\n * as upstream does.\n */\nexport function readPinnedRows<TData extends RowData>(\n table: TMDataGridTable<TData>,\n position: \"top\" | \"bottom\",\n): Array<Row<TMDataGridFeatures, TData>> {\n const ids = table.store.state.rowPinning[position];\n if (ids.length === 0) return [];\n const visible = table.getPrePaginatedRowModel().rowsById;\n const all = table.getCoreRowModel().rowsById;\n const rows: Array<Row<TMDataGridFeatures, TData>> = [];\n for (const id of ids) {\n const row = visible[id] ?? all[id];\n if (row === undefined) continue;\n if (!row.getIsAllParentsExpanded()) continue;\n rows.push(row);\n }\n return rows;\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport {\n isTMDataGridFilterValue,\n type TMDataGridFilterOperator,\n} from \"./filterOperators\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/** A matched slice of a cell's text, `start` inclusive to `end` exclusive. */\nexport type TMDataGridMatchRange = { start: number; end: number };\n\n/**\n * The operators whose match is a contiguous substring - the ones highlighting\n * can point at. Equality highlights nothing: marking the whole cell says\n * nothing the filter did not already say.\n */\nconst HIGHLIGHTABLE_OPERATORS: ReadonlyArray<TMDataGridFilterOperator> = [\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n];\n\n/**\n * Every needle that could highlight in a given column, keyed by column id -\n * the quick search for the columns it searches, plus any contains-family\n * column filter. `null` while nothing highlightable is active, which is the\n * common case and the cheap one.\n *\n * The fuzzy quick search still contributes its raw text: when the needle occurs\n * contiguously it is highlighted, and a typo-match with no contiguous\n * occurrence is not highlighted at all.\n */\nexport function buildMatchNeedles<TData extends RowData>(\n table: TMDataGridTable<TData>,\n): Map<string, ReadonlyArray<string>> | null {\n const state = table.store.state;\n const global =\n typeof state.globalFilter === \"string\" ? state.globalFilter.trim() : \"\";\n\n const byColumn = new Map<string, Array<string>>();\n for (const filter of state.columnFilters) {\n if (!isTMDataGridFilterValue(filter.value)) continue;\n const { operator, value } = filter.value;\n if (!HIGHLIGHTABLE_OPERATORS.includes(operator)) continue;\n if (typeof value !== \"string\" || value === \"\") continue;\n const needles = byColumn.get(filter.id) ?? [];\n needles.push(value);\n byColumn.set(filter.id, needles);\n }\n\n if (global === \"\" && byColumn.size === 0) return null;\n\n const map = new Map<string, ReadonlyArray<string>>();\n for (const column of table.getAllLeafColumns()) {\n const needles: Array<string> = [];\n if (global !== \"\" && column.getCanGlobalFilter()) needles.push(global);\n const own = byColumn.get(column.id);\n if (own !== undefined) needles.push(...own);\n if (needles.length > 0) map.set(column.id, needles);\n }\n return map.size > 0 ? map : null;\n}\n\n/**\n * Where the needles occur in the text, case-insensitively, merged where they\n * overlap or touch - so two needles covering \"St\" and \"tock\" come back as one\n * range rather than nested marks. `null` when nothing matches.\n */\nexport function findMatchRanges(\n text: string,\n needles: ReadonlyArray<string>,\n): Array<TMDataGridMatchRange> | null {\n const haystack = text.toLowerCase();\n const found: Array<TMDataGridMatchRange> = [];\n for (const needle of needles) {\n const lowered = needle.toLowerCase();\n if (lowered === \"\") continue;\n let index = haystack.indexOf(lowered);\n while (index !== -1) {\n found.push({ start: index, end: index + lowered.length });\n index = haystack.indexOf(lowered, index + 1);\n }\n }\n if (found.length === 0) return null;\n\n found.sort((a, b) => a.start - b.start || a.end - b.end);\n const merged: Array<TMDataGridMatchRange> = [];\n for (const range of found) {\n const last = merged.at(-1);\n if (last !== undefined && range.start <= last.end) {\n last.end = Math.max(last.end, range.end);\n } else {\n merged.push({ ...range });\n }\n }\n return merged;\n}\n","import { Checkbox, Loader, Menu, type MenuProps, Text } from \"@mantine/core\";\nimport {\n type Cell,\n type Column,\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 CSSProperties,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type UIEvent,\n useCallback,\n useEffect,\n useLayoutEffect,\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 {\n TMDataGridHeaderCell,\n type TMDataGridColumnMenuItemsRenderer,\n} from \"./TMDataGridHeaderCell\";\nimport {\n TMDataGridCellEditor,\n type TMDataGridCellEditorClose,\n} from \"./TMDataGridCellEditor\";\nimport { TMDataGridEntryRows } from \"./TMDataGridEntryRows\";\nimport { getColumnAlign, isControlColumn } from \"../core/columnUtils\";\nimport { draftCellContext } from \"../core/draftCellContext\";\nimport {\n getEditFieldName,\n type TMDataGridEditState,\n} from \"../core/editEngine\";\nimport {\n getNextEditableCell,\n resolveCellMove,\n type TMDataGridCellPosition,\n} from \"../core/cellNavigation\";\nimport { FOCUSABLE_IN_CELL, focusEditorContent } from \"../core/editorFocus\";\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, hasMountedCells } from \"../core/autosize\";\nimport {\n getDisplayedRows,\n getSelectableRowIds,\n isPagingActive,\n resolveRowSelectionClick,\n} from \"../core/rowSelection\";\nimport { readPinnedRows } from \"../core/rowPinning\";\nimport { buildMatchNeedles, findMatchRanges } from \"../core/matchHighlight\";\nimport { ROW_NUMBER_COLUMN_ID } from \"./TMDataGridRowNumberColumn\";\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 * 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\n/**\n * The text with its matched slices wrapped in `<mark>` - or handed back\n * whole when nothing matches. Only ever called on string output; a renderer\n * returning its own elements never reaches this.\n */\nfunction withMatchHighlights(\n text: string,\n needles: ReadonlyArray<string>,\n): ReactNode {\n const ranges = findMatchRanges(text, needles);\n if (ranges === null) return text;\n const parts: Array<ReactNode> = [];\n let cursor = 0;\n for (const range of ranges) {\n if (range.start > cursor) parts.push(text.slice(cursor, range.start));\n parts.push(\n <mark key={range.start} className={classes.matchHighlight}>\n {text.slice(range.start, range.end)}\n </mark>,\n );\n cursor = range.end;\n }\n if (cursor < text.length) parts.push(text.slice(cursor));\n return parts;\n}\n\nfunction TMDataGridBodyCell({\n cell,\n rowHeight,\n layout,\n nav,\n editor,\n contentOverride,\n highlightNeedles,\n onFocus,\n onClick,\n onMouseDown,\n onMouseEnter,\n onDoubleClick,\n onContextMenu,\n}: {\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n rowHeight: number;\n layout: TMDataGridColumnLayout;\n nav?: TMDataGridCellNav;\n /** The mounted editor, when this is the cell being edited. */\n editor?: ReactNode;\n /**\n * Replaces the column renderer's output - the row-number gutter, whose\n * value only the body knows. `undefined` means \"render normally\".\n */\n contentOverride?: ReactNode;\n /**\n * Needles to highlight in string output - see `enableMatchHighlighting`.\n * `undefined` almost always: only set while a highlightable filter is\n * active for this column.\n */\n highlightNeedles?: ReadonlyArray<string>;\n onFocus?: () => void;\n onClick?: (event: MouseEvent<HTMLDivElement>) => void;\n onMouseDown?: (event: MouseEvent<HTMLDivElement>) => void;\n onMouseEnter?: () => void;\n onDoubleClick?: (event: MouseEvent<HTMLDivElement>) => void;\n onContextMenu?: (event: MouseEvent<HTMLDivElement>) => void;\n}) {\n // The edit markers subscribe here, per cell, all to the one projection\n // store - so typing in an editor repaints the edited row's cells and\n // nothing else. Constant `false` everywhere while editing is off.\n const { table, edit } = useTMDataGridContext();\n const fieldName = getEditFieldName(cell.column);\n const cellRowId = cell.row.id;\n const isControl = isControlColumn(cell.column.id);\n const isDirty = useSelector(edit.store, (state) => {\n if (fieldName === null) return false;\n const projection = state.rows[cellRowId];\n return projection !== undefined && projection.dirtyFields.includes(fieldName);\n });\n const isInvalid = useSelector(edit.store, (state) => {\n if (fieldName === null) return false;\n const projection = state.rows[cellRowId];\n return projection !== undefined && projection.errorFields.includes(fieldName);\n });\n // The whole draft, not one field: a computed or custom renderer may read any\n // field off the row, so every data cell of a drafted row repaints together\n // when its draft moves - and only then, `values` being reference-stable\n // across meta-only form events. `undefined` everywhere else.\n const draftValues = useSelector(edit.store, (state) =>\n isControl ? undefined : state.rows[cellRowId]?.values,\n );\n return (\n <div\n // `gridcell` rather than `cell` is what tells a screen reader the arrow\n // keys move a cursor here, so it is set together with the tab stop rather\n // 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 // Both coordinates are always present, not only under cell selection:\n // autosize finds a column's mounted cells by the column id, and the pair\n // is how a test addresses one cell -\n // `[data-row-id=\"42\"][data-column-id=\"name\"]`. The cell-navigation\n // selectors also require `data-cell`, so they are unaffected.\n data-row-id={cell.row.id}\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 onClick={onClick}\n onMouseDown={onMouseDown}\n onMouseEnter={onMouseEnter}\n onDoubleClick={onDoubleClick}\n data-editing={editor !== undefined || undefined}\n data-dirty={isDirty || undefined}\n data-invalid={isInvalid || undefined}\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={isControl}\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 {editor ?? (\n <span className={classes.cellContent}>\n {(() => {\n // A row with a live form shows its draft, not `data`: the column's\n // own renderer over a context reading the form's values. The\n // drafts that outlive their editor - parked ones, cellConfirm's\n // kept ones - are the point; group cells are excluded because no\n // group row ever has a form.\n const draftContext =\n draftValues !== undefined &&\n contentOverride === undefined &&\n !cell.getIsPlaceholder() &&\n !cell.getIsAggregated()\n ? draftCellContext(cell, draftValues)\n : undefined;\n // Highlighting reproduces the *default* renderer, value then\n // `toString`, with the matched parts marked. A column with its own\n // `cell` is excluded: its renderer is not the default one, and the\n // grid does not modify a custom renderer's output.\n if (\n highlightNeedles !== undefined &&\n contentOverride === undefined &&\n !cell.getIsPlaceholder() &&\n !cell.getIsAggregated() &&\n cell.column.columnDef.cell === table.getDefaultColumnDef().cell\n ) {\n const value =\n draftContext !== undefined\n ? draftContext.renderValue()\n : cell.renderValue();\n if (typeof value === \"string\" || typeof value === \"number\") {\n return withMatchHighlights(String(value), highlightNeedles);\n }\n }\n if (draftContext !== undefined) {\n return flexRender(cell.column.columnDef.cell, draftContext);\n }\n return contentOverride ?? renderCellContent(cell);\n })()}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * The virtualized body rows, wrapped in the single Menu that serves all of them\n * when `renderRowContextMenu` 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 `renderRowContextMenu` 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 * The grid's own items for this menu: the cell copy and export items, under\n * `cellSelection: \"range\"`, and `null` otherwise.\n *\n * Placing it decides the order. Ignore it and the grid keeps today's\n * behavior, rendering its items above a divider and yours below.\n */\n internalItems: ReactNode;\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 TMDataGridRowContextMenuRenderer<TData extends RowData> = (\n args: TMDataGridRowContextMenuArgs<TData>,\n) => ReactNode;\n\n/**\n * What the `onCellClick` family receives - the cell with its row and column,\n * in the consumer's own row type, plus the pointer event.\n */\nexport type TMDataGridCellEventArgs<TData extends RowData> = {\n cell: Cell<TMDataGridFeatures, TData, unknown>;\n row: Row<TMDataGridFeatures, TData>;\n column: Column<TMDataGridFeatures, TData, unknown>;\n event: MouseEvent<HTMLElement>;\n};\n\n/**\n * Inline styles for a row. Widened to accept CSS variables, because setting\n * `--row-bg` is the supported way to colour a row - see {@link\n * TMDataGridTableProps.rowStyle}.\n */\nexport type TMDataGridRowStyle =\n | CSSProperties\n | (CSSProperties & Record<`--${string}`, string | number>);\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 * Called when a body cell is clicked. Composes, never suppresses: whatever\n * the click already does - selecting, highlighting, moving the cell cursor\n * - still happens. Group rows sit out the cell handlers the way they sit\n * out `onRowClick`, and for the same reason.\n */\n onCellClick?: (args: TMDataGridCellEventArgs<TData>) => void;\n /** As {@link onCellClick}; a double-click that opens an editor still does. */\n onCellDoubleClick?: (args: TMDataGridCellEventArgs<TData>) => void;\n /**\n * As {@link onCellClick}; `renderRowContextMenu` and the cell-selection menu still\n * open. To suppress the browser's own menu on a grid with neither, call\n * `event.preventDefault()` here.\n */\n onCellContextMenu?: (args: TMDataGridCellEventArgs<TData>) => void;\n /**\n * Class for a body row - a string, or a function of the row (group rows\n * included; test `row.getIsGrouped()` to skip them). Added after the grid's\n * own row class.\n */\n rowClassName?:\n | string\n | ((row: Row<TMDataGridFeatures, TData>) => string | undefined);\n /**\n * Inline style for a body row. To colour a row, set `--row-bg` rather than\n * `background`: the row's own background, its sticky pinned cells and the\n * cell-range tint all read that variable, and hover/selection/highlight\n * keep working on top of it - a raw `background` bypasses all of them.\n *\n * ```tsx\n * rowStyle={(row) =>\n * row.original.overdue ? { \"--row-bg\": \"var(--mantine-color-red-0)\" } : undefined\n * }\n * ```\n */\n rowStyle?:\n | TMDataGridRowStyle\n | ((row: Row<TMDataGridFeatures, TData>) => TMDataGridRowStyle | undefined);\n /**\n * Every second row takes `--dg-row-striped-bg`. Computed from the row's\n * position in the view - sorting and filtering restripe, and the stripes\n * stay put while the virtualizer mounts and unmounts rows.\n */\n striped?: boolean;\n /**\n * Called when the scroll *arrives* at an edge - once per arrival, not per\n * scroll event, and not on mount (the grid starts at the top-left edge).\n * For loading more rows as the end approaches, `onReachEnd` is the better\n * hook: it fires rows-early and latches per row count.\n */\n onScrollToTop?: () => void;\n /** As {@link onScrollToTop}, for the bottom edge. */\n onScrollToBottom?: () => void;\n /** As {@link onScrollToTop}, for the left edge. */\n onScrollToLeft?: () => void;\n /** As {@link onScrollToTop}, for the right edge. */\n onScrollToRight?: () => void;\n /**\n * Rendered centred in the body when the view is empty - the branded blank\n * slate. It takes over states 3 and 4 of the empty matrix (see the docs):\n * loading still shows the loader, and open entry rows still show only\n * themselves. `hasActiveFilters` says which emptiness this is - a filter\n * that matched nothing wants a \"clear filters\" invitation, a grid with no\n * data wants a \"create the first one\".\n */\n renderEmptyState?: (args: {\n hasActiveFilters: boolean;\n table: Table<TMDataGridFeatures, TData>;\n }) => ReactNode;\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 * renderRowContextMenu={({ 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 * `internalItems` is the grid's own half - place it to control the order,\n * ignore it and the grid keeps its items above a divider and yours below.\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 renderRowContextMenu?: TMDataGridRowContextMenuRenderer<TData>;\n /**\n * Replaces a column menu's contents, taking the grid's own items and\n * returning the full list.\n *\n * ```tsx\n * <TMDataGrid.Table\n * renderColumnMenuItems={({ column, internalItems }) => [\n * ...internalItems,\n * <Menu.Divider key=\"custom\" />,\n * <Menu.Item key=\"stats\" onClick={() => showStats(column.id)}>\n * Statistics\n * </Menu.Item>,\n * ]}\n * />\n * ```\n *\n * Returning an empty list leaves the column with no menu button, the same as\n * a column whose every feature is switched off.\n */\n renderColumnMenuItems?: TMDataGridColumnMenuItemsRenderer;\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 * Accessible name for the grid: what a screen reader announces on entry, and\n * what `getByRole(\"grid\", { name })` matches. Set it on any page holding more\n * than one grid; without it they are all announced as \"grid\".\n */\n \"aria-label\"?: string;\n /** As {@link \"aria-label\"}, pointing at an element that already names it. */\n \"aria-labelledby\"?: string;\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 work at any row count. Pagination is opt in through\n * `enablePagination`, or implied by `manualPagination`.\n */\nexport function TMDataGridTable<TData extends RowData = TMDataGridRowData>({\n onRowClick,\n onCellClick,\n onCellDoubleClick,\n onCellContextMenu,\n rowClassName,\n rowStyle,\n striped = false,\n onScrollToTop,\n onScrollToBottom,\n onScrollToLeft,\n onScrollToRight,\n renderEmptyState,\n renderRowContextMenu,\n renderColumnMenuItems,\n rowContextMenuProps,\n cellExport,\n onReachEnd,\n reachEndThreshold = 10,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n}: TMDataGridTableProps<TData>) {\n const {\n table,\n ui,\n edit,\n features,\n labels,\n rowHeight,\n controlSize,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n scrollerRef,\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 // Which cell has an editor open. The projection (dirty/error markers) is\n // subscribed per cell instead - see TMDataGridBodyCell.\n const editActive = useSelector(edit.store, (state) => state.active);\n // Row mode opens whole rows and any number of them at once, so which rows\n // are showing editors is the set of open forms, not the single active slot.\n const editOpenRowIds = useSelector(edit.store, (state) => state.openRowIds);\n const newRowCount = useSelector(edit.store, (state) => state.newRows.length);\n const deletedRowIds = useSelector(edit.store, (state) => state.deletedRowIds);\n // Rows carrying a dirty draft, for the row-level marker. Derived from the\n // same projections the cells subscribe to; the array's identity churns with\n // `openRowIds`' own per-publish churn, so this adds no new render class.\n const editDirtyRowIds = useSelector(edit.store, (state) =>\n state.openRowIds.filter(\n (id) => (state.rows[id]?.dirtyFields.length ?? 0) > 0,\n ),\n );\n // Rows parked in the draft store, waiting for Save. A separate marker from\n // `data-dirty`, which covers any row being typed into: after a partial save\n // these are what is left, so one selector highlights everything still\n // pending.\n const editDraftRowIds = useSelector(\n edit.store,\n (state) => state.committedRowIds,\n );\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 // Per-column highlight needles, or `null` while off or nothing is active -\n // the common case, costing one flag check per render.\n const matchNeedles = features.matchHighlighting\n ? buildMatchNeedles(table)\n : null;\n\n // The edge blocks. `getDisplayedRows` above has already taken these out of\n // the scrolling order; stale ids resolve to nothing - see readPinnedRows.\n const pinnedTopRows = features.rowPinning ? readPinnedRows(table, \"top\") : [];\n const pinnedBottomRows = features.rowPinning\n ? readPinnedRows(table, \"bottom\")\n : [];\n const pinnedRowCount = pinnedTopRows.length + pinnedBottomRows.length;\n\n // The row-number gutter's numbers: one pass over the view per render, only\n // while the lane exists. A cell cannot know its display position, so the\n // body hands each row its number - group rows get none (they are headings\n // over the rows being counted), and paging continues the count across\n // pages rather than restarting every page at 1.\n let rowNumberById: Map<string, number> | null = null;\n if (features.rowNumbers) {\n rowNumberById = new Map();\n let n = isPagingActive(table, features)\n ? table.store.state.pagination.pageIndex *\n table.store.state.pagination.pageSize\n : 0;\n for (const viewRow of rows) {\n if (!viewRow.getIsGrouped()) rowNumberById.set(viewRow.id, ++n);\n }\n }\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 each after the first rows are in the\n * DOM.\n *\n * The wait is required. The virtualizer measures its scroll element in an\n * effect and mounts its first rows in the render that follows, so on the\n * mounting commit this column has a header and no cells, and autosize would\n * fit the header alone and keep that width for the rest of the session. The\n * ids are therefore held in a set, and each one is dropped only once it has\n * been measured against mounted content.\n *\n * A ref rather than an effect dependency: a column is sized once per mount,\n * and only while no persisted or user width covers it - autosizing again on a\n * data change would fight a width the user has since dragged. Built from\n * every leaf column rather than the visible ones, so a column hidden at mount\n * is still sized when it is shown.\n */\n const pendingAutoSizeRef = useRef<Set<string> | null>(null);\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (container === null) return;\n pendingAutoSizeRef.current ??= new Set(\n table\n .getAllLeafColumns()\n .filter((column) => column.columnDef.meta?.autoSize === true)\n .map((column) => column.id),\n );\n const pending = pendingAutoSizeRef.current;\n if (pending.size === 0) return;\n\n for (const columnId of [...pending]) {\n if (columnId in table.store.state.columnSizing) {\n pending.delete(columnId);\n continue;\n }\n if (!hasMountedCells(container, columnId)) continue;\n autosizeColumn({ table, columnId, container });\n pending.delete(columnId);\n }\n });\n\n /**\n * The header's height, published as `--dg-header-height` for the entry\n * block to stick under - never measured otherwise (`top: 0` needs no\n * number). A ResizeObserver, mounted only while the block is in use: the\n * same discipline `renderDetails` applies to `measureElement`.\n */\n const gridElementRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (newRowCount === 0 && pinnedTopRows.length === 0) return;\n const grid = gridElementRef.current;\n if (grid === null) return;\n const headerRows = grid.querySelectorAll<HTMLElement>(\n \"[data-dg-header-row]\",\n );\n const measure = () => {\n let total = 0;\n for (const headerRow of headerRows) total += headerRow.offsetHeight;\n grid.style.setProperty(\"--dg-header-height\", `${total}px`);\n };\n measure();\n const observer = new ResizeObserver(measure);\n for (const headerRow of headerRows) observer.observe(headerRow);\n return () => observer.disconnect();\n }, [newRowCount, pinnedTopRows.length]);\n\n /**\n * The entry block's height, published as `--dg-entry-height` so the pinned\n * top block can stack under it - measured only while both blocks exist,\n * which is the only time the offset is anything but 0.\n */\n useEffect(() => {\n if (newRowCount === 0 || pinnedTopRows.length === 0) return;\n const grid = gridElementRef.current;\n if (grid === null) return;\n const entryBlock = grid.querySelector<HTMLElement>(\"[data-dg-entry-block]\");\n if (entryBlock === null) return;\n const measure = () =>\n grid.style.setProperty(\"--dg-entry-height\", `${entryBlock.offsetHeight}px`);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(entryBlock);\n return () => {\n observer.disconnect();\n grid.style.removeProperty(\"--dg-entry-height\");\n };\n }, [newRowCount, pinnedTopRows.length]);\n\n /**\n * The summary row's height, published as `--dg-summary-height` so the\n * pinned bottom block sticks above it rather than underneath it.\n */\n useEffect(() => {\n if (pinnedBottomRows.length === 0) return;\n const grid = gridElementRef.current;\n if (grid === null) return;\n const summaryRow = grid.querySelector<HTMLElement>(\n '[data-dg-part=\"summary-row\"]',\n );\n if (summaryRow === null) return;\n const measure = () =>\n grid.style.setProperty(\n \"--dg-summary-height\",\n `${summaryRow.offsetHeight}px`,\n );\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(summaryRow);\n return () => {\n observer.disconnect();\n grid.style.removeProperty(\"--dg-summary-height\");\n };\n }, [pinnedBottomRows.length]);\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 /**\n * A live `size` (or `meta.rowHeight`) change moves what `estimateSize`\n * answers, but the virtualizer's measurement cache does not list that option\n * among its dependencies - by its own docs, changing the estimate means\n * calling `measure()`. Without this the spacers keep the old height until\n * something else invalidates the cache, so the scroll range and the window\n * disagree with the rows actually painted.\n */\n const prevRowHeightRef = useRef(rowHeight);\n useEffect(() => {\n if (prevRowHeightRef.current === rowHeight) return;\n prevRowHeightRef.current = rowHeight;\n virtualizer.measure();\n }, [rowHeight, virtualizer]);\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 * `api.scrollToRow`, implemented where the virtualizer is.\n *\n * Registered in an effect rather than during render, and with no dependency\n * array so it re-registers on every one: the closure has to see this render's\n * `rows`, which sorting, filtering and paging all change. A grid whose Table\n * has unmounted leaves the hook's default behind, which answers `false`.\n */\n useEffect(() => {\n scrollerRef.current = ({ rowId, align = \"auto\" }) => {\n // Already parked at an edge, and outside the scrolling order - see\n // `getDisplayedRows`. Nothing to scroll, but the row *is* on screen, so\n // reporting failure would be the wrong answer.\n if (\n pinnedTopRows.some((row) => row.id === rowId) ||\n pinnedBottomRows.some((row) => row.id === rowId)\n ) {\n return true;\n }\n const index = rows.findIndex((row) => row.id === rowId);\n if (index < 0) return false;\n virtualizer.scrollToIndex(index, { align });\n return true;\n };\n return () => {\n scrollerRef.current = () => false;\n };\n });\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 // Pinned rows count as content: with every visible row pinned to an edge,\n // an empty-state message beside them would contradict what is on screen.\n const isEmpty = rows.length === 0 && pinnedRowCount === 0;\n // Which emptiness this is. The body already subscribes to the whole table\n // store, so these reads are reactive.\n const emptyGlobalFilter = table.store.state.globalFilter;\n const hasActiveFilters =\n table.store.state.columnFilters.length > 0 ||\n (typeof emptyGlobalFilter === \"string\"\n ? emptyGlobalFilter.trim() !== \"\"\n : emptyGlobalFilter != null);\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 // The value-or-function pair resolved per row, across the same erasure\n // crossing `onRowClick` makes.\n const rowClassNameFor = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n ): string | undefined =>\n typeof rowClassName === \"function\"\n ? rowClassName(row as unknown as Row<TMDataGridFeatures, TData>)\n : rowClassName;\n const rowStyleFor = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n ): CSSProperties | undefined =>\n typeof rowStyle === \"function\"\n ? rowStyle(row as unknown as Row<TMDataGridFeatures, TData>)\n : rowStyle;\n\n // The same erasure crossing `onRowClick` makes, once for all three cell\n // handlers.\n const cellEventArgs = (\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>,\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n event: MouseEvent<HTMLElement>,\n ): TMDataGridCellEventArgs<TData> =>\n ({\n cell,\n row,\n column: cell.column,\n event,\n }) as unknown as TMDataGridCellEventArgs<TData>;\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 // Cell editing - the gestures. The engine owns the forms; this component\n // owns where the editor opens from (keys, double-click) and where the\n // focus lands when it closes.\n // ---------------------------------------------------------------------------\n\n /** The pending type-to-edit seed, consumed by the editor host on mount. */\n const editSeedRef = useRef<string | undefined>(undefined);\n const takeEditSeed = () => {\n const seed = editSeedRef.current;\n editSeedRef.current = undefined;\n return seed;\n };\n\n /**\n * The row's first cell that edits, in visual order - where the caret goes\n * for a gesture that named no column, which is the edit lane's pencil.\n */\n const firstEditableColumnId = (rowId: string): string | null => {\n const row = rows.find((candidate) => candidate.id === rowId);\n if (row === undefined) return null;\n const cells = [\n ...row.getLeftVisibleCells(),\n ...row.getCenterVisibleCells(),\n ...row.getRightVisibleCells(),\n ];\n return (\n cells.find((cell) => edit.canEditCell(row, cell.column))?.column.id ??\n null\n );\n };\n\n /**\n * The `active` the caret has already been placed for. Identity, not value:\n * `beginOn` publishes a fresh object per gesture, so re-opening the same\n * cell is a new intent, while every later render for the same gesture - a\n * remount as the virtualizer scrolls among open rows - is not.\n */\n const placedEditCaretRef = useRef<TMDataGridEditState[\"active\"]>(null);\n\n /**\n * Puts the caret in the cell the open gesture named, once per gesture.\n * See `focusEditorContent` for where inside the editor it lands.\n *\n * A layout effect, ahead of the focused-cell effect below: the ring follows\n * the caret there rather than fighting it.\n */\n useLayoutEffect(() => {\n if (editActive === null) {\n placedEditCaretRef.current = null;\n return;\n }\n if (placedEditCaretRef.current === editActive) return;\n const container = scrollContainerRef.current;\n if (container === null) return;\n // The lane's pencil names no column - the row's first editable cell.\n const columnId =\n editActive.columnId ?? firstEditableColumnId(editActive.rowId);\n if (columnId === null) {\n placedEditCaretRef.current = editActive;\n return;\n }\n const editor = container.querySelector<HTMLElement>(\n `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(editActive.rowId)}\"]` +\n `[data-column-id=\"${CSS.escape(columnId)}\"]`,\n );\n // Not mounted yet - the virtualizer is still bringing the row in. The\n // intent stays up, and the next render tries again.\n if (editor === null) return;\n placedEditCaretRef.current = editActive;\n focusEditorContent(editor);\n });\n\n /** DOM focus back onto a cell - after Escape, or a commit with nowhere to go. */\n const refocusCell = (position: TMDataGridCellPosition) => {\n const container = scrollContainerRef.current;\n if (container === null) return;\n wantsCellFocusRef.current = true;\n findCellElement(container, position)?.focus();\n };\n\n const openEditor = (position: TMDataGridCellPosition) => {\n if (cellSelection) ui.actions.setFocusedCell(position);\n // Row mode edits whole rows: any editable cell's open gesture opens all of\n // them, exactly as the lane's pencil does. The column still travels, as\n // the cell the caret belongs in - the one the gesture named. Dropping it\n // here sent the caret to the row's first editable cell instead, which the\n // focused-cell effect above then pulled back onto the cell just clicked,\n // leaving the row open with the caret in none of its editors.\n edit.begin({ rowId: position.rowId, columnId: position.columnId });\n };\n\n const handleEditorClose = (\n position: TMDataGridCellPosition,\n close: TMDataGridCellEditorClose,\n ) => {\n // Where the keyboard goes: Enter moves down, Tab to the next editable\n // cell (cellConfirm's deferring variants move the same way, draft kept) -\n // everything else, and a saved row, goes back to where the edit was.\n const move =\n close.via === \"enter\"\n ? \"down\"\n : close.via === \"tab\" || close.via === \"defer-tab\"\n ? 1\n : close.via === \"shift-tab\" || close.via === \"defer-shift-tab\"\n ? -1\n : null;\n if (move === null || features.editMode === \"row\") {\n refocusCell(position);\n return;\n }\n const rowIndex = rows.findIndex((row) => row.id === position.rowId);\n const columnIndex = orderedColumns.findIndex(\n (column) => column.id === position.columnId,\n );\n if (rowIndex < 0 || columnIndex < 0) {\n refocusCell(position);\n return;\n }\n if (move === \"down\") {\n if (rowIndex + 1 < rows.length) {\n moveFocusedCell({ rowIndex: rowIndex + 1, columnIndex });\n } else {\n refocusCell(position);\n }\n return;\n }\n const next = getNextEditableCell({\n from: { rowIndex, columnIndex },\n direction: move,\n rowCount: rows.length,\n columnCount: orderedColumns.length,\n isEditable: (coords) => {\n const row = rows[coords.rowIndex];\n const column = orderedColumns[coords.columnIndex];\n return (\n row !== undefined &&\n column !== undefined &&\n edit.canEditCell(row, column)\n );\n },\n });\n if (next !== null) moveFocusedCell(next);\n else refocusCell(position);\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 // Editing keys, ahead of the step-into pair - an editable cell's Enter\n // opens its editor, and only a non-editable cell's falls through to the\n // control it holds.\n const keyRow = rows[rowIndex];\n const keyColumn = orderedColumns[columnIndex];\n if (\n features.editing &&\n keyRow !== undefined &&\n keyColumn !== undefined &&\n edit.canEditCell(keyRow, keyColumn)\n ) {\n if (event.key === \"Enter\" || event.key === \"F2\") {\n event.preventDefault();\n openEditor({ rowId, columnId });\n return;\n }\n // The quick single-cell gestures - Delete-to-clear and type-to-edit -\n // sit out row mode, whose whole point is that nothing commits until\n // the row's explicit save.\n if (features.editMode !== \"row\") {\n // Clear-and-commit, without opening anything - the spreadsheet Delete.\n if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n void edit\n .clearCell(rowId, columnId)\n .then(() => refocusCell({ rowId, columnId }));\n return;\n }\n // Type-to-edit: a printable character opens the editor seeded with\n // itself. Space stays the row-selection key, modifiers stay shortcuts.\n if (\n event.key.length === 1 &&\n event.key !== \" \" &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n editSeedRef.current = event.key;\n openEditor({ rowId, columnId });\n return;\n }\n }\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 // An open editor outranks the ring, wherever it is. Row mode opens a whole\n // row from one gesture, so the caret legitimately sits in a cell other\n // than the one that gesture landed the ring on - the lane's pencil is the\n // plain case, focusing its own cell on the way to opening the row. Pulling\n // the caret back onto that cell would leave the row open with the caret in\n // none of its editors, and the user with nothing to type into.\n if (\n document.activeElement instanceof Element &&\n document.activeElement.closest('[data-dg-part=\"editor\"]') !== null\n ) {\n return;\n }\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 // `rowIndex < 0` is a pinned row: those sit out the cell range, so\n // moving the selection onto one would resolve to no rectangle at all\n // and drop the selection the user could still see at the edge.\n if (\n rowIndex >= 0 &&\n !isWithinBounds(selectionBounds, rowIndex, columnIndex)\n ) {\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 // The body list, then the edge blocks: pinning takes a row out of the\n // scrolling order, and unpinning is the first thing its menu exists to\n // offer, so a menu that could not resolve a pinned row would strand it\n // there. Searched in that order because the body holds nearly every row.\n const contextMenuRow =\n contextMenuTarget === null\n ? undefined\n : (rows.find((row) => row.id === contextMenuTarget.rowId) ??\n pinnedTopRows.find((row) => row.id === contextMenuTarget.rowId) ??\n pinnedBottomRows.find((row) => row.id === contextMenuTarget.rowId));\n\n const canRenderRowMenu =\n renderRowContextMenu !== undefined &&\n contextMenuTarget !== null &&\n contextMenuRow !== undefined &&\n !contextMenuRow.getIsGrouped();\n\n\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 consumer's half, built for the open row only - so the render prop runs\n * once per opened menu rather than once per mounted row. `null` back from it\n * means this row has no menu, which is also how the menu stays shut.\n *\n * `internalItems` is a getter, and reading it is the signal: a consumer who\n * touches it has taken the composition over, so the grid stops prepending\n * its own half. One who never mentions it gets today's behavior, the cell\n * items above a divider. The alternative - a second prop declaring intent -\n * asks people to say twice what the placement already says.\n *\n * The casts put back the concrete row type the context boundary erased - the\n * same crossing `onRowClick` makes.\n */\n let tookOverMenu = false;\n const rowMenuContent = canRenderRowMenu\n ? (renderRowContextMenu({\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 get internalItems() {\n tookOverMenu = true;\n return cellMenuContent;\n },\n }) ?? null)\n : null;\n\n /**\n * The two halves, in the order they apply to: the cells first, since the\n * right-click landed on one, then whatever the consumer offers for the row.\n * When the consumer takes the composition over, what they returned is the\n * entire menu.\n */\n const contextMenuContent = tookOverMenu\n ? rowMenuContent\n : cellMenuContent === null && rowMenuContent === null\n ? null\n : (\n <>\n {cellMenuContent}\n {cellMenuContent !== null && rowMenuContent !== null && (\n <Menu.Divider />\n )}\n {rowMenuContent}\n </>\n );\n\n /**\n * Which edges the scroll position is currently at. Seeded \"at top-left\",\n * which is where a grid mounts - so the callbacks report *arrivals*, and\n * mounting fires nothing.\n */\n const scrollEdgesRef = useRef({\n top: true,\n bottom: false,\n left: true,\n right: false,\n });\n const hasEdgeCallbacks =\n onScrollToTop !== undefined ||\n onScrollToBottom !== undefined ||\n onScrollToLeft !== undefined ||\n onScrollToRight !== undefined;\n\n /**\n * The context menu's dropdown is anchored to a fixed viewport point, so it\n * does not travel with the row when the body scrolls - and under\n * virtualization the row it belongs to may unmount entirely. It therefore\n * closes on scroll, as a desktop context menu does.\n *\n * The edge callbacks share the handler. Reading scroll offsets here costs\n * no layout; the 1px tolerance absorbs fractional offsets under browser\n * zoom, where a \"fully scrolled\" position can land at 799.5 of 800.\n */\n const handleScroll =\n contextMenuTarget || hasEdgeCallbacks\n ? (event: UIEvent<HTMLDivElement>) => {\n if (contextMenuTarget) closeContextMenu();\n if (!hasEdgeCallbacks) return;\n const el = event.currentTarget;\n const next = {\n top: el.scrollTop <= 1,\n bottom: el.scrollTop + el.clientHeight >= el.scrollHeight - 1,\n left: el.scrollLeft <= 1,\n right: el.scrollLeft + el.clientWidth >= el.scrollWidth - 1,\n };\n const previous = scrollEdgesRef.current;\n scrollEdgesRef.current = next;\n if (next.top && !previous.top) onScrollToTop?.();\n if (next.bottom && !previous.bottom) onScrollToBottom?.();\n if (next.left && !previous.left) onScrollToLeft?.();\n if (next.right && !previous.right) onScrollToRight?.();\n }\n : 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 ref={gridElementRef}\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-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n // Set while `meta.loading` is, whether or not the body has rows to\n // show - a refetch over existing rows is still a fetch, and a test\n // waiting for the grid to settle has nothing else to wait on.\n aria-busy={loading === true ? true : undefined}\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 +\n pinnedRowCount +\n headerGroups.length +\n (hasSummaryRow ? 1 : 0)\n }\n aria-colcount={orderedColumns.length}\n // Body rows the grid is currently showing - the page under\n // pagination, everything the filters left otherwise, edge blocks\n // included. Most of them are not in the DOM, so this is what a test\n // waits on rather than counting nodes.\n data-dg-row-count={rows.length + pinnedRowCount}\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 data-dg-header-row\n // The scrolled-under shadow belongs to the boundary between\n // header and body - the last header row, not every stacked\n // group row above it. See the stylesheet.\n data-dg-header-last={\n groupIndex === headerGroups.length - 1 || undefined\n }\n className={classes.headerRow}\n >\n {headerGroup.headers.map((header) => (\n <TMDataGridHeaderCell\n renderColumnMenuItems={renderColumnMenuItems}\n key={header.id}\n header={header}\n layout={layoutFor(header.column.id)}\n />\n ))}\n </div>\n ))}\n </div>\n\n {/* The entry block - new rows being typed, stuck under the header.\n Present only while `edit.addRow()` has open entries. */}\n {features.editing && newRowCount > 0 && (\n <TMDataGridEntryRows\n orderedColumns={orderedColumns}\n layoutFor={layoutFor}\n rowHeight={rowHeight}\n />\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 `renderRowContextMenu`.\n enabled={renderRowContextMenu !== undefined || cellRangeSelection}\n menuContent={contextMenuContent}\n menuProps={rowContextMenuProps}\n onContextMenu={handleContextMenu}\n onClose={closeContextMenu}\n >\n {(() => {\n /**\n * One renderer for every body row, wherever it sits: the\n * virtualized centre, or a pinned edge block. `viewIndex` is the\n * row's index in the scrolling view - `-1` for a pinned row,\n * which takes it out of striping, row measurement and the cell\n * range, all of which are statements about the scrolling order.\n * Scoped here rather than a component so the row keeps closing\n * over the body's handlers without threading them as props.\n */\n const renderBodyRow = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n viewIndex: number,\n ariaRowIndex: number,\n pinnedAt?: \"top\" | \"bottom\",\n ) => {\n const isGroupRow = row.getIsGrouped();\n const isInteractive = rowGesturesFor(row);\n const rowCells = [\n ...row.getLeftVisibleCells(),\n ...row.getCenterVisibleCells(),\n ...row.getRightVisibleCells(),\n ];\n // Row mode opens every editable cell of the row at once, and\n // rows accumulate: a second row opening leaves the first one\n // open, so every row holding a form shows its editors. Which of\n // them holds the caret is not decided here - see\n // placeEditCaret, which places it once per gesture.\n //\n // A parked row is not one of them. It keeps its form, so it is\n // still \"open\", but it has been decided: it renders its draft\n // through the column's own renderer until `begin` reopens it.\n const rowEditing =\n features.editMode === \"row\" &&\n editOpenRowIds.includes(row.id) &&\n !editDraftRowIds.includes(row.id);\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={row.id}\n role=\"row\"\n aria-rowindex={ariaRowIndex}\n data-dg-part=\"row\"\n data-row-id={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 why no second virtual item is needed.\n data-index={\n renderDetails && viewIndex >= 0 ? viewIndex : undefined\n }\n ref={\n renderDetails && viewIndex >= 0\n ? virtualizer.measureElement\n : undefined\n }\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 // Which edge block the row sits in, for styling hooks.\n data-pinned={pinnedAt}\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 // Marked deleted under draft: struck through and inert\n // until submitAll reports it, or the mark is toggled back.\n data-deleted={\n deletedRowIds.length > 0 && deletedRowIds.includes(row.id)\n }\n // Carrying a dirty draft - the row-level face of the cells'\n // own data-dirty markers, for row-scoped styling.\n data-dirty={\n editDirtyRowIds.length > 0 &&\n editDirtyRowIds.includes(row.id)\n }\n // Committed into the draft store, waiting for Save.\n data-draft={\n editDraftRowIds.length > 0 &&\n editDraftRowIds.includes(row.id)\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 // From the row's position in the whole view, so the stripes\n // survive the virtualizer's moving window - see the prop.\n data-striped={\n striped && viewIndex >= 0 ? viewIndex % 2 === 1 : undefined\n }\n className={[classes.bodyRow, rowClassNameFor(row)]\n .filter(Boolean)\n .join(\" \")}\n style={{\n minHeight: rowHeight,\n cursor: isInteractive ? \"pointer\" : undefined,\n ...rowStyleFor(row),\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 that too,\n // but would also stop cell values being copied, so it is\n // prevented on 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. `renderRowContextMenu` 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 (renderRowContextMenu && !isGroupRow) || cellRangeSelection\n ? () => {\n contextMenuRowRef.current = row.id;\n }\n : undefined\n }\n >\n {rowCells.map((cell, cellIndex) => {\n const isEditingCell =\n (editActive !== null &&\n editActive.rowId === row.id &&\n editActive.columnId === cell.column.id) ||\n (rowEditing && edit.canEditCell(row, cell.column));\n return (\n <TMDataGridBodyCell\n key={cell.id}\n cell={cell}\n rowHeight={rowHeight}\n layout={layoutFor(cell.column.id)}\n contentOverride={\n rowNumberById !== null &&\n cell.column.id === ROW_NUMBER_COLUMN_ID\n ? rowNumberById.get(row.id)\n : undefined\n }\n highlightNeedles={matchNeedles?.get(cell.column.id)}\n editor={\n isEditingCell ? (\n <TMDataGridCellEditor\n cell={cell}\n row={row}\n takeSeedText={takeEditSeed}\n onClose={(close) =>\n handleEditorClose(\n { rowId: row.id, columnId: cell.column.id },\n close,\n )\n }\n />\n ) : undefined\n }\n onClick={\n onCellClick && !isGroupRow\n ? (event) =>\n onCellClick(cellEventArgs(cell, row, event))\n : undefined\n }\n onDoubleClick={\n (features.editing || onCellDoubleClick) && !isGroupRow\n ? (event) => {\n onCellDoubleClick?.(\n cellEventArgs(cell, row, event),\n );\n if (!features.editing) return;\n if (!edit.canEditCell(row, cell.column)) return;\n openEditor({\n rowId: row.id,\n columnId: cell.column.id,\n });\n }\n : undefined\n }\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(rangeBounds, viewIndex, cellIndex)\n : isCellAt(focusedCell, row.id, cell.column.id),\n edges: boundsEdges(rangeBounds, viewIndex, cellIndex),\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 renderRowContextMenu || cellRangeSelection || onCellContextMenu\n ? (event) => {\n contextMenuColumnRef.current = cell.column.id;\n if (isGroupRow) return;\n onCellContextMenu?.(\n cellEventArgs(cell, row, event),\n );\n }\n : undefined\n }\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-dg-part=\"details\"\n data-row-id={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\n return (\n <>\n {/* The pinned edge blocks. Same sticky mechanics as the\n entry block - the *block* is the sticky element, its rows\n flow normally inside it. `role=\"presentation\"` keeps the\n wrapper out of the accessibility tree, so the rows stay\n direct children of the rowgroup. Inside the rowgroup so\n a right-click on a pinned row still opens the menu. */}\n {pinnedTopRows.length > 0 && (\n <div\n role=\"presentation\"\n data-dg-part=\"pinned-top\"\n className={classes.pinnedTopBlock}\n >\n {pinnedTopRows.map((row, index) =>\n renderBodyRow(\n row,\n -1,\n headerGroups.length + index + 1,\n \"top\",\n ),\n )}\n </div>\n )}\n\n {paddingTop > 0 && (\n <div\n aria-hidden\n style={{ gridColumn: \"1/-1\", height: paddingTop }}\n />\n )}\n\n {virtualItems.map((virtualItem) => {\n const row = rows[virtualItem.index];\n if (!row) return null;\n return renderBodyRow(\n row,\n virtualItem.index,\n virtualItem.index +\n headerGroups.length +\n pinnedTopRows.length +\n 1,\n );\n })}\n\n {paddingBottom > 0 && (\n <div\n aria-hidden\n style={{ gridColumn: \"1/-1\", height: paddingBottom }}\n />\n )}\n\n {pinnedBottomRows.length > 0 && (\n <div\n role=\"presentation\"\n data-dg-part=\"pinned-bottom\"\n className={classes.pinnedBottomBlock}\n >\n {pinnedBottomRows.map((row, index) =>\n renderBodyRow(\n row,\n -1,\n headerGroups.length +\n pinnedTopRows.length +\n rows.length +\n index +\n 1,\n \"bottom\",\n ),\n )}\n </div>\n )}\n </>\n );\n })()}\n </TMDataGridBodyRowGroup>\n\n {/* The empty matrix, one state at a time: loading wins (data is on\n its way, \"empty\" would be a lie), open entry rows show only\n themselves (a \"no rows\" under the row being typed reads as a\n contradiction), then the consumer's blank slate, then the two\n defaults - filtered-empty with its search icon, truly-empty as\n plain text, because only one of them is the user's own doing. */}\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 && newRowCount === 0 && (\n <div role=\"row\" className={classes.messageRow}>\n {renderEmptyState !== undefined ? (\n renderEmptyState({\n hasActiveFilters,\n table: table as unknown as Table<TMDataGridFeatures, TData>,\n })\n ) : hasActiveFilters ? (\n <>\n <SearchIcon size={40} stroke={1.4} opacity={0.4} />\n <Text span size={controlSize} c=\"dimmed\">\n {noResultsLabel}\n </Text>\n </>\n ) : (\n <Text span size={controlSize} c=\"dimmed\">\n {labels.noRows}\n </Text>\n )}\n </div>\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={\n rows.length + pinnedRowCount + headerGroups.length + 1\n }\n // Also what the height measurement above looks for. One\n // attribute serves both now that the part name *is* the\n // published contract rather than a testing-only alias.\n data-dg-part=\"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\n.summaryCount {\n white-space: nowrap;\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 (\n <div data-dg-part=\"toolbar\" className={classes.toolbar}>\n {children}\n </div>\n );\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\" data-dg-part=\"loading\" 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 const shown = table.getRowCount();\n const total =\n table.options.meta?.totalRowCount ??\n table.getPreFilteredRowModel().rows.length;\n\n return (\n <Text\n span\n size={controlSize}\n c=\"dimmed\"\n className={classes.summaryCount}\n data-dg-part=\"summary-count\"\n >\n {children !== undefined ? children : `${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 data-dg-part=\"columns-button\"\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 // Also what the panel's click-away handler tests for, so that a click\n // here reads as a toggle rather than as a click outside.\n data-dg-part=\"filter-button\"\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 { TMDataGridDraftActions } from \"./TMDataGridDraftActions\";\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 /** Set on the root element. */\n id?: string;\n /**\n * Names this grid for tests. The grid names its own pieces with\n * `data-dg-part` rather than minting test ids, and those repeat across\n * grids - scope through this one and they stop colliding:\n *\n * ```ts\n * page.getByTestId(\"orders\").locator('[data-dg-part=\"row\"][data-row-id=\"42\"]')\n * ```\n *\n * See the Testing docs page for the full attribute contract.\n */\n \"data-testid\"?: string;\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 edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\n size = DEFAULT_TMDATAGRID_SIZE,\n children,\n className,\n style,\n id,\n \"data-testid\": testId,\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 edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\n size,\n rowHeight,\n controlSize: SIZE_CONTROL_SIZE[size],\n }),\n [\n table,\n ui,\n edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\n size,\n rowHeight,\n ],\n );\n\n return (\n <TMDataGridContextProvider value={api}>\n <div\n id={id}\n data-testid={testId}\n // The handle everything else scopes off - see the `data-testid` prop.\n data-dg-root\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 DraftActions: TMDataGridDraftActions,\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 { Input, RangeSlider } from \"@mantine/core\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport { operatorTakesRangeValue } from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for `number` columns: a range slider whose\n * bounds are seeded from the values present in the data, writing the\n * `between` pair. Pair it with `meta.filter.defaultOperator: \"between\"` so\n * the filter opens on it; any non-range operator falls back to the standard\n * input.\n */\nexport function DgRangeSliderFilter(args: TMDataGridFilterControlArgs) {\n const { column, operator, value, onChange, size, labels } = args;\n if (!operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n\n // Bounds from the faceted index - the min and max actually in the data.\n const numbers: number[] = [];\n for (const key of column.getFacetedUniqueValues().keys()) {\n const numeric = Number(key);\n if (Number.isFinite(numeric)) numbers.push(numeric);\n }\n const min = numbers.length > 0 ? Math.min(...numbers) : 0;\n const max = numbers.length > 0 ? Math.max(...numbers) : 100;\n\n const pair = Array.isArray(value) ? value : [\"\", \"\"];\n const lower = pair[0] === undefined || pair[0] === \"\" ? min : Number(pair[0]);\n const upper = pair[1] === undefined || pair[1] === \"\" ? max : Number(pair[1]);\n\n return (\n <Input.Wrapper label={labels.filterValue} size={size} w={180}>\n <RangeSlider\n size={size}\n mt={6}\n min={min}\n max={max}\n minRange={0}\n value={[\n Math.min(Math.max(lower, min), max),\n Math.min(Math.max(upper, min), max),\n ]}\n thumbFromLabel={labels.filterFrom}\n thumbToLabel={labels.filterTo}\n onChange={([nextLower, nextUpper]) =>\n onChange([String(nextLower), String(nextUpper)])\n }\n />\n </Input.Wrapper>\n );\n}\n","import { Group, TextInput } from \"@mantine/core\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport { operatorTakesRangeValue } from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for `date` columns: a From/To pair of\n * native date inputs writing the `between` pair - no `@mantine/dates`\n * involved, like the built-in date editor. Pair it with\n * `meta.filter.defaultOperator: \"between\"`; any non-range operator falls back\n * to the standard input.\n */\nexport function DgDateRangeFilter(args: TMDataGridFilterControlArgs) {\n const { operator, value, onChange, size, labels } = args;\n if (!operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n\n const pair: [string, string] = Array.isArray(value)\n ? [String(value[0] ?? \"\"), String(value[1] ?? \"\")]\n : [\"\", \"\"];\n\n return (\n <Group gap={4} wrap=\"nowrap\" align=\"flex-start\">\n <TextInput\n label={labels.filterFrom}\n size={size}\n w={88}\n type=\"date\"\n value={pair[0]}\n onChange={(event) => onChange([event.currentTarget.value, pair[1]])}\n />\n <TextInput\n label={labels.filterTo}\n size={size}\n w={88}\n type=\"date\"\n value={pair[1]}\n onChange={(event) => onChange([pair[0], event.currentTarget.value])}\n />\n </Group>\n );\n}\n","import { Autocomplete } from \"@mantine/core\";\nimport { resolveColumnOptions } from \"../../core/columnOptions\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport {\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for text-shaped columns: a free-text input\n * that also offers the values present in the data (or the column's declared\n * `meta.options`) as suggestions. Set or range operators fall back to the\n * standard input.\n */\nexport function DgAutocompleteFilter(args: TMDataGridFilterControlArgs) {\n const { column, table, operator, value, onChange, options, size, labels } =\n args;\n if (operatorTakesArrayValue(operator) || operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n const needsValue = operatorNeedsValue(operator);\n // `options` arrives pre-resolved only for declared or select-shaped\n // columns; on a plain string column the suggestions come from the faceted\n // values, resolved here.\n const suggestions =\n options.length > 0\n ? options\n : resolveColumnOptions({ table, column, fallback: \"faceted\" });\n\n return (\n <Autocomplete\n label={labels.filterValue}\n size={size}\n w={180}\n comboboxProps={{ withinPortal: false }}\n disabled={!needsValue}\n placeholder={needsValue ? labels.filterValuePlaceholder : \"\"}\n data={suggestions.map((option) => option.value)}\n limit={20}\n value={needsValue && typeof value === \"string\" ? value : \"\"}\n onChange={onChange}\n />\n );\n}\n","import { Input, SegmentedControl } from \"@mantine/core\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport {\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for `boolean` columns: an All / Yes / No\n * segmented control - All clears the value, which deactivates the filter.\n * Set or range operators fall back to the standard input.\n */\nexport function DgTriStateFilter(args: TMDataGridFilterControlArgs) {\n const { operator, value, onChange, size, labels } = args;\n if (operatorTakesArrayValue(operator) || operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n const needsValue = operatorNeedsValue(operator);\n const scalar = typeof value === \"string\" ? value : \"\";\n\n return (\n <Input.Wrapper label={labels.filterValue} size={size}>\n <SegmentedControl\n size={size}\n disabled={!needsValue}\n data={[\n { value: \"all\", label: labels.filterAll },\n { value: \"true\", label: labels.booleanTrue },\n { value: \"false\", label: labels.booleanFalse },\n ]}\n value={scalar === \"true\" || scalar === \"false\" ? scalar : \"all\"}\n onChange={(next) => onChange(next === \"all\" ? \"\" : next)}\n />\n </Input.Wrapper>\n );\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 between: \"är mellan\",\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 LAYOUT\",\n columnsResetHint:\n \"Återställer kolumnernas synlighet, ordning, bredder, fästning och gruppering\",\n rowNumberColumnLabel: \"Radnummer\",\n noRows: \"Inga rader att visa\",\n\n filterColumn: \"Kolumn\",\n filterOperator: \"Operator\",\n filterValue: \"Värde\",\n filterValuePlaceholder: \"Filtervärde\",\n filterFrom: \"Från\",\n filterTo: \"Till\",\n filterAll: \"Alla\",\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 editCell: (column) => `Redigera ${column}`,\n confirmEdit: \"Spara\",\n cancelEdit: \"Avbryt\",\n editColumnLabel: \"Redigera\",\n editRow: \"Redigera rad\",\n saveRow: \"Spara rad\",\n cancelRowEdit: \"Avbryt redigering\",\n editRowErrors: \"Åtgärda de markerade cellerna\",\n saveAllEdits: (rows) => (rows === 1 ? \"Spara 1 rad\" : `Spara ${rows} rader`),\n discardAllEdits: \"Förkasta\",\n editRowsStillOpen: (rows) =>\n rows === 1 ? \"1 rad redigeras fortfarande\" : `${rows} rader redigeras fortfarande`,\n confirmNewRow: \"Lägg till rad\",\n discardNewRow: \"Släng ny rad\",\n deleteRow: \"Ta bort rad\",\n restoreRow: \"Återställ rad\",\n revertRow: \"Ångra ändringar\",\n rowStateNew: \"Ny rad\",\n rowStateEdited: \"Ändrad rad\",\n rowStateDeleted: \"Markerad för borttagning\",\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 *\n * Every data row counts once. Grouping builds its group rows from this model\n * rather than into it, so a grouped grid totals its records, not its records\n * plus their subtotals; a tree counts parents and children alike.\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 // `flatRows`, not `rows`: the filtered model nests under `getSubRows`, and\n // the top-level array would total a tree's roots and drop every child.\n // Grouping does not nest it - the group rows are built from this model, not\n // held in it - so a grouped grid is unaffected either way.\n const rows = erased.getFilteredRowModel().flatRows;\n // Leaf and child rows are the same set here: this is already every row.\n return aggregationFns[fn](columnId, rows, rows);\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","Row","RowData","TableFeatures","TMDataGridFilterValue","operator","TMDataGridFilterOperator","value","ReadonlyArray","TMDataGridColumnType","FILTER_OPERATOR_LABELS","Record","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","between","before","after","onOrBefore","onOrAfter","isAnyOf","isNoneOf","isEmpty","isNotEmpty","STRING_OPERATORS","NUMBER_OPERATORS","DATE_OPERATORS","BOOLEAN_OPERATORS","SELECT_OPERATORS","VALUELESS_OPERATORS","ARRAY_OPERATORS","RANGE_OPERATORS","OPERATORS_BY_TYPE","string","number","boolean","date","select","multiSelect","DEFAULT_OPERATOR_BY_TYPE","getOperatorsForType","type","getDefaultOperator","operatorNeedsValue","includes","operatorTakesArrayValue","operatorTakesRangeValue","emptyValueForOperator","isTMDataGridFilterValue","isFilterActive","Array","isArray","some","entry","String","trim","formatFilterLabel","label","filter","operatorLabels","text","map","join","toIsoDay","Date","Number","isNaN","getTime","toLocaleDateString","match","exec","boundHolds","cellValue","bound","end","boundText","numericCell","NaN","numericBound","cellDay","boundDay","isEmptyCell","undefined","length","matchesFilter","set","toLowerCase","cellEntries","hit","min","max","filterText","filterDay","numericFilter","compareNumeric","cellText","needle","tmDataGridFilterFn","row","TFeatures","TData","columnId","filterValue","getValue","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","id","detailsToggle","DetailsHeader","getPrePaginatedRowModel","flatRows","detailRows","state","rows","target","allExpanded","collapseAllDetails","expandAllDetails","setExpanded","expand","t7","createDetailsColumn","label","TData","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","header","cell","FormApi","getBy","AnyFieldApi","AnyFormApi","StandardSchemaV1","batch","Store","Cell","Column","Row","RowData","ComponentType","TMDataGridRowData","TMDataGridFeatures","TMDataGridTable","isColumnEditableForRow","isColumnEditSwitchedOff","isControlColumn","TMDataGridColumnType","TMDataGridSize","TMDataGridEditMode","TMDataGridRowEditForm","TMDataGridEditField","TMDataGridValidator","args","value","fieldApi","TMDataGridFieldValidate","onMount","onChange","onChangeAsync","onChangeAsyncDebounceMs","onBlur","onBlurAsync","onSubmit","onSubmitAsync","TMDataGridRowValidators","onSubmitAsyncDebounceMs","TMDataGridTableValidateArgs","TData","rowId","isNew","rows","ReadonlyArray","TMDataGridTableValidators","Promise","TMDataGridEditChange","columnId","field","previous","next","TMDataGridEditCommitArgs","original","changes","Array","source","TMDataGridEditRowProjection","dirtyFields","errorFields","errorMessages","message","hasRowError","isSubmitting","values","TMDataGridEditState","active","openRowIds","Record","committedRowIds","newRows","tempId","committed","deletedRowIds","EMPTY_EDIT_STATE","getOpenRowIds","state","filter","includes","some","newRow","length","ErasedRow","ErasedColumn","TMDataGridEditorArgs","form","cell","row","column","table","commit","cancel","size","seedText","TMDataGridEditorComponent","TMDataGridEditValueMapArgs","TMDataGridEditValueMap","TMDataGridColumnEditOptions","enabled","editor","validate","mapValue","TMDataGridRowAddArgs","TMDataGridRowDeleteArgs","TMDataGridSaveDraftsArgs","updated","created","deleted","added","TMDataGridSaveOutcomes","TMDataGridSaveDraftsResult","isSaved","outcomes","id","undefined","TMDataGridEditCommitDraftsArgs","TMDataGridEditEngineContext","editMode","draft","rowValidators","tableValidators","editableColumnIds","isRowEditable","onEditCommit","onSaveDrafts","newRowDefaults","onRowAdd","onRowDelete","getEditFieldName","columnDef","meta","edit","fromMeta","accessorKey","clearedValueForType","type","TMDataGridAddRowsOptions","TMDataGridAddRowsResult","open","TMDataGridEditApi","store","getForm","canEditCell","canEditRow","isColumnEditable","begin","target","deactivate","cancelAll","commitAll","saveDrafts","submitAll","clearCell","setCellValue","setRowValues","addRow","Partial","addRows","options","deleteRow","canDeleteRows","clearFormSourcedFieldErrors","fieldMeta","errorSourceMap","name","Object","entries","staleKeys","map","key","setFieldMeta","errorMap","fromEntries","sameValue","a","b","is","isArray","every","entry","i","Date","getTime","hasAnyError","errors","error","firstErrorText","text","SUBMIT_VALIDATE_TRIGGERS","const","isValidationError","result","runFieldValidator","validator","schema","issues","createEditEngine","getContext","FormEntry","lastSubmitOk","submitErrors","parkOnly","pendingCommit","unsubscribe","unmount","forms","Map","newRowCounter","savingDrafts","draftCollector","draftAddCollector","allowed","editableColumns","getAllLeafColumns","validateColumnFields","getRow","fields","normalized","normalizeFieldValidate","trigger","keys","mergedRows","Set","getCoreRowModel","flatRows","has","push","held","get","runTableValidators","validators","sync","mergeSubmitResults","results","only","shape","mergedFields","merged","composeValidators","consumerAsync","fromConsumer","fromTable","diff","project","live","flatMap","kept","current","change","publishRow","setState","prev","setActive","setNewRowCommitted","find","setCommitted","drop","delete","createForm","defaultValues","addArgs","setErrorMap","Error","String","mount","subscription","subscribe","set","getIsGrouped","context","takeFieldErrors","handleSubmit","beginOn","entryForm","getColumn","openElsewhere","other","then","ok","seedNewRow","defaults","tempIds","takeDeletedRowIds","committedFormIds","openIds","all","Boolean","saveInFlight","saveDraftsInner","finally","committedIds","deletedIds","collected","allValid","savedAll","savedDeletions","committedOk","savedOk","writeFields","writes","setFieldValue","writableField","ActionIcon","Group","Loader","Tooltip","useSelector","ColumnDef","Row","RowData","classes","useCellControlTabIndex","useTMDataGridContext","TMDataGridFeatures","firstErrorText","CheckIcon","CloseIcon","PencilIcon","PlusIcon","RestoreIcon","TrashIcon","EDIT_COLUMN_ID","RowStateIndicator","t0","$","_c","state","rowId","label","error","Icon","t1","t2","undefined","t3","t4","rowStateIndicator","t5","EditLaneCell","row","edit","features","labels","tabIndex","id","openRowIds","includes","isOpen","store","state_0","rows","projection","state_1","newRows","some","newRow","tempId","isNew","state_2","find","newRow_0","committed","isConfirmedNew","state_3","committedRowIds","isCommitted","t6","state_4","deletedRowIds","isMarkedDeleted","getIsGrouped","hasErrors","hasRowError","errorFields","length","t7","getForm","errors","errorMessages","message","editRowErrors","rowError","t8","canDeleteRows","deleteRow","event","stopPropagation","trash","t9","rowStateNew","t10","event_0","begin","columnId","t11","Symbol","for","t12","editRow","t13","t14","cancel","t15","t16","discardNewRow","t17","t18","commit","confirmNewRow","rowStateDeleted","event_1","restoreRow","canEditRow","isSubmitting","loading","rowStateEdited","event_2","revertRow","editMode","event_3","event_4","saveRow","save","event_5","cancelRowEdit","createEditColumn","wide","TData","width","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","header","cell","aggregatedCell","Row","RowData","TMDataGridFeatures","getGroupDataRows","row","TData","Array","subRows","length","getLeafRows","filter","leaf","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","id","t8","event","stopPropagation","toggleExpanded","t9","Symbol","for","t10","chevron","t11","groupLabel","t12","t13","length","groupCount","t14","GroupHeader","compare","grouping","_temp","groupColumnLabel","columnId","column","getColumn","map","join","state","createGroupColumn","TData","meta","enableOrdering","size","minSize","enableSorting","enableColumnFilter","enableGlobalFilter","enableHiding","enablePinning","cell","aggregatedCell","header","ColumnDef","RowData","TMDataGridFeatures","ROW_NUMBER_COLUMN_ID","createRowNumberColumn","label","TData","id","meta","align","enableOrdering","size","minSize","maxSize","enableResizing","enableSorting","enableColumnFilter","enableGlobalFilter","enablePinning","enableHiding","header","cell","Row","RowData","RowSelectionState","TMDataGridFeatureFlags","getGroupDataRows","TMDataGridFeatures","TMDataGridTable","getDisplayedRows","table","TData","features","Array","rows","isPagingActive","getPaginatedRowModel","getPrePaginatedRowModel","rowPinning","top","bottom","store","state","length","pinned","Set","filter","row","has","id","pagination","grouping","TMDataGridRowClickModifiers","toggle","extend","ResolveRowSelectionClickArgs","ReadonlyArray","rowId","anchorRowId","modifiers","selection","canReplaceSelection","ResolvedRowSelection","getSelectableRowIds","dataRow","getCanSelect","map","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","enableHiding","enablePinning","header","cell","aggregatedCell","Row","getDefaultOperator","TMDataGridColumnType","TMDataGridFilterOperator","DETAILS_COLUMN_ID","EDIT_COLUMN_ID","GROUP_COLUMN_ID","ROW_NUMBER_COLUMN_ID","SELECT_COLUMN_ID","TMDataGridRowData","TMDataGridColumnMeta","TMDataGridFeatures","TMDataGridFilterControlComponent","ColumnLike","id","columnDef","header","meta","parent","getColumnLabel","column","label","getColumnType","type","getColumnDefaultOperator","filter","defaultOperator","getColumnFilterControl","control","isColumnEditSwitchedOff","edit","enabled","isColumnEditableForRow","row","getColumnAlign","align","isControlColumn","columnId","isGeneratedColumn","isColumnReorderable","enableOrdering","undefined","Button","Checkbox","ScrollArea","Text","TextInput","Tooltip","useSelector","useState","classes","useTMDataGridContext","getColumnLabel","SearchIcon","TMDataGridColumnsPanel","$","_c","table","labels","controlSize","resetSettings","search","setSearch","columnVisibility","store","_temp","T0","columns","setAllVisible","shownCount","t0","t1","t2","t3","t4","t5","t6","visibleInPanel","columnsSearchPlaceholder","getAllLeafColumns","filter","_temp2","needle","trim","toLowerCase","column_0","column","includes","t7","column_1","id","length","visible","setColumnVisibility","previous","next","column_2","columnsPanel","t8","Symbol","for","event","currentTarget","value","t9","columnsPanelSearch","Autosize","columnsPanelList","t10","column_3","event_0","toggleVisibility","checked","map","columnsNoMatch","t11","t12","event_1","t13","columnsShowHideAll","t14","t15","columnsReset","t16","columnsResetHint","t17","columnsPanelFooter","t18","getCanHide","state","Button","Group","Text","useSelector","shallow","ReactNode","useTMDataGridContext","getOpenRowIds","getDisplayedRows","TMDataGridScrollAlign","TMDataGridScrollToRowArgs","useDraftCount","edit","store","_temp2","state","committedRowIds","length","newRows","filter","_temp","deletedRowIds","newRow","committed","useOpenCount","_temp3","useOpenRowIds","$","_c","t0","Symbol","for","compare","EditSaveButton","labels","draftCount","isSubmitting","_temp4","t1","saveDrafts","t2","saveAllEdits","t3","openRowIds","some","rowId","rows","EditOpenRowsNote","openCount","editRowsStillOpen","EditDiscardButton","pendingCount","cancelAll","discardAllEdits","EDIT_ACTIONS_CONTROLS","TMDataGridDraftActionsControls","Save","Discard","OpenRowsNote","TMDataGridDraftActionsState","ReadonlyArray","TMDataGridDraftActionsActions","save","Promise","commitAll","discard","scrollToRow","args","scrollToFirstOpenRow","align","TMDataGridDraftActionsSlotArgs","actions","Controls","TMDataGridDraftActionsProps","renderActions","TMDataGridDraftActions","undefined","features","table","_temp5","editing","t4","state_0","openIds","open","Set","first","find","row","has","id","rowId_0","tempId","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","Group","MultiSelect","Select","TextInput","optionsToComboboxData","getColumnType","TMDataGridFilterControlArgs","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","TMDataGridFilterValueInput","t0","$","_c","column","operator","value","onChange","options","size","labels","type","t1","needsValue","scalarValue","inputType","t2","Array","isArray","String","rangeValue","t3","event","currentTarget","t4","filterFrom","t5","event_0","t6","filterTo","t7","filterValue","Symbol","for","withinPortal","filterValuePlaceholder","booleanTrue","label","booleanFalse","t8","t9","next","t10","event_1","ActionIcon","Button","Select","Stack","Text","TextInput","useSelector","useEffect","useRef","classes","useTMDataGridContext","resolveColumnOptions","getColumnDefaultOperator","getColumnFilterControl","getColumnLabel","getColumnType","TMDataGridFilterOperator","TMDataGridFilterValue","emptyValueForOperator","getDefaultOperator","getOperatorsForType","isTMDataGridFilterValue","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","CloseIcon","TMDataGridFilterValueInput","FALLBACK_FILTER","operator","value","asFilterValue","valueShape","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","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","operator_1","t6","column_2","filter_6","canAddFilter","filters","event_0","key","stopPropagation","Symbol","for","t7","closeFilters","t8","filterPanelHeader","t9","t10","filter_7","column_3","value_1","type","needsValue","scalarValue","options","columnDef","meta","undefined","fallback","ValueControl","filterRow","filterColumn","withinPortal","next","filterOperator","operator_2","label","operators","next_0","next_1","filterValue","filterValuePlaceholder","event_1","currentTarget","t11","t12","t13","t14","filterPanelFooter","t15","t16","filterPanel","column_0","getCanFilter","state_0","state","filterPanelOpen","compareItems","rankItem","RankingInfo","createSortedRowModel","Row","RowData","RowModel","Table","TableFeatures","TMDataGridQuickSearchMode","FUZZY_FILTER_FN_NAME","FuzzyFilterMeta","fuzzyRank","isFuzzyFilterMeta","value","rank","fuzzyGlobalFilterFn","row","TFeatures","TData","columnId","filterValue","addMeta","meta","String","getValue","passed","bestRank","best","columnFiltersMeta","Record","Object","values","isRankingActive","table","globalFilterFn","options","state","store","sorting","Array","grouping","globalFilter","length","trim","createFuzzyRankedSortedRowModel","base","getSorted","lastModel","ranked","model","rows","sort","a","b","rankA","rankB","flatRows","rowsById","FILTER_OPERATOR_LABELS","TMDataGridFilterOperator","TMDataGridLabels","operators","Record","manageColumns","filters","searchPlaceholder","searchLabel","clearSearch","columnsSearchPlaceholder","columnsNoMatch","search","columnsShowHideAll","columnsReset","columnsResetHint","rowNumberColumnLabel","noRows","filterColumn","filterOperator","filterValue","filterValuePlaceholder","filterFrom","filterTo","filterAll","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","editCell","confirmEdit","cancelEdit","editColumnLabel","editRow","saveRow","cancelRowEdit","editRowErrors","saveAllEdits","rows","discardAllEdits","editRowsStillOpen","confirmNewRow","discardNewRow","deleteRow","restoreRow","revertRow","rowStateNew","rowStateEdited","rowStateDeleted","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","PERSIST_PAYLOAD_VERSION","VERSION_FIELD","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","collectLeafColumnIds","defs","into","def","columns","length","accessorKey","id","replaceAll","header","push","realignToColumns","known","ReadonlySet","has","keepIds","filter","keepKeys","T","fromEntries","entries","keepEntries","realigned","left","right","readPersistedState","knownColumnIds","Set","writePersistedState","Column","RowData","TMDataGridRowData","isColumnReorderable","TMDataGridEditMode","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","editing","editMode","editDraft","editNewRowsSticky","rowNumbers","rowPinning","matchHighlighting","readFeatureFlags","options","Pick","TData","undefined","enableRowSelection","enableSorting","enableColumnFilters","enableGlobalFilter","enableHiding","enableColumnPinning","enableColumnResizing","enableColumnOrdering","enableMultiRowSelection","enablePagination","manualPagination","enableGrouping","mode","draft","newRowsSticky","enableRowNumbers","enableRowPinning","enableMatchHighlighting","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","NextEditableCellArgs","direction","isEditable","coords","getNextEditableCell","total","start","step","index","floor","isSameCell","a","b","TableState","TMDataGridFeatures","GridState","CONTROLLED_SLICE_HANDLERS","columnFilters","columnOrder","columnPinning","columnResizing","columnSizing","columnVisibility","expanded","globalFilter","grouping","pagination","rowPinning","rowSelection","sorting","const","Partial","Record","TMDataGridControlledSlice","ControlledOptions","state","atoms","hasOwn","value","key","Object","prototype","hasOwnProperty","call","isDataObject","proto","getPrototypeOf","sameStateValue","a","b","is","Date","getTime","Array","isArray","length","every","item","index","keys","withoutUndefinedSlices","undefined","values","includes","compacted","entries","stabilizeControlledState","next","previous","stabilized","changed","nextValue","previousValue","findFrozenStateSlices","options","slice","handler","filter","map","useCreateStore","aggregationFns","ColumnDef","columnFacetingFeature","columnFilteringFeature","columnGroupingFeature","columnOrderingFeature","columnPinningFeature","columnResizingFeature","columnSizingFeature","columnVisibilityFeature","createColumnHelper","createExpandedRowModel","createFacetedMinMaxValues","createFacetedRowModel","createFacetedUniqueValues","createFilteredRowModel","createGroupedRowModel","createPaginatedRowModel","filterFns","globalFilteringFeature","metaHelper","Row","RowData","rowExpandingFeature","rowPaginationFeature","rowPinningFeature","rowSelectionFeature","rowSortingFeature","sortFns","Table","tableFeatures","TableOptions","TableState","useTable","Store","MutableRefObject","ReactNode","useCallback","useEffect","useMemo","useRef","useState","TMDataGridRowData","TMDataGridOptionsSource","createEditEngine","TMDataGridEditApi","TMDataGridEditCommitArgs","TMDataGridSaveDraftsArgs","TMDataGridSaveDraftsResult","TMDataGridEditEngineContext","TMDataGridColumnEditOptions","TMDataGridEditMode","TMDataGridRowAddArgs","TMDataGridRowDeleteArgs","TMDataGridRowValidators","TMDataGridTableValidators","emptyValueForOperator","TMDataGridColumnType","tmDataGridFilterFn","getColumnDefaultOperator","isControlColumn","TMDataGridColumnFilterOptions","createFuzzyRankedSortedRowModel","fuzzyGlobalFilterFn","TMDataGridQuickSearchMode","mergeLabels","TMDataGridLabels","TMDataGridLabelsOverride","collectLeafColumnIds","hasPersistenceKeys","readPersistedState","TMDataGridPersistence","writePersistedState","readFeatureFlags","TMDataGridCellSelectionMode","TMDataGridFeatureFlags","TMDataGridSelectionMode","isSameCell","TMDataGridCellPosition","findFrozenStateSlices","stabilizeControlledState","withoutUndefinedSlices","TMDataGridCellRange","createSelectColumn","SELECT_COLUMN_ID","createGroupColumn","GROUP_COLUMN_ID","createDetailsColumn","DETAILS_COLUMN_ID","createEditColumn","EDIT_COLUMN_ID","createRowNumberColumn","ROW_NUMBER_COLUMN_ID","PERSIST_DEBOUNCE_MS","TMDataGridColumnMeta","label","type","options","flex","align","autoSize","enableOrdering","filter","edit","TMDataGridTableMeta","loading","noResultsLabel","rowHeight","totalRowCount","tmDataGridFeatures","filteredRowModel","groupedRowModel","sortedRowModel","expandedRowModel","paginatedRowModel","facetedRowModel","facetedMinMaxValues","facetedUniqueValues","tmDataGrid","tmDataGridFuzzy","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","TMDataGridScrollAlign","TMDataGridScrollToRowArgs","TMDataGridScroller","TMDataGridApi","ui","features","labels","renderDetails","renderDetailsEstHeight","overscan","resetSettings","scrollToRow","scrollerRef","TMDataGridEditingCallbacks","rowValidators","tableValidators","isRowEditable","onCommit","Promise","newRowDefaults","onRowAdd","onRowDelete","TMDataGridEditingOptions","mode","columns","ReadonlyArray","draft","onSaveDrafts","onCommitDrafts","newRowsSticky","UseTMDataGridOptions","Omit","editing","getRowId","NonNullable","persist","enableColumnOrdering","enablePagination","enableRowNumbers","quickSearchMode","enableMatchHighlighting","selectionMode","showSelectedBackground","defaultHighlightedRowId","onHighlightedRowChange","cellSelection","onFocusedCellChange","TMDataGridColumnDef","withoutControlColumnVisibility","visibility","Record","scrubbed","id","Object","keys","withTMDataGridDefaults","Array","map","column","isArray","filterFn","aggregationFn","undefined","aggregatedCell","useTMDataGrid","labelsOverride","editMode","editDraft","pinningEnabled","enableColumnPinning","selectColumnEnabled","selectColumn","groupColumnEnabled","grouping","detailsColumnEnabled","editColumnEnabled","selectColumnLabel","groupColumnLabel","detailsColumnLabel","editColumnLabel","rowNumberColumnLabel","rowNumbersEnabled","rowNumbers","editWideLane","base","persistedState","initialGrouping","initialState","groupingActiveRef","state","length","consumerState","controlledColumnVisibility","columnVisibility","requestedState","current","controlledStateRef","Partial","republishControlledStateRef","controlledState","pinnedResizingRef","selectSettledState","resizing","columnResizing","pinned","isResizingColumn","columnResizeMode","enableSorting","enableColumnResizing","globalFilterFn","groupedColumnMode","getRowCanExpand","enableRowPinning","getIsGrouped","columnPinning","left","right","pagination","pageIndex","pageSize","editContextRef","editableColumnIds","onEditCommit","previousEditPolicyRef","previous","cancelAll","console","error","slice","handler","warn","previousGrouping","store","setColumnVisibility","old","subscription","subscribe","setColumnOrder","unsubscribe","timeout","ReturnType","setTimeout","pending","flush","clearTimeout","setState","prev","anchor","focus","onHighlightedRowChangeRef","onFocusedCellChangeRef","resetSettingsRef","initial","setGrouping","setColumnSizing","columnSizing","columnOrder","setColumnPinning","openColumnFilter","api","getColumn","getFilterValue","operator","setFilterValue","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","t9","Symbol","for","bb0","filter","_temp2","length","t10","filterPills","Boolean","join","Group","t11","filter_0","column","getColumn","id","label","value","pill","setColumnFilters","other","clearFilter","tabIndex","pillLabel","type","operatorLabels","operators","map","clearAllFilters","t12","state","useSelector","shallow","ReadonlyStore","Store","TRANSIENT_SLICE","useSettledTableState","store","$","_c","t0","Symbol","for","compare","_temp","state","settled","slice","value","Object","entries","ActionIcon","Group","Select","Text","Tooltip","RowData","useMemo","ReactNode","classes","useTMDataGridContext","getGridCapabilities","useSettledTableState","isPagingActive","ChevronLeftIcon","ChevronRightIcon","TMDataGridTable","TMDataGridPaginationState","pageIndex","pageSize","pageCount","rowCount","canPreviousPage","canNextPage","from","to","TMDataGridPaginationActions","setPageIndex","setPageSize","previousPage","nextPage","firstPage","lastPage","TMDataGridPaginationApi","state","actions","TMDataGridPaginationControls","PageSize","Range","Pager","TMDataGridPaginationSlotArgs","Controls","getTMDataGridPaginationApi","table","TData","isPaging","store","pagination","getRowCount","getPageCount","getCanPreviousPage","getCanNextPage","Math","min","index","size","PaginationPageSize","t0","$","_c","pageSizeOptions","features","labels","controlSize","t1","paging","t2","includes","sort","_temp","sizeOptions","t3","rowsPerPage","t4","t5","map","String","t6","t7","value","Number","t8","t9","a","b","PaginationRange","T0","total","pageRange","groupedAllRows","getFilteredRowModel","rows","length","PaginationPager","Symbol","for","TMDataGridFooterProps","ReadonlyArray","renderPagination","args","DEFAULT_PAGE_SIZE_OPTIONS","TMDataGridFooter","undefined","canPaginate","bb0","footer","pagingSuspendedHint","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","mountedCells","container","columnId","NodeListOf","id","CSS","escape","querySelectorAll","hasMountedCells","length","measureColumnContentWidth","widest","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","isGeneratedColumn","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","keepGeneratedColumnsOutermost","pinning","generated","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","keepGeneratedColumnsOutermost","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","TMDataGridTableInstance","ReturnType","TMDataGridHeader","TMDataGridColumnMenuItemsArgs","column","table","internalItems","Array","TMDataGridColumnMenuItemsRenderer","args","TMDataGridHeaderCell","t0","$","_c","header","layout","renderColumnMenuItems","api","features","labels","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","finalItems","freezeRenderedWidths","handleDragEnd","handleDragLeave","handleDragOver","handleDragStart","handleDrop","isAnyResizing","isDragged","isDropTarget","isFiltered","isResizing","isSorted","label","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","container_0","sizing","state","columnSizing","frozen","leaf","getLeafHeaders","querySelector","CSS","escape","Math","round","Object","keys","setColumnSizing","previous","t16","setPinned","position","pin","setColumnPinning","menuItems","t17","t18","toggleSorting","t19","sortAsc","t20","t21","t22","sortDesc","t23","push","filterMenuItem","menuItemActive","getToggleGroupingHandler","ungroup","groupBy","groupedId","groupedColumn","getColumn","toggleGrouping","expand","setExpanded","rows","getPrePaginatedRowModel","flatRows","expanded","target","expandAllGroups","collapseAllGroups","pinLeft","t24","pinRight","t25","t26","t27","unpin","direction","previous_0","next_0","moveLeft","moveRight","toggleVisibility","hideColumn","setColumnsPanelOpen","manageColumns","isDivider","at","pop","hasMenu","headerCellSortable","headerCellFiltered","headerCellDragging","headerCellDropBefore","headerCellDropAfter","isBoundary","stickyLeft","stickyRight","headerCell","Boolean","cellClass","join","offset","right","zIndex","_temp3","event_4","getToggleSortingHandler","t28","columnDef","isPlaceholder","headerTitle","getContext","t29","headerActions","headerAction","filterOn","event_5","stopPropagation","sortAction","sortColumn","columnMenu","event_6","_temp4","_temp5","t30","columnSeparator","columnSeparatorResizable","columnSeparatorActive","event_8","getResizeHandler","event_9","_temp6","event_11","t31","cell","t32","opened_0","opened","t33","t34","_temp7","t35","event_12","event_10","event_7","event_3","shiftKey","state_0","columnResizing","isResizingColumn","columnOrder","node","type","Divider","useStore","useLayoutEffect","useRef","RefObject","firstErrorText","TMDataGridEditField","useFieldValue","field","store","_temp","state","value","useFieldError","_temp2","meta","errors","ReadonlyArray","selectAllOnFocus","event","currentTarget","target","HTMLInputElement","select","useCaretKeeper","$","_c","inputRef","caret","t0","Symbol","for","pending","current","input","shift","length","next","Math","max","min","position","setSelectionRange","t1","remember","input_0","selectionStart","Checkbox","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridBooleanEditor","t0","$","_c","field","column","size","labels","value","error","t1","editCell","t2","t3","event","handleChange","currentTarget","checked","t4","handleBlur","TextInput","useRef","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridDateEditor","t0","$","_c","field","column","size","labels","value","error","writesDates","Date","t1","toLocaleDateString","slice","text","t2","editCell","t3","event","next","currentTarget","handleChange","current","t4","handleBlur","MultiSelect","TMDataGridEditorArgs","optionsToComboboxData","resolveColumnOptions","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridMultiSelectEditor","t0","$","_c","field","column","row","table","size","labels","value","error","t1","Symbol","for","withinPortal","t2","editCell","t3","fallback","t4","Array","isArray","map","String","t5","next","handleChange","t6","handleBlur","NumberInput","useState","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","selectAllOnFocus","useCaretKeeper","useFieldError","useFieldValue","TMDataGridNumberEditor","t0","$","_c","field","column","size","labels","value","error","inputRef","remember","typed","setTyped","parsedTyped","Number","textDescribesField","isFinite","t1","editCell","t2","t3","next","current","handleChange","parsed","t4","handleBlur","Select","TMDataGridEditorArgs","optionsToComboboxData","resolveColumnOptions","getColumnLabel","useTMDataGridContext","useFieldError","useFieldValue","TMDataGridSelectEditor","t0","$","_c","field","column","row","table","size","commit","labels","features","value","error","t1","Symbol","for","withinPortal","t2","editCell","t3","fallback","t4","t5","next","handleChange","editMode","t6","handleBlur","TextInput","TMDataGridEditorArgs","getColumnLabel","useTMDataGridContext","selectAllOnFocus","useCaretKeeper","useFieldError","useFieldValue","TMDataGridStringEditor","t0","$","_c","field","column","size","labels","value","error","inputRef","remember","t1","editCell","t2","t3","event","currentTarget","handleChange","t4","handleBlur","ActionIcon","FieldApi","Cell","Row","ComponentType","FocusEvent","KeyboardEvent","useEffect","useRef","useState","classes","TMDataGridRowData","useTMDataGridContext","getEditFieldName","normalizeFieldValidate","TMDataGridEditField","TMDataGridEditorArgs","TMDataGridEditValueMap","TMDataGridFeatures","CheckIcon","CloseIcon","TMDataGridBooleanEditor","TMDataGridDateEditor","TMDataGridMultiSelectEditor","TMDataGridNumberEditor","TMDataGridSelectEditor","TMDataGridStringEditor","BUILT_IN_EDITORS","Record","string","number","boolean","date","select","multiSelect","TMDataGridCellEditorClose","committed","via","TMDataGridCellEditor","cell","row","takeSeedText","onClose","inEntryBlock","args","table","edit","features","labels","controlSize","isRowShaped","editMode","column","form","getForm","id","fieldName","seedText","mapValueRef","undefined","current","columnDef","meta","mapValue","field","created","name","validators","validate","write","handleChange","bind","updater","map","previous","state","value","prev","mount","type","seeded","Number","isFinite","closingRef","commitAndClose","Promise","ok","commit","cancelAndClose","cancel","deferAndClose","deactivate","handleKeyDown","event","HTMLDivElement","key","preventDefault","stopPropagation","shiftKey","handleBlur","next","relatedTarget","Node","currentTarget","contains","then","size","Editor","editor","cellEditor","cellEditorActions","confirmEdit","cancelEdit","FOCUSABLE_IN_CELL","join","focusEditorContent","editor","HTMLElement","target","querySelector","focus","flexRender","useTable","Column","Row","useSelector","useLayoutEffect","useMemo","useRef","classes","sticky","TMDataGridRowData","useTMDataGridContext","getColumnAlign","isColumnEditableForRow","isControlColumn","TMDataGridEditApi","focusEditorContent","tmDataGridFeatures","TMDataGridFeatures","TMDataGridCellEditor","EDIT_COLUMN_ID","TMDataGridColumnLayout","ErasedColumn","isEntryCellEditable","row","column","edit","isColumnEditable","TMDataGridEntryRows","t0","$","_c","orderedColumns","layoutFor","rowHeight","table","features","newRows","store","_temp","activeEntry","_temp2","blockRef","focusedTempIdRef","focusedActiveRef","t1","newest","at","tempId","undefined","current","block","editor","querySelector","CSS","escape","t2","key","rowId","columnId","block_0","editor_0","t3","t4","t5","committed","getForm","state","values","options","defaultValues","map","data","_row","index","String","columns","getRowId","entryTable","length","t6","t7","editNewRowsSticky","entryRows","getCoreRowModel","rows","t8","Map","_temp3","committedById","t9","entryRow","get","id","stickyRows","filter","flowRows","entryRow_0","t10","entryRow_1","pinnedZ","cellsById","getAllCells","_temp4","committed_0","cell_0","layout","editable","cell","begin","entryCell","isBoundary","pinnedAt","stickyLeft","stickyRight","Boolean","join","minHeight","left","offset","right","position","zIndex","columnDef","getContext","cellContent","_temp5","_temp6","renderEntryRow","entryBlock","entryRow_2","entryFlowBlock","entryRow_3","newRow_0","newRow","state_0","active","some","TMDataGridColumnTrack","id","track","minWidth","TMDataGridResizeProgress","isResizingColumn","columnSizingStart","Array","deltaPercentage","TMDataGridSizeBounds","minSize","maxSize","TMDataGridOffsetPatch","columnId","side","offset","TMDataGridResizePreview","gridTemplateColumns","offsets","DEFAULT_MIN_SIZE","DEFAULT_MAX_SIZE","Number","MAX_SAFE_INTEGER","draggedWidth","startWidth","bounds","dragged","Math","round","max","min","laneOffsets","lane","widthOf","Generator","resizePreview","progress","tracks","boundsOf","leftLane","rightLane","length","widths","Map","set","template","width","get","push","undefined","inLane","some","has","find","join","Cell","CellContext","Row","TMDataGridRowData","TMDataGridFeatures","ErasedCell","ErasedRow","ErasedCellContext","RowInternals","original","_valuesCache","Record","_uniqueValuesCache","draftCellContext","cell","draftValues","draftRow","Object","create","row","internals","draftCell","table","column","getValue","id","renderValue","options","renderFallbackValue","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","Row","RowData","TMDataGridFeatures","TMDataGridTable","readPinnedRows","table","TData","position","Array","ids","store","state","rowPinning","length","visible","getPrePaginatedRowModel","rowsById","all","getCoreRowModel","rows","id","row","undefined","getIsAllParentsExpanded","push","RowData","isTMDataGridFilterValue","TMDataGridFilterOperator","TMDataGridTable","TMDataGridMatchRange","start","end","HIGHLIGHTABLE_OPERATORS","ReadonlyArray","buildMatchNeedles","table","TData","Map","state","store","global","globalFilter","trim","byColumn","Array","filter","columnFilters","value","operator","includes","needles","get","id","push","set","size","map","column","getAllLeafColumns","getCanGlobalFilter","own","undefined","length","findMatchRanges","text","haystack","toLowerCase","found","needle","lowered","index","indexOf","sort","a","b","merged","range","last","at","Math","max","Checkbox","Loader","Menu","MenuProps","Text","Cell","Column","flexRender","Row","RowData","Table","useSelector","useVirtualizer","CSSProperties","KeyboardEvent","MouseEvent","ReactNode","UIEvent","useCallback","useEffect","useLayoutEffect","useRef","useState","classes","sticky","TMDataGridRowData","useTMDataGridContext","TMDataGridFilterPanel","TMDataGridHeaderCell","TMDataGridColumnMenuItemsRenderer","TMDataGridCellEditor","TMDataGridCellEditorClose","TMDataGridEntryRows","getColumnAlign","isControlColumn","resizePreview","TMDataGridColumnTrack","useSettledTableState","draftCellContext","getEditFieldName","TMDataGridEditState","getNextEditableCell","resolveCellMove","TMDataGridCellPosition","FOCUSABLE_IN_CELL","focusEditorContent","boundsCellCount","boundsEdges","isWithinBounds","resolveRangeBounds","buildCellMatrix","DEFAULT_CELL_EXPORT_OPTIONS","downloadTextFile","toClipboardText","toExcelCsv","writeClipboardText","TMDataGridCellExportOptions","autosizeColumn","hasMountedCells","getDisplayedRows","getSelectableRowIds","isPagingActive","resolveRowSelectionClick","readPinnedRows","buildMatchNeedles","findMatchRanges","ROW_NUMBER_COLUMN_ID","SearchIcon","TMDataGridFeatures","TMDataGridColumnLayout","pinnedAt","offset","isBoundary","UNPINNED_LAYOUT","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","withMatchHighlights","text","needles","ReadonlyArray","ranges","parts","Array","cursor","range","start","push","slice","matchHighlight","end","length","TMDataGridBodyCell","t0","$","_c","rowHeight","layout","nav","editor","contentOverride","highlightNeedles","onFocus","onClick","onMouseDown","onMouseEnter","onDoubleClick","onContextMenu","table","edit","t1","fieldName","cellRowId","row","id","t2","isControl","t3","state","projection","rows","dirtyFields","includes","isDirty","store","t4","state_0","projection_0","errorFields","isInvalid","t5","state_1","values","draftValues","t6","t7","t8","t9","t10","t11","t12","t13","t14","t15","t16","t17","t18","t19","t20","t21","t22","t23","stickyLeft","t24","stickyRight","t25","bodyCell","filter","Boolean","t26","join","t27","t28","t29","t30","t31","minHeight","position","zIndex","t32","cellContent","draftContext","getDefaultColumnDef","value","renderValue","String","t33","TMDataGridBodyRowGroup","enabled","menuContent","menuProps","onClose","children","Symbol","for","display","rowGroup","opened","TMDataGridRowContextMenuArgs","TData","close","internalItems","TMDataGridRowContextMenuRenderer","args","TMDataGridCellEventArgs","event","TMDataGridRowStyle","Record","TMDataGridTableProps","onRowClick","onCellClick","onCellDoubleClick","onCellContextMenu","rowClassName","rowStyle","striped","onScrollToTop","onScrollToBottom","onScrollToLeft","onScrollToRight","renderEmptyState","hasActiveFilters","renderRowContextMenu","renderColumnMenuItems","rowContextMenuProps","Omit","cellExport","onReachEnd","reachEndThreshold","TMDataGridTable","ariaLabel","ariaLabelledBy","ui","features","labels","controlSize","renderDetails","renderDetailsEstHeight","overscan","scrollerRef","highlightedRowId","focusedCell","cellRange","editActive","active","editOpenRowIds","openRowIds","newRowCount","newRows","deletedRowIds","editDirtyRowIds","editDraftRowIds","committedRowIds","loading","noResultsLabel","noResults","options","meta","scrollContainerRef","HTMLDivElement","matchNeedles","matchHighlighting","pinnedTopRows","rowPinning","pinnedBottomRows","pinnedRowCount","rowNumberById","Map","rowNumbers","n","pagination","pageIndex","pageSize","viewRow","getIsGrouped","set","showsDetails","getIsExpanded","pendingAutoSizeRef","Set","current","getAllLeafColumns","autoSize","map","pending","size","columnSizing","delete","gridElementRef","grid","headerRows","querySelectorAll","measure","total","headerRow","offsetHeight","style","setProperty","observer","ResizeObserver","observe","disconnect","entryBlock","removeProperty","summaryRow","pageCount","getPageCount","setPageIndex","virtualizer","count","getScrollElement","estimateSize","index","measureElement","element","_entry","instance","height","indexFromElement","getItemKey","initialRect","width","prevRowHeightRef","virtualItems","getVirtualItems","paddingTop","paddingBottom","getTotalSize","at","align","some","findIndex","scrollToIndex","reachEndFiredForCountRef","warnedReachEndPaginationRef","lastMountedIndex","console","warn","leftLeafColumns","getLeftVisibleLeafColumns","rightLeafColumns","getRightVisibleLeafColumns","centerLeafColumns","getCenterVisibleLeafColumns","orderedColumns","centerHeaderGroups","getCenterHeaderGroups","leftHeaderGroups","getLeftHeaderGroups","rightHeaderGroups","getRightHeaderGroups","headerGroups","group","headers","columnTracks","isFixed","minSize","maxSize","isResized","isPinned","getIsPinned","minWidth","track","getSize","flex","gridTemplateColumns","c","gridMinWidth","reduce","sum","columnLayout","widthOf","leftOffset","rightOffset","reverse","layoutFor","get","previewRef","tracks","leftLane","rightLane","painted","subscription","subscribe","preview","progress","columnResizing","boundsOf","getColumn","side","offsets","unsubscribe","isEmpty","emptyGlobalFilter","globalFilter","columnFilters","trim","leafHeaders","hasSummaryRow","footer","selectsOnRowClick","rowClickSelects","rowIsInteractive","highlightRow","rowGesturesFor","handleRowActivate","modifiers","toggle","extend","getCanSelect","resolved","anchorRowId","selectionAnchorRowId","selection","rowSelection","canReplaceSelection","setRowSelection","actions","setSelectionAnchor","setHighlightedRow","rowClassNameFor","rowStyleFor","cellEventArgs","cellSelection","cellRangeSelection","wantsCellFocusRef","appliedCellRef","focusedRowIndex","focusedColumnIndex","focusedCellIsMounted","item","firstMountedRow","tabStopCell","isCellAt","rangeBounds","rowIndexOf","columnIndexOf","setRangeTo","anchor","setCellRange","focus","selectionBounds","selectedCellCount","selectedDataColumnCount","exportOptions","exportIncludesHeaders","setExportIncludesHeaders","includeHeaders","buildSelectionMatrix","columns","bounds","decimalComma","copySelection","matrix","isDraggingRange","setIsDraggingRange","stop","window","addEventListener","removeEventListener","startRangeDrag","setFocusedCell","exportSelectionCsv","fileName","separator","moveFocusedCell","coords","rowIndex","editSeedRef","takeEditSeed","seed","firstEditableColumnId","find","candidate","cells","getLeftVisibleCells","getCenterVisibleCells","getRightVisibleCells","canEditCell","placedEditCaretRef","refocusCell","openEditor","begin","handleEditorClose","move","via","editMode","next","from","direction","rowCount","columnCount","isEditable","selectRowFromCell","handleGridKeyDown","target","dataset","key","closest","preventDefault","ctrlKey","metaKey","keyRow","keyColumn","editing","clearCell","then","altKey","interactive","shiftKey","pageRows","Math","max","floor","clientHeight","contains","document","activeElement","Element","preventScroll","contextMenuTarget","setContextMenuTarget","closeContextMenu","contextMenuRowRef","contextMenuColumnRef","handleContextMenu","contextMenuRow","canRenderRowMenu","cellMenuContent","cellCount","copy","exportCsv","previous","input","tookOverMenu","rowMenuContent","getAllCells","contextMenuContent","scrollEdgesRef","hasEdgeCallbacks","handleScroll","el","currentTarget","scrollTop","scrollHeight","clientWidth","scrollWidth","tableWrapper","scrollContainer","multiRowSelection","headerGroup","groupIndex","header","renderBodyRow","viewIndex","ariaRowIndex","isGroupRow","isInteractive","rowCells","rowEditing","takesKeyboard","depth","getIsSelected","showSelectedBackground","bodyRow","cellIndex","isEditingCell","button","detailsCell","stopPropagation","pinnedTopBlock","gridColumn","virtualItem","pinnedBottomBlock","messageRow","noRows","summaryCell","isPlaceholder","ActionIcon","Loader","Popover","Text","Tooltip","useSelector","ReactNode","classes","TMDataGridColumnsPanel","useTMDataGridContext","getGridCapabilities","useSettledTableState","isFilterActive","BurgerIcon","FilterIcon","openColumnFilter","TMDataGridToolbar","t0","$","_c","children","t1","toolbar","TMDataGridToolbarSpacer","Symbol","for","toolbarSpacer","TMDataGridLoadingIndicator","table","labels","options","meta","loading","TMDataGridSummaryCount","controlSize","store","getRowCount","shown","t2","totalRowCount","getPreFilteredRowModel","rows","length","total","t3","undefined","t4","summaryCount","TMDataGridColumnsButton","ui","features","opened","_temp","canHideAny","manageColumns","actions","toggleColumnsPanel","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","TMDataGridDraftActions","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","id","TMDataGridRoot","t0","$","_c","table","ui","edit","features","labels","renderDetails","renderDetailsEstHeight","overscan","resetSettings","scrollToRow","scrollerRef","t1","testId","undefined","rowHeight","options","meta","t2","t3","controlSize","api","t4","root","filter","Boolean","t5","join","t6","t7","TMDataGrid","Object","assign","Toolbar","Spacer","SummaryCount","LoadingIndicator","Search","DraftActions","ColumnsButton","FilterButton","Table","Footer","FilterPanel","FilterPills","ColumnsPanel","Input","RangeSlider","TMDataGridFilterControlArgs","operatorTakesRangeValue","TMDataGridFilterValueInput","DgRangeSliderFilter","args","$","_c","column","operator","value","onChange","size","labels","t0","numbers","key","getFacetedUniqueValues","keys","numeric","Number","isFinite","push","min","length","Math","max","Array","isArray","pair","lower","undefined","upper","t1","filterValue","t2","t3","t4","t5","t6","nextLower","nextUpper","String","filterFrom","filterTo","t7","Group","TextInput","TMDataGridFilterControlArgs","operatorTakesRangeValue","TMDataGridFilterValueInput","DgDateRangeFilter","args","$","_c","operator","value","onChange","size","labels","t0","Array","isArray","String","pair","t1","event","currentTarget","t2","filterFrom","t3","event_0","t4","filterTo","t5","Autocomplete","resolveColumnOptions","TMDataGridFilterControlArgs","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","TMDataGridFilterValueInput","DgAutocompleteFilter","args","$","_c","column","table","operator","value","onChange","options","size","labels","t0","needsValue","t1","length","fallback","suggestions","t2","filterValue","t3","Symbol","for","withinPortal","t4","t5","filterValuePlaceholder","t6","map","_temp","t7","t8","option","Input","SegmentedControl","TMDataGridFilterControlArgs","operatorNeedsValue","operatorTakesArrayValue","operatorTakesRangeValue","TMDataGridFilterValueInput","DgTriStateFilter","args","$","_c","operator","value","onChange","size","labels","t0","needsValue","scalar","t1","t2","filterAll","label","t3","booleanTrue","t4","booleanFalse","t5","t6","t7","next","t8","t9","filterValue","TMDataGridLabels","TMDATAGRID_LABELS_SV","operators","contains","equals","notEquals","startsWith","endsWith","greaterThan","greaterThanOrEqual","lessThan","lessThanOrEqual","between","before","after","onOrBefore","onOrAfter","isAnyOf","isNoneOf","isEmpty","isNotEmpty","manageColumns","filters","searchPlaceholder","searchLabel","clearSearch","columnsSearchPlaceholder","columnsNoMatch","search","columnsShowHideAll","columnsReset","columnsResetHint","rowNumberColumnLabel","noRows","filterColumn","filterOperator","filterValue","filterValuePlaceholder","filterFrom","filterTo","filterAll","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","editCell","confirmEdit","cancelEdit","editColumnLabel","editRow","saveRow","cancelRowEdit","editRowErrors","saveAllEdits","rows","discardAllEdits","editRowsStillOpen","confirmNewRow","discardNewRow","deleteRow","restoreRow","revertRow","rowStateNew","rowStateEdited","rowStateDeleted","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","flatRows"],"sources":["../src/tmdatagrid/components/TMDataGrid.module.css","../src/tmdatagrid/components/TMDataGridColumnsPanel.module.css","../src/tmdatagrid/TMDataGridContext.ts","../src/tmdatagrid/core/filterOperators.ts","../src/tmdatagrid/components/TMDataGridDetailsColumn.module.css","../src/tmdatagrid/core/expanding.ts","../src/tmdatagrid/components/TMDataGridDetailsColumn.tsx","../src/tmdatagrid/components/TMDataGridTable.module.css","../src/tmdatagrid/core/editEngine.ts","../src/tmdatagrid/components/TMDataGridEditColumn.tsx","../src/tmdatagrid/components/TMDataGridGroupColumn.module.css","../src/tmdatagrid/core/grouping.ts","../src/tmdatagrid/components/TMDataGridGroupColumn.tsx","../src/tmdatagrid/components/TMDataGridRowNumberColumn.tsx","../src/tmdatagrid/core/rowSelection.ts","../src/tmdatagrid/components/TMDataGridSelectColumn.tsx","../src/tmdatagrid/core/columnUtils.ts","../src/tmdatagrid/components/TMDataGridColumnsPanel.tsx","../src/tmdatagrid/components/TMDataGridDraftActions.tsx","../src/tmdatagrid/components/TMDataGridFilterPanel.module.css","../src/tmdatagrid/core/columnOptions.ts","../src/tmdatagrid/components/filters/TMDataGridFilterValueInput.tsx","../src/tmdatagrid/components/TMDataGridFilterPanel.tsx","../src/tmdatagrid/components/TMDataGridFilterPills.module.css","../src/tmdatagrid/core/quickSearch.ts","../src/tmdatagrid/core/labels.ts","../src/tmdatagrid/core/persistence.ts","../src/tmdatagrid/core/capabilities.ts","../src/tmdatagrid/core/cellNavigation.ts","../src/tmdatagrid/core/controlledState.ts","../src/tmdatagrid/useTMDataGrid.tsx","../src/tmdatagrid/components/TMDataGridFilterPills.tsx","../src/tmdatagrid/components/TMDataGridFooter.module.css","../src/tmdatagrid/core/useSettledTableState.ts","../src/tmdatagrid/components/TMDataGridFooter.tsx","../src/tmdatagrid/components/TMDataGridSearch.tsx","../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/components/editors/editorShared.ts","../src/tmdatagrid/components/editors/TMDataGridBooleanEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridDateEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridMultiSelectEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridSelectEditor.tsx","../src/tmdatagrid/components/editors/TMDataGridStringEditor.tsx","../src/tmdatagrid/components/TMDataGridCellEditor.tsx","../src/tmdatagrid/core/editorFocus.ts","../src/tmdatagrid/components/TMDataGridEntryRows.tsx","../src/tmdatagrid/core/resizePreview.ts","../src/tmdatagrid/core/draftCellContext.ts","../src/tmdatagrid/core/cellRange.ts","../src/tmdatagrid/core/cellExport.ts","../src/tmdatagrid/core/rowPinning.ts","../src/tmdatagrid/core/matchHighlight.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/components/filters/DgRangeSliderFilter.tsx","../src/tmdatagrid/components/filters/DgDateRangeFilter.tsx","../src/tmdatagrid/components/filters/DgAutocompleteFilter.tsx","../src/tmdatagrid/components/filters/DgTriStateFilter.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 /* The frame's corner radius. Any length or Mantine radius token; `0` squares\n the grid off against a card or a full-bleed page. Override it on the grid:\n <TMDataGrid style={{ \"--dg-radius\": 0 }} />\n The root clips its overflow, so the header and the last row follow it. */\n --dg-radius: var(--mantine-radius-md);\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 /* Every second row under `striped`. A whisper of the text colour over the\n body, so one declaration is right in both themes. */\n --dg-row-striped-bg: color-mix(\n in srgb,\n var(--mantine-color-text) 3.5%,\n var(--mantine-color-body)\n );\n /* A confirmed entry row under draft mode - entered, awaiting Save all. A\n whisper of green over the body, one declaration for both themes. */\n --dg-row-new-bg: color-mix(\n in srgb,\n var(--mantine-color-green-6) 8%,\n var(--mantine-color-body)\n );\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 /* The pinned-row slot serves both sticky rows: the summary along the\n bottom and the entry block under the header. */\n --dg-z-pinned-row: 4;\n --dg-z-pinned-row-pinned-cell: 5;\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(--dg-radius);\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","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 filter model plain,\n * serialisable JSON, so a server-side `manualFiltering` table can forward\n * `columnFilters` to the API unchanged.\n *\n * `value` is a string array under `isAnyOf` / `isNoneOf` (the set the cell is\n * tested against), a `[min, max]` pair under `between` (an empty string means\n * that end is open), and a single string everywhere else - dates travel as\n * ISO `YYYY-MM-DD` strings, booleans as `\"true\"` / `\"false\"`. Still plain\n * 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 | \"between\"\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 between: \"is between\",\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 \"between\",\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 \"between\",\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\n/** Operators whose value is a `[min, max]` pair. */\nconst RANGE_OPERATORS: readonly TMDataGridFilterOperator[] = [\"between\"];\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\n/** Whether the operator's value is a `[min, max]` pair - `between`. */\nexport function operatorTakesRangeValue(\n operator: TMDataGridFilterOperator,\n): boolean {\n return RANGE_OPERATORS.includes(operator);\n}\n\n/** The untouched value a fresh filter starts with - the operator's shape, empty. */\nexport function emptyValueForOperator(\n operator: TMDataGridFilterOperator,\n): string | ReadonlyArray<string> {\n if (operatorTakesArrayValue(operator)) return [];\n if (operatorTakesRangeValue(operator)) return [\"\", \"\"];\n return \"\";\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 // A `between` pair is `[\"\", \"\"]` while untouched, so an array is active\n // once some entry says something, not merely by existing.\n return Array.isArray(value.value)\n ? value.value.some((entry) => String(entry).trim() !== \"\")\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 =\n operator === \"between\" && Array.isArray(value)\n ? value.map((entry) => String(entry).trim()).join(\"–\")\n : Array.isArray(value)\n ? value.join(\", \")\n : 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\n/** One end of a `between` interval. An empty bound is an open end. */\nfunction boundHolds(\n cellValue: unknown,\n bound: string,\n end: \"min\" | \"max\",\n): boolean {\n const boundText = bound.trim();\n if (boundText === \"\") return true;\n\n const numericCell = typeof cellValue === \"number\" ? cellValue : Number.NaN;\n const numericBound = Number(boundText);\n if (!Number.isNaN(numericCell) && !Number.isNaN(numericBound)) {\n return end === \"min\"\n ? numericCell >= numericBound\n : numericCell <= numericBound;\n }\n\n const cellDay = toIsoDay(cellValue);\n const boundDay = toIsoDay(boundText);\n if (cellDay === null || boundDay === null) return false;\n return end === \"min\" ? cellDay >= boundDay : cellDay <= boundDay;\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 // A closed or half-open interval. Each present end must hold; an empty end\n // is open - and a fully empty pair matches everything, the same way a blank\n // needle does. Ends compare the way the single-ended operators would:\n // numerically when both sides are numbers, by calendar day otherwise.\n if (operator === \"between\") {\n const [min, max] = Array.isArray(value)\n ? [String(value[0] ?? \"\"), String(value[1] ?? \"\")]\n : [String(value), \"\"];\n return (\n boundHolds(cellValue, min, \"min\") && boundHolds(cellValue, max, \"max\")\n );\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, so `equals` on a date column means\n // \"is this day\" rather than a string comparison against the Date's default\n // 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","/* 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 data-dg-part=\"details-toggle\"\n data-row-id={row.id}\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 data-dg-part=\"details-toggle-all\"\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. Moving\n * or hiding the toggle would leave rows with panels that cannot be opened.\n *\n * Last of the three because it acts on a single record.\n *\n * A second toggle elsewhere is supported: `row.toggleExpanded()` is the entire\n * interface, and this lane is only the control 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","/* 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 /* Lets .messageRow size itself to the scrollport (100cqi) instead of the\n full column-track width, so its content centres in the visible window. */\n container-type: inline-size;\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/* The scrolled-under shadow: a soft band under the header, only while body\n rows are actually beneath it. On the last header row - the header/body\n boundary - not on every stacked group row. A scroll-driven animation, like\n the pinned-lane gradients: the shadow tracks the scroll on the compositor\n with no listener and no render, and an inactive timeline (nothing to\n scroll) leaves `opacity: 0` standing, so a grid that fits shows nothing.\n Where unsupported there is simply no shadow - the header's border already\n draws the boundary. */\n.headerRow[data-dg-header-last]::after {\n content: \"\";\n position: absolute;\n inset: 100% 0 auto 0;\n height: 6px;\n pointer-events: none;\n background: linear-gradient(\n to bottom,\n var(--dg-header-shadow-color, rgba(0, 0, 0, 0.14)),\n transparent\n );\n opacity: 0;\n}\n\n@supports (animation-timeline: scroll()) {\n .headerRow[data-dg-header-last]::after {\n animation: dg-header-shadow linear both;\n animation-timeline: scroll(nearest block);\n /* Arrives over the first rows leaving, reads as depth not as a fade. */\n animation-range: 0px 24px;\n }\n}\n\n@keyframes dg-header-shadow {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\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/* Every second row, under the Table's `striped` prop. Painted from the row's\n own position (`data-striped`), never `:nth-child`: virtualization mounts a\n moving window of rows, so document position says nothing about data\n position. Declared before the hover rule, which is the stronger statement\n and wins at equal specificity. */\n.bodyRow[data-striped=\"true\"] {\n --row-bg: var(--dg-row-striped-bg);\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/* The editing cell hands its box to the editor: the text padding comes off so\n the input can fill the track, and the input's own chrome takes over. */\n.bodyCell[data-editing] {\n padding: 0 calc(var(--dg-padding) / 2);\n}\n\n.cellEditor {\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n gap: 2px;\n}\n\n/* cellConfirm's ✓ / ✕ pair, beside the input. */\n.cellEditorActions {\n display: flex;\n align-items: center;\n flex: 0 0 auto;\n}\n\n/* Corner triangles for a cell's edit state, drawn like a spreadsheet's: a\n draft not yet saved is blue, a value failing validation is red. The cell\n needs a positioning context; pinned and focused cells set their own inline\n `position`, which wins over this. */\n.bodyCell[data-dirty],\n.bodyCell[data-invalid] {\n position: relative;\n}\n\n.bodyCell[data-dirty]::after,\n.bodyCell[data-invalid]::after {\n content: \"\";\n position: absolute;\n top: 0;\n right: 0;\n border: 5px solid transparent;\n border-top-color: var(--mantine-primary-color-filled);\n border-right-color: var(--mantine-primary-color-filled);\n}\n\n/* Invalid wins over dirty - a cell is usually both. */\n.bodyCell[data-invalid]::after {\n border-top-color: var(--mantine-color-error);\n border-right-color: var(--mantine-color-error);\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/* Spans every column track, but the rendered box is pinned to the scrollport:\n sticky at the left edge and exactly one container-width wide, so the\n centred content stays in the middle of the window however far the grid is\n scrolled horizontally. */\n.messageRow {\n grid-column: 1 / -1;\n position: sticky;\n left: 0;\n width: 100cqi;\n justify-self: start;\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/* Marked deleted under draft: struck through and inert until submitAll\n reports it - a row about to go away must not keep taking edits. Interaction\n comes off the data cells, not the row: `pointer-events: none` on the row\n would also kill the edit lane's Restore, which is the one control the row\n still needs (jsdom does not enforce pointer-events, so only a real browser\n ever saw that bug). */\n.bodyRow[data-deleted=\"true\"] {\n text-decoration: line-through;\n opacity: 0.55;\n}\n\n.bodyRow[data-deleted=\"true\"] .bodyCell:not([data-control-column=\"true\"]) {\n pointer-events: none;\n}\n\n/* The entry block - one row per edit.addRow(), under the header on the same\n subgrid tracks as everything else. The *block* is the sticky element, not\n the rows: sticky siblings would all compete for the same `top` and stack\n onto one spot, while a single sticky wrapper lets its rows flow normally\n inside it. Subgrid twice over keeps the cells on the outer tracks.\n `--dg-header-height` is measured only while the block exists. */\n.entryBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n top: var(--dg-header-height, 0px);\n z-index: var(--dg-z-pinned-row, 4);\n}\n\n.entryRow {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n}\n\n/* Confirmed entry rows in the scrolling flow (the default; `newRowsSticky`\n keeps them in the sticky block instead). Same tracks, no stickiness - they\n sit above the body rows and scroll with them. */\n.entryFlowBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n}\n\n/* The pinned edge blocks - user-pinned rows held at the top or bottom of the\n body, on the entry block's sticky mechanics: the block is the sticky\n element, its rows flow normally inside it. The top block stacks under the\n entry block when both exist; `--dg-entry-height` is measured only then, so\n the offset is otherwise the header alone. The bottom block stacks above the\n summary row the same way. Rows are opaque already (`--row-bg` paints the\n body colour), so the blocks only add the edge borders. */\n.pinnedTopBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n top: calc(var(--dg-header-height, 0px) + var(--dg-entry-height, 0px));\n z-index: var(--dg-z-pinned-row, 4);\n}\n\n.pinnedTopBlock > :last-child > [role=\"cell\"] {\n border-bottom: 2px solid var(--mantine-color-default-border);\n}\n\n.pinnedBottomBlock {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n position: sticky;\n bottom: var(--dg-summary-height, 0px);\n z-index: var(--dg-z-pinned-row, 4);\n}\n\n.pinnedBottomBlock > :first-child > [role=\"cell\"] {\n border-top: 2px solid var(--mantine-color-default-border);\n}\n\n.entryCell {\n display: flex;\n align-items: center;\n padding: 0 calc(var(--dg-padding) / 2);\n border-bottom: 2px solid var(--mantine-primary-color-filled);\n /* Opaque: the body scrolls underneath it. */\n background-color: var(--mantine-color-body);\n font-size: var(--dg-font-size);\n}\n\n.entryCell[data-control-column=\"true\"] {\n padding: 0;\n justify-content: center;\n}\n\n/* A committed entry row - entered, awaiting Save all. It reads as a value\n row: text padding, the body's border weight, and the \"new\" tint instead of\n the editing underline. */\n.entryRow[data-committed=\"true\"] .entryCell {\n padding: 0 var(--dg-padding);\n border-bottom: 1px solid var(--mantine-color-default-border);\n background-color: var(--dg-row-new-bg, var(--mantine-color-body));\n}\n\n.entryRow[data-committed=\"true\"] .entryCell[data-control-column=\"true\"] {\n padding: 0;\n}\n\n/* Draft mode's change marker in the edit lane - dimmed beside the buttons\n that act, red when validation blocks the row. */\n.rowStateIndicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n flex: 0 0 auto;\n color: var(--mantine-color-dimmed);\n}\n\n.rowStateIndicator[data-error] {\n color: var(--mantine-color-error);\n}\n\n.entryCell[data-align=\"right\"] {\n justify-content: flex-end;\n}\n\n.entryCell[data-align=\"center\"] {\n justify-content: center;\n}\n\n/* The matched slice of a cell's text, while `enableMatchHighlighting` is on\n and a contains-family filter or the quick search is active. `mark` resets\n the browser's default so the colour is the grid's to state - override with\n `--dg-match-highlight-bg` on the grid. */\n.matchHighlight {\n background-color: var(\n --dg-match-highlight-bg,\n light-dark(var(--mantine-color-yellow-2), rgba(250, 176, 5, 0.35))\n );\n color: inherit;\n border-radius: 2px;\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","import {\n FormApi,\n getBy,\n type AnyFieldApi,\n type AnyFormApi,\n type StandardSchemaV1,\n} from \"@tanstack/react-form\";\nimport { batch, Store } from \"@tanstack/store\";\nimport type { Cell, Column, Row, RowData } from \"@tanstack/react-table\";\nimport type { ComponentType } from \"react\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\nimport {\n isColumnEditableForRow,\n isColumnEditSwitchedOff,\n isControlColumn,\n} from \"./columnUtils\";\nimport type { TMDataGridColumnType } from \"./filterOperators\";\nimport type { TMDataGridSize } from \"./sizes\";\n\n/**\n * What counts as a commit - one axis, each mode a thin policy over the same\n * engine. Where a commit *goes* is the other axis, `editing.draft`: out to\n * the consumer, or into the draft store. See `editing` on\n * `UseTMDataGridOptions`.\n *\n * | Mode | Enter | Tab | Focus leaves | Escape |\n * | ---- | ----- | --- | ------------ | ------ |\n * | `\"cell\"` | commits | commits, caret moves on | commits | cancels |\n * | `\"cellConfirm\"` | commits | keeps the draft, caret moves on | keeps the draft | cancels |\n * | `\"row\"` | commits the row | the browser's, along the row | nothing | cancels the row |\n *\n * An entry row is row-shaped in every mode - every editable cell open at\n * once, the browser's Tab between them, and an explicit ✓.\n */\nexport type TMDataGridEditMode = \"cell\" | \"cellConfirm\" | \"row\";\n\n/**\n * One editing row's live form. TanStack Form's `FormApi`, not a wrapper: the\n * engine is a form library, and everything mid-edit - values, dirty state,\n * errors, async validation, submit lifecycle - is form state, read off\n * `form.store` with the same selector idiom as the rest of the grid.\n *\n * The alias erases Form's validator generics the way `TMDataGridRowData`\n * erases the row type: the concrete types lived at the `useTMDataGrid` call.\n */\nexport type TMDataGridRowEditForm = AnyFormApi;\n\n/** The live field a cell editor binds to - TanStack Form's own `FieldApi`. */\nexport type TMDataGridEditField = AnyFieldApi;\n\n/**\n * A validator as TanStack Form takes it: a Standard Schema (Zod, Valibot,\n * ArkType…) or a plain function returning an error or nothing. Forwarded\n * untouched - the vocabulary is Form's, not a grid re-implementation.\n */\nexport type TMDataGridValidator =\n | StandardSchemaV1<unknown, unknown>\n | ((args: { value: never; fieldApi: never }) => unknown);\n\n/**\n * `meta.edit.validate` - per-column field validators. A bare schema or function is\n * shorthand for `{ onChange: it }`; the object form takes every trigger\n * TanStack Form defines, `Async` variants and debounce included.\n */\nexport type TMDataGridFieldValidate =\n | TMDataGridValidator\n | {\n onMount?: TMDataGridValidator;\n onChange?: TMDataGridValidator;\n onChangeAsync?: TMDataGridValidator;\n onChangeAsyncDebounceMs?: number;\n onBlur?: TMDataGridValidator;\n onBlurAsync?: TMDataGridValidator;\n onSubmit?: TMDataGridValidator;\n onSubmitAsync?: TMDataGridValidator;\n };\n\n/**\n * `rowValidators` - form-level validators for the whole row, where\n * cross-field rules live. Passed into each row form's `validators` untouched;\n * pathed issues land on the matching fields, pathless ones on the row.\n */\nexport type TMDataGridRowValidators = {\n onMount?: TMDataGridValidator;\n onChange?: TMDataGridValidator;\n onChangeAsync?: TMDataGridValidator;\n onChangeAsyncDebounceMs?: number;\n onBlur?: TMDataGridValidator;\n onBlurAsync?: TMDataGridValidator;\n onSubmit?: TMDataGridValidator;\n onSubmitAsync?: TMDataGridValidator;\n onSubmitAsyncDebounceMs?: number;\n};\n\n/** What `editing.tableValidators` is handed for one commit. */\nexport type TMDataGridTableValidateArgs<\n TData extends RowData = TMDataGridRowData,\n> = {\n /** The committing row, as drafted. */\n value: TData;\n /** Its id - `addRow`'s temp id for an entry row. */\n rowId: string;\n /** Whether the row is an entry row, not yet in `data`. */\n isNew: boolean;\n /**\n * The collection as it would stand if this commit landed: every data row\n * overlaid with its draft where one is held (this row's `value` included),\n * entry rows appended, deletion-marked rows removed. Unfiltered - a rule\n * sees the whole collection whatever the view shows.\n */\n rows: ReadonlyArray<{ rowId: string; value: TData }>;\n};\n\n/**\n * `editing.tableValidators` - rules that need the other rows: no duplicate\n * keys, no overlapping ranges, allocations summing to a total. Run at every\n * commit, after the row's own validators, and again per parked row during\n * `saveDrafts` - so a draft invalidated by a later edit blocks the save.\n *\n * Return nothing to pass, a message, or Form's `{ form, fields }` shape;\n * pathed issues land on the committing row's cells, pathless ones on the row.\n * `onSubmit` runs first, and its failure stands without `onSubmitAsync`\n * running.\n */\nexport type TMDataGridTableValidators<\n TData extends RowData = TMDataGridRowData,\n> = {\n onSubmit?: (args: TMDataGridTableValidateArgs<TData>) => unknown;\n onSubmitAsync?: (\n args: TMDataGridTableValidateArgs<TData>,\n ) => unknown | Promise<unknown>;\n};\n\n/** One field's before/after across a commit. */\nexport type TMDataGridEditChange = {\n /** Column the field maps back to, for consumers thinking in columns. */\n columnId: string;\n /** The data path - `getEditFieldName` of the column. */\n field: string;\n previous: unknown;\n next: unknown;\n};\n\nexport type TMDataGridEditCommitArgs<TData extends RowData> = {\n rowId: string;\n /** The whole row as edited - for the consumer who saves records. */\n value: TData;\n /** The row as it was when editing began. */\n original: TData;\n /** Per-field diff - for the consumer who PATCHes. One entry in cell mode. */\n changes: Array<TMDataGridEditChange>;\n /** Which policy committed. */\n source: TMDataGridEditMode;\n};\n\n/** What one open row's form looks like from outside - the cell markers. */\nexport type TMDataGridEditRowProjection = {\n /** Field names whose value differs from the original. */\n dirtyFields: ReadonlyArray<string>;\n /** Field names carrying a validation error, live or from a failed commit. */\n errorFields: ReadonlyArray<string>;\n /**\n * Those errors as text: what each cell editor is showing, plus what the\n * row's last failed commit found. The second half is the reason this\n * exists - Form clears a field's errors when its editor unmounts, so a row\n * left invalid would go back to looking like an ordinary edited row. Such\n * a message is dropped as soon as its field's value moves: the fix is what\n * clears the mark.\n */\n errorMessages: ReadonlyArray<{ field: string; message: string }>;\n /** A row-level error - a pathless `.refine()`, or a rejected commit. */\n hasRowError: boolean;\n isSubmitting: boolean;\n /**\n * The row as drafted - the form's `state.values`. Reference-stable while no\n * value changes, so a cell may subscribe to it and repaint only when its\n * row's draft actually moves.\n */\n values: TMDataGridRowData;\n};\n\n/**\n * The grid-facing index of everything mid-edit. A projection synced from the\n * open forms' stores, so body cells subscribe to this one store for their\n * dirty/error markers instead of one store per form. Only the editor host\n * reads a form's store directly - it is mounted for one cell at a time.\n */\nexport type TMDataGridEditState = {\n /**\n * The cell the last open gesture named - where the caret goes. In row mode\n * the whole row is editing whatever this says, so there it is only the\n * caret's cell, and `null` for the lane's pencil, which names no column.\n */\n active: { rowId: string; columnId: string | null } | null;\n /**\n * Rows with a live form, committed or not - every row the grid is holding\n * work for. A row is *open* (undecided form state) when it is in here and\n * not in {@link committedRowIds}.\n */\n openRowIds: ReadonlyArray<string>;\n rows: Record<string, TMDataGridEditRowProjection>;\n /**\n * The draft store's edit slice: existing rows whose form passed its submit\n * and is parked, waiting for `saveDrafts`. A subset of `openRowIds` - the\n * values stay in the row's form, this records which side of the line the\n * row is on. `begin` on one of these takes it back out, into form state.\n *\n * Only `editing.draft` parks. Without it a commit goes straight to the\n * consumer and the form is dropped, so this stays empty.\n */\n committedRowIds: ReadonlyArray<string>;\n /**\n * Rows being created, not yet in `data`. `committed` is the draft store's\n * add slice: the entry row passed its submit and renders as a value row\n * until `begin` re-opens it. Without `editing.draft` a commit adds through\n * `onRowAdd` and the entry is dropped, so it never turns `true`.\n */\n newRows: ReadonlyArray<{ tempId: string; committed: boolean }>;\n /** The draft store's delete slice: rows marked deleted, awaiting the save. */\n deletedRowIds: ReadonlyArray<string>;\n};\n\nconst EMPTY_EDIT_STATE: TMDataGridEditState = {\n active: null,\n openRowIds: [],\n rows: {},\n committedRowIds: [],\n newRows: [],\n deletedRowIds: [],\n};\n\n/**\n * The rows still *open*: holding a live form nobody has decided yet.\n *\n * Narrower than {@link TMDataGridEditState.openRowIds}, which is every row\n * with a form, the parked ones included. A row qualifies here when it is not\n * parked in the draft store and there is something to lose - an entered row\n * always counts, an existing one only once a value has moved.\n *\n * The order is the engine's: the order the forms were opened.\n */\nexport function getOpenRowIds(\n state: TMDataGridEditState,\n): ReadonlyArray<string> {\n return state.openRowIds.filter(\n (rowId) =>\n !state.committedRowIds.includes(rowId) &&\n !state.newRows.some(\n (newRow) => newRow.tempId === rowId && newRow.committed,\n ) &&\n (state.newRows.some((newRow) => newRow.tempId === rowId) ||\n (state.rows[rowId]?.dirtyFields.length ?? 0) > 0),\n );\n}\n\ntype ErasedRow = Row<TMDataGridFeatures, TMDataGridRowData>;\ntype ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\n\n/**\n * What a cell editor is handed - deliberately both vocabularies at once. The\n * form side is TanStack Form's real `field` API (`field.state.value`,\n * `field.state.meta.errors`, `field.handleChange`, `field.handleBlur`), so a\n * custom calendar, slider or async combobox binds to it exactly as it would\n * inside any TanStack Form. The table side is where the editor is standing.\n *\n * The built-ins are implemented against this same contract, so\n * `meta.edit.editor` is not a special case - it is the slot the defaults\n * fill, and the exported built-ins can be wrapped instead of replaced.\n */\nexport type TMDataGridEditorArgs = {\n /** The live TanStack Form field for this cell. */\n field: TMDataGridEditField;\n /** The whole row form, for the rare editor that reads sibling fields. */\n form: TMDataGridRowEditForm;\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n row: ErasedRow;\n column: ErasedColumn;\n table: TMDataGridTable<TMDataGridRowData>;\n /** What Enter would do - commit the edit. For the editor's own UI. */\n commit: () => Promise<boolean>;\n /** What Escape would do - drop the draft. */\n cancel: () => void;\n size: TMDataGridSize;\n /**\n * Set when typing opened the editor (the Sheets gesture) - the built-ins\n * replace the value with it and keep typing. A custom editor may ignore it.\n */\n seedText?: string;\n};\n\n/**\n * `meta.edit.editor` - replaces the built-in editor for this column. Rendered\n * as JSX, never invoked as a bare function, so hooks are legal inside. Define\n * it at module scope: a new identity per render remounts the editor mid-edit.\n */\nexport type TMDataGridEditorComponent = ComponentType<TMDataGridEditorArgs>;\n\n/** What `meta.edit.mapValue` is handed for one write. */\nexport type TMDataGridEditValueMapArgs = {\n /** The value the editor just wrote. */\n value: unknown;\n /** What the field held before this write - for length-aware masks. */\n previous: unknown;\n row: ErasedRow;\n column: ErasedColumn;\n table: TMDataGridTable<TMDataGridRowData>;\n};\n\n/**\n * `meta.edit.mapValue` - the value on its way into the draft, mapped.\n *\n * Runs on every write an editor makes, which for a text input is every\n * keystroke and for a select is every pick, so the mapped value is what the\n * user sees, what validators judge and what commits.\n */\nexport type TMDataGridEditValueMap = (\n args: TMDataGridEditValueMapArgs,\n) => unknown;\n\n/**\n * `meta.edit` - everything about how this column is edited, in one place,\n * mirroring the `edit.*` engine the grid exposes at runtime.\n *\n * ```tsx\n * meta: {\n * type: \"string\",\n * edit: {\n * enabled: (row) => row.original.status !== \"Locked\",\n * validate: z.string().min(2, \"Too short\"),\n * mapValue: ({ value }) =>\n * typeof value === \"string\" ? value.toUpperCase() : value,\n * },\n * }\n * ```\n *\n * `meta.type` and `meta.options` stay outside this namespace on purpose: one\n * declaration of each feeds the cell editor and the filter panel alike.\n */\nexport type TMDataGridColumnEditOptions = {\n /**\n * Whether this column's cells take edits, once `editMode` is on. `false`\n * switches the column off outright; a predicate decides per row. Defaults\n * to editable for any column that maps to a field - see {@link field}.\n */\n enabled?:\n | boolean\n | ((row: Row<TMDataGridFeatures, TMDataGridRowData>) => boolean);\n /**\n * The data path this column edits, when it is not the `accessorKey` - the\n * only way a column built on `accessorFn` becomes editable. Dot paths reach\n * into nested records: `\"address.city\"`.\n */\n field?: string;\n /**\n * Replaces the built-in editor for this column. See\n * {@link TMDataGridEditorComponent}.\n */\n editor?: TMDataGridEditorComponent;\n /**\n * Field-level validators, in TanStack Form's own vocabulary. A bare Zod\n * schema (or any Standard Schema, or a plain function) means\n * `{ onChange: it }`; the object form takes every trigger Form defines.\n */\n validate?: TMDataGridFieldValidate;\n /**\n * Maps every value an editor writes before it reaches the draft - uppercase\n * a code, strip spaces from an IBAN, clamp a number into range. See\n * {@link TMDataGridEditValueMap}.\n */\n mapValue?: TMDataGridEditValueMap;\n};\n\n/** A new row being committed - `onRowAdd`, and `saveDrafts`'s `created`. */\nexport type TMDataGridRowAddArgs<TData extends RowData> = {\n /** The engine's placeholder id; the real id is the consumer's to mint. */\n tempId: string;\n value: TData;\n};\n\n/** A deletion - `onRowDelete`. */\nexport type TMDataGridRowDeleteArgs<TData extends RowData> = {\n rowId: string;\n row: Row<TMDataGridFeatures, TData>;\n};\n\n/**\n * The draft store, flushed - what `saveDrafts` hands `onSaveDrafts`. Every\n * committed change at once, so a server can apply it as one transaction.\n * Rows still open (undecided form state) are not in here and stay open.\n */\nexport type TMDataGridSaveDraftsArgs<TData extends RowData> = {\n /** Committed edits to existing rows; each entry carries its `rowId`. */\n updated: Array<TMDataGridEditCommitArgs<TData>>;\n /** Committed new rows from the entry block; each entry carries its `tempId`. */\n created: Array<TMDataGridRowAddArgs<TData>>;\n /** Ids marked deleted while the drafts accumulated. */\n deleted: Array<string>;\n /** @deprecated Renamed to {@link updated}. Removed in a later beta. */\n rows: Array<TMDataGridEditCommitArgs<TData>>;\n /** @deprecated Renamed to {@link created}. Removed in a later beta. */\n added: Array<TMDataGridRowAddArgs<TData>>;\n};\n\n/**\n * Which entries of one bucket saved. `true`, or an id the map does not name,\n * saved and is dropped from the draft store; `false` failed and keeps its\n * draft. A bare boolean answers for the whole bucket.\n */\nexport type TMDataGridSaveOutcomes = boolean | Record<string, boolean>;\n\n/**\n * What `onSaveDrafts` may return to save part of the store.\n *\n * Returning nothing saves everything, and throwing saves nothing. Between\n * those, name the ids that failed: they keep their drafts, committed and\n * ready for the next save, while the rest are dropped. The grid marks them\n * with nothing beyond the state itself - a failed edit keeps `data-draft`,\n * a failed deletion keeps `data-deleted` - so the display is the consumer's.\n */\nexport type TMDataGridSaveDraftsResult = {\n /** Keyed by `rowId`. */\n updated?: TMDataGridSaveOutcomes;\n /** Keyed by `tempId`. */\n created?: TMDataGridSaveOutcomes;\n /** Keyed by `rowId`. */\n deleted?: TMDataGridSaveOutcomes;\n};\n\n/** Whether one id of a bucket saved. Unnamed ids saved. */\nfunction isSaved(\n outcomes: TMDataGridSaveOutcomes | undefined,\n id: string,\n): boolean {\n if (outcomes === undefined) return true;\n if (typeof outcomes === \"boolean\") return outcomes;\n return outcomes[id] !== false;\n}\n\n/**\n * @deprecated Renamed to {@link TMDataGridSaveDraftsArgs} - the payload is\n * the draft store being saved, not a commit. Removed in a later beta.\n */\nexport type TMDataGridEditCommitDraftsArgs<TData extends RowData> =\n TMDataGridSaveDraftsArgs<TData>;\n\n/** What the engine reads fresh on every call - see `createEditEngine`. */\nexport type TMDataGridEditEngineContext = {\n table: TMDataGridTable<TMDataGridRowData>;\n editMode: TMDataGridEditMode;\n /** `editing.draft` - whether a commit parks instead of reaching out. */\n draft: boolean;\n rowValidators?: TMDataGridRowValidators;\n tableValidators?: TMDataGridTableValidators;\n /**\n * `editing.columns` - the allowlist, or `undefined` for \"every column that\n * maps to a field\".\n */\n editableColumnIds?: ReadonlyArray<string>;\n isRowEditable?: (row: ErasedRow) => boolean;\n onEditCommit?: (\n args: TMDataGridEditCommitArgs<TMDataGridRowData>,\n ) => void | Promise<void>;\n onSaveDrafts?: (\n args: TMDataGridSaveDraftsArgs<TMDataGridRowData>,\n ) =>\n | void\n | TMDataGridSaveDraftsResult\n | Promise<void | TMDataGridSaveDraftsResult>;\n /**\n * Seed values for `addRow`, under the values it is called with. A function\n * is called per added row.\n */\n newRowDefaults?: TMDataGridRowData | (() => TMDataGridRowData);\n onRowAdd?: (\n args: TMDataGridRowAddArgs<TMDataGridRowData>,\n ) => void | Promise<void>;\n onRowDelete?: (\n args: TMDataGridRowDeleteArgs<TMDataGridRowData>,\n ) => void | Promise<void>;\n};\n\n/**\n * The data path a column edits, or `null` for a column that has none.\n *\n * `accessorKey` is the true path and Form addresses fields by dot-path, so\n * nested rows need no extra handling: `accessorKey: \"address.city\"` edits\n * `values.address.city`. A column built on `accessorFn` has no path and is not\n * editable unless `meta.edit.field` names one. TanStack's default column id\n * turns dots into underscores, which is why this starts from `accessorKey` and\n * never from `id`.\n */\nexport function getEditFieldName(column: {\n columnDef: { meta?: { edit?: { field?: string } } };\n}): string | null {\n const fromMeta = column.columnDef.meta?.edit?.field;\n if (fromMeta) return fromMeta;\n const accessorKey = (column.columnDef as Record<string, unknown>)[\n \"accessorKey\"\n ];\n return typeof accessorKey === \"string\" ? accessorKey : null;\n}\n\n/** What Delete writes into a cell - the type's honest empty value. */\nexport function clearedValueForType(type: TMDataGridColumnType): unknown {\n switch (type) {\n case \"string\":\n return \"\";\n case \"multiSelect\":\n return [];\n case \"boolean\":\n return false;\n default:\n return null;\n }\n}\n\n/** `edit.addRows` options. */\nexport type TMDataGridAddRowsOptions = {\n /**\n * Submit each row as it is added instead of leaving it open. Defaults to\n * `false` - the rows open as editable entry rows, as `addRow` does.\n */\n commit?: boolean;\n};\n\n/** What `edit.addRows` reports back. Every added row is in exactly one list. */\nexport type TMDataGridAddRowsResult = {\n /** Temp ids that committed - parked as drafts, or added outright. */\n committed: Array<string>;\n /**\n * Temp ids still open in the entry block: everything, when `commit` was\n * not asked for; the rows that failed validation, when it was.\n */\n open: Array<string>;\n};\n\n/**\n * The engine plus its store - `api.edit`.\n *\n * \"One row, one form\": `getForm` hands out the same `FormApi` the inline\n * editors write through, so a consumer can render it in a drawer or a detail\n * panel and share values, dirty state and errors with the cells.\n */\nexport type TMDataGridEditApi<\n TData extends RowData = TMDataGridRowData,\n> = {\n /** The projection store - subscribe with `useSelector(edit.store, …)`. */\n store: Store<TMDataGridEditState>;\n /** Current snapshot, for reads outside React. */\n readonly state: TMDataGridEditState;\n /** rowId → live form. The source of truth for everything mid-edit. */\n getForm: (rowId: string) => TMDataGridRowEditForm | undefined;\n /**\n * Whether this cell may open an editor: the column maps to a field, nothing\n * switched it off, and the row takes edits at all.\n */\n canEditCell: (row: ErasedRow, column: ErasedColumn) => boolean;\n /** Whether the row takes edits at all - the edit lane's pencil gate. */\n canEditRow: (row: ErasedRow) => boolean;\n /**\n * Whether the column takes edits at all, with no row in hand: it maps to a\n * field, `editing.columns` lists it if that option is set, and\n * `meta.edit.enabled` is not `false`. A per-row `enabled` predicate is the\n * row's half of the question - `canEditCell` asks both.\n */\n isColumnEditable: (column: ErasedColumn) => boolean;\n /**\n * Opens an editor. In row mode the whole row opens either way and `columnId`\n * only says which cell takes the caret; `null` (the lane's pencil) leaves it\n * to the row's first editable cell.\n */\n begin: (target: { rowId: string; columnId: string | null }) => void;\n /**\n * Commits one row - `form.handleSubmit` under the hood. Resolves `true`\n * when the form is gone: validation passed and `onEditCommit` resolved, or\n * there was nothing to save. `false` keeps the form open with its errors.\n */\n commit: (rowId: string) => Promise<boolean>;\n /** Drops one row's draft. */\n cancel: (rowId: string) => void;\n /**\n * Closes the editor without touching the draft - what blur does under\n * `\"cellConfirm\"`, where the dirty cell keeps waiting for its ✓.\n */\n deactivate: () => void;\n /** Drops every draft - open form state and the draft store alike. */\n cancelAll: () => void;\n /**\n * Submits every open row, as if each had been OK'd: a row that validates\n * commits (into the draft store with `editing.draft` on, straight to the\n * consumer without it), a row that fails stays open with its errors.\n * `true` when every row committed. Under `editing.draft` it sends nothing\n * to the consumer by itself - that is `saveDrafts`.\n */\n commitAll: () => Promise<boolean>;\n /**\n * Flushes the draft store: every committed edit, added row and deletion\n * mark reaches the consumer, through `onSaveDrafts` in one call when it is\n * set, or row by row through `onCommit` / `onRowAdd` / `onRowDelete`.\n *\n * Rows still open are left alone - they keep their form state and stay\n * open. `true` when everything landed; a rejected save keeps every draft.\n */\n saveDrafts: () => Promise<boolean>;\n /**\n * @deprecated Split into {@link commitAll} and {@link saveDrafts}, which is\n * exactly what this now does. Removed in a later beta.\n */\n submitAll: () => Promise<boolean>;\n /** Writes the type's empty value into a cell and commits it - Delete. */\n clearCell: (rowId: string, columnId: string) => Promise<boolean>;\n /**\n * Writes one cell and commits the row - a typed edit without the typing,\n * for toolbar actions and bulk fills. Under `editing.draft` the row parks\n * in the draft store exactly as a hand-made edit does, so it carries the\n * same change markers and the same per-row revert.\n *\n * The row need not be mounted; a row inside a collapsed group takes the\n * write. Resolves `false` when the cell takes no edit - no such row or\n * column, `editing.columns` excludes it, `meta.edit.enabled` is off, or the\n * row is not editable - and when validation refuses the value, which leaves\n * the row open carrying its errors.\n *\n * `value` is the stored value: no editor runs, so `meta.edit.mapValue`\n * does not either. `meta.edit.validate` does.\n */\n setCellValue: (\n rowId: string,\n columnId: string,\n value: unknown,\n ) => Promise<boolean>;\n /**\n * {@link setCellValue} for several cells of one row, in a single commit -\n * one consumer call and one draft entry rather than one per column. Keys\n * are column ids.\n *\n * All or nothing: if any named cell takes no edit, nothing is written and\n * this resolves `false`.\n */\n setRowValues: (\n rowId: string,\n values: Record<string, unknown>,\n ) => Promise<boolean>;\n /**\n * Opens a new entry row (the sticky block under the header) seeded from\n * `newRowDefaults`. `values` overrides that seed key by key, so\n * `addRow()` opens a blank row and `addRow({ status: \"draft\" })` opens one\n * that starts filled in. Returns its temporary id - a form with no backing\n * row yet. Committing it calls `onRowAdd`, or parks it for `saveDrafts`\n * under `editing.draft`.\n */\n addRow: (values?: Partial<TData>) => string;\n /**\n * Opens entry rows for a list of records at once - one state write for the\n * batch, where a loop over `addRow` is one per row. Each row is seeded over\n * `newRowDefaults` exactly as `addRow` does.\n *\n * `commit: true` submits each row as it lands, which is what an import\n * wants: rows that validate commit (parked in the draft store under\n * `editing.draft`, added through `onRowAdd` without it - once per row),\n * and rows that fail stay open in the entry block carrying their errors,\n * for the user to fix. The result says which went which way.\n */\n addRows: (\n rows: ReadonlyArray<Partial<TData>>,\n options?: TMDataGridAddRowsOptions,\n ) => Promise<TMDataGridAddRowsResult>;\n /**\n * Deletes a row: `onRowDelete` straight away, or under `editing.draft` a\n * toggle of the id in `deletedRowIds` - the row renders struck through\n * until `saveDrafts` reports it. On an uncommitted entry row it just\n * discards the entry.\n */\n deleteRow: (rowId: string) => void;\n /** Whether delete chrome makes sense - the lane's trash gate. */\n canDeleteRows: () => boolean;\n};\n\nfunction clearFormSourcedFieldErrors(form: TMDataGridRowEditForm): void {\n const fieldMeta = form.state.fieldMeta as Record<\n string,\n { errorSourceMap?: Record<string, unknown> }\n >;\n for (const [name, meta] of Object.entries(fieldMeta)) {\n const staleKeys = Object.entries(meta.errorSourceMap ?? {})\n .filter(([, source]) => source === \"form\")\n .map(([key]) => key);\n if (staleKeys.length === 0) continue;\n form.setFieldMeta(name as never, (previous) => ({\n ...previous,\n errorMap: {\n ...previous.errorMap,\n ...Object.fromEntries(staleKeys.map((key) => [key, undefined])),\n },\n }));\n }\n}\n\n/** Arrays compare by element so a multiSelect edit-back-to-same is clean. */\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((entry, i) => Object.is(entry, b[i]));\n }\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n return false;\n}\n\nfunction hasAnyError(errors: ReadonlyArray<unknown>): boolean {\n return errors.some((error) => error !== undefined && error !== null);\n}\n\n/**\n * The first error as text, whatever shape the validator produced - TanStack\n * Form keeps errors verbatim, so a Zod issue arrives as `{ message }`, a\n * plain function's return arrives as it was, and a form-level schema's\n * pathless issues arrive keyed under an empty path (`{ \"\": [issues] }`).\n * This digs until it finds a message.\n */\nexport function firstErrorText(error: unknown): string | undefined {\n if (error === null || error === undefined) return undefined;\n if (typeof error === \"string\") return error;\n if (Array.isArray(error)) {\n for (const entry of error) {\n const text = firstErrorText(entry);\n if (text !== undefined) return text;\n }\n return undefined;\n }\n if (typeof error === \"object\") {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\") return message;\n for (const value of Object.values(error)) {\n const text = firstErrorText(value);\n if (text !== undefined) return text;\n }\n }\n return undefined;\n}\n\n/**\n * The triggers a submit runs, in the order Form would: a value that fails its\n * column's `onChange` rule fails the submit too.\n */\nconst SUBMIT_VALIDATE_TRIGGERS = [\n \"onChange\",\n \"onChangeAsync\",\n \"onSubmit\",\n \"onSubmitAsync\",\n] as const;\n\n/** Whether a validator's return counts as an error. */\nfunction isValidationError(result: unknown): boolean {\n return result !== undefined && result !== null && result !== false;\n}\n\n/**\n * Runs one field validator the way TanStack Form would - a Standard Schema\n * (Zod, Valibot…) or a plain function - and returns its error, or undefined.\n */\nasync function runFieldValidator(\n validator: unknown,\n value: unknown,\n): Promise<unknown> {\n if (typeof validator === \"function\") {\n return await (\n validator as (args: { value: unknown; fieldApi: unknown }) => unknown\n )({ value, fieldApi: undefined });\n }\n if (\n typeof validator === \"object\" &&\n validator !== null &&\n \"~standard\" in validator\n ) {\n const schema = validator as StandardSchemaV1<unknown, unknown>;\n const result = await schema[\"~standard\"].validate(value);\n const { issues } = result as {\n issues?: ReadonlyArray<{ message: string }>;\n };\n if (issues === undefined || issues.length === 0) return undefined;\n return issues[0]?.message ?? \"Invalid\";\n }\n return undefined;\n}\n\n/**\n * Builds the edit engine. A factory over React so it is headless-testable;\n * `getContext` is read fresh on every call, which is how the engine always\n * sees the latest table, mode and consumer callbacks without being rebuilt.\n *\n * Virtualization, per the plan: nothing here is DOM. A form is a plain object\n * in a map keyed by rowId - scroll its row away and the editor unmounts, the\n * form keeps its values, meta and errors; scroll back and the editor\n * re-mounts over the same form.\n */\nexport function createEditEngine(\n getContext: () => TMDataGridEditEngineContext,\n): TMDataGridEditApi {\n const store = new Store<TMDataGridEditState>(EMPTY_EDIT_STATE);\n\n type FormEntry = {\n form: TMDataGridRowEditForm;\n original: TMDataGridRowData;\n /** An entry-block row - a form with no backing row yet. */\n isNew: boolean;\n /**\n * In the draft store: this row's form passed its submit and is parked,\n * waiting for `saveDrafts`. Mirrored into the state's `committedRowIds`\n * (existing rows) or `newRows[].committed` (entry rows).\n */\n committed: boolean;\n /** Set by the wrapped onSubmit when the consumer's commit resolved. */\n lastSubmitOk: boolean;\n /**\n * What the last failed commit found, field by field, with the value it\n * found it on. Form clears a field's errors when its editor unmounts, so\n * without this a row that failed on the way out would keep its draft and\n * lose the reason. `project` drops an entry once its value has moved.\n */\n submitErrors: Array<{ field: string; value: unknown; message: string }>;\n /**\n * The park: this submit validates and puts the row in the draft store\n * instead of calling the consumer. Set by `commit` per attempt - `true`\n * only while `editing.draft` is on and outside `saveDrafts`, which is\n * what closes the per-row escape hatches (the lane's ✓,\n * Delete-to-clear) at the engine.\n */\n parkOnly: boolean;\n /** A commit already running - Enter and blur race on the same edit. */\n pendingCommit: Promise<boolean> | null;\n unsubscribe: () => void;\n unmount: () => void;\n };\n const forms = new Map<string, FormEntry>();\n let newRowCounter = 0;\n /** Lets `commit` tell a `saveDrafts` flush apart from a lone commit. */\n let savingDrafts = false;\n\n /**\n * While `saveDrafts` runs with an `onSaveDrafts`, each row's wrapped\n * onSubmit contributes its args here instead of calling `onEditCommit` -\n * validation stays per row (Form's), the consumer call becomes one.\n */\n let draftCollector: Array<TMDataGridEditCommitArgs<TMDataGridRowData>> | null =\n null;\n let draftAddCollector: Array<TMDataGridRowAddArgs<TMDataGridRowData>> | null =\n null;\n\n /**\n * The column's half of the rule, with no row in hand: it is a consumer\n * column mapping to a field, `editing.columns` lists it if that is set, and\n * `meta.edit.enabled` has not switched it off outright. A per-row predicate\n * on `enabled` is the row's half and is not asked here.\n */\n const isColumnEditable = (column: ErasedColumn): boolean => {\n if (isControlColumn(column.id)) return false;\n if (getEditFieldName(column) === null) return false;\n const allowed = getContext().editableColumnIds;\n if (allowed !== undefined && !allowed.includes(column.id)) return false;\n return !isColumnEditSwitchedOff(column);\n };\n\n const editableColumns = (): Array<ErasedColumn> =>\n getContext().table.getAllLeafColumns().filter(isColumnEditable);\n\n /**\n * Every column's `meta.edit.validate`, run against a row's values.\n *\n * Field validators belong to the mounted editor, so a row committed with\n * no editors on screen - an import, a programmatic commit, a row whose\n * cells are scrolled out - would otherwise submit without them ever\n * running. This is the engine running the same rules itself, so a commit\n * validates the same wherever it comes from. The result is Form's\n * `{ fields }` shape, which plants each error on its own field.\n */\n const validateColumnFields = async (\n values: TMDataGridRowData,\n rowId: string,\n isNew: boolean,\n ): Promise<Record<string, unknown> | undefined> => {\n const row = isNew ? undefined : getRow(rowId);\n const fields: Record<string, unknown> = {};\n for (const column of editableColumns()) {\n // A column switched off for this row has no editor and takes no edit,\n // so its rule is not this row's to satisfy.\n if (row !== undefined && !isColumnEditableForRow(column, row)) continue;\n const field = getEditFieldName(column);\n if (field === null) continue;\n const normalized = normalizeFieldValidate(\n column.columnDef.meta?.edit?.validate,\n );\n if (normalized === undefined) continue;\n const value = getBy(values, field);\n for (const trigger of SUBMIT_VALIDATE_TRIGGERS) {\n const validator = normalized[trigger];\n if (validator === undefined) continue;\n const error = await runFieldValidator(validator, value);\n if (isValidationError(error)) {\n fields[field] = error;\n break;\n }\n }\n }\n return Object.keys(fields).length > 0 ? fields : undefined;\n };\n\n /**\n * The collection as a table validator sees it: every data row overlaid\n * with its draft where a form holds one, entry rows appended, and rows\n * marked deleted removed. The committing row contributes the values being\n * submitted, not what `data` still says. Built from the core row model, so\n * it is unfiltered and never contains group rows.\n */\n const mergedRows = (\n rowId: string,\n value: TMDataGridRowData,\n isNew: boolean,\n ): Array<{ rowId: string; value: TMDataGridRowData }> => {\n const deleted = new Set(store.state.deletedRowIds);\n const rows: Array<{ rowId: string; value: TMDataGridRowData }> = [];\n for (const row of getContext().table.getCoreRowModel().flatRows) {\n if (deleted.has(row.id)) continue;\n if (row.id === rowId) {\n rows.push({ rowId, value });\n continue;\n }\n const held = forms.get(row.id);\n rows.push({\n rowId: row.id,\n value:\n held === undefined\n ? (row.original as TMDataGridRowData)\n : (held.form.state.values as TMDataGridRowData),\n });\n }\n for (const newRow of store.state.newRows) {\n if (newRow.tempId === rowId) continue;\n const held = forms.get(newRow.tempId);\n if (held === undefined || deleted.has(newRow.tempId)) continue;\n rows.push({\n rowId: newRow.tempId,\n value: held.form.state.values as TMDataGridRowData,\n });\n }\n if (isNew) rows.push({ rowId, value });\n return rows;\n };\n\n /**\n * Runs `editing.tableValidators` for one commit. `onSubmit` first; its\n * failure stands and `onSubmitAsync` is not consulted, mirroring how the\n * column triggers short-circuit.\n */\n const runTableValidators = async (\n value: TMDataGridRowData,\n rowId: string,\n isNew: boolean,\n ): Promise<unknown> => {\n const validators = getContext().tableValidators;\n if (\n validators?.onSubmit === undefined &&\n validators?.onSubmitAsync === undefined\n ) {\n return undefined;\n }\n const args: TMDataGridTableValidateArgs = {\n value,\n rowId,\n isNew,\n rows: mergedRows(rowId, value, isNew),\n };\n const sync = validators.onSubmit?.(args);\n if (isValidationError(sync)) return sync;\n return await validators.onSubmitAsync?.(args);\n };\n\n /**\n * One submit pass's results folded into Form's error shape. A single\n * source passes through untouched (its own shape preserved); several merge\n * into `{ form, fields }`, the later source winning a field collision and\n * the form slot alike.\n */\n const mergeSubmitResults = (\n results: ReadonlyArray<unknown>,\n fields: Record<string, unknown> | undefined,\n ): unknown => {\n const errors = results.filter(isValidationError);\n if (errors.length === 0) {\n return fields === undefined ? undefined : { fields };\n }\n if (errors.length === 1) {\n const only = errors[0];\n if (fields === undefined) return only;\n if (typeof only === \"object\" && only !== null) {\n const shape = only as { fields?: Record<string, unknown> };\n return { ...shape, fields: { ...fields, ...(shape.fields ?? {}) } };\n }\n return { form: only, fields };\n }\n let form: unknown;\n let mergedFields: Record<string, unknown> = { ...(fields ?? {}) };\n for (const error of errors) {\n if (typeof error === \"object\" && error !== null) {\n const shape = error as {\n form?: unknown;\n fields?: Record<string, unknown>;\n };\n if (isValidationError(shape.form)) form = shape.form;\n mergedFields = { ...mergedFields, ...(shape.fields ?? {}) };\n } else {\n form = error;\n }\n }\n const merged: { form?: unknown; fields?: Record<string, unknown> } = {};\n if (form !== undefined) merged.form = form;\n if (Object.keys(mergedFields).length > 0) merged.fields = mergedFields;\n return merged;\n };\n\n /**\n * The row's `validators`, with column validation and the table rules folded\n * into the submit pass. The consumer's own `rowValidators` are passed\n * through untouched except for `onSubmitAsync`, which now also carries the\n * column rules and `editing.tableValidators` - later sources win a merge,\n * so the order is columns, then the table rules, then the row's own.\n */\n const composeValidators = (\n rowId: string,\n isNew: boolean,\n ): Record<string, unknown> => {\n const rowValidators = (getContext().rowValidators ?? {}) as Record<\n string,\n unknown\n >;\n const consumerAsync = rowValidators[\"onSubmitAsync\"];\n return {\n ...rowValidators,\n onSubmitAsync: async (args: { value: unknown }) => {\n const value = args.value as TMDataGridRowData;\n const fromConsumer =\n consumerAsync === undefined\n ? undefined\n : await (consumerAsync as (a: unknown) => unknown)(args);\n const fromTable = await runTableValidators(value, rowId, isNew);\n const fields = await validateColumnFields(value, rowId, isNew);\n return mergeSubmitResults([fromTable, fromConsumer], fields);\n },\n };\n };\n\n const diff = (\n entry: FormEntry,\n values: TMDataGridRowData,\n ): Array<TMDataGridEditChange> => {\n const changes: Array<TMDataGridEditChange> = [];\n for (const column of editableColumns()) {\n const field = getEditFieldName(column);\n if (field === null) continue;\n const previous: unknown = getBy(entry.original, field);\n const next: unknown = getBy(values, field);\n if (!sameValue(previous, next)) {\n changes.push({ columnId: column.id, field, previous, next });\n }\n }\n return changes;\n };\n\n const project = (entry: FormEntry): TMDataGridEditRowProjection => {\n const state = entry.form.state;\n const values = state.values as TMDataGridRowData;\n const live = Object.entries(state.fieldMeta).flatMap(([name, meta]) => {\n // The empty path is a pathless (row-level) issue's landing spot - it\n // belongs to `hasRowError`, not to any cell's marker.\n if (name === \"\") return [];\n const errors = (meta as { errors: ReadonlyArray<unknown> }).errors;\n if (!hasAnyError(errors)) return [];\n return [{ field: name, message: firstErrorText(errors) ?? \"\" }];\n });\n // What a closed editor left behind, minus everything the user has since\n // changed - editing the field is the answer to its message.\n const kept = entry.submitErrors.filter(\n (error) =>\n !live.some((current) => current.field === error.field) &&\n sameValue(getBy(values, error.field), error.value),\n );\n const errorMessages = [\n ...live,\n ...kept.map(({ field, message }) => ({ field, message })),\n ];\n return {\n dirtyFields: diff(entry, values).map((change) => change.field),\n errorFields: errorMessages.map((error) => error.field),\n errorMessages,\n hasRowError: hasAnyError(state.errors),\n isSubmitting: state.isSubmitting,\n values,\n };\n };\n\n const publishRow = (rowId: string) => {\n const entry = forms.get(rowId);\n store.setState((prev) => {\n const rows = { ...prev.rows };\n if (entry === undefined) delete rows[rowId];\n else rows[rowId] = project(entry);\n return { ...prev, rows, openRowIds: [...forms.keys()] };\n });\n };\n\n const setActive = (active: TMDataGridEditState[\"active\"]) => {\n store.setState((prev) => ({ ...prev, active }));\n };\n\n const setNewRowCommitted = (tempId: string, committed: boolean) => {\n store.setState((prev) => {\n const target = prev.newRows.find((newRow) => newRow.tempId === tempId);\n if (target === undefined || target.committed === committed) return prev;\n return {\n ...prev,\n newRows: prev.newRows.map((newRow) =>\n newRow.tempId === tempId ? { ...newRow, committed } : newRow,\n ),\n };\n });\n };\n\n /**\n * Moves an existing row across the line between form state and the draft\n * store. The values never move - they stay in the row's form; this records\n * which side the row is on, and the entry's flag keeps the two in step.\n */\n const setCommitted = (rowId: string, committed: boolean) => {\n const entry = forms.get(rowId);\n if (entry !== undefined) entry.committed = committed;\n store.setState((prev) => {\n const has = prev.committedRowIds.includes(rowId);\n if (has === committed) return prev;\n return {\n ...prev,\n committedRowIds: committed\n ? [...prev.committedRowIds, rowId]\n : prev.committedRowIds.filter((id) => id !== rowId),\n };\n });\n };\n\n const drop = (rowId: string) => {\n const entry = forms.get(rowId);\n if (entry === undefined) return;\n entry.unsubscribe();\n entry.unmount();\n forms.delete(rowId);\n store.setState((prev) => {\n const rows = { ...prev.rows };\n delete rows[rowId];\n return {\n ...prev,\n rows,\n openRowIds: [...forms.keys()],\n committedRowIds: prev.committedRowIds.filter((id) => id !== rowId),\n newRows: entry.isNew\n ? prev.newRows.filter((newRow) => newRow.tempId !== rowId)\n : prev.newRows,\n active: prev.active?.rowId === rowId ? null : prev.active,\n };\n });\n };\n\n const createForm = (\n rowId: string,\n original: TMDataGridRowData,\n isNew: boolean,\n ): FormEntry => {\n const entry: FormEntry = {\n original,\n isNew,\n committed: false,\n lastSubmitOk: false,\n submitErrors: [],\n parkOnly: false,\n pendingCommit: null,\n unsubscribe: () => {},\n unmount: () => {},\n form: new FormApi({\n defaultValues: original,\n // The consumer's vocabulary is Form's own; the cast erases the\n // validator generics the same way the row type is erased. The column\n // rules ride along in the submit pass - see `composeValidators`.\n validators: composeValidators(rowId, isNew) as never,\n onSubmit: async ({ value }) => {\n // A new row commits whole: it is an add, not a diff against\n // anything that exists.\n if (entry.isNew) {\n const addArgs: TMDataGridRowAddArgs<TMDataGridRowData> = {\n tempId: rowId,\n value: value as TMDataGridRowData,\n };\n if (draftAddCollector !== null) {\n draftAddCollector.push(addArgs);\n entry.lastSubmitOk = true;\n return;\n }\n // Parked: validated and held for Save all - no consumer call.\n if (entry.parkOnly) {\n entry.lastSubmitOk = true;\n return;\n }\n try {\n await getContext().onRowAdd?.(addArgs);\n entry.lastSubmitOk = true;\n } catch (error) {\n entry.form.setErrorMap({\n onSubmit:\n error instanceof Error ? error.message : String(error),\n } as never);\n }\n return;\n }\n const changes = diff(entry, value as TMDataGridRowData);\n const args: TMDataGridEditCommitArgs<TMDataGridRowData> = {\n rowId,\n value: value as TMDataGridRowData,\n original,\n changes,\n source: getContext().editMode,\n };\n if (draftCollector !== null) {\n draftCollector.push(args);\n entry.lastSubmitOk = true;\n return;\n }\n // Parked: validated and held for Save all - no consumer call.\n if (entry.parkOnly) {\n entry.lastSubmitOk = true;\n return;\n }\n try {\n await getContext().onEditCommit?.(args);\n entry.lastSubmitOk = true;\n } catch (error) {\n // A rejected save keeps the form open, the message on the row.\n entry.form.setErrorMap({\n onSubmit:\n error instanceof Error ? error.message : String(error),\n } as never);\n }\n },\n }) as TMDataGridRowEditForm,\n };\n entry.unmount = entry.form.mount();\n const subscription = entry.form.store.subscribe(() => publishRow(rowId));\n entry.unsubscribe = () => subscription.unsubscribe();\n forms.set(rowId, entry);\n publishRow(rowId);\n return entry;\n };\n\n const canEditRow = (row: ErasedRow): boolean => {\n if (row.getIsGrouped()) return false;\n return getContext().isRowEditable?.(row) !== false;\n };\n\n const canEditCell = (row: ErasedRow, column: ErasedColumn): boolean => {\n const context = getContext();\n if (row.getIsGrouped()) return false;\n if (!isColumnEditable(column)) return false;\n if (!isColumnEditableForRow(column, row)) return false;\n if (context.isRowEditable !== undefined && !context.isRowEditable(row)) {\n return false;\n }\n return true;\n };\n\n const getRow = (rowId: string): ErasedRow | undefined => {\n try {\n return getContext().table.getRow(rowId);\n } catch {\n // TanStack throws for an id that is not in the current row model.\n return undefined;\n }\n };\n\n /**\n * The row's field errors as they stand, with the value each was found on.\n * Read straight after a failed submit, while every editor is still mounted\n * and Form still holds what its validators said.\n */\n const takeFieldErrors = (\n entry: FormEntry,\n ): Array<{ field: string; value: unknown; message: string }> => {\n const values = entry.form.state.values as TMDataGridRowData;\n return Object.entries(entry.form.state.fieldMeta).flatMap(\n ([field, meta]) => {\n if (field === \"\") return [];\n const errors = (meta as { errors: ReadonlyArray<unknown> }).errors;\n const message = hasAnyError(errors) ? firstErrorText(errors) : undefined;\n if (message === undefined) return [];\n return [{ field, value: getBy(values, field), message }];\n },\n );\n };\n\n const commit = async (rowId: string): Promise<boolean> => {\n const entry = forms.get(rowId);\n if (entry === undefined) return true;\n // Enter and blur race on the same edit; the second caller joins the\n // first's commit instead of submitting the row twice.\n if (entry.pendingCommit !== null) return entry.pendingCommit;\n // A pristine form has nothing to say - drop it without a consumer call.\n // Not for a new row: adding an untouched entry is still an add.\n if (\n !entry.isNew &&\n diff(entry, entry.form.state.values as TMDataGridRowData).length === 0\n ) {\n drop(rowId);\n return true;\n }\n // Field errors the *form's* validator planted are cleared before the\n // submit re-runs it: a field with no mounted editor is never revalidated\n // by Form itself, so a pathed issue would otherwise outlive its fix and\n // block `canSubmit` forever. The validator puts back whatever still holds.\n clearFormSourcedFieldErrors(entry.form);\n entry.lastSubmitOk = false;\n entry.submitErrors = [];\n entry.parkOnly = getContext().draft && !savingDrafts;\n entry.pendingCommit = (async () => {\n try {\n await entry.form.handleSubmit();\n } finally {\n entry.pendingCommit = null;\n }\n if (!entry.lastSubmitOk) {\n // Snapshot before the caller closes the editor: the field errors go\n // with it, and the row is about to be left carrying them.\n entry.submitErrors = takeFieldErrors(entry);\n publishRow(rowId);\n return false;\n }\n if (entry.parkOnly) {\n // Into the draft store: the row's values stay in its form, and the\n // grid records that they are decided. An entry row renders as a\n // value row, an edited row as its draft - both until `begin` takes\n // the row back out into form state, or `saveDrafts` flushes it.\n entry.committed = true;\n if (entry.isNew) setNewRowCommitted(rowId, true);\n else setCommitted(rowId, true);\n store.setState((prev) =>\n prev.active?.rowId === rowId ? { ...prev, active: null } : prev,\n );\n return true;\n }\n drop(rowId);\n return true;\n })();\n return entry.pendingCommit;\n };\n\n const beginOn = (rowId: string, columnId: string | null) => {\n // An entry row has no backing row in the table; opening one re-arms its\n // editors - with `editing.draft` on, that is how a parked row is edited\n // again.\n const entryForm = forms.get(rowId);\n if (entryForm?.isNew === true) {\n entryForm.committed = false;\n setNewRowCommitted(rowId, false);\n setActive({ rowId, columnId });\n return;\n }\n const row = getRow(rowId);\n if (row === undefined) return;\n if (columnId !== null) {\n const column = getContext().table.getColumn(columnId);\n if (column === undefined || !canEditCell(row, column)) return;\n } else if (getContext().isRowEditable?.(row) === false) {\n return;\n }\n if (!forms.has(rowId)) createForm(rowId, row.original, false);\n // Reopening a committed row takes it back out of the draft store: what\n // the user is now editing is undecided again, and `saveDrafts` must not\n // send it until it is committed afresh.\n else if (forms.get(rowId)?.committed === true) setCommitted(rowId, false);\n setActive({ rowId, columnId });\n };\n\n const begin: TMDataGridEditApi[\"begin\"] = ({ rowId, columnId }) => {\n const { editMode } = getContext();\n // Each mode's policy about a row already open elsewhere:\n //\n // | Mode | Another row open |\n // | ---- | ---------------- |\n // | cell | committed - Sheets; a failed commit keeps holding the edit |\n // | row, cellConfirm | accumulates. Every draft waits for its own save,\n // so a second row opening can neither discard the first nor be refused\n // by it - nothing about one row's form bears on another's |\n //\n // A parked row is not \"open\": it has had its submit and is waiting for\n // the save, so it is skipped rather than put through a second one. An\n // entry row is skipped too - it is row-shaped in every mode, and its ✓\n // is the decision, so the sweep must not add a half-typed row.\n if (editMode === \"cell\") {\n const openElsewhere = [...forms.keys()].find((id) => {\n const other = forms.get(id);\n return id !== rowId && other?.committed !== true && other?.isNew !== true;\n });\n if (openElsewhere !== undefined) {\n void commit(openElsewhere).then((ok) => {\n if (ok) beginOn(rowId, columnId);\n });\n return;\n }\n }\n beginOn(rowId, columnId);\n };\n\n const cancel = (rowId: string) => {\n drop(rowId);\n };\n\n const deactivate = () => {\n setActive(null);\n };\n\n const cancelAll = () => {\n for (const rowId of [...forms.keys()]) drop(rowId);\n store.setState((prev) => ({\n ...prev,\n active: null,\n committedRowIds: [],\n deletedRowIds: [],\n }));\n };\n\n const addRow = (values?: TMDataGridRowData): string => {\n newRowCounter += 1;\n const tempId = `__new__${newRowCounter}`;\n createForm(tempId, seedNewRow(values), true);\n store.setState((prev) => ({\n ...prev,\n newRows: [...prev.newRows, { tempId, committed: false }],\n }));\n return tempId;\n };\n\n /** Seeds one entry row's values - `newRowDefaults` under `values`. */\n const seedNewRow = (values?: TMDataGridRowData): TMDataGridRowData => {\n const { newRowDefaults } = getContext();\n const defaults =\n typeof newRowDefaults === \"function\"\n ? newRowDefaults()\n : (newRowDefaults ?? {});\n // The argument wins over the defaults key by key, so a caller can seed\n // one field and leave the rest of `newRowDefaults` standing.\n return { ...defaults, ...values };\n };\n\n const addRows = async (\n rows: ReadonlyArray<TMDataGridRowData>,\n options?: TMDataGridAddRowsOptions,\n ): Promise<TMDataGridAddRowsResult> => {\n const tempIds: Array<string> = [];\n // One notification for the batch: `createForm` publishes its row as it\n // mounts, so an import of hundreds would otherwise wake every subscriber\n // once per row before the entry block has even been told they exist.\n batch(() => {\n for (const values of rows) {\n newRowCounter += 1;\n const tempId = `__new__${newRowCounter}`;\n createForm(tempId, seedNewRow(values), true);\n tempIds.push(tempId);\n }\n store.setState((prev) => ({\n ...prev,\n newRows: [\n ...prev.newRows,\n ...tempIds.map((tempId) => ({ tempId, committed: false })),\n ],\n }));\n });\n\n if (options?.commit !== true) return { committed: [], open: tempIds };\n\n // In order, so a consumer's `onRowAdd` sees the rows as the file had\n // them. A row that fails validation stays open carrying its errors.\n const committed: Array<string> = [];\n const open: Array<string> = [];\n for (const tempId of tempIds) {\n const ok = await commit(tempId);\n (ok ? committed : open).push(tempId);\n }\n return { committed, open };\n };\n\n const deleteRow = (rowId: string) => {\n const entry = forms.get(rowId);\n // Deleting an unsaved entry row is just discarding the entry.\n if (entry?.isNew === true) {\n drop(rowId);\n return;\n }\n const context = getContext();\n if (context.draft) {\n // A toggle: the second press unmarks - the mark is a draft too.\n store.setState((prev) => ({\n ...prev,\n deletedRowIds: prev.deletedRowIds.includes(rowId)\n ? prev.deletedRowIds.filter((id) => id !== rowId)\n : [...prev.deletedRowIds, rowId],\n }));\n return;\n }\n const row = getRow(rowId);\n if (row === undefined) return;\n // Confirmation is the consumer's business, in their onRowDelete.\n void context.onRowDelete?.({ rowId, row });\n };\n\n const canDeleteRows = (): boolean => {\n const context = getContext();\n if (context.draft) {\n return (\n context.onRowDelete !== undefined ||\n context.onSaveDrafts !== undefined\n );\n }\n return context.onRowDelete !== undefined;\n };\n\n /** The pending deletions, reported and cleared by `saveDrafts`. */\n const takeDeletedRowIds = (): Array<string> => {\n const deleted = [...store.state.deletedRowIds];\n if (deleted.length > 0) {\n store.setState((prev) => ({ ...prev, deletedRowIds: [] }));\n }\n return deleted;\n };\n\n /** The draft store's rows: committed forms, in the order they landed. */\n const committedFormIds = (): Array<string> =>\n [...forms.keys()].filter((rowId) => forms.get(rowId)?.committed === true);\n\n const commitAll = async (): Promise<boolean> => {\n // Only the open ones - a row already in the draft store has had its\n // submit and must not be put through a second one here.\n const openIds = [...forms.keys()].filter(\n (rowId) => forms.get(rowId)?.committed !== true,\n );\n const results = await Promise.all(openIds.map((rowId) => commit(rowId)));\n return results.every(Boolean);\n };\n\n /**\n * The in-flight save. A second call while `onSaveDrafts` awaits would\n * re-collect the same payload and send it again - a double-clicked Save\n * would create every pending entry row twice - so concurrent calls join\n * this promise instead of starting a save of their own.\n */\n let saveInFlight: Promise<boolean> | null = null;\n\n const saveDrafts = (): Promise<boolean> => {\n if (saveInFlight !== null) return saveInFlight;\n // While this runs, `commit` really commits - `editing.draft` parks\n // otherwise. Single-threaded flag, same idiom as the collectors.\n savingDrafts = true;\n saveInFlight = saveDraftsInner().finally(() => {\n savingDrafts = false;\n saveInFlight = null;\n });\n return saveInFlight;\n };\n\n const saveDraftsInner = async (): Promise<boolean> => {\n const committedIds = committedFormIds();\n const deletedIds = [...store.state.deletedRowIds];\n // Nothing decided: open rows are not this verb's business, so a grid\n // mid-edit with an empty draft store saves cleanly and stays as it is.\n if (committedIds.length === 0 && deletedIds.length === 0) return true;\n\n if (getContext().onSaveDrafts === undefined) {\n // The default: the per-row loop - edits through `onEditCommit`, entry\n // rows through `onRowAdd`, marked deletions through `onRowDelete`.\n const results = await Promise.all(\n committedIds.map((rowId) => commit(rowId)),\n );\n for (const rowId of takeDeletedRowIds()) {\n const row = getRow(rowId);\n if (row !== undefined) {\n await getContext().onRowDelete?.({ rowId, row });\n }\n }\n return results.every(Boolean);\n }\n\n // One consumer call for the lot. Validation stays Form's, per row: rows\n // that fail keep their forms and markers; the valid ones travel\n // together, and only a resolved save drops them - a rejected save keeps\n // every draft, deletions included.\n const collected: Array<TMDataGridEditCommitArgs<TMDataGridRowData>> = [];\n const added: Array<TMDataGridRowAddArgs<TMDataGridRowData>> = [];\n draftCollector = collected;\n draftAddCollector = added;\n let allValid = true;\n try {\n for (const rowId of committedIds) {\n const entry = forms.get(rowId);\n if (entry === undefined) continue;\n entry.lastSubmitOk = false;\n await entry.form.handleSubmit();\n if (!entry.lastSubmitOk) allValid = false;\n }\n } finally {\n draftCollector = null;\n draftAddCollector = null;\n }\n const deleted = deletedIds;\n if (collected.length > 0 || added.length > 0 || deleted.length > 0) {\n let result: void | TMDataGridSaveDraftsResult;\n try {\n result = await getContext().onSaveDrafts?.({\n updated: collected,\n created: added,\n deleted,\n // The pre-2.0 names, still filled - see TMDataGridSaveDraftsArgs.\n rows: collected,\n added,\n });\n } catch {\n return false;\n }\n\n // Nothing returned saves the lot. A result names what failed; those\n // keep their drafts, committed, so the next save retries them.\n const outcomes = result ?? {};\n let savedAll = true;\n\n for (const args of collected) {\n if (isSaved(outcomes.updated, args.rowId)) drop(args.rowId);\n else savedAll = false;\n }\n for (const args of added) {\n if (isSaved(outcomes.created, args.tempId)) drop(args.tempId);\n else savedAll = false;\n }\n const savedDeletions = deleted.filter((id) =>\n isSaved(outcomes.deleted, id),\n );\n if (savedDeletions.length > 0) {\n store.setState((prev) => ({\n ...prev,\n deletedRowIds: prev.deletedRowIds.filter(\n (id) => !savedDeletions.includes(id),\n ),\n }));\n }\n if (savedDeletions.length < deleted.length) savedAll = false;\n\n if (!savedAll) return false;\n }\n return allValid;\n };\n\n /** @deprecated The old one-shot save - `commitAll` then `saveDrafts`. */\n const submitAll = async (): Promise<boolean> => {\n const committedOk = await commitAll();\n const savedOk = await saveDrafts();\n return committedOk && savedOk;\n };\n\n /**\n * The write path behind `clearCell`, `setCellValue` and `setRowValues`:\n * fill the row's own form and commit it, exactly as a ✓ on an open editor\n * would. Uses the form already open on the row when there is one, so a\n * programmatic write joins an edit in progress rather than discarding it.\n *\n * No editor is involved, so `meta.edit.mapValue` does not run - the caller\n * writes the stored value itself. Validation is untouched: this is the same\n * `commit`, so `meta.edit.validate` and `editing.rowValidators` still decide\n * whether the row lands, and a failure leaves the row open carrying its\n * errors.\n */\n const writeFields = async (\n rowId: string,\n writes: ReadonlyArray<{ field: string; value: unknown }>,\n ): Promise<boolean> => {\n const row = getRow(rowId);\n if (row === undefined) return false;\n if (writes.length === 0) return true;\n const entry = forms.get(rowId) ?? createForm(rowId, row.original, false);\n for (const { field, value } of writes) {\n entry.form.setFieldValue(field as never, value as never);\n }\n return commit(rowId);\n };\n\n /** The field a cell writes to, or `null` when that cell takes no edit. */\n const writableField = (rowId: string, columnId: string): string | null => {\n const row = getRow(rowId);\n const column = getContext().table.getColumn(columnId);\n if (row === undefined || column === undefined) return null;\n if (!canEditCell(row, column)) return null;\n return getEditFieldName(column);\n };\n\n const clearCell = async (\n rowId: string,\n columnId: string,\n ): Promise<boolean> => {\n const column = getContext().table.getColumn(columnId);\n const field = writableField(rowId, columnId);\n if (field === null || column === undefined) return false;\n return writeFields(rowId, [\n {\n field,\n value: clearedValueForType(column.columnDef.meta?.type ?? \"string\"),\n },\n ]);\n };\n\n const setCellValue = async (\n rowId: string,\n columnId: string,\n value: unknown,\n ): Promise<boolean> => {\n const field = writableField(rowId, columnId);\n if (field === null) return false;\n return writeFields(rowId, [{ field, value }]);\n };\n\n const setRowValues = async (\n rowId: string,\n values: Record<string, unknown>,\n ): Promise<boolean> => {\n const writes: Array<{ field: string; value: unknown }> = [];\n for (const [columnId, value] of Object.entries(values)) {\n const field = writableField(rowId, columnId);\n // All or nothing: one cell that takes no edit fails the call before\n // anything is written, so a bulk action cannot half-apply unnoticed.\n if (field === null) return false;\n writes.push({ field, value });\n }\n return writeFields(rowId, writes);\n };\n\n return {\n store,\n get state() {\n return store.state;\n },\n getForm: (rowId) => forms.get(rowId)?.form,\n canEditCell,\n canEditRow,\n isColumnEditable,\n begin,\n commit,\n cancel,\n deactivate,\n cancelAll,\n commitAll,\n saveDrafts,\n submitAll,\n clearCell,\n setCellValue,\n setRowValues,\n addRow,\n addRows,\n deleteRow,\n canDeleteRows,\n };\n}\n\n/**\n * `meta.edit.validate` normalised to the object TanStack Form's `validators`\n * option takes - a bare schema or function is shorthand for `{ onChange }`.\n */\nexport function normalizeFieldValidate(\n validate: TMDataGridFieldValidate | undefined,\n): Record<string, unknown> | undefined {\n if (validate === undefined) return undefined;\n if (typeof validate === \"function\" || \"~standard\" in validate) {\n return { onChange: validate };\n }\n return validate as Record<string, unknown>;\n}\n","import { ActionIcon, Group, Loader, Tooltip } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport type { ColumnDef, Row, RowData } from \"@tanstack/react-table\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport {\n useCellControlTabIndex,\n useTMDataGridContext,\n} from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\nimport { firstErrorText } from \"../core/editEngine\";\nimport {\n CheckIcon,\n CloseIcon,\n PencilIcon,\n PlusIcon,\n RestoreIcon,\n TrashIcon,\n} from \"./icons\";\n\nexport const EDIT_COLUMN_ID = \"__edit__\";\n\n/**\n * The draft store's change marker in the lane - what kind of change the row\n * is holding for the save. Non-interactive; the buttons beside it act.\n * `data-state` is the styling hook, `data-error` flips it red and puts the\n * message in the tooltip in place of the state's name.\n */\nfunction RowStateIndicator({\n state,\n rowId,\n label,\n error,\n}: {\n state: \"new\" | \"edited\" | \"deleted\";\n rowId: string;\n label: string;\n error: string | null;\n}) {\n const Icon =\n state === \"new\" ? PlusIcon : state === \"edited\" ? PencilIcon : TrashIcon;\n return (\n <Tooltip label={error ?? label} withArrow>\n <span\n role=\"img\"\n aria-label={label}\n data-dg-part=\"row-state\"\n data-state={state}\n data-row-id={rowId}\n data-error={error !== null || undefined}\n className={classes.rowStateIndicator}\n >\n <Icon size={16} stroke={1.6} />\n </span>\n </Tooltip>\n );\n}\n\n/**\n * One row's slot in the edit lane, driven off the edit store. Two things\n * decide what it holds, and they are the two axes of `editing`:\n *\n * | Row is | Lane holds | From |\n * | ------ | ---------- | ---- |\n * | parked in the draft store | the change marker and the way back out - revert, discard or restore | `editing.draft` |\n * | open | the mode's own controls: Save and Cancel | `editing.mode` |\n * | neither | the pencil (row mode) and the trash | `editing.mode` |\n *\n * A row error turns the Save red with the message in its tooltip - a\n * pathless `.refine()` has nowhere else to land, and a field error outlives\n * the editor that found it. A parked row never offers a save: it has had its\n * submit, and `TMDataGrid.DraftActions` is what sends it.\n */\nfunction EditLaneCell<TData extends RowData>({\n row,\n}: {\n row: Row<TMDataGridFeatures, TData>;\n}) {\n const { edit, features, labels } = useTMDataGridContext();\n const tabIndex = useCellControlTabIndex();\n const rowId = row.id;\n const isOpen = useSelector(edit.store, (state) =>\n state.openRowIds.includes(rowId),\n );\n const projection = useSelector(edit.store, (state) => state.rows[rowId]);\n const isNew = useSelector(edit.store, (state) =>\n state.newRows.some((newRow) => newRow.tempId === rowId),\n );\n const isConfirmedNew = useSelector(\n edit.store,\n (state) =>\n state.newRows.find((newRow) => newRow.tempId === rowId)?.committed ===\n true,\n );\n // Parked: the row passed its submit and is waiting for the save. A subset\n // of the open rows, so it is asked about first - the two overlap.\n const isCommitted = useSelector(edit.store, (state) =>\n state.committedRowIds.includes(rowId),\n );\n const isMarkedDeleted = useSelector(edit.store, (state) =>\n state.deletedRowIds.includes(rowId),\n );\n\n if (row.getIsGrouped()) return null;\n\n const hasErrors =\n projection !== undefined &&\n (projection.hasRowError || projection.errorFields.length > 0);\n // The row's own message first - a pathless issue is about the row - then\n // the first field's, which is what a failed commit left behind.\n const rowError = hasErrors\n ? (firstErrorText(edit.getForm(rowId)?.state.errors ?? []) ??\n projection.errorMessages[0]?.message ??\n labels.editRowErrors)\n : null;\n\n const trash = edit.canDeleteRows() ? (\n <Tooltip label={labels.deleteRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.deleteRow}\n data-dg-part=\"delete-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.deleteRow(rowId);\n }}\n >\n <TrashIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n ) : null;\n\n // An entry row: ✓ enters it - an add, or a park under `editing.draft` -\n // and ✕ discards the entry. A parked entry waits for the save as a value\n // row: marked new, re-openable, still discardable.\n if (isNew) {\n if (isConfirmedNew) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n <RowStateIndicator\n state=\"new\"\n rowId={rowId}\n label={labels.rowStateNew}\n error={rowError}\n />\n <Tooltip label={labels.editRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.editRow}\n data-dg-part=\"edit-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.begin({ rowId, columnId: null });\n }}\n >\n <PencilIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n <Tooltip label={labels.discardNewRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.discardNewRow}\n data-dg-part=\"discard-new-row\"\n data-row-id={rowId}\n onClick={() => edit.cancel(rowId)}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n return (\n <Group gap={0} wrap=\"nowrap\">\n <Tooltip label={labels.confirmNewRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"green\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.confirmNewRow}\n data-dg-part=\"confirm-new-row\"\n data-row-id={rowId}\n onClick={() => void edit.commit(rowId)}\n >\n <CheckIcon size={16} stroke={2} />\n </ActionIcon>\n </Tooltip>\n <Tooltip label={labels.discardNewRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.discardNewRow}\n data-dg-part=\"discard-new-row\"\n data-row-id={rowId}\n onClick={() => edit.cancel(rowId)}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n\n // A deletion mark is a draft like any other - restorable in place.\n if (isMarkedDeleted) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n <RowStateIndicator\n state=\"deleted\"\n rowId={rowId}\n label={labels.rowStateDeleted}\n error={null}\n />\n <Tooltip label={labels.restoreRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.restoreRow}\n data-dg-part=\"restore-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.deleteRow(rowId);\n }}\n >\n <RestoreIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n\n // The pencil means \"this row edits\"; a row that does not gets nothing.\n if (!edit.canEditRow(row as never)) return null;\n\n if (projection?.isSubmitting) {\n return <Loader size=\"xs\" aria-label={labels.loading} />;\n }\n\n // Parked in the draft store: the mark, and the way back out. No trash\n // beside the revert - the two undo-shaped icons were too easy to mistake\n // for one another, so a drafted row reverts first, then deletes.\n if (isCommitted) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n <RowStateIndicator\n state=\"edited\"\n rowId={rowId}\n label={labels.rowStateEdited}\n error={rowError}\n />\n <Tooltip label={labels.revertRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.revertRow}\n data-dg-part=\"revert-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.cancel(rowId);\n }}\n >\n <RestoreIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n }\n\n if (!isOpen) {\n return (\n <Group gap={0} wrap=\"nowrap\">\n {features.editMode === \"row\" && (\n <Tooltip label={labels.editRow} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.editRow}\n data-dg-part=\"edit-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.begin({ rowId, columnId: null });\n }}\n >\n <PencilIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n )}\n {trash}\n </Group>\n );\n }\n\n const save = (\n <ActionIcon\n variant=\"subtle\"\n color={hasErrors ? \"red\" : \"green\"}\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.saveRow}\n data-dg-part=\"save-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n void edit.commit(rowId);\n }}\n >\n <CheckIcon size={16} stroke={2} />\n </ActionIcon>\n );\n\n return (\n <Group gap={0} wrap=\"nowrap\">\n {rowError === null ? (\n <Tooltip label={labels.saveRow} withArrow>\n {save}\n </Tooltip>\n ) : (\n <Tooltip label={rowError} withArrow>\n {save}\n </Tooltip>\n )}\n <Tooltip label={labels.cancelRowEdit} withArrow>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"sm\"\n tabIndex={tabIndex}\n aria-label={labels.cancelRowEdit}\n data-dg-part=\"cancel-row\"\n data-row-id={rowId}\n onClick={(event) => {\n event.stopPropagation();\n edit.cancel(rowId);\n }}\n >\n <CloseIcon size={16} stroke={1.6} />\n </ActionIcon>\n </Tooltip>\n </Group>\n );\n}\n\n/**\n * The generated edit lane, appended and pinned right - the row's Save at the\n * end of the row under `mode: \"row\"`, the state marker and revert under\n * `editing.draft`, mirroring the checkbox lane's build on the left.\n */\nexport function createEditColumn<TData extends RowData>(\n label = \"Edit\",\n /** A draft lane holds three controls where the rest hold two. */\n wide = false,\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n const width = wide ? 88 : 64;\n return {\n id: EDIT_COLUMN_ID,\n meta: {\n label,\n align: \"center\",\n enableOrdering: false,\n },\n // Wide enough for the pair (or draft's trio) it holds while editing.\n size: width,\n minSize: width,\n maxSize: width,\n enableResizing: false,\n enableSorting: false,\n enableColumnFilter: false,\n enableGlobalFilter: false,\n // The row's Save, Cancel and Delete live here, so hiding the lane would\n // strand an open row with no way to commit or discard it. Same rule as the\n // checkbox lane: chrome the grid generates is not a user setting.\n enableHiding: false,\n // Structurally pinned to the right; not movable.\n enablePinning: false,\n header: () => null,\n cell: ({ row }) => <EditLaneCell row={row} />,\n // Group rows: same reasoning as the checkbox lane - without this the\n // cell renders blank on aggregated rows, but here blank is also correct,\n // so the aggregated cell renders the same (null for groups).\n aggregatedCell: ({ row }) => <EditLaneCell row={row} />,\n };\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 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 { 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 data-dg-part=\"group-toggle\"\n data-row-id={row.id}\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 type { ColumnDef, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\nexport const ROW_NUMBER_COLUMN_ID = \"__rowNumber__\";\n\n/**\n * The generated row-number gutter, prepended under `enableRowNumbers` -\n * outermost left, before even the checkbox lane, the way a spreadsheet keeps\n * its gutter outside everything.\n *\n * The def renders nothing itself: a cell cannot know its display position,\n * so the body computes the numbers - one pass over the view, group rows\n * skipped (they are headings over the rows being counted), continuing across\n * pages - and substitutes them in. See `TMDataGridTable`.\n *\n * A system lane: fixed width, no menu, no resize, never exported, and its\n * visibility follows the option rather than the columns panel.\n */\nexport function createRowNumberColumn<TData extends RowData>(\n label = \"Row number\",\n): ColumnDef<TMDataGridFeatures, TData, unknown> {\n return {\n id: ROW_NUMBER_COLUMN_ID,\n meta: {\n label,\n align: \"center\",\n // Anchors the left edge with the checkbox lane; nothing moves past 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 enablePinning: false,\n enableHiding: false,\n header: () => \"#\",\n // The body substitutes the number; a row without one - a group row -\n // falls through to this.\n cell: () => null,\n };\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 *\n * Rows pinned to an edge leave this list - they render in their own sticky\n * blocks, outside the scrolling order a shift-click range or the virtualizer\n * walks. See `readPinnedRows`.\n */\nexport function getDisplayedRows<TData extends RowData>(\n table: TMDataGridTable<TData>,\n features: TMDataGridFeatureFlags,\n): Array<Row<TMDataGridFeatures, TData>> {\n const rows = isPagingActive(table, features)\n ? table.getPaginatedRowModel().rows\n : table.getPrePaginatedRowModel().rows;\n if (!features.rowPinning) return rows;\n const { top, bottom } = table.store.state.rowPinning;\n if (top.length === 0 && bottom.length === 0) return rows;\n const pinned = new Set([...top, ...bottom]);\n return rows.filter((row) => !pinned.has(row.id));\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, which replaces the selection. `false` for a\n * checkbox, which is only ever additive: ticking one box does not clear the\n * others, and shift-clicking one adds the range rather than replacing 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 data-dg-part=\"select-all\"\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 holds the leaves,\n // and TanStack's `getIsSelected()` is a plain lookup in that map. A group\n // therefore asks about its descendants instead, so the box means \"all of\n // these\" and goes indeterminate as soon 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 data-dg-part=\"select-row\"\n data-row-id={row.id}\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 // Not a column the user chose, so not one they can switch off: hiding the\n // lane would take the grid's only way to select a row with it, with the\n // row-selection state left behind and no way back to it. Keeping it out of\n // \"Manage columns\" follows from this - the panel lists what can be hidden.\n enableHiding: 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 { Row } from \"@tanstack/react-table\";\nimport {\n getDefaultOperator,\n type TMDataGridColumnType,\n type TMDataGridFilterOperator,\n} from \"./filterOperators\";\nimport { DETAILS_COLUMN_ID } from \"../components/TMDataGridDetailsColumn\";\nimport { EDIT_COLUMN_ID } from \"../components/TMDataGridEditColumn\";\nimport { GROUP_COLUMN_ID } from \"../components/TMDataGridGroupColumn\";\nimport { ROW_NUMBER_COLUMN_ID } from \"../components/TMDataGridRowNumberColumn\";\nimport { SELECT_COLUMN_ID } from \"../components/TMDataGridSelectColumn\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridColumnMeta, TMDataGridFeatures } from \"../useTMDataGrid\";\nimport type { TMDataGridFilterControlComponent } from \"./filterControls\";\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\n/**\n * The operator a fresh filter on this column starts with -\n * `meta.filter.defaultOperator`, else the type's default.\n */\nexport function getColumnDefaultOperator(\n column: ColumnLike,\n): TMDataGridFilterOperator {\n return (\n column.columnDef.meta?.filter?.defaultOperator ??\n getDefaultOperator(getColumnType(column))\n );\n}\n\n/**\n * This column's filter-panel value control - `meta.filter.control`, or\n * `undefined` for the built-in shape-by-operator input.\n */\nexport function getColumnFilterControl(\n column: ColumnLike,\n): TMDataGridFilterControlComponent | undefined {\n return column.columnDef.meta?.filter?.control;\n}\n\n/**\n * Whether `meta.edit.enabled` switches this column off outright, ignoring any\n * per-row predicate. For the passes that have no row in hand - listing which\n * columns a row form covers, finding the first cell an opened row should put\n * the caret in.\n */\nexport function isColumnEditSwitchedOff(column: ColumnLike): boolean {\n return column.columnDef.meta?.edit?.enabled === false;\n}\n\n/**\n * Whether `meta.edit.enabled` lets this column's cell on this row be edited -\n * the switch, then the predicate.\n *\n * This is only the column's half of the rule. A cell also needs the column to\n * map to a field (`getEditFieldName`) and the row to take edits at all\n * (`isRowEditable`); `edit.canEditCell` is the whole question.\n */\nexport function isColumnEditableForRow(\n column: ColumnLike,\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n): boolean {\n const enabled = column.columnDef.meta?.edit?.enabled;\n if (enabled === false) return false;\n if (typeof enabled === \"function\") return enabled(row);\n return true;\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 fixed-width thing - the checkbox, the details\n * chevron, the row number.\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 content in an unpadded cell.\n * Their headers carry no column menu, and none of them is ever exported -\n * they hold chrome, not values.\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 (\n columnId === SELECT_COLUMN_ID ||\n columnId === DETAILS_COLUMN_ID ||\n columnId === EDIT_COLUMN_ID ||\n columnId === ROW_NUMBER_COLUMN_ID\n );\n}\n\n/**\n * Whether the grid generated this column rather than the consumer declaring it\n * - the four control lanes plus the tree column.\n *\n * These hold the grid's own chrome, and they keep the edges of the row: the\n * generated left lanes before every consumer column, the edit lane after all of\n * them. `isControlColumn` answers a narrower question about layout, and leaves\n * the tree column out because it is padded like a data column.\n */\nexport function isGeneratedColumn(columnId: string): boolean {\n return isControlColumn(columnId) || columnId === GROUP_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","import {\n Button,\n Checkbox,\n ScrollArea,\n Text,\n TextInput,\n Tooltip,\n} 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, labels, controlSize, resetSettings } = useTMDataGridContext();\n const [search, setSearch] = useState(\"\");\n\n const columnVisibility = useSelector(\n table.store,\n (state) => state.columnVisibility,\n );\n\n // Only what can actually be hidden. A column with `enableHiding: false` is\n // left out rather than listed and disabled: a box that cannot be ticked only\n // invites the question, and every generated lane is one - the checkbox and\n // edit lanes hold the controls the grid needs, the tree column follows the\n // grouping state, the row-number gutter follows `enableRowNumbers`. None of\n // them is a setting.\n const columns = table\n .getAllLeafColumns()\n .filter((column) => column.getCanHide());\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 shownCount = columns.filter(\n (column) => columnVisibility[column.id] !== false,\n ).length;\n\n /**\n * Show or hide every listed column.\n *\n * Not `table.toggleAllColumnsVisible`, which writes a visibility entry for\n * *every* leaf column: showing all would publish the tree column - hidden\n * because nothing is grouped, not because the user hid it - and hiding all\n * would force the same column visible, since it writes `!getCanHide()` for\n * the columns it will not touch. Either way a lane the panel never listed\n * changes state, and persistence then keeps it that way.\n */\n const setAllVisible = (visible: boolean) => {\n table.setColumnVisibility((previous) => {\n const next = { ...previous };\n for (const column of columns) next[column.id] = visible;\n return next;\n });\n };\n\n return (\n <div data-dg-part=\"columns-panel\" 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-dg-part=\"columns-search\"\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 data-dg-part=\"columns-toggle\"\n data-column-id={column.id}\n checked={columnVisibility[column.id] !== false}\n onChange={(event) =>\n column.toggleVisibility(event.currentTarget.checked)\n }\n />\n ))}\n {visibleInPanel.length === 0 && (\n <Text span 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 data-dg-part=\"columns-toggle-all\"\n checked={shownCount === columns.length}\n indeterminate={shownCount > 0 && shownCount < columns.length}\n onChange={(event) => setAllVisible(event.currentTarget.checked)}\n />\n {/* The whole layout, not only visibility: one reset with an honest\n scope, stated in the tooltip. `table.resetColumnVisibility()` would\n also be wrong under persistence - it resets to `initialState`,\n which the mount built *from* the persisted payload. */}\n <Tooltip label={labels.columnsResetHint} withArrow>\n <Button\n variant=\"subtle\"\n size=\"compact-sm\"\n data-dg-part=\"columns-reset\"\n onClick={() => resetSettings()}\n >\n {labels.columnsReset}\n </Button>\n </Tooltip>\n </div>\n </div>\n );\n}\n","import { Button, Group, Text } from \"@mantine/core\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { shallow } from \"@tanstack/store\";\nimport type { ReactNode } from \"react\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getOpenRowIds } from \"../core/editEngine\";\nimport { getDisplayedRows } from \"../core/rowSelection\";\nimport type {\n TMDataGridScrollAlign,\n TMDataGridScrollToRowArgs,\n} from \"../useTMDataGrid\";\n\n/**\n * How many rows the draft store holds - parked edits, parked entry rows and\n * deletion marks. This is what Save sends, so it is what Save counts: a row\n * the user is still typing into is not in here.\n */\nfunction useDraftCount(): number {\n const { edit } = useTMDataGridContext();\n return useSelector(\n edit.store,\n (state) =>\n state.committedRowIds.length +\n state.newRows.filter((newRow) => newRow.committed).length +\n state.deletedRowIds.length,\n );\n}\n\n/**\n * How many rows are still open - edited or entered but not parked, so not\n * part of the save. Surfaced beside Save so an undecided row is visible\n * rather than silently left behind.\n */\nfunction useOpenCount(): number {\n const { edit } = useTMDataGridContext();\n return useSelector(edit.store, (state) => getOpenRowIds(state).length);\n}\n\n/**\n * The ids behind {@link useOpenCount}. Shallow-compared: the array would\n * otherwise be a new one on every edit-store publish, and it is handed to\n * `renderActions`, where it may well end up in a dependency array.\n */\nfunction useOpenRowIds(): ReadonlyArray<string> {\n const { edit } = useTMDataGridContext();\n return useSelector(edit.store, getOpenRowIds, { compare: shallow });\n}\n\n/*\n * Module scope, like the pagination controls and for the same reason: a\n * component defined inside the render body is a new type every render, so\n * React would remount the buttons underneath an interaction.\n */\n\nfunction EditSaveButton() {\n const { edit, labels } = useTMDataGridContext();\n const draftCount = useDraftCount();\n const isSubmitting = useSelector(edit.store, (state) =>\n state.openRowIds.some((rowId) => state.rows[rowId]?.isSubmitting === true),\n );\n\n return (\n <Button\n size=\"compact-sm\"\n disabled={draftCount === 0}\n loading={isSubmitting}\n data-dg-part=\"save-all\"\n data-draft-count={draftCount}\n onClick={() => void edit.saveDrafts()}\n >\n {labels.saveAllEdits(draftCount)}\n </Button>\n );\n}\n\n/** The count of rows left open, or nothing while every row is decided. */\nfunction EditOpenRowsNote() {\n const { labels } = useTMDataGridContext();\n const openCount = useOpenCount();\n if (openCount === 0) return null;\n return (\n <Text\n size=\"xs\"\n c=\"dimmed\"\n data-dg-part=\"open-rows-note\"\n data-open-count={openCount}\n >\n {labels.editRowsStillOpen(openCount)}\n </Text>\n );\n}\n\nfunction EditDiscardButton() {\n const { edit, labels } = useTMDataGridContext();\n // Discard drops everything the grid is holding, open rows included, so it\n // stays live while anything is uncommitted.\n const pendingCount = useDraftCount() + useOpenCount();\n\n return (\n <Button\n variant=\"subtle\"\n color=\"gray\"\n size=\"compact-sm\"\n disabled={pendingCount === 0}\n data-dg-part=\"discard-all\"\n onClick={() => edit.cancelAll()}\n >\n {labels.discardAllEdits}\n </Button>\n );\n}\n\nconst EDIT_ACTIONS_CONTROLS: TMDataGridDraftActionsControls = {\n Save: EditSaveButton,\n Discard: EditDiscardButton,\n OpenRowsNote: EditOpenRowsNote,\n};\n\n/** What the edit chrome is showing. */\nexport type TMDataGridDraftActionsState = {\n /**\n * Rows in the draft store, which is what Save sends: committed edits,\n * committed entry rows and deletion marks.\n */\n draftCount: number;\n /**\n * Rows still open - edited or entered but not committed, so not part of\n * the save. They stay open across a save.\n */\n openCount: number;\n /**\n * The ids behind {@link openCount}, in the order the grid opened them - a\n * sort, a filter or a page never moves this list. An entered row appears as\n * its `tempId`.\n *\n * Narrower than `edit.state.openRowIds`, which is every row holding a form,\n * the parked ones included. And note the ordering:\n * {@link TMDataGridDraftActionsActions.scrollToFirstOpenRow} takes \"first\"\n * in display order, so it need not be `openRowIds[0]`.\n */\n openRowIds: ReadonlyArray<string>;\n /**\n * @deprecated Was \"everything uncommitted\", which Save no longer sends.\n * Reads as `draftCount + openCount`; use whichever you meant.\n */\n pendingCount: number;\n /** Whether a submit is in flight. */\n isSubmitting: boolean;\n};\n\n/** What the edit chrome can do. */\nexport type TMDataGridDraftActionsActions = {\n /** Saves the draft store. Open rows are left alone. */\n save: () => Promise<boolean>;\n /** Submits every open row, committing the ones that validate. */\n commitAll: () => Promise<boolean>;\n /** Drops everything - open form state and the draft store alike. */\n discard: () => void;\n /**\n * `grid.scrollToRow`, so a control in here can take the user to a row\n * without the grid being threaded down to it.\n */\n scrollToRow: (args: TMDataGridScrollToRowArgs) => boolean;\n /**\n * Scrolls to the first row still open, taking \"first\" in display order: the\n * topmost open row under the current sort, filter and page. That need not\n * be {@link TMDataGridDraftActionsState.openRowIds}`[0]`, which is the\n * order the grid opened them in.\n *\n * Answers whether an open row could be reached. `false` when nothing is\n * open, and when every open row is filtered out, on another page or\n * collapsed inside a group. An open entry row answers `true` without\n * scrolling - it is sticky under the header, so it is on screen already -\n * and so does an open row pinned to an edge. The scroll goes through\n * `scrollToRow`, so before `TMDataGrid.Table` has mounted there is nothing\n * to scroll and the answer is `false`.\n */\n scrollToFirstOpenRow: (align?: TMDataGridScrollAlign) => boolean;\n};\n\n/** The pre-bound pieces of the built-in edit chrome. */\nexport type TMDataGridDraftActionsControls = {\n /** Save, with the draft count, disabled while the draft store is empty. */\n Save: () => ReactNode;\n /** Discard, disabled while nothing is pending. */\n Discard: () => ReactNode;\n /** The \"N rows still being edited\" note, or nothing while there are none. */\n OpenRowsNote: () => ReactNode;\n};\n\n/** What {@link TMDataGridDraftActionsProps.renderActions} is handed. */\nexport type TMDataGridDraftActionsSlotArgs = {\n state: TMDataGridDraftActionsState;\n actions: TMDataGridDraftActionsActions;\n Controls: TMDataGridDraftActionsControls;\n};\n\nexport type TMDataGridDraftActionsProps = {\n /**\n * Replaces the built-in Save/Discard pair, and is handed the pieces of it.\n *\n * ```tsx\n * <TMDataGrid.DraftActions\n * renderActions={({ state, Controls }) => (\n * <Group>\n * {state.draftCount > 0 && <Badge>{state.draftCount}</Badge>}\n * <Controls.OpenRowsNote />\n * <Controls.Save />\n * <Controls.Discard />\n * </Group>\n * )}\n * />\n * ```\n */\n renderActions?: (args: TMDataGridDraftActionsSlotArgs) => ReactNode;\n};\n\n/**\n * The draft store's toolbar chrome: Save with the store's count, Discard, and\n * a note counting the rows still open. Save sends the store and leaves open\n * rows alone, so it greys out while nothing is parked however much is being\n * typed - the note is what makes those rows visible.\n *\n * Works under any `editing.mode`. The toolbar is declarative: the grid does\n * not decide for you, so include this only when the grid runs a draft store -\n * without `editing.draft` there is nothing to save and Save stays disabled.\n *\n * ```tsx\n * <TMDataGrid.Toolbar>\n * <TMDataGrid.SummaryCount />\n * <TMDataGrid.Spacer />\n * <TMDataGrid.DraftActions />\n * </TMDataGrid.Toolbar>\n * ```\n */\nexport function TMDataGridDraftActions({\n renderActions,\n}: TMDataGridDraftActionsProps = {}) {\n const { edit, features, table, scrollToRow } = useTMDataGridContext();\n const draftCount = useDraftCount();\n const openRowIds = useOpenRowIds();\n const isSubmitting = useSelector(edit.store, (state) =>\n state.openRowIds.some((rowId) => state.rows[rowId]?.isSubmitting === true),\n );\n\n if (!features.editing) return null;\n\n if (renderActions) {\n return renderActions({\n state: {\n draftCount,\n openCount: openRowIds.length,\n openRowIds,\n pendingCount: draftCount + openRowIds.length,\n isSubmitting,\n },\n actions: {\n save: () => edit.saveDrafts(),\n commitAll: () => edit.commitAll(),\n discard: () => edit.cancelAll(),\n scrollToRow,\n scrollToFirstOpenRow: (align) => {\n // Read through the store rather than closing over this render's\n // arrays: display order is only decided here, at the click.\n const state = edit.state;\n const openIds = getOpenRowIds(state);\n if (openIds.length === 0) return false;\n const open = new Set(openIds);\n const first = getDisplayedRows(table, features).find((row) =>\n open.has(row.id),\n );\n if (first !== undefined) {\n return scrollToRow({ rowId: first.id, align });\n }\n // Nothing left in the scrolling order, which does not mean nothing\n // is visible: an entry row is sticky under the header, and a pinned\n // row is parked at an edge - `scrollToRow` answers for that one.\n return openIds.some(\n (rowId) =>\n state.newRows.some((newRow) => newRow.tempId === rowId) ||\n scrollToRow({ rowId, align }),\n );\n },\n },\n Controls: EDIT_ACTIONS_CONTROLS,\n });\n }\n\n return (\n <Group gap=\"xs\" wrap=\"nowrap\">\n <EditOpenRowsNote />\n <EditSaveButton />\n <EditDiscardButton />\n </Group>\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 { Group, MultiSelect, Select, TextInput } from \"@mantine/core\";\nimport { optionsToComboboxData } from \"../../core/columnOptions\";\nimport { getColumnType } from \"../../core/columnUtils\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport {\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../../core/filterOperators\";\n\n/**\n * The built-in value control of a filter-panel row - what renders when a\n * column declares no `meta.filter.control`. Shaped by the operator: a\n * multi-select for the set operators, a From/To pair for `between`, a Yes/No\n * dropdown for booleans, a typed input otherwise.\n *\n * Exported so a custom control can fall back to it for the operators it does\n * not care about, instead of rebuilding them.\n */\nexport function TMDataGridFilterValueInput({\n column,\n operator,\n value,\n onChange,\n options,\n size,\n labels,\n}: TMDataGridFilterControlArgs) {\n const type = getColumnType(column);\n const needsValue = operatorNeedsValue(operator);\n const scalarValue = typeof value === \"string\" ? value : \"\";\n const inputType =\n type === \"number\" ? \"number\" : type === \"date\" ? \"date\" : \"text\";\n\n if (operatorTakesRangeValue(operator)) {\n const rangeValue: [string, string] = Array.isArray(value)\n ? [String(value[0] ?? \"\"), String(value[1] ?? \"\")]\n : [\"\", \"\"];\n return (\n // The interval's two ends. Either may stay empty (an open end), and\n // each writes its slot of the `[min, max]` pair.\n <Group gap={4} wrap=\"nowrap\" align=\"flex-start\">\n <TextInput\n label={labels.filterFrom}\n size={size}\n w={88}\n type={inputType}\n data-dg-part=\"filter-value-from\"\n value={rangeValue[0]}\n onChange={(event) =>\n onChange([event.currentTarget.value, rangeValue[1]])\n }\n />\n <TextInput\n label={labels.filterTo}\n size={size}\n w={88}\n type={inputType}\n data-dg-part=\"filter-value-to\"\n value={rangeValue[1]}\n onChange={(event) =>\n onChange([rangeValue[0], event.currentTarget.value])\n }\n />\n </Group>\n );\n }\n\n if (operatorTakesArrayValue(operator)) {\n // The set the cell is tested against. Options come from `meta.options`;\n // a select column that declares none still gets the values present in\n // the data, via the faceted index.\n return (\n <MultiSelect\n label={labels.filterValue}\n size={size}\n w={180}\n comboboxProps={{ withinPortal: false }}\n searchable\n data-dg-part=\"filter-value\"\n data={optionsToComboboxData(options)}\n value={Array.isArray(value) ? [...value] : []}\n onChange={onChange}\n />\n );\n }\n\n if (type === \"boolean\") {\n return (\n <Select\n label={labels.filterValue}\n size={size}\n w={180}\n comboboxProps={{ withinPortal: false }}\n data-dg-part=\"filter-value\"\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) => onChange(next ?? \"\")}\n />\n );\n }\n\n return (\n <TextInput\n label={labels.filterValue}\n size={size}\n w={180}\n type={needsValue ? inputType : \"text\"}\n data-dg-part=\"filter-value\"\n disabled={!needsValue}\n placeholder={needsValue ? labels.filterValuePlaceholder : \"\"}\n value={needsValue ? scalarValue : \"\"}\n onChange={(event) => onChange(event.currentTarget.value)}\n />\n );\n}\n","import {\n ActionIcon,\n Button,\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 { resolveColumnOptions } from \"../core/columnOptions\";\nimport {\n getColumnDefaultOperator,\n getColumnFilterControl,\n getColumnLabel,\n getColumnType,\n} from \"../core/columnUtils\";\nimport {\n type TMDataGridFilterOperator,\n type TMDataGridFilterValue,\n emptyValueForOperator,\n getDefaultOperator,\n getOperatorsForType,\n isTMDataGridFilterValue,\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../core/filterOperators\";\nimport { CloseIcon } from \"./icons\";\nimport { TMDataGridFilterValueInput } from \"./filters/TMDataGridFilterValueInput\";\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 three value shapes an operator can take. A typed value survives an\n * operator or column change only within its shape - a set is not a range,\n * even though both are arrays.\n */\nfunction valueShape(\n operator: TMDataGridFilterOperator,\n): \"scalar\" | \"set\" | \"range\" {\n if (operatorTakesArrayValue(operator)) return \"set\";\n if (operatorTakesRangeValue(operator)) return \"range\";\n return \"scalar\";\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-part=\"filter-button\"]')) 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 = target\n ? getColumnDefaultOperator(target)\n : getDefaultOperator(\"string\");\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 valueShape(operator) === valueShape(current.operator)\n ? current.value\n : emptyValueForOperator(operator);\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 any shape boundary.\n const value =\n valueShape(operator) === valueShape(current.operator)\n ? current.value\n : emptyValueForOperator(operator);\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 const operator = getColumnDefaultOperator(nextColumn);\n table.setColumnFilters([\n ...columnFilters,\n {\n id: nextColumn.id,\n value: {\n operator,\n value: emptyValueForOperator(operator),\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 data-dg-part=\"filter-panel\"\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 span 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 data-dg-part=\"filter-panel-close\"\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 scalarValue = typeof value.value === \"string\" ? value.value : \"\";\n // Pre-resolved only where options mean something out of the box -\n // a declared set, or a select-shaped column's faceted values. A\n // custom control wanting faceted values elsewhere resolves them\n // itself; resolving here would build the faceted index for every\n // filtered column.\n const options =\n column &&\n (column.columnDef.meta?.options !== undefined ||\n type === \"select\" ||\n type === \"multiSelect\")\n ? resolveColumnOptions({ table, column, fallback: \"faceted\" })\n : [];\n const ValueControl =\n (column === undefined ? undefined : getColumnFilterControl(column)) ??\n TMDataGridFilterValueInput;\n\n return (\n <div\n key={filter.id}\n // The row is the handle: a `meta.filter.control` renders whatever\n // it likes in the value slot, so the one thing a test can always\n // count on is which row it is in.\n data-dg-part=\"filter-row\"\n data-column-id={filter.id}\n className={classes.filterRow}\n >\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n size=\"lg\"\n aria-label={labels.removeFilter}\n data-dg-part=\"filter-remove\"\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-dg-part=\"filter-column\"\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-dg-part=\"filter-operator\"\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 {column ? (\n // The value slot: `meta.filter.control` if the column declares\n // one, the built-in shape-by-operator input otherwise - both\n // through the same value-only contract.\n <ValueControl\n column={column}\n table={table}\n operator={value.operator}\n value={value.value}\n onChange={(next) => patchFilter(filter.id, { value: next })}\n options={options}\n size={controlSize}\n labels={labels}\n />\n ) : (\n // The column is gone from the definition; the row survives\n // only to be re-pointed or removed.\n <TextInput\n label={labels.filterValue}\n size={controlSize}\n w={180}\n data-dg-part=\"filter-value\"\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 data-dg-part=\"filter-add\"\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 data-dg-part=\"filter-clear-all\"\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 compareItems,\n rankItem,\n type RankingInfo,\n} from \"@tanstack/match-sorter-utils\";\nimport {\n createSortedRowModel,\n type Row,\n type RowData,\n type RowModel,\n type Table,\n type TableFeatures,\n} from \"@tanstack/react-table\";\n\n/** How the quick search matches - see `quickSearchMode` on the hook options. */\nexport type TMDataGridQuickSearchMode = \"fuzzy\" | \"contains\";\n\n/**\n * The fuzzy filter's registry name - what `globalFilterFn` resolves to while\n * `quickSearchMode` is `\"fuzzy\"`. The rank ordering keys off this name, so an\n * explicit `globalFilterFn` override switches the ordering off with it.\n */\nexport const FUZZY_FILTER_FN_NAME = \"tmDataGridFuzzy\";\n\n/** What {@link fuzzyGlobalFilterFn} records per column via `addMeta`. */\ntype FuzzyFilterMeta = { fuzzyRank: RankingInfo };\n\nfunction isFuzzyFilterMeta(value: unknown): value is FuzzyFilterMeta {\n if (typeof value !== \"object\" || value === null) return false;\n const rank = (value as { fuzzyRank?: unknown }).fuzzyRank;\n return (\n typeof rank === \"object\" &&\n rank !== null &&\n typeof (rank as { rank?: unknown }).rank === \"number\"\n );\n}\n\n/**\n * Match-sorter ranking as the global filter: a row passes when a globally\n * filterable column ranks above match-sorter's threshold - typos and skipped\n * characters forgiven - and the rank is recorded for the ordering to read.\n *\n * TanStack stops probing a row's columns at the first passing one, so the\n * recorded ranks cover the columns up to and including it; the best of those\n * stands for the row. Good enough for a quick search: the first passing\n * column is almost always the one the user is looking at.\n */\nexport function fuzzyGlobalFilterFn<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(\n row: Row<TFeatures, TData>,\n columnId: string,\n filterValue: unknown,\n addMeta?: (meta: FuzzyFilterMeta) => void,\n): boolean {\n const rank = rankItem(\n String(row.getValue(columnId) ?? \"\"),\n String(filterValue),\n );\n addMeta?.({ fuzzyRank: rank });\n return rank.passed;\n}\n\n/** The best fuzzy rank any column recorded for this row, or `null`. */\nfunction bestRank<TFeatures extends TableFeatures, TData extends RowData>(\n row: Row<TFeatures, TData>,\n): RankingInfo | null {\n let best: RankingInfo | null = null;\n // As a plain record, for the same generic-features reason as the options\n // read in isRankingActive.\n const { columnFiltersMeta } = row as {\n columnFiltersMeta?: Record<string, unknown>;\n };\n for (const meta of Object.values(columnFiltersMeta ?? {})) {\n if (!isFuzzyFilterMeta(meta)) continue;\n if (best === null || meta.fuzzyRank.rank > best.rank) best = meta.fuzzyRank;\n }\n return best;\n}\n\n/**\n * Whether the ranked ordering applies: the fuzzy quick search is narrowing\n * the grid, and nothing else claims an order - no sort, no grouping.\n */\nfunction isRankingActive<TFeatures extends TableFeatures, TData extends RowData>(\n table: Table<TFeatures, TData>,\n): boolean {\n // Off the options as a plain record: a generic `TFeatures` does not carry\n // the global-filtering feature's option types, and this file stays generic\n // to avoid a cycle with useTMDataGrid.\n const { globalFilterFn } = table.options as { globalFilterFn?: unknown };\n if (globalFilterFn !== FUZZY_FILTER_FN_NAME) return false;\n const state = table.store.state as {\n sorting?: Array<unknown>;\n grouping?: Array<unknown>;\n globalFilter?: unknown;\n };\n return (\n (state.sorting?.length ?? 0) === 0 &&\n (state.grouping?.length ?? 0) === 0 &&\n typeof state.globalFilter === \"string\" &&\n state.globalFilter.trim() !== \"\"\n );\n}\n\n/**\n * The sorted row model, with one addition: while {@link isRankingActive},\n * rows order by match quality, best first. Declarative - the ordering is\n * derived from filter state, never written into `sorting`, so no column\n * claims `aria-sort`, the persisted slice stays untouched, and the user's\n * next sort click suspends it just by existing.\n *\n * Sits upstream of pagination, so a ranked first page really is the best\n * matches of the whole set.\n */\nexport function createFuzzyRankedSortedRowModel<\n TFeatures extends TableFeatures,\n TData extends RowData,\n>(): (table: Table<TFeatures, TData>) => () => RowModel<TFeatures, TData> {\n const base = createSortedRowModel<TFeatures, TData>();\n return (table) => {\n const getSorted = base(table);\n // One-slot memo: every input of the ordering - filter text, data, the\n // sorting and grouping states - changes the sorted model's identity, so\n // the model alone is the cache key.\n let lastModel: RowModel<TFeatures, TData> | null = null;\n let ranked: RowModel<TFeatures, TData> | null = null;\n return () => {\n const model = getSorted();\n if (!isRankingActive(table)) return model;\n if (model === lastModel && ranked !== null) return ranked;\n const rows = [...model.rows].sort((a, b) => {\n const rankA = bestRank(a);\n const rankB = bestRank(b);\n if (rankA !== null && rankB !== null) return compareItems(rankA, rankB);\n return rankA !== null ? -1 : rankB !== null ? 1 : 0;\n });\n ranked = { rows, flatRows: model.flatRows, rowsById: model.rowsById };\n lastModel = model;\n return ranked;\n };\n };\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 /** Tooltip on the reset button, stating everything the reset covers. */\n columnsResetHint: string;\n /** Menu/panel name of the generated row-number gutter. */\n rowNumberColumnLabel: string;\n /**\n * The truly-empty message - no data and no filters. Filtered-empty says\n * {@link noResults} instead; only one of the two is the user's own doing.\n */\n noRows: string;\n\n // Filter panel\n filterColumn: string;\n filterOperator: string;\n filterValue: string;\n filterValuePlaceholder: string;\n /** The lower bound of a `between` filter. */\n filterFrom: string;\n /** The upper bound of a `between` filter. */\n filterTo: string;\n /** `DgTriStateFilter`'s no-filter segment. */\n filterAll: 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 editing\n /** `aria-label` of an open cell editor's input. */\n editCell: (column: string) => string;\n /** cellConfirm's ✓ beside the input. */\n confirmEdit: string;\n /** cellConfirm's ✕ beside the input. */\n cancelEdit: string;\n /** The generated edit lane's name in the column manager. */\n editColumnLabel: string;\n /** The lane's pencil. */\n editRow: string;\n /** The lane's ✓ while a row edit is open. */\n saveRow: string;\n /** The lane's ✕ while a row edit is open. */\n cancelRowEdit: string;\n /** Save tooltip when field errors block the row, with no row message. */\n editRowErrors: string;\n /** `DraftActions`' Save, with the count of rows in the draft store. */\n saveAllEdits: (rows: number) => string;\n /** `DraftActions`' Discard. */\n discardAllEdits: string;\n /**\n * `DraftActions`' note about rows still open - edited but not committed, so\n * not part of the save. Shown only while there are any.\n */\n editRowsStillOpen: (rows: number) => string;\n /** The entry row's ✓ - commit the add. */\n confirmNewRow: string;\n /** The entry row's ✕ - drop the entry. */\n discardNewRow: string;\n /** The lane's trash can. */\n deleteRow: string;\n /** The lane's undo on a row marked deleted (draft). */\n restoreRow: string;\n /** The lane's undo on a row with a dirty draft (draft) - drops it. */\n revertRow: string;\n /** The lane's state icon on a confirmed entry row (draft). */\n rowStateNew: string;\n /** The lane's state icon on a row with a dirty draft (draft). */\n rowStateEdited: string;\n /** The lane's state icon on a row marked deleted (draft). */\n rowStateDeleted: 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 LAYOUT\",\n columnsResetHint:\n \"Resets column visibility, order, widths, pinning and grouping\",\n rowNumberColumnLabel: \"Row number\",\n noRows: \"No rows to show\",\n\n filterColumn: \"Column\",\n filterOperator: \"Operator\",\n filterValue: \"Value\",\n filterValuePlaceholder: \"Filter value\",\n filterFrom: \"From\",\n filterTo: \"To\",\n filterAll: \"All\",\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 editCell: (column) => `Edit ${column}`,\n confirmEdit: \"Save\",\n cancelEdit: \"Cancel\",\n editColumnLabel: \"Edit\",\n editRow: \"Edit row\",\n saveRow: \"Save row\",\n cancelRowEdit: \"Cancel edit\",\n editRowErrors: \"Fix the marked cells\",\n saveAllEdits: (rows) => (rows === 1 ? \"Save 1 row\" : `Save ${rows} rows`),\n discardAllEdits: \"Discard\",\n editRowsStillOpen: (rows) =>\n rows === 1 ? \"1 row still being edited\" : `${rows} rows still being edited`,\n confirmNewRow: \"Add row\",\n discardNewRow: \"Discard new row\",\n deleteRow: \"Delete row\",\n restoreRow: \"Restore row\",\n revertRow: \"Revert changes\",\n rowStateNew: \"New row\",\n rowStateEdited: \"Edited row\",\n rowStateDeleted: \"Marked for deletion\",\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 holds a piece of state and returns `[value, setValue]`. Here the\n * table already holds 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 conflict with 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\n/**\n * Version stamped into every stored payload, under a key no state slice can\n * collide with. A payload whose version does not match is dropped whole: a\n * migration would be guessing at a shape this code no longer knows, and the\n * cost of dropping is one lost layout. Payloads written before versioning\n * existed (≤0.4.0) have no stamp and are dropped the same way - the 1.0\n * wave's one-time break, named in its changeset.\n */\nexport const PERSIST_PAYLOAD_VERSION = 1;\nconst VERSION_FIELD = \"__v\";\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 if (record[VERSION_FIELD] !== PERSIST_PAYLOAD_VERSION) return {};\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> = { [VERSION_FIELD]: PERSIST_PAYLOAD_VERSION };\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/**\n * The leaf column ids a set of column defs will produce, by TanStack's own\n * derivation: `id`, else `accessorKey` with dots replaced by underscores,\n * else a string `header`. Mirrored here so restored state can be realigned\n * against the columns that will actually exist - deriving ids any other way\n * would realign against names the table never uses.\n */\nexport function collectLeafColumnIds(\n defs: ReadonlyArray<unknown>,\n into: string[] = [],\n): string[] {\n for (const def of defs) {\n if (typeof def !== \"object\" || def === null) continue;\n const record = def as Record<string, unknown>;\n if (Array.isArray(record.columns) && record.columns.length > 0) {\n collectLeafColumnIds(record.columns, into);\n continue;\n }\n const accessorKey =\n typeof record.accessorKey === \"string\" ? record.accessorKey : undefined;\n const id =\n (typeof record.id === \"string\" ? record.id : undefined) ??\n accessorKey?.replaceAll(\".\", \"_\") ??\n (typeof record.header === \"string\" ? record.header : undefined);\n if (id !== undefined) into.push(id);\n }\n return into;\n}\n\n/**\n * Drops restored entries that name columns the grid no longer has.\n *\n * A stored layout outlives the column set: a column removed between deploys\n * would otherwise linger forever - a ghost id in the order, a width for\n * nothing, and worse, a *filter or sort that is active but has no column to\n * show for itself*. New columns need no counterpart here: TanStack appends\n * columns missing from `columnOrder` on its own, in definition order.\n */\nfunction realignToColumns(\n restored: Partial<GridState>,\n known: ReadonlySet<string>,\n): Partial<GridState> {\n const has = (id: unknown): boolean =>\n typeof id === \"string\" && known.has(id);\n const keepIds = (values: ReadonlyArray<string>) => values.filter(has);\n const keepKeys = <T,>(record: Record<string, T>) =>\n Object.fromEntries(Object.entries(record).filter(([id]) => has(id)));\n const keepEntries = <T extends { id: string }>(entries: ReadonlyArray<T>) =>\n entries.filter((entry) => has(entry.id));\n\n const realigned: Partial<GridState> = { ...restored };\n if (restored.columnOrder) realigned.columnOrder = keepIds(restored.columnOrder);\n if (restored.grouping) realigned.grouping = keepIds(restored.grouping);\n if (restored.columnVisibility) {\n realigned.columnVisibility = keepKeys(restored.columnVisibility);\n }\n if (restored.columnSizing) {\n realigned.columnSizing = keepKeys(restored.columnSizing);\n }\n if (restored.columnPinning) {\n realigned.columnPinning = {\n left: keepIds(restored.columnPinning.left ?? []),\n right: keepIds(restored.columnPinning.right ?? []),\n };\n }\n if (restored.sorting) realigned.sorting = keepEntries(restored.sorting);\n if (restored.columnFilters) {\n realigned.columnFilters = keepEntries(restored.columnFilters);\n }\n return realigned;\n}\n\n/**\n * State to merge into `initialState`, read once on mount.\n *\n * With `knownColumnIds` - every id the grid is about to construct, generated\n * lanes included - the column-shaped slices are realigned first; see\n * {@link realignToColumns}. Without it the payload is returned as stored.\n */\nexport function readPersistedState(\n persistence?: TMDataGridPersistence,\n knownColumnIds?: ReadonlyArray<string>,\n): Partial<GridState> {\n const storage = resolveStorage(persistence);\n const { data, settings } = resolveKeys(persistence);\n const deserialize = persistence?.deserialize ?? defaultDeserialize;\n const restored = {\n ...readSlices(storage, settings, deserialize),\n ...readSlices(storage, data, deserialize),\n };\n return knownColumnIds === undefined\n ? restored\n : realignToColumns(restored, new Set(knownColumnIds));\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 { TMDataGridEditMode } from \"./editEngine\";\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 /** Whether cells can be edited at all - the `editing` option was set. */\n editing: boolean;\n /** What counts as a commit, or `null` while editing is off. */\n editMode: TMDataGridEditMode | null;\n /**\n * Where a commit goes - `editing.draft`. On, commits park in the grid's\n * draft store and leave through `edit.saveDrafts()`; off, each one reaches\n * the consumer as it happens.\n */\n editDraft: boolean;\n /**\n * Whether a parked entry row stays pinned in the sticky entry block until\n * the draft store is saved - `editing.newRowsSticky`, which needs\n * `editing.draft`. Off by default: a parked row joins the scrolling flow\n * instead, so entering many rows cannot fill the viewport with sticky\n * chrome.\n */\n editNewRowsSticky: boolean;\n /** The generated row-number gutter - `enableRowNumbers`. Off by default. */\n rowNumbers: boolean;\n /**\n * Whether rows can be pinned to the top or bottom edge - `enableRowPinning`,\n * boolean or per-row predicate. Off by default: pinning has no built-in\n * gesture, so a grid that never calls `row.pin()` has nothing to gain from\n * the body watching the state.\n */\n rowPinning: boolean;\n /**\n * Whether cells highlight the matched text while a contains-family filter\n * or the quick search is active - `enableMatchHighlighting`. Off by\n * default, so a grid that has not asked pays nothing per cell.\n */\n matchHighlighting: 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 | \"editing\"\n | \"enableRowNumbers\"\n | \"enableRowPinning\"\n | \"enableMatchHighlighting\"\n >,\n): TMDataGridFeatureFlags {\n const selectionMode = options.selectionMode ?? \"checkbox\";\n // Editing brings the cell cursor with it: Enter, F2 and type-to-edit all\n // address \"the focused cell\", which only exists under cell selection. An\n // explicit `cellSelection` still wins, `\"range\"` included.\n const cellSelectionMode =\n options.cellSelection ?? (options.editing !== undefined ? \"single\" : \"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 editing: options.editing !== undefined,\n editMode: options.editing?.mode ?? null,\n editDraft: options.editing?.draft === true,\n editNewRowsSticky:\n options.editing?.draft === true &&\n options.editing.newRowsSticky === true,\n rowNumbers: options.enableRowNumbers === true,\n // A predicate counts as on - some rows may still pin.\n rowPinning:\n options.enableRowPinning === true ||\n typeof options.enableRowPinning === \"function\",\n matchHighlighting: options.enableMatchHighlighting === 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 the grid handles \"does not resolve\" explicitly.\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\nexport type NextEditableCellArgs = {\n from: TMDataGridCellCoords;\n /** `1` is Tab, `-1` is Shift+Tab. */\n direction: 1 | -1;\n rowCount: number;\n columnCount: number;\n /** Whether the cell at these coordinates takes edits. */\n isEditable: (coords: TMDataGridCellCoords) => boolean;\n};\n\n/**\n * The next editable cell in reading order, wrapping to the next row - and\n * from the last cell of the grid back to the first. `null` when no other\n * cell is editable.\n *\n * Deliberately wrapping where {@link resolveCellMove} deliberately clamps:\n * arrows are a coordinate space and clamp so the destination is predictable,\n * but Tab mid-edit is the spreadsheet's \"next field\" - at the end of a row\n * the next field is on the next row, which is a convention, not a surprise.\n */\nexport function getNextEditableCell({\n from,\n direction,\n rowCount,\n columnCount,\n isEditable,\n}: NextEditableCellArgs): TMDataGridCellCoords | null {\n const total = rowCount * columnCount;\n if (total === 0) return null;\n const start = from.rowIndex * columnCount + from.columnIndex;\n for (let step = 1; step < total; step += 1) {\n const index = (start + direction * step + total * step) % total;\n const coords = {\n rowIndex: Math.floor(index / columnCount),\n columnIndex: index % columnCount,\n };\n if (isEditable(coords)) return coords;\n }\n return null;\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 type { TableState } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\ntype GridState = TableState<TMDataGridFeatures>;\n\n/**\n * Support for TanStack's `state` option (controlled state).\n *\n * table-core re-reads `options.state` on every render (`useTable` calls\n * `setOptions` while rendering) and writes any slice whose value is not\n * identical to the table's current value into the table's atom. The write\n * publishes the store and re-renders the consumer, so a slice object built in\n * the render body causes an infinite render loop.\n *\n * {@link stabilizeControlledState} prevents the loop by forwarding the\n * previous render's value for a slice whose contents are unchanged.\n * {@link findFrozenStateSlices} detects a controlled slice without its\n * `onXChange` callback, which the grid cannot write to.\n */\n\n/**\n * The `onXChange` option that owns each controlled slice - every slice v9\n * defines. `globalFilterFn` is not among them: in this beta it is a table\n * option, not state.\n */\nexport const CONTROLLED_SLICE_HANDLERS = {\n columnFilters: \"onColumnFiltersChange\",\n columnOrder: \"onColumnOrderChange\",\n columnPinning: \"onColumnPinningChange\",\n columnResizing: \"onColumnResizingChange\",\n columnSizing: \"onColumnSizingChange\",\n columnVisibility: \"onColumnVisibilityChange\",\n expanded: \"onExpandedChange\",\n globalFilter: \"onGlobalFilterChange\",\n grouping: \"onGroupingChange\",\n pagination: \"onPaginationChange\",\n rowPinning: \"onRowPinningChange\",\n rowSelection: \"onRowSelectionChange\",\n sorting: \"onSortingChange\",\n} as const satisfies Partial<Record<keyof GridState, string>>;\n\nexport type TMDataGridControlledSlice = keyof typeof CONTROLLED_SLICE_HANDLERS;\n\n/** The options {@link findFrozenStateSlices} reads - a subset of `TableOptions`. */\ntype ControlledOptions = {\n state?: Partial<GridState>;\n /**\n * The v9 way of owning a slice: an atom the table writes through directly.\n * It outranks `state`, so a slice backed by one is never frozen.\n */\n atoms?: Record<string, unknown>;\n} & Partial<\n Record<(typeof CONTROLLED_SLICE_HANDLERS)[TMDataGridControlledSlice], unknown>\n>;\n\nconst hasOwn = (value: object, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\n/**\n * A plain data object: `Object.prototype` or null prototype. table-core builds\n * its state maps with `Object.create(null)`, so null prototypes must compare\n * as plain objects.\n */\nfunction isDataObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Structural equality for state values.\n *\n * `Date`s compare by time; the built-in date filters hold them in filter\n * values. `Map`s and class instances compare by identity, so a controlled\n * slice containing one rebuilt each render reads as changed on every render\n * and re-renders the table. Use primitives, plain objects, arrays or `Date`s\n * in controlled state.\n */\nexport function sameStateValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (a instanceof Date || b instanceof Date) {\n return (\n a instanceof Date && b instanceof Date && a.getTime() === b.getTime()\n );\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b)) return false;\n return (\n a.length === b.length &&\n a.every((item, index) => sameStateValue(item, b[index]))\n );\n }\n if (!isDataObject(a) || !isDataObject(b)) return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n return keys.every((key) => hasOwn(b, key) && sameStateValue(a[key], b[key]));\n}\n\n/**\n * Removes keys whose value is `undefined`, as in\n * `state: { sorting: cond ? sorting : undefined }`.\n *\n * TanStack's sync writes every present key into the slice's atom, `undefined`\n * included, which breaks everything that reads the slice. A key set to\n * `undefined` is treated as not controlled: the key is removed and the slice\n * falls back to the table's own state. Identity is preserved when there is\n * nothing to remove; the stabilizer compares by it.\n */\nexport function withoutUndefinedSlices(\n state: Partial<GridState> | undefined,\n): Partial<GridState> | undefined {\n if (state === undefined) return state;\n if (!Object.values(state).includes(undefined)) return state;\n const compacted: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(state)) {\n if (value !== undefined) compacted[key] = value;\n }\n return compacted as Partial<GridState>;\n}\n\n/**\n * Returns `next` with every slice that structurally equals its counterpart in\n * `previous` replaced by the previous object, so table-core's identity-based\n * sync finds nothing to write. Returns `previous` when nothing changed.\n */\nexport function stabilizeControlledState(\n next: Partial<GridState> | undefined,\n previous: Partial<GridState> | undefined,\n): Partial<GridState> | undefined {\n if (next === undefined || previous === undefined || next === previous) {\n return next;\n }\n\n const keys = Object.keys(next);\n const stabilized: Record<string, unknown> = {};\n let changed = keys.length !== Object.keys(previous).length;\n\n for (const key of keys) {\n const nextValue = (next as Record<string, unknown>)[key];\n const previousValue = (previous as Record<string, unknown>)[key];\n if (hasOwn(previous, key) && sameStateValue(nextValue, previousValue)) {\n // Unchanged contents: keep the object the table already holds.\n stabilized[key] = previousValue;\n } else {\n stabilized[key] = nextValue;\n changed = true;\n }\n }\n\n return changed ? (stabilized as Partial<GridState>) : previous;\n}\n\n/**\n * Controlled slices without a write path: `state.x` is set but no `onXChange`\n * was passed and no external atom owns the slice. TanStack routes every write\n * through the callback, so such a slice cannot change. Reported so the hook\n * can warn in development; `initialState` is the option for a starting value.\n */\nexport function findFrozenStateSlices(\n options: ControlledOptions,\n): Array<{ slice: TMDataGridControlledSlice; handler: string }> {\n const state = options.state;\n if (state === undefined) return [];\n\n return (\n Object.entries(CONTROLLED_SLICE_HANDLERS) as Array<\n [TMDataGridControlledSlice, string]\n >\n )\n .filter(\n ([slice, handler]) =>\n // Undefined-valued keys are removed before the table sees them; the\n // slice is not controlled.\n (state as Record<string, unknown>)[slice] !== undefined &&\n (options as Record<string, unknown>)[handler] === undefined &&\n options.atoms?.[slice] === undefined,\n )\n .map(([slice, handler]) => ({ slice, handler }));\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 filterFns,\n globalFilteringFeature,\n metaHelper,\n type Row,\n type RowData,\n rowExpandingFeature,\n rowPaginationFeature,\n rowPinningFeature,\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 {\n type MutableRefObject,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { TMDataGridRowData } from \"./TMDataGridContext\";\nimport type { TMDataGridOptionsSource } from \"./core/columnOptions\";\nimport {\n createEditEngine,\n type TMDataGridEditApi,\n type TMDataGridEditCommitArgs,\n type TMDataGridSaveDraftsArgs,\n type TMDataGridSaveDraftsResult,\n type TMDataGridEditEngineContext,\n type TMDataGridColumnEditOptions,\n type TMDataGridEditMode,\n type TMDataGridRowAddArgs,\n type TMDataGridRowDeleteArgs,\n type TMDataGridRowValidators,\n type TMDataGridTableValidators,\n} from \"./core/editEngine\";\nimport {\n emptyValueForOperator,\n type TMDataGridColumnType,\n tmDataGridFilterFn,\n} from \"./core/filterOperators\";\nimport { getColumnDefaultOperator, isControlColumn } from \"./core/columnUtils\";\nimport type { TMDataGridColumnFilterOptions } from \"./core/filterControls\";\nimport {\n createFuzzyRankedSortedRowModel,\n fuzzyGlobalFilterFn,\n type TMDataGridQuickSearchMode,\n} from \"./core/quickSearch\";\nimport {\n mergeLabels,\n type TMDataGridLabels,\n type TMDataGridLabelsOverride,\n} from \"./core/labels\";\nimport {\n collectLeafColumnIds,\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 {\n findFrozenStateSlices,\n stabilizeControlledState,\n withoutUndefinedSlices,\n} from \"./core/controlledState\";\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\";\nimport {\n createEditColumn,\n EDIT_COLUMN_ID,\n} from \"./components/TMDataGridEditColumn\";\nimport {\n createRowNumberColumn,\n ROW_NUMBER_COLUMN_ID,\n} from \"./components/TMDataGridRowNumberColumn\";\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/**\n * Per-column configuration the grid's own components read.\n *\n * The filter and edit stages each get a namespace, `filter` and `edit`,\n * mirroring the feature's runtime API. What the column *is* stays flat:\n * `label`, `type`, `options`, `align`, `flex`, `autoSize`, `enableOrdering`.\n * `type` and `options` are read by both stages, so one declaration of each\n * feeds the filter panel and the cell editor, which is why they sit outside\n * both namespaces.\n */\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 * How this column filters: the operator a fresh filter starts with, and the\n * value control the filter panel renders for it.\n *\n * ```tsx\n * meta: {\n * type: \"number\",\n * filter: { defaultOperator: \"between\", control: DgRangeSliderFilter },\n * }\n * ```\n *\n * See {@link TMDataGridColumnFilterOptions}.\n */\n filter?: TMDataGridColumnFilterOptions;\n /**\n * How this column is edited: whether it takes edits, which field they write\n * to, which editor opens, what validates the field and what maps the value\n * on its way in.\n *\n * ```tsx\n * meta: {\n * type: \"string\",\n * edit: { validate: z.string().min(2, \"Too short\") },\n * }\n * ```\n *\n * See {@link TMDataGridColumnEditOptions}.\n */\n edit?: TMDataGridColumnEditOptions;\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 rowPinningFeature,\n\n filteredRowModel: createFilteredRowModel(),\n groupedRowModel: createGroupedRowModel(),\n // The sorted model plus the fuzzy quick search's rank ordering - see\n // core/quickSearch.ts for when the ordering applies.\n sortedRowModel: createFuzzyRankedSortedRowModel(),\n expandedRowModel: createExpandedRowModel(),\n paginatedRowModel: createPaginatedRowModel(),\n facetedRowModel: createFacetedRowModel(),\n facetedMinMaxValues: createFacetedMinMaxValues(),\n facetedUniqueValues: createFacetedUniqueValues(),\n\n filterFns: {\n ...filterFns,\n tmDataGrid: tmDataGridFilterFn,\n tmDataGridFuzzy: fuzzyGlobalFilterFn,\n },\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/** Where a scrolled-to row lands in the viewport. TanStack's own alignments. */\nexport type TMDataGridScrollAlign = \"auto\" | \"start\" | \"center\" | \"end\";\n\nexport type TMDataGridScrollToRowArgs = {\n /** The row's id, as `getRowId` produced it. */\n rowId: string;\n /** Defaults to `\"auto\"` - the nearest edge, leaving a visible row alone. */\n align?: TMDataGridScrollAlign;\n};\n\n/** @internal The body's scroll implementation. See `scrollToRow`. */\nexport type TMDataGridScroller = (args: TMDataGridScrollToRowArgs) => boolean;\n\n/** What `useTMDataGrid` returns - spread straight onto `<TMDataGrid />`. */\nexport type TMDataGridApi<TData extends RowData> = {\n table: TMDataGridTable<TData>;\n ui: TMDataGridUiStore;\n /**\n * The edit engine - open forms, dirty/error projections, and the verbs\n * (`begin`, `commit`, `cancel`, `submitAll`). `edit.getForm(rowId)` hands\n * out the same TanStack Form the inline editors write through, so a drawer\n * or detail panel can share a row's draft. Inert until `editing` is set.\n */\n edit: TMDataGridEditApi<TData>;\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 * Puts the settings state - visibility, order, widths, pinning, grouping -\n * back to what a first visit with clean storage would have shown: the\n * consumer's `initialState` plus the structural lanes. With persistence\n * configured the reset writes through to storage like any other change.\n *\n * This, not TanStack's `resetColumnX()` family, is the reset for a\n * persisted grid: those reset to `initialState`, and the grid bakes the\n * restored payload into `initialState` at mount - they would \"reset\" to\n * the very layout being discarded.\n */\n resetSettings: () => void;\n /**\n * Scrolls a row into view. The grid is always virtualized, so a row far down\n * the list has no element to scroll to - this moves the virtualizer instead,\n * which is the only thing that can put one there.\n *\n * ```ts\n * grid.scrollToRow({ rowId: \"42\", align: \"center\" });\n * ```\n *\n * Answers whether the row could be reached. `false` means it is not in the\n * current view at all - filtered out, on another page, or an id that matches\n * no row - and nothing scrolled. A pinned row answers `true` without\n * scrolling: it is already parked at an edge.\n *\n * Identity is stable, so it is safe in a dependency array.\n */\n scrollToRow: (args: TMDataGridScrollToRowArgs) => boolean;\n /**\n * @internal Wiring for `TMDataGrid.Table`, which holds the virtualizer and\n * fills this in. Not part of the public API.\n */\n scrollerRef: MutableRefObject<TMDataGridScroller>;\n};\n\n/** The editing members every mode shares. See {@link TMDataGridEditingOptions}. */\ntype TMDataGridEditingCallbacks<TData extends RowData> = {\n /**\n * Form-level validators for the whole editing row - where cross-field\n * rules live. TanStack Form's own vocabulary, Standard Schema included:\n *\n * ```tsx\n * rowValidators: {\n * onSubmit: z.object({ salary: z.number().positive() })\n * .refine((r) => r.status !== \"Terminated\" || r.salary === 0, {\n * message: \"A terminated employee has no salary\",\n * }),\n * }\n * ```\n *\n * Pathed issues land on the matching columns; pathless ones on the row.\n */\n rowValidators?: TMDataGridRowValidators;\n /**\n * Rules that need the other rows - no duplicate keys, no overlapping\n * ranges, allocations summing to a total. Handed the committing row and\n * `rows`, the collection as it would stand if the commit landed: every\n * draft overlaid, entry rows appended, deletion-marked rows removed.\n *\n * ```tsx\n * tableValidators: {\n * onSubmit: ({ value, rowId, rows }) =>\n * rows.some((r) => r.rowId !== rowId && r.value.code === value.code)\n * ? { fields: { code: \"Duplicate code\" } }\n * : undefined,\n * }\n * ```\n *\n * Runs at every commit, after the row's own validators, and again per\n * parked row during `saveDrafts` - a draft another edit has invalidated\n * blocks the save. Pathed issues land on the committing row's cells,\n * pathless ones on the row.\n */\n tableValidators?: TMDataGridTableValidators<TData>;\n /** Rows the pencil skips - `false` keeps a row read-only in every mode. */\n isRowEditable?: (row: Row<TMDataGridFeatures, TData>) => boolean;\n /**\n * Called when an edit commits. The grid never mutates `data`: apply the\n * change and let the new data arrive back through `data` as always. The\n * engine drops the draft only when this resolves - a slow save keeps the\n * draft visible with a busy marker - and a rejection keeps the form open\n * with the error on the row.\n *\n * `changes` is the per-field diff (one entry in cell mode), for a PATCH.\n * `value` is the entire edited row, for saving a record.\n */\n onCommit?: (args: TMDataGridEditCommitArgs<TData>) => void | Promise<void>;\n /**\n * Seed values for `edit.addRow()` - the entry row's starting point. A\n * function is called per added row (fresh timestamps, empty arrays).\n * `edit.addRow(values)` overrides this key by key for that one row.\n */\n newRowDefaults?: TData | (() => TData);\n /**\n * Called when an entry row commits: `Enter` or the lane's ✓, or\n * `saveDrafts` under `editing.draft`. Create the record and let it arrive\n * back through `data`; the engine's `tempId` never leaves the grid.\n */\n onRowAdd?: (args: TMDataGridRowAddArgs<TData>) => void | Promise<void>;\n /**\n * Called by `edit.deleteRow` - confirmation, if any, belongs in here. Under\n * `editing.draft` deletions accumulate in `edit.state.deletedRowIds`\n * instead and are reported by `saveDrafts`. Setting this also puts the\n * trash can in the edit lane.\n */\n onRowDelete?: (args: TMDataGridRowDeleteArgs<TData>) => void | Promise<void>;\n};\n\n/**\n * The `editing` option: one object that turns editing on and holds\n * everything about it. Two axes, and they are independent: `mode` picks what\n * counts as a commit, `draft` picks where that commit goes.\n *\n * | Mode | Commit | Cancel | Controls |\n * | ---- | ------ | ------ | -------- |\n * | `\"cell\"` | Enter, Tab, blur - Sheets | Escape | none |\n * | `\"cellConfirm\"` | ✓ or Enter; Tab and blur keep the draft | ✕ or Escape | ✓ / ✕ beside the input |\n * | `\"row\"` | Save in the edit lane, or Enter | Cancel, or Escape | generated edit lane |\n *\n * | `draft` | Where a commit goes |\n * | ------- | ------------------- |\n * | `false` (default) | Out as it happens - `onCommit`, `onRowAdd`, `onRowDelete` |\n * | `true` | Into the grid's draft store; `edit.saveDrafts()` sends the lot |\n *\n * So `{ mode: \"row\", draft: true }` is \"edit a row, the lane's ✓ parks it,\n * the toolbar's Save sends every parked row at once\", and\n * `{ mode: \"cell\", draft: true }` is the same store filled cell by cell.\n *\n * Setting `editing` makes `getRowId` required - drafts are keyed by row id,\n * and the index fallback would name a different record after any sort - and\n * `onSaveDrafts` exists only under `draft: true`, the one configuration with\n * a draft store to save.\n *\n * The object may be written inline: the callbacks are read through a ref\n * every render, so its identity does not matter.\n *\n * One TanStack Form per editing row; drafts survive scrolling because the\n * forms live outside the DOM, keyed by row id. Which columns edit, and with\n * what, is declared per column under `meta.edit`: `meta.type` picks the\n * built-in editor, and `enabled`, `field`, `editor`, `validate` and `mapValue`\n * override the rest.\n */\nexport type TMDataGridEditingOptions<TData extends RowData> =\n TMDataGridEditingCallbacks<TData> & {\n /** What counts as a commit. See the table above. */\n mode: TMDataGridEditMode;\n /**\n * The column ids that take edits, by id. Unset - the default - every\n * column mapping to a data path is editable, which is what a grid whose\n * columns are mostly the record itself wants.\n *\n * Set it for the other shape: a grid of reference data with one or two\n * columns the user maintains, where naming those is shorter and harder to\n * get wrong than switching every other column off one by one.\n *\n * This gates before `meta.edit`, never past it: a column left out takes no\n * edits whatever its own meta says, and a column listed here still answers\n * to its `meta.edit.enabled`.\n */\n columns?: ReadonlyArray<string>;\n } & (\n | {\n /**\n * Commits park in the grid's draft store instead of reaching the\n * consumer, and leave together through `edit.saveDrafts()`. The\n * edit lane gains the change markers and the per-row revert, the\n * trash marks a row for deletion rather than deleting it, and\n * `TMDataGrid.DraftActions` gets something to save.\n */\n draft: true;\n /**\n * The bulk save: called once by `edit.saveDrafts()` with the\n * whole draft store - committed edits, added rows and deletion\n * marks - so a server can apply it as one transaction. Without it,\n * `saveDrafts` falls back to the per-row\n * {@link TMDataGridEditingCallbacks.onCommit} loop.\n *\n * Rows still open are not in the payload and stay open. Returning\n * nothing saves the whole store and throwing saves none of it;\n * return a {@link TMDataGridSaveDraftsResult} to save part of it.\n */\n onSaveDrafts?: (\n args: TMDataGridSaveDraftsArgs<TData>,\n ) =>\n | void\n | TMDataGridSaveDraftsResult\n | Promise<void | TMDataGridSaveDraftsResult>;\n /**\n * @deprecated Renamed to {@link onSaveDrafts} - it fires when the\n * draft store is saved, not when a row commits into it. Still\n * honoured; removed in a later beta.\n */\n onCommitDrafts?: (\n args: TMDataGridSaveDraftsArgs<TData>,\n ) =>\n | void\n | TMDataGridSaveDraftsResult\n | Promise<void | TMDataGridSaveDraftsResult>;\n /**\n * Keep parked entry rows pinned in the sticky entry block until\n * the draft store is saved. Off by default: a parked row joins the\n * scrolling flow above the body rows instead - the block a row is\n * *typed* into is always sticky, but parked rows scroll, so\n * entering many cannot fill the viewport with sticky chrome.\n */\n newRowsSticky?: boolean;\n }\n | {\n /** Every commit reaches the consumer as it happens. The default. */\n draft?: false;\n /** Only `draft: true` has a store to save - see the other branch. */\n onSaveDrafts?: never;\n /** @deprecated See {@link onSaveDrafts}. */\n onCommitDrafts?: never;\n /** Parked entry rows exist only under `draft: true` - see there. */\n newRowsSticky?: never;\n }\n );\n\nexport type UseTMDataGridOptions<TData extends RowData> = Omit<\n TableOptions<TMDataGridFeatures, TData>,\n \"features\"\n> &\n (\n | { editing?: undefined }\n | {\n /** Turns editing on. See {@link TMDataGridEditingOptions}. */\n editing: TMDataGridEditingOptions<TData>;\n /**\n * Required once `editing` is set: the forms are keyed by row id and\n * live outside the DOM, and the index fallback points at a different\n * record after any sort.\n */\n getRowId: NonNullable<\n TableOptions<TMDataGridFeatures, TData>[\"getRowId\"]\n >;\n }\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 * The row-number gutter: a generated lane, outermost left, numbering the\n * rows of the current view - sorted, filtered, continuing across pages,\n * with group rows unnumbered. Off by default.\n */\n enableRowNumbers?: boolean;\n /**\n * How the quick search (`TMDataGrid.Search`) matches. `\"fuzzy\"` - the\n * default - forgives typos and skipped characters, and while it is the\n * only thing narrowing the grid (no sort, no grouping) the rows order by\n * match quality, best first. `\"contains\"` is plain substring matching.\n * An explicit `globalFilterFn` overrides both.\n */\n quickSearchMode?: TMDataGridQuickSearchMode;\n /**\n * Highlights the matched text in cells while a contains-family column\n * filter or the quick search is active. Default-rendered cells only - a\n * column with its own `cell` renderer opts out by existing; a fuzzy\n * typo-match with no contiguous occurrence shows no highlight. Off by\n * default.\n */\n enableMatchHighlighting?: 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\n * accurate for panels that open off screen, such as restored `expanded`\n * state. An approximate value 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 */\n/**\n * Drops the control lanes' entries from a visibility map.\n *\n * They are all `enableHiding: false`, but TanStack applies `columnVisibility`\n * regardless - the option only gates `toggleVisibility` - so a stale `false`\n * would hide a lane nothing in the grid can bring back: restored from storage\n * written before 2.1 (when the checkbox lane was still hideable), or passed in\n * `initialState`. The tree column is not scrubbed; its entry is the grid's own,\n * written after this.\n */\nfunction withoutControlColumnVisibility(\n visibility: Record<string, boolean>,\n): Record<string, boolean> {\n const scrubbed = { ...visibility };\n for (const id of Object.keys(scrubbed)) {\n if (isControlColumn(id)) delete scrubbed[id];\n }\n return scrubbed;\n}\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 enableRowNumbers,\n selectionMode,\n showSelectedBackground,\n defaultHighlightedRowId,\n onHighlightedRowChange,\n cellSelection,\n onFocusedCellChange,\n editing,\n renderDetails,\n renderDetailsEstHeight = DEFAULT_DETAILS_EST_HEIGHT,\n overscan = DEFAULT_OVERSCAN,\n ...options\n}: UseTMDataGridOptions<TData>): TMDataGridApi<TData> {\n // The one place `editing` is unpacked - the engine and the flags keep their\n // own vocabulary (`editMode`, `onEditCommit`), so the mapping lives here.\n const editMode = editing?.mode;\n const editDraft = editing?.draft === true;\n\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 enableRowNumbers,\n selectionMode,\n showSelectedBackground,\n cellSelection,\n editing,\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 // Row mode's Save sits at the end of the row - the lane is its chrome. It\n // also appears wherever the trash can has somewhere to report to, and\n // always under `draft`, where it is the change marker and the per-row\n // revert - with or without `onSaveDrafts`, since the per-row fallback is a\n // first-class configuration.\n const editColumnEnabled =\n editing !== undefined &&\n (editing.mode === \"row\" || editDraft || editing.onRowDelete !== undefined);\n\n // The generated lanes bake `meta.label` into their definitions, so the memo\n // depends on the 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 const editColumnLabel = labels.editColumnLabel;\n const rowNumberColumnLabel = labels.rowNumberColumnLabel;\n const rowNumbersEnabled = features.rowNumbers;\n // A draft lane holds three controls (state icon, undo, trash) where the\n // rest hold two - it gets the wider track.\n const editWideLane = editDraft;\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 // The gutter sits outside everything, the way a spreadsheet's does.\n ...(rowNumbersEnabled\n ? [createRowNumberColumn<TData>(rowNumberColumnLabel)]\n : []),\n ...(selectColumnEnabled\n ? [createSelectColumn<TData>(selectColumnLabel)]\n : []),\n ...(groupColumnEnabled ? [createGroupColumn<TData>(groupColumnLabel)] : []),\n ...(detailsColumnEnabled\n ? [createDetailsColumn<TData>(detailsColumnLabel)]\n : []),\n ...base,\n // Last and pinned right - the row's Save belongs at the end of the row.\n ...(editColumnEnabled\n ? [createEditColumn<TData>(editColumnLabel, editWideLane)]\n : []),\n ];\n }, [\n options.columns,\n rowNumbersEnabled,\n selectColumnEnabled,\n detailsColumnEnabled,\n groupColumnEnabled,\n editColumnEnabled,\n editWideLane,\n rowNumberColumnLabel,\n selectColumnLabel,\n groupColumnLabel,\n detailsColumnLabel,\n editColumnLabel,\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 // Realigned against the ids this render is about to construct - lanes\n // included - so a column removed between deploys does not leave a ghost\n // sort, filter or width behind.\n const [persistedState] = useState(() =>\n readPersistedState(persist, collectLeafColumnIds(columns)),\n );\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 // Current grouping state, feeding the tree column's entry in a controlled\n // `columnVisibility` (below). A ref, not state: it is only read while\n // building the options, and the store change that updates it re-renders the\n // hook anyway. A controlled `grouping` takes precedence over the persisted\n // one; grouping held in an external atom is not readable here and is\n // corrected by the effect below with one extra write on mount.\n const groupingActiveRef = useRef(\n (options.state?.grouping ?? initialGrouping).length > 0,\n );\n\n // Removes keys set to `undefined` before TanStack writes them into the\n // slice atoms; such a key means the slice is not controlled.\n const consumerState = withoutUndefinedSlices(options.state);\n\n // A controlled `columnVisibility` replaces the whole map on every options\n // sync, including the grid's own entries, so the tree column's entry must be\n // re-applied here. Entries for the control columns are removed, as they are\n // for `initialState`: their visibility follows the feature options, not the\n // visibility map.\n const controlledColumnVisibility = consumerState?.columnVisibility;\n const requestedState =\n consumerState !== undefined && controlledColumnVisibility !== undefined\n ? {\n ...consumerState,\n columnVisibility: {\n ...withoutControlColumnVisibility(controlledColumnVisibility),\n ...(groupColumnEnabled\n ? { [GROUP_COLUMN_ID]: groupingActiveRef.current }\n : {}),\n },\n }\n : consumerState;\n\n // Controlled state is synced to the table on every render and compared by\n // identity, so a `state` object built in the consumer's render body would\n // cause an infinite render loop. Unchanged slices are forwarded with the\n // previous render's identity instead - see controlledState.ts.\n const controlledStateRef = useRef<Partial<TableState<TMDataGridFeatures>>>(\n undefined,\n );\n // Exception: the grouping workaround below republishes `columnOrder` and\n // `columnVisibility` with unchanged contents and a new identity to repair\n // table-core's missing memo deps - the exact write stabilization cancels.\n // After it runs, one render forwards the controlled state unstabilized so\n // the new identities reach the atoms. A single render cannot loop.\n const republishControlledStateRef = useRef(false);\n const controlledState = republishControlledStateRef.current\n ? requestedState\n : stabilizeControlledState(requestedState, controlledStateRef.current);\n republishControlledStateRef.current = false;\n controlledStateRef.current = controlledState;\n\n /**\n * What the hook's own subscription watches.\n *\n * `useTable` re-renders whoever called it whenever a state slice changes\n * identity, and `columnResizing` publishes a new delta on every pointer move\n * of a resize drag - so without this the consumer's component, and the whole\n * grid under it, would re-render for each of those moves. The slice is\n * pinned to the identity it had when the drag started: a drag starting and a\n * drag ending still publish, the deltas in between do not.\n *\n * The live deltas stay on `table.store.state`, which is where the grid reads\n * them - see the resize preview in TMDataGridTable.\n */\n const pinnedResizingRef = useRef<\n TableState<TMDataGridFeatures>[\"columnResizing\"] | null\n >(null);\n const selectSettledState = useCallback(\n (state: TableState<TMDataGridFeatures>) => {\n const resizing = state.columnResizing;\n const pinned = pinnedResizingRef.current;\n if (\n pinned === null ||\n pinned.isResizingColumn !== resizing.isResizingColumn\n ) {\n pinnedResizingRef.current = resizing;\n return state;\n }\n return { ...state, columnResizing: pinned };\n },\n [],\n );\n\n const table = useTable({\n // The grid paints a running drag itself, one style write per frame - see\n // the resize preview in TMDataGridTable - and takes the width into state\n // once, when the pointer is released. `\"onChange\"` publishes a width on\n // every pointer move instead, which re-renders the grid for each of them.\n columnResizeMode: \"onEnd\",\n enableSorting: true,\n enableColumnResizing: true,\n // The quick search's matcher. Fuzzy by default (Q4); `\"contains\"` keeps\n // plain substring matching, and an explicit `globalFilterFn` in the\n // options below overrides both - which also switches the rank ordering\n // off, since it keys off this exact name.\n globalFilterFn:\n options.quickSearchMode === \"contains\"\n ? \"includesString\"\n : \"tmDataGridFuzzy\",\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 // Always a predicate, never the passthrough: TanStack defaults the option\n // to `true` once the feature is registered, and the grid's default is off.\n // Group rows never pin - TanStack builds one on its first child's record,\n // so a pinned group would drag an arbitrary data row's identity to the\n // edge. The consumer's own predicate still decides the data rows.\n enableRowPinning: (row: Row<TMDataGridFeatures, TData>) =>\n !row.getIsGrouped() &&\n (typeof options.enableRowPinning === \"function\"\n ? options.enableRowPinning(row)\n : options.enableRowPinning === true),\n features: tmDataGridFeatures,\n columns: columns as TableOptions<TMDataGridFeatures, TData>[\"columns\"],\n // The stabilized controlled state; `undefined` when nothing is controlled.\n state: controlledState,\n initialState: {\n ...options.initialState,\n ...persistedState,\n columnVisibility: {\n ...withoutControlColumnVisibility({\n ...options.initialState?.columnVisibility,\n ...persistedState.columnVisibility,\n }),\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 ...(rowNumbersEnabled && pinningEnabled ? [ROW_NUMBER_COLUMN_ID] : []),\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 !== ROW_NUMBER_COLUMN_ID &&\n id !== SELECT_COLUMN_ID &&\n id !== DETAILS_COLUMN_ID &&\n id !== GROUP_COLUMN_ID,\n ),\n ],\n // The edit lane mirrors the generated columns on the left: structurally\n // pinned, outermost, re-applied over anything restored.\n right: [\n ...(\n persistedState.columnPinning?.right ??\n options.initialState?.columnPinning?.right ??\n []\n ).filter((id) => id !== EDIT_COLUMN_ID),\n ...(editColumnEnabled && pinningEnabled ? [EDIT_COLUMN_ID] : []),\n ],\n },\n pagination: {\n pageIndex: 0,\n pageSize: 25,\n ...options.initialState?.pagination,\n ...persistedState.pagination,\n },\n },\n }, selectSettledState);\n\n // The edit engine. Built once per mount; everything it needs later - the\n // table, the mode, the consumer's callbacks - is read through a ref updated\n // every render, so forms created at `begin()` always call the latest\n // `onEditCommit` (the onHighlightedRowChangeRef pattern, applied wholesale).\n const editContextRef = useRef<TMDataGridEditEngineContext>(null as never);\n editContextRef.current = {\n table: table as unknown as TMDataGridTable<TMDataGridRowData>,\n editMode: editMode ?? \"cell\",\n draft: editDraft,\n rowValidators: editing?.rowValidators,\n tableValidators: editing?.tableValidators as\n TMDataGridEditEngineContext[\"tableValidators\"],\n editableColumnIds: editing?.columns,\n isRowEditable:\n editing?.isRowEditable as TMDataGridEditEngineContext[\"isRowEditable\"],\n onEditCommit:\n editing?.onCommit as TMDataGridEditEngineContext[\"onEditCommit\"],\n // The deprecated name still works; the new one wins if both are set.\n onSaveDrafts: (editing?.onSaveDrafts ??\n editing?.onCommitDrafts) as TMDataGridEditEngineContext[\"onSaveDrafts\"],\n newRowDefaults:\n editing?.newRowDefaults as TMDataGridEditEngineContext[\"newRowDefaults\"],\n onRowAdd: editing?.onRowAdd as TMDataGridEditEngineContext[\"onRowAdd\"],\n onRowDelete:\n editing?.onRowDelete as TMDataGridEditEngineContext[\"onRowDelete\"],\n };\n // The engine is erased; the row type comes back on the way out, which is\n // what makes `edit.addRow(values)` check against `TData`.\n const [edit] = useState(\n () =>\n createEditEngine(\n () => editContextRef.current,\n ) as unknown as TMDataGridEditApi<TData>,\n );\n\n // Switching either axis mid-flight drops every draft: the policies disagree\n // about what an open form means, and carrying one across is how a row\n // parked for `saveDrafts` silently commits to the consumer instead.\n const previousEditPolicyRef = useRef({ editMode, editDraft });\n useEffect(() => {\n const previous = previousEditPolicyRef.current;\n if (previous.editMode === editMode && previous.editDraft === editDraft) {\n return;\n }\n previousEditPolicyRef.current = { editMode, editDraft };\n edit.cancelAll();\n }, [editMode, editDraft, edit]);\n\n // Editing without stable ids points every draft at whatever record slides\n // into that index after a sort. Loud, once, in development.\n useEffect(() => {\n if (editing !== undefined && options.getRowId === undefined) {\n console.error(\n \"TMDataGrid: editing requires getRowId - drafts are keyed by row id, and the index fallback names a different record after any sort or filter.\",\n );\n }\n // The check is a mount-time contract, not something to re-run per render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // A controlled slice without its `onXChange` cannot change: TanStack routes\n // every write through the callback, and the next options sync restores the\n // consumer's value. Warned once in development; `initialState` is the option\n // for a starting value.\n useEffect(() => {\n for (const { slice, handler } of findFrozenStateSlices(options)) {\n console.warn(\n `TMDataGrid: state.${slice} is controlled but no ${handler} was passed - the slice cannot change. Add ${handler}, or use initialState.${slice} for a starting value.`,\n );\n }\n // A mount-time contract, like the check above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\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 // Update the ref before any write: it feeds the visibility injection\n // above, and a write below re-renders the hook. With a stale ref the\n // injection would restore the old value on every render. This also\n // corrects the mount value when an external atom owns `grouping`, which\n // the ref's initializer cannot read.\n groupingActiveRef.current = previousGrouping.length > 0;\n\n // The tree column's entry in `initialState` only reaches a slice the\n // table owns. With `columnVisibility` in an external atom the entry is\n // missing, and a missing entry means visible: the tree column would\n // render in an ungrouped grid. The entry is seeded here through the table\n // API instead, so the write reaches whichever store owns the slice. No-op\n // when the entry is already correct. `?.`: an external atom can hold\n // `undefined`.\n if (\n table.store.state.columnVisibility?.[GROUP_COLUMN_ID] !==\n (previousGrouping.length > 0)\n ) {\n table.setColumnVisibility((old) => ({\n ...old,\n [GROUP_COLUMN_ID]: previousGrouping.length > 0,\n }));\n }\n\n const subscription = table.store.subscribe((state) => {\n if (state.grouping === previousGrouping) return;\n previousGrouping = state.grouping;\n // Keeps the entry injected into a controlled `columnVisibility` (see\n // requestedState) in sync with grouping.\n groupingActiveRef.current = state.grouping.length > 0;\n // On a controlled slice the writes below round-trip through the\n // consumer's handler; the next render must forward them unstabilized.\n // See republishControlledStateRef.\n republishControlledStateRef.current = true;\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 a state change can arrive on every pointer\n // move - a resize drag under `columnResizeMode: \"onChange\"`, a range\n // selection - and `setItem` serialises synchronously on the main thread. The\n // trailing edge is enough: storage only has to agree with the table once the\n // 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 matters more here: a drag publishes a\n // new corner on every mouse move, and most of those land on the cell\n // the 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 // The same recipe the mount uses for `initialState`, minus the persisted\n // layer - see the api's JSDoc for why TanStack's own resets cannot do this.\n // Ref-and-stable-wrapper, like the edit engine's context: the recipe reads\n // this render's flags, the callback identity never changes.\n const resetSettingsRef = useRef<() => void>(() => {});\n resetSettingsRef.current = () => {\n const initial = options.initialState;\n const grouping = [...(initial?.grouping ?? [])];\n table.setGrouping(grouping);\n table.setColumnVisibility({\n ...withoutControlColumnVisibility({ ...initial?.columnVisibility }),\n // The tree lane's visibility tracks the grouping, never the user.\n ...(groupColumnEnabled ? { [GROUP_COLUMN_ID]: grouping.length > 0 } : {}),\n });\n table.setColumnSizing({ ...initial?.columnSizing });\n table.setColumnOrder([...(initial?.columnOrder ?? [])]);\n table.setColumnPinning({\n left: [\n ...(rowNumbersEnabled && pinningEnabled ? [ROW_NUMBER_COLUMN_ID] : []),\n ...(selectColumnEnabled && pinningEnabled ? [SELECT_COLUMN_ID] : []),\n ...(groupColumnEnabled && pinningEnabled ? [GROUP_COLUMN_ID] : []),\n ...(detailsColumnEnabled && pinningEnabled ? [DETAILS_COLUMN_ID] : []),\n ...(initial?.columnPinning?.left ?? []).filter(\n (id) =>\n id !== ROW_NUMBER_COLUMN_ID &&\n id !== SELECT_COLUMN_ID &&\n id !== DETAILS_COLUMN_ID &&\n id !== GROUP_COLUMN_ID,\n ),\n ],\n right: [\n ...(initial?.columnPinning?.right ?? []).filter(\n (id) => id !== EDIT_COLUMN_ID,\n ),\n ...(editColumnEnabled && pinningEnabled ? [EDIT_COLUMN_ID] : []),\n ],\n });\n };\n const resetSettings = useCallback(() => resetSettingsRef.current(), []);\n\n // Filled in by `TMDataGrid.Table` on every render, because only the body\n // holds the virtualizer and the current view. Returns `false` until one is\n // mounted, since there is nothing to scroll before then.\n const scrollerRef = useRef<TMDataGridScroller>(() => false);\n const scrollToRow = useCallback(\n (args: TMDataGridScrollToRowArgs) => scrollerRef.current(args),\n [],\n );\n\n return {\n table,\n ui,\n edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\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 const operator = getColumnDefaultOperator(column);\n column.setFilterValue({\n operator,\n value: emptyValueForOperator(operator),\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 data-dg-part=\"filter-pills\"\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 data-dg-part=\"filter-pill\"\n data-column-id={filter.id}\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 // No test id of its own: Mantine types these props as\n // `CloseButtonProps`, which has no room for `data-*`. The pill\n // carries one, and the ✕ is the only button inside it.\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 { useSelector } from \"@tanstack/react-store\";\nimport { shallow } from \"@tanstack/store\";\nimport type { ReadonlyStore, Store } from \"@tanstack/store\";\n\n/** The one slice a settled subscription leaves out. */\nconst TRANSIENT_SLICE = \"columnResizing\";\n\n/**\n * Subscribes to every table state slice except the transient resize state.\n *\n * `columnResizing` publishes a new delta on every pointer move of a resize\n * drag. Nothing renders from those deltas - the divider highlight reads\n * `isResizingColumn` through its own selector, and the drag itself is painted\n * straight onto the grid's track list (see `resizePreview`) - so a component\n * subscribed to the whole store would re-render the grid dozens of times a\n * second for state it does not show.\n *\n * The comparison is shallow over the remaining slices, which is the\n * granularity TanStack publishes at: a slice keeps its identity until it\n * changes.\n */\nexport function useSettledTableState<TState extends object>(\n store: Store<TState> | ReadonlyStore<TState>,\n): void {\n useSelector(\n store,\n (state) => {\n const settled: Record<string, unknown> = {};\n for (const [slice, value] of Object.entries(state)) {\n if (slice !== TRANSIENT_SLICE) settled[slice] = value;\n }\n return settled;\n },\n { compare: shallow },\n );\n}\n","import { ActionIcon, Group, Select, Text, Tooltip } from \"@mantine/core\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport { useMemo, type ReactNode } from \"react\";\nimport classes from \"./TMDataGridFooter.module.css\";\nimport { useTMDataGridContext } from \"../TMDataGridContext\";\nimport { getGridCapabilities } from \"../core/capabilities\";\nimport { useSettledTableState } from \"../core/useSettledTableState\";\nimport { isPagingActive } from \"../core/rowSelection\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"./icons\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/** What the pager is showing. The read half of {@link TMDataGridPaginationApi}. */\nexport type TMDataGridPaginationState = {\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 /**\n * Whether the pager is slicing anything right now. `false` while a grouping\n * is active, which suspends paging - see `isPagingActive`.\n */\n isPagingActive: boolean;\n /** First and last row number on this page, 1-based, for a range label. */\n from: number;\n to: number;\n};\n\n/** What the pager can do. The write half of {@link TMDataGridPaginationApi}. */\nexport type TMDataGridPaginationActions = {\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 * Pagination state and actions, split into the half you read and the half you\n * call.\n *\n * The split is what makes a partial override possible: a consumer replacing\n * only the range label reads `state` and never touches `actions`, and one\n * replacing only the buttons does the opposite.\n */\nexport type TMDataGridPaginationApi = {\n state: TMDataGridPaginationState;\n actions: TMDataGridPaginationActions;\n};\n\n/**\n * The pre-bound pieces of the built-in pager.\n *\n * Each renders exactly what the default footer renders, already wired to the\n * table and already respecting the suspended-paging state - so a custom layout\n * keeps the parts it likes rather than rebuilding them to look the same.\n */\nexport type TMDataGridPaginationControls = {\n /** \"Rows per page\" and its select. */\n PageSize: () => ReactNode;\n /** The \"1–25 of 300\" range label. */\n Range: () => ReactNode;\n /** The previous/next buttons. */\n Pager: () => ReactNode;\n};\n\n/** What {@link TMDataGridFooterProps.renderPagination} is handed. */\nexport type TMDataGridPaginationSlotArgs = TMDataGridPaginationApi & {\n Controls: TMDataGridPaginationControls;\n};\n\n/**\n * Reads {@link TMDataGridPaginationApi} off a table. The Footer feeds it to the\n * `renderPagination` slot; a pager living outside the Footer can call it with\n * the table from `useTMDataGrid` directly.\n *\n * `Controls` are not here: they are components bound to the grid context, and\n * this function takes only a table.\n */\nexport function getTMDataGridPaginationApi<TData extends RowData>(\n table: TMDataGridTable<TData>,\n isPaging = true,\n): TMDataGridPaginationApi {\n const { pageIndex, pageSize } = table.store.state.pagination;\n const rowCount = table.getRowCount();\n return {\n state: {\n pageIndex,\n pageSize,\n pageCount: table.getPageCount(),\n rowCount,\n canPreviousPage: table.getCanPreviousPage(),\n canNextPage: table.getCanNextPage(),\n isPagingActive: isPaging,\n from: rowCount === 0 ? 0 : pageIndex * pageSize + 1,\n to: Math.min(rowCount, (pageIndex + 1) * pageSize),\n },\n actions: {\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}\n\n/*\n * The three controls are module-scope components on purpose. Defined inside\n * the Footer they would be a new component type on every render, so React\n * would unmount and remount the pager between one render and the next - which\n * detaches the button a click is landing on mid-interaction.\n */\n\nfunction PaginationPageSize({\n pageSizeOptions,\n}: {\n pageSizeOptions: ReadonlyArray<number>;\n}) {\n const { table, features, labels, controlSize } = useTMDataGridContext();\n useSettledTableState(table.store);\n const paging = isPagingActive(table, features);\n const { pageSize } = table.store.state.pagination;\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 <Group gap=\"xs\" wrap=\"nowrap\">\n {/* `span`, here and in every other label the grid renders: Mantine's\n Text is a `<p>` by default, and a grid dropped into prose - a docs\n page, a CMS body, Mantine's own Typography - picks up that context's\n `p` margins. A bottom margin on a flex item shifts its border box up\n off centre, which is how the pager came to sit a half-line below its\n own label. Chrome labels are not prose. */}\n <Text span 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-dg-part=\"page-size\"\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}\n\nfunction PaginationRange() {\n const { table, features, labels, controlSize } = useTMDataGridContext();\n useSettledTableState(table.store);\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\n return (\n <Text span size={controlSize} c=\"dimmed\" data-dg-part=\"page-range\">\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}\n\nfunction PaginationPager() {\n const { table, features, labels } = useTMDataGridContext();\n useSettledTableState(table.store);\n const paging = isPagingActive(table, features);\n\n return (\n <Group gap={4} wrap=\"nowrap\">\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n aria-label={labels.previousPage}\n data-dg-part=\"page-prev\"\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 data-dg-part=\"page-next\"\n disabled={!paging || !table.getCanNextPage()}\n onClick={() => table.nextPage()}\n >\n <ChevronRightIcon size={18} stroke={1.6} />\n </ActionIcon>\n </Group>\n );\n}\n\nexport type TMDataGridFooterProps = {\n pageSizeOptions?: ReadonlyArray<number>;\n /**\n * Replaces the built-in pager, and is handed the pieces of it.\n *\n * ```tsx\n * <TMDataGrid.Footer\n * renderPagination={({ state, actions, Controls }) => (\n * <Group>\n * <Controls.PageSize />\n * <MyJumpToPage page={state.pageIndex} onJump={actions.setPageIndex} />\n * <Controls.Pager />\n * </Group>\n * )}\n * />\n * ```\n */\n renderPagination?: (args: TMDataGridPaginationSlotArgs) => ReactNode;\n};\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\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 = DEFAULT_PAGE_SIZE_OPTIONS,\n renderPagination,\n}: TMDataGridFooterProps) {\n const { table, features, labels } = useTMDataGridContext();\n useSettledTableState(table.store);\n\n // Bound once per option list rather than per render, so the controls keep\n // their identity and the elements they render keep theirs.\n const Controls = useMemo<TMDataGridPaginationControls>(\n () => ({\n PageSize: () => <PaginationPageSize pageSizeOptions={pageSizeOptions} />,\n Range: PaginationRange,\n Pager: PaginationPager,\n }),\n [pageSizeOptions],\n );\n\n if (!getGridCapabilities(table, features).canPaginate) return null;\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\n if (renderPagination) {\n const { state, actions } = getTMDataGridPaginationApi(table, paging);\n return (\n <div data-dg-part=\"footer\" className={classes.footer}>\n {renderPagination({ state, actions, Controls })}\n </div>\n );\n }\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\n data-dg-part=\"footer\"\n className={classes.footer}\n data-paging-suspended={!paging}\n >\n {/* The default render is the controls in order - which is what makes\n `renderPagination` a rearrangement rather than a rebuild. */}\n <Controls.PageSize />\n <Controls.Range />\n <Controls.Pager />\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 data-dg-part=\"search\"\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 data-dg-part=\"search-clear\"\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","/* 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/* A filtered column reads as active: its rows are a subset, and nothing else in\n the header says so once the filter panel is closed. A sorted one is not\n tinted - the arrow, pinned visible for as long as the sort lasts, already\n says which column sorts and which way. */\n.headerCellFiltered .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/* See the sort ActionIcon: an unsorted column's arrow is an invitation, not a\n state, so it sits back until the pointer is on it. */\n.sortAction[data-sorted=\"false\"] {\n opacity: 0.55;\n}\n\n.sortAction[data-sorted=\"false\"]:hover {\n opacity: 1;\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/** One column's body cells that are currently in the DOM. */\nfunction mountedCells(\n container: HTMLElement,\n columnId: string,\n): NodeListOf<HTMLElement> {\n const id = CSS.escape(columnId);\n return container.querySelectorAll<HTMLElement>(\n `[role=\"cell\"][data-column-id=\"${id}\"],` +\n `[role=\"gridcell\"][data-column-id=\"${id}\"]`,\n );\n}\n\n/**\n * Whether this column has any body cell in the DOM to measure.\n *\n * A caller sizing a column on its own schedule rather than from a gesture has\n * to ask: the virtualizer mounts its first rows a render *after* the grid\n * itself mounts, and a measurement taken before that fits the header alone.\n */\nexport function hasMountedCells(\n container: HTMLElement,\n columnId: string,\n): boolean {\n return mountedCells(container, columnId).length > 0;\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. With no rows mounted at all the\n * header is the only thing left to measure, which is a width that fits the\n * title and nothing else - see `hasMountedCells`.\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 for (const cell of mountedCells(container, columnId)) {\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-column-id=\"${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, isGeneratedColumn } 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/**\n * Puts the generated lanes back on the outside of both pinned lanes: the ones\n * on the left before every consumer column, the edit lane after all of them.\n *\n * `column.pin(\"right\")` appends, so pinning a column right would otherwise drop\n * it outside the edit lane, so the row's Save and Delete would no longer be\n * last in the row. Pinning left appends too, which is already correct there,\n * but the same pass keeps both lanes in place whatever a consumer writes into\n * `columnPinning` directly.\n *\n * Relative order is preserved inside each part, so a user's own arrangement of\n * the pinned columns survives.\n */\nexport function keepGeneratedColumnsOutermost(\n pinning: ColumnPinningState,\n): ColumnPinningState {\n const generated = (id: string) => isGeneratedColumn(id);\n return {\n left: [\n ...pinning.left.filter(generated),\n ...pinning.left.filter((id) => !generated(id)),\n ],\n right: [\n ...pinning.right.filter((id) => !generated(id)),\n ...pinning.right.filter(generated),\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 keepGeneratedColumnsOutermost,\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\n/** The table as the header cell sees it, after the context type erasure. */\ntype TMDataGridTableInstance = ReturnType<\n typeof useTMDataGridContext\n>[\"table\"];\n\nexport type TMDataGridHeader = Header<\n TMDataGridFeatures,\n TMDataGridRowData,\n unknown\n>;\n\n/** What {@link TMDataGridColumnMenuItemsRenderer} is handed. */\nexport type TMDataGridColumnMenuItemsArgs = {\n column: TMDataGridHeader[\"column\"];\n table: TMDataGridTableInstance;\n /**\n * The items the grid would have rendered, in order, dividers included.\n * Return them to keep the built-in menu, splice around them to extend it,\n * or drop them to replace it.\n */\n internalItems: Array<ReactNode>;\n};\n\n/**\n * Replaces a column's menu contents. Returning an empty list leaves the column\n * with no menu button at all, the same as a column whose every feature is off.\n */\nexport type TMDataGridColumnMenuItemsRenderer = (\n args: TMDataGridColumnMenuItemsArgs,\n) => Array<ReactNode>;\n\nexport function TMDataGridHeaderCell({\n header,\n layout,\n renderColumnMenuItems,\n}: {\n header: TMDataGridHeader;\n layout: TMDataGridColumnLayout;\n renderColumnMenuItems?: TMDataGridColumnMenuItemsRenderer;\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 // Any column, not just this one: a resize elsewhere must not leave a\n // neighbouring header ready to start a native drag under the pointer.\n const isAnyResizing = resizingColumnId !== false;\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 * Writes the width this header's columns are rendered with into\n * `columnSizing`, for the ones that have no width there yet.\n *\n * An unresized column is a fluid (`fr`) track: it renders at whatever share\n * of the grid it is given, while `column.getSize()` keeps reporting the\n * declared `size`. Anything that switches a column to exact pixels has to\n * close that gap first, or the column jumps from the width on screen to the\n * declared one.\n *\n * Under a held pointer that jump is more than cosmetic: it slides the\n * divider out from under the cursor onto the neighbouring header, where the\n * browser starts a native column-move drag instead. That drag swallows the\n * `mouseup` the resize listens for, so the resize keeps running after the\n * button is released.\n */\n function freezeRenderedWidths() {\n const container = cellRef.current?.closest<HTMLElement>(\n \"[data-dg-scroll-container]\",\n );\n if (!container) return;\n const sizing = table.store.state.columnSizing;\n const frozen: Record<string, number> = {};\n for (const leaf of header.getLeafHeaders()) {\n const id = leaf.column.id;\n if (id in sizing) continue;\n const width = container\n .querySelector<HTMLElement>(\n `[role=\"columnheader\"][data-column-id=\"${CSS.escape(id)}\"]`,\n )\n ?.getBoundingClientRect().width;\n if (width) frozen[id] = Math.round(width);\n }\n if (Object.keys(frozen).length === 0) return;\n table.setColumnSizing((previous) => ({ ...previous, ...frozen }));\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) freezeRenderedWidths();\n column.pin(position);\n // `pin(\"right\")` appends, which would leave the column outside the edit\n // lane. Normalising after the pin rather than writing the lane by hand\n // keeps TanStack's own handling of a header group's leaves.\n table.setColumnPinning(keepGeneratedColumnsOutermost);\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 // The handback: the consumer is given what the grid would have rendered and\n // returns what should be. Trimmed again afterwards, because a consumer that\n // drops the last group can leave a divider stranded the same way.\n const finalItems = renderColumnMenuItems\n ? [...renderColumnMenuItems({ column, table, internalItems: menuItems })]\n : menuItems;\n while (finalItems.length > 0 && isDivider(finalItems.at(-1))) {\n finalItems.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 && finalItems.length > 0 && !isControlColumn(column.id);\n\n const cellClass = [\n classes.headerCell,\n canSort ? classes.headerCellSortable : \"\",\n // Only the filter tints the title. `data-active` below stays\n // sorted-or-filtered - it is the queryable state, not the styling hook.\n isFiltered ? classes.headerCellFiltered : \"\",\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-dg-part=\"header\"\n // The same coordinate the body, summary and entry cells carry, so one\n // selector reaches a column's header and its cells alike.\n data-column-id={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\" announces that this\n // header sorts, which is wrong on one that does not.\n aria-sort={\n canSort\n ? isSorted\n ? sortDirection\n ? \"descending\"\n : \"ascending\"\n : \"none\"\n : undefined\n }\n className={cellClass}\n // Dropped while any column is resizing, so that dragging the separator\n // resizes the column instead of starting to move it - and so that a\n // header the divider passes under cannot start a move of its own. The\n // resize handler records the column on mousedown, before the first\n // pointer move.\n draggable={canReorder && !isAnyResizing}\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 data-dg-part=\"header-filter\"\n data-column-id={column.id}\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} ${classes.sortAction}`}\n data-pinned-visible={isSorted}\n // The arrow is the only sort indicator now that the title no\n // longer tints, so it takes the colour while the sort holds. On\n // an unsorted column it is only the hover affordance, and stays a\n // faded grey so the two are not confused.\n data-sorted={isSorted}\n variant=\"subtle\"\n color={isSorted ? undefined : \"gray\"}\n size=\"xs\"\n aria-label={labels.sortColumn(label)}\n data-dg-part=\"header-sort\"\n data-column-id={column.id}\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-dg-part=\"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 data-dg-part=\"header-menu\"\n data-column-id={column.id}\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 {finalItems}\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 // The drag starts from `column.getSize()`, so the rendered width has\n // to be in `columnSizing` before the handler reads it - otherwise\n // the first pointer move snaps a fluid column to its declared size.\n onMouseDown={\n canResize\n ? (event) => {\n suppressSortRef.current = true;\n freezeRenderedWidths();\n header.getResizeHandler()(event);\n }\n : undefined\n }\n onTouchStart={\n canResize\n ? (event) => {\n freezeRenderedWidths();\n header.getResizeHandler()(event);\n }\n : undefined\n }\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. `finalItems` 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 {finalItems}\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 { useStore } from \"@tanstack/react-form\";\nimport { useLayoutEffect, useRef, type RefObject } from \"react\";\nimport { firstErrorText, type TMDataGridEditField } from \"../../core/editEngine\";\n\n/** The field's live value - one subscription, on the field's own store. */\nexport function useFieldValue(field: TMDataGridEditField): unknown {\n return useStore(field.store, (state) => state.value as unknown);\n}\n\n/** The field's first error, for the Mantine input's `error` prop. */\nexport function useFieldError(field: TMDataGridEditField): string | undefined {\n return useStore(field.store, (state) =>\n firstErrorText(state.meta.errors as ReadonlyArray<unknown>),\n );\n}\n\n/** Select-all on focus - F2/Enter open with the value ready to replace. */\nexport function selectAllOnFocus(event: { currentTarget: unknown }): void {\n const target = event.currentTarget;\n if (target instanceof HTMLInputElement) target.select();\n}\n\n/**\n * Keeps the caret where it was typed when the value comes back changed.\n *\n * A column with `meta.edit.mapValue` writes something other than what the\n * input holds, so React reassigns `input.value` - and the browser collapses\n * the selection to the end of the field. Typing into the middle of a value\n * then jumped to the end on every keystroke.\n *\n * `remember` records the caret as the change is handed over; the effect puts\n * it back once the mapped value has rendered, shifted by however much the map\n * changed the length so a mask that inserts or strips characters keeps the\n * caret beside the same text. Without a map nothing is recorded twice and the\n * restore is a no-op, so an unmapped column is untouched.\n */\nexport function useCaretKeeper(): {\n inputRef: RefObject<HTMLInputElement | null>;\n remember: (input: HTMLInputElement) => void;\n} {\n const inputRef = useRef<HTMLInputElement | null>(null);\n const caret = useRef<{ position: number; length: number } | null>(null);\n\n useLayoutEffect(() => {\n const pending = caret.current;\n const input = inputRef.current;\n caret.current = null;\n if (pending === null || input === null) return;\n const shift = input.value.length - pending.length;\n const next = Math.max(\n 0,\n Math.min(pending.position + shift, input.value.length),\n );\n input.setSelectionRange(next, next);\n });\n\n return {\n inputRef,\n remember: (input) => {\n if (input.selectionStart === null) return;\n caret.current = {\n position: input.selectionStart,\n length: input.value.length,\n };\n },\n };\n}\n","import { Checkbox } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/** The built-in editor for `meta.type: \"boolean\"` - a focused checkbox. */\nexport function TMDataGridBooleanEditor({\n field,\n column,\n size,\n}: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n return (\n <Checkbox\n size={size}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n checked={value === true}\n onChange={(event) => field.handleChange(event.currentTarget.checked)}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { TextInput } from \"@mantine/core\";\nimport { useRef } from \"react\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/**\n * The built-in editor for `meta.type: \"date\"` - the native\n * `<input type=\"date\">` styled by Mantine, no `@mantine/dates` involved. A\n * consumer wanting a real picker plugs one in through `meta.edit.editor`.\n */\nexport function TMDataGridDateEditor({\n field,\n column,\n size,\n}: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n // The cell's original shape decides what the editor writes back: a `Date`\n // cell keeps getting Dates, an ISO-string cell keeps getting strings -\n // decided once at open, so clearing and retyping cannot flip the type.\n const writesDates = useRef(value instanceof Date);\n\n const text =\n value instanceof Date\n ? value.toLocaleDateString(\"sv-SE\")\n : typeof value === \"string\"\n ? value.slice(0, 10)\n : \"\";\n\n return (\n <TextInput\n size={size}\n w=\"100%\"\n type=\"date\"\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n value={text}\n onChange={(event) => {\n const next = event.currentTarget.value;\n if (next === \"\") {\n field.handleChange(null);\n return;\n }\n field.handleChange(\n writesDates.current ? new Date(`${next}T00:00:00`) : next,\n );\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { MultiSelect } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport {\n optionsToComboboxData,\n resolveColumnOptions,\n} from \"../../core/columnOptions\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/**\n * The built-in editor for `meta.type: \"multiSelect\"` - cells holding string\n * arrays. Never commits on pick: building a set takes several, so the commit\n * stays on Enter/blur like a text edit.\n */\nexport function TMDataGridMultiSelectEditor({\n field,\n column,\n row,\n table,\n size,\n}: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n return (\n <MultiSelect\n size={size}\n w=\"100%\"\n searchable\n comboboxProps={{ withinPortal: false }}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n data={optionsToComboboxData(\n resolveColumnOptions({ table, column, row, fallback: \"faceted\" }),\n )}\n value={Array.isArray(value) ? value.map(String) : []}\n onChange={(next) => field.handleChange(next)}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { NumberInput } from \"@mantine/core\";\nimport { useState } from \"react\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport {\n selectAllOnFocus,\n useCaretKeeper,\n useFieldError,\n useFieldValue,\n} from \"./editorShared\";\n\n/** The built-in editor for `meta.type: \"number\"`. */\nexport function TMDataGridNumberEditor({ field, column, size }: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n const { inputRef, remember } = useCaretKeeper();\n /**\n * The last text Mantine reported instead of a number - \"-\" or \"1e\" on the\n * way to one. Held so a half-typed number stays on screen while the field\n * itself holds no value.\n */\n const [typed, setTyped] = useState<string | null>(null);\n // The field is the source of truth: the text survives only while it still\n // describes what the field holds, so a write from outside the editor -\n // `edit.setCellValue`, a revert - replaces it rather than being masked.\n const parsedTyped = typed === null || typed === \"\" ? null : Number(typed);\n const textDescribesField = Number.isFinite(parsedTyped)\n ? parsedTyped === value\n : value === null;\n return (\n <NumberInput\n ref={inputRef}\n size={size}\n w=\"100%\"\n onFocus={selectAllOnFocus}\n hideControls\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n value={\n typed !== null && textDescribesField\n ? typed\n : typeof value === \"number\"\n ? value\n : \"\"\n }\n onChange={(next) => {\n if (inputRef.current !== null) remember(inputRef.current);\n if (typeof next === \"number\") {\n setTyped(null);\n field.handleChange(next);\n return;\n }\n // Mantine reports a number once one can be parsed and a string while\n // it cannot: \"\" for an empty cell, partial input on the way to a\n // number. Anything that does not parse leaves the field empty rather\n // than `NaN` - which is a number to every validator and would commit\n // as one, with no message a user could act on.\n setTyped(next);\n const parsed = Number(next);\n field.handleChange(\n next !== \"\" && Number.isFinite(parsed) ? parsed : null,\n );\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { Select } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport {\n optionsToComboboxData,\n resolveColumnOptions,\n} from \"../../core/columnOptions\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport { useFieldError, useFieldValue } from \"./editorShared\";\n\n/**\n * The built-in editor for `meta.type: \"select\"`. Options come from the same\n * `meta.options` the filter panel reads - with the row in hand, so a\n * function source can depend on the record being edited.\n */\nexport function TMDataGridSelectEditor({\n field,\n column,\n row,\n table,\n size,\n commit,\n}: TMDataGridEditorArgs) {\n const { labels, features } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n return (\n <Select\n size={size}\n w=\"100%\"\n searchable\n // Inside the cell, so picking an option is not a click-away - the same\n // reason the filter panel keeps its dropdowns unportalled.\n comboboxProps={{ withinPortal: false }}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n data={optionsToComboboxData(\n resolveColumnOptions({ table, column, row, fallback: \"faceted\" }),\n )}\n value={typeof value === \"string\" ? value : null}\n onChange={(next) => {\n field.handleChange(next);\n // Sheets semantics under `\"cell\"`: a pick is the edit, so it commits.\n // The confirming modes leave the draft for their explicit commit.\n if (next !== null && features.editMode === \"cell\") void commit();\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { TextInput } from \"@mantine/core\";\nimport type { TMDataGridEditorArgs } from \"../../core/editEngine\";\nimport { getColumnLabel } from \"../../core/columnUtils\";\nimport { useTMDataGridContext } from \"../../TMDataGridContext\";\nimport {\n selectAllOnFocus,\n useCaretKeeper,\n useFieldError,\n useFieldValue,\n} from \"./editorShared\";\n\n/** The built-in editor for `meta.type: \"string\"` (and the default). */\nexport function TMDataGridStringEditor({ field, column, size }: TMDataGridEditorArgs) {\n const { labels } = useTMDataGridContext();\n const value = useFieldValue(field);\n const error = useFieldError(field);\n const { inputRef, remember } = useCaretKeeper();\n return (\n <TextInput\n ref={inputRef}\n size={size}\n w=\"100%\"\n onFocus={selectAllOnFocus}\n aria-label={labels.editCell(getColumnLabel(column))}\n data-dg-part=\"editor-input\"\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(event) => {\n remember(event.currentTarget);\n field.handleChange(event.currentTarget.value);\n }}\n onBlur={field.handleBlur}\n error={error}\n />\n );\n}\n","import { ActionIcon } from \"@mantine/core\";\nimport { FieldApi } from \"@tanstack/react-form\";\nimport type { Cell, Row } from \"@tanstack/react-table\";\nimport {\n type ComponentType,\n type FocusEvent,\n type KeyboardEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport { type TMDataGridRowData, useTMDataGridContext } from \"../TMDataGridContext\";\nimport {\n getEditFieldName,\n normalizeFieldValidate,\n type TMDataGridEditField,\n type TMDataGridEditorArgs,\n type TMDataGridEditValueMap,\n} from \"../core/editEngine\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\nimport { CheckIcon, CloseIcon } from \"./icons\";\nimport { TMDataGridBooleanEditor } from \"./editors/TMDataGridBooleanEditor\";\nimport { TMDataGridDateEditor } from \"./editors/TMDataGridDateEditor\";\nimport { TMDataGridMultiSelectEditor } from \"./editors/TMDataGridMultiSelectEditor\";\nimport { TMDataGridNumberEditor } from \"./editors/TMDataGridNumberEditor\";\nimport { TMDataGridSelectEditor } from \"./editors/TMDataGridSelectEditor\";\nimport { TMDataGridStringEditor } from \"./editors/TMDataGridStringEditor\";\n\nconst BUILT_IN_EDITORS: Record<\n string,\n ComponentType<TMDataGridEditorArgs>\n> = {\n string: TMDataGridStringEditor,\n number: TMDataGridNumberEditor,\n boolean: TMDataGridBooleanEditor,\n date: TMDataGridDateEditor,\n select: TMDataGridSelectEditor,\n multiSelect: TMDataGridMultiSelectEditor,\n};\n\n/** How an editor closed, for the table to decide where the focus goes. */\nexport type TMDataGridCellEditorClose =\n | { committed: true; via: \"enter\" | \"tab\" | \"shift-tab\" | \"pick\" }\n | { committed: false; via: \"escape\" }\n /** `cellConfirm`: the editor closed, the draft stays, waiting for its ✓. */\n | { committed: false; via: \"defer-tab\" | \"defer-shift-tab\" };\n\n/**\n * The host an editing cell mounts - it owns the field, the keys and the blur\n * policy; the editor inside it (a built-in picked by `meta.type`, or the\n * column's `meta.edit.editor`) owns the input.\n *\n * The form outlives this component by design: scrolling the row away\n * unmounts the host, and the form in the engine's map keeps the draft.\n */\nexport function TMDataGridCellEditor({\n cell,\n row,\n takeSeedText,\n onClose,\n inEntryBlock = false,\n}: {\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n row: Row<TMDataGridFeatures, TMDataGridRowData>;\n /** Consumes the pending type-to-edit seed, when typing opened this editor. */\n takeSeedText: () => string | undefined;\n /** After the editor closed itself - the table moves the focus. */\n onClose: (args: TMDataGridCellEditorClose) => void;\n /**\n * Hosted by the entry block rather than a body cell. An entry row is\n * row-shaped in every mode: Enter enters the whole row, Tab stays the\n * browser's - walking the row's own inputs the way row mode's do - and\n * focus leaving decides nothing, because the ✓ is the decision.\n */\n inEntryBlock?: boolean;\n}) {\n const { table, edit, features, labels, controlSize } = useTMDataGridContext();\n // Row mode mounts one host per editable cell of the row; every key that\n // commits or cancels acts on the whole row's form either way, but Tab must\n // stay the browser's (it walks the row's inputs) and blur must do nothing\n // (focus moves between this row's own editors). The entry block is built\n // the same way, in every mode, so it follows the same two rules.\n const isRowShaped = features.editMode === \"row\" || inEntryBlock;\n const column = cell.column;\n const form = edit.getForm(row.id);\n const fieldName = getEditFieldName(column);\n const [seedText] = useState(() => takeSeedText());\n\n /**\n * The column's current `mapValue`, for the field below to read at write\n * time. No dependency array, so it re-registers every render: the field is\n * created once and kept, and a map redeclared per render would otherwise be\n * frozen at the one this editor opened with. Declared above the seed effect,\n * which writes through the same field.\n */\n const mapValueRef = useRef<TMDataGridEditValueMap | undefined>(undefined);\n useEffect(() => {\n mapValueRef.current = column.columnDef.meta?.edit?.mapValue;\n });\n\n // One FieldApi per open editor, over the row's long-lived form. Created\n // imperatively (the documented core usage) because the form was too.\n const [field] = useState<TMDataGridEditField>(() => {\n const created = new FieldApi({\n form: form as never,\n name: fieldName as never,\n validators: normalizeFieldValidate(\n column.columnDef.meta?.edit?.validate,\n ) as never,\n }) as unknown as TMDataGridEditField;\n\n // `meta.edit.mapValue` lives here rather than in each editor, so one\n // implementation covers the six built-ins, any `meta.edit.editor` and the\n // type-to-edit seed below - everything that writes through this field.\n // Form's own paths (validation, reset, `form.setFieldValue`) hold the\n // form, not this field, so a cleared cell and a rolled-back draft stay\n // exactly what the engine wrote.\n const write = created.handleChange.bind(created);\n created.handleChange = ((updater: unknown) => {\n const map = mapValueRef.current;\n const previous = created.state.value as unknown;\n // Form takes a value or an updater; resolve one so `mapValue` is only\n // ever handed the value itself.\n const value =\n typeof updater === \"function\"\n ? (updater as (prev: unknown) => unknown)(previous)\n : updater;\n write(\n (map === undefined\n ? value\n : map({ value, previous, row, column, table })) as never,\n );\n }) as typeof created.handleChange;\n\n return created;\n });\n useEffect(() => field.mount(), [field]);\n\n // Type-to-edit: the seed replaces the value, as it does in a spreadsheet.\n // Only for the types where keystrokes are the input.\n useEffect(() => {\n if (seedText === undefined) return;\n const type = column.columnDef.meta?.type ?? \"string\";\n if (type === \"string\") {\n field.handleChange(seedText as never);\n } else if (type === \"number\") {\n const seeded = Number(seedText);\n if (Number.isFinite(seeded)) field.handleChange(seeded as never);\n }\n // Once, at open.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const closingRef = useRef(false);\n\n const commitAndClose = async (\n via: \"enter\" | \"tab\" | \"shift-tab\" | \"pick\",\n ): Promise<boolean> => {\n if (closingRef.current) return false;\n const ok = await edit.commit(row.id);\n if (ok && !closingRef.current) {\n closingRef.current = true;\n onClose({ committed: true, via });\n }\n return ok;\n };\n\n const cancelAndClose = () => {\n if (closingRef.current) return;\n closingRef.current = true;\n edit.cancel(row.id);\n onClose({ committed: false, via: \"escape\" });\n };\n\n /**\n * `cellConfirm`: the key closes the editor and leaves the draft where it\n * is, waiting for the ✓. Moving along the row is not a decision about it;\n * Enter is, and commits instead.\n */\n const deferAndClose = (via: \"defer-tab\" | \"defer-shift-tab\") => {\n if (closingRef.current) return;\n closingRef.current = true;\n edit.deactivate();\n onClose({ committed: false, via });\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n // Enter is OK, in every mode: the row's form submits and has to pass\n // validation. Where a commit *goes* is `editing.draft`'s business, not\n // this key's - out to the consumer, or into the draft store.\n void commitAndClose(\"enter\");\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancelAndClose();\n } else if (event.key === \"Tab\" && !isRowShaped) {\n event.preventDefault();\n event.stopPropagation();\n // `cellConfirm` is the one mode where leaving a cell decides nothing:\n // the caret moves on and the draft waits for its ✓.\n if (features.editMode === \"cellConfirm\") {\n deferAndClose(event.shiftKey ? \"defer-shift-tab\" : \"defer-tab\");\n } else {\n void commitAndClose(event.shiftKey ? \"shift-tab\" : \"tab\");\n }\n }\n };\n\n /**\n * Focus left the editor entirely - a click somewhere else. Under `\"cell\"`\n * that commits (Sheets): a row the user has walked away from is a row they\n * are done typing into, and where the commit lands is `editing.draft`'s\n * business. A commit blocked by validation keeps the form and its invalid\n * marker, with the editor closed.\n */\n const handleBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (closingRef.current) return;\n // Row mode and the entry block: the row's other editors are outside this\n // host, and focus moving between them is not leaving the edit. Blur means\n // nothing there; the lane's buttons and the keys end the edit.\n if (isRowShaped) return;\n const next = event.relatedTarget;\n if (next instanceof Node && event.currentTarget.contains(next)) return;\n closingRef.current = true;\n if (features.editMode === \"cellConfirm\") {\n // The draft stays, dirty-marked, waiting for its ✓.\n edit.deactivate();\n return;\n }\n void edit.commit(row.id).then((ok) => {\n if (!ok) edit.deactivate();\n });\n };\n\n if (form === undefined || fieldName === null) return null;\n\n const args: TMDataGridEditorArgs = {\n field,\n form,\n cell,\n row,\n column,\n table,\n commit: () => commitAndClose(\"pick\"),\n cancel: cancelAndClose,\n size: controlSize,\n seedText,\n };\n\n const Editor =\n column.columnDef.meta?.edit?.editor ??\n BUILT_IN_EDITORS[column.columnDef.meta?.type ?? \"string\"] ??\n TMDataGridStringEditor;\n\n return (\n <div\n className={classes.cellEditor}\n data-dg-part=\"editor\"\n data-row-id={row.id}\n data-column-id={column.id}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n // The cell underneath listens for selection gestures; a click inside\n // the editor is about the editor.\n onMouseDown={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n >\n <Editor {...args} />\n {/* cellConfirm's chrome: the draft only commits through the ✓ (or\n Enter), so the pair sits right beside the input. */}\n {features.editMode === \"cellConfirm\" && (\n <div className={classes.cellEditorActions}>\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"green\"\n aria-label={labels.confirmEdit}\n data-dg-part=\"editor-confirm\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => void commitAndClose(\"pick\")}\n >\n <CheckIcon size={14} stroke={2} />\n </ActionIcon>\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"gray\"\n aria-label={labels.cancelEdit}\n data-dg-part=\"editor-cancel\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={cancelAndClose}\n >\n <CloseIcon size={14} stroke={2} />\n </ActionIcon>\n </div>\n )}\n </div>\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 */\nexport const 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 * Puts the caret inside a mounted editor host.\n *\n * `editor-input` is the part a built-in publishes for exactly this, and the\n * first focusable descendant is the fallback that makes a custom editor work\n * without publishing anything. The grid places the caret this way rather than\n * leaving it to the editor, because an editor is free not to bother - and then\n * the cell opened with the caret still outside it.\n */\nexport function focusEditorContent(editor: HTMLElement): void {\n const target =\n editor.querySelector<HTMLElement>('[data-dg-part=\"editor-input\"]') ??\n editor.querySelector<HTMLElement>(FOCUSABLE_IN_CELL);\n target?.focus();\n}\n","import {\n flexRender,\n useTable,\n type Column,\n type Row,\n} from \"@tanstack/react-table\";\nimport { useSelector } from \"@tanstack/react-store\";\nimport { useLayoutEffect, useMemo, useRef } from \"react\";\nimport classes from \"./TMDataGridTable.module.css\";\nimport sticky from \"./sticky.module.css\";\nimport { type TMDataGridRowData, useTMDataGridContext } from \"../TMDataGridContext\";\nimport {\n getColumnAlign,\n isColumnEditableForRow,\n isControlColumn,\n} from \"../core/columnUtils\";\nimport type { TMDataGridEditApi } from \"../core/editEngine\";\nimport { focusEditorContent } from \"../core/editorFocus\";\nimport {\n tmDataGridFeatures,\n type TMDataGridFeatures,\n} from \"../useTMDataGrid\";\nimport { TMDataGridCellEditor } from \"./TMDataGridCellEditor\";\nimport { EDIT_COLUMN_ID } from \"./TMDataGridEditColumn\";\nimport type { TMDataGridColumnLayout } from \"./TMDataGridTable\";\n\ntype ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;\n\n/**\n * Whether an entry cell edits. `edit.canEditCell` asks the main table for\n * the row, and an entry row is precisely not there yet - so the structural\n * half of the same rule is applied to the entry table's own row.\n */\nfunction isEntryCellEditable(\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n column: ErasedColumn,\n edit: TMDataGridEditApi,\n): boolean {\n if (!edit.isColumnEditable(column)) return false;\n return isColumnEditableForRow(column, row);\n}\n\n/**\n * The sticky entry block - one row of open editors per `edit.addRow()`,\n * pinned under the header. The one place stickiness is genuinely required:\n * an existing row that scrolls away has a place to scroll back to, a row\n * being typed into does not exist anywhere else.\n *\n * A second, tiny table instance over the new rows' seed values - same\n * columns, its own `useTable`, no sorting or filtering ever exercised - so\n * these are real `Cell`s and the editor host, the typed editors and the\n * validators all apply unchanged. The forms live in the same engine map as\n * every other draft, keyed by their temporary ids.\n *\n * Enter commits the entry - `onRowAdd`, or a park under `editing.draft`,\n * where `saveDrafts` reports it in `created`; Escape discards it. The edit\n * lane, when present, offers the same pair as buttons.\n */\nexport function TMDataGridEntryRows({\n orderedColumns,\n layoutFor,\n rowHeight,\n}: {\n orderedColumns: ReadonlyArray<ErasedColumn>;\n layoutFor: (columnId: string) => TMDataGridColumnLayout;\n rowHeight: number;\n}) {\n const { table, edit, features } = useTMDataGridContext();\n const newRows = useSelector(edit.store, (state) => state.newRows);\n // The reopen gesture: `begin` on a committed entry row flips it back to\n // editors and names the cell double-clicked - where the caret goes.\n const activeEntry = useSelector(edit.store, (state) =>\n state.active !== null &&\n state.newRows.some(\n (newRow) => newRow.tempId === state.active?.rowId && !newRow.committed,\n )\n ? state.active\n : null,\n );\n const blockRef = useRef<HTMLDivElement>(null);\n /** The entry row the caret has already been placed in. */\n const focusedTempIdRef = useRef<string | null>(null);\n /** The reopen target (`rowId:columnId`) the caret has already landed in. */\n const focusedActiveRef = useRef<string | null>(null);\n\n /**\n * The caret goes into a row the moment `edit.addRow()` opens it, landing in\n * its first editable cell - the same placement the main table makes for a\n * row opened by a gesture, and made here for the same reason: an editor is\n * free not to focus itself, and then a new row appeared with the caret\n * still outside it.\n */\n useLayoutEffect(() => {\n const newest = newRows.at(-1)?.tempId;\n if (newest === undefined) {\n focusedTempIdRef.current = null;\n return;\n }\n if (focusedTempIdRef.current === newest) return;\n const block = blockRef.current;\n if (block === null) return;\n const editor = block.querySelector<HTMLElement>(\n `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(newest)}\"]`,\n );\n // Not mounted yet; the next render tries again, as the table's does.\n if (editor === null) return;\n focusedTempIdRef.current = newest;\n focusEditorContent(editor);\n });\n\n /**\n * The caret for a reopen: `begin` on a committed row re-arms its editors\n * and the double-clicked cell's editor should hold the caret, not the\n * row's first. Keyed separately from the add effect above - the row was\n * already focused once when it was added.\n */\n useLayoutEffect(() => {\n if (activeEntry === null) {\n focusedActiveRef.current = null;\n return;\n }\n const key = `${activeEntry.rowId}:${activeEntry.columnId ?? \"\"}`;\n if (focusedActiveRef.current === key) return;\n const block = blockRef.current;\n if (block === null) return;\n const editor = block.querySelector<HTMLElement>(\n activeEntry.columnId !== null\n ? `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(activeEntry.rowId)}\"][data-column-id=\"${CSS.escape(activeEntry.columnId)}\"]`\n : `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(activeEntry.rowId)}\"]`,\n );\n // Not mounted yet; the next render tries again, as the add effect does.\n if (editor === null) return;\n focusedActiveRef.current = key;\n focusEditorContent(editor);\n });\n\n // Open (uncommitted) rows keep the seed values frozen at addRow - the live values\n // belong to the forms, which the editors read directly, and this table only\n // provides row and cell identity. A committed row's cells render values, so\n // there the draft itself is the row; the memo recomputes on every\n // commit/reopen because either flips `newRows`' identity.\n const data = useMemo(\n () =>\n newRows.map(\n ({ tempId, committed }) =>\n ((committed\n ? edit.getForm(tempId)?.state.values\n : edit.getForm(tempId)?.options.defaultValues) ??\n {}) as TMDataGridRowData,\n ),\n [newRows, edit],\n );\n\n const entryTable = useTable({\n features: tmDataGridFeatures,\n columns: table.options.columns,\n data,\n getRowId: (_row, index) => newRows[index]?.tempId ?? String(index),\n });\n\n if (newRows.length === 0) return null;\n\n const entryRows = entryTable.getCoreRowModel().rows;\n const committedById = new Map(\n newRows.map((newRow) => [newRow.tempId, newRow.committed]),\n );\n // A row being *typed* into is always sticky - it exists nowhere else to\n // scroll back to. A committed row joins the scrolling flow unless\n // `newRowsSticky` keeps it pinned, so entering many rows cannot fill the\n // viewport with sticky chrome.\n const stickyRows = entryRows.filter(\n (entryRow) =>\n features.editNewRowsSticky || committedById.get(entryRow.id) !== true,\n );\n const flowRows = features.editNewRowsSticky\n ? []\n : entryRows.filter((entryRow) => committedById.get(entryRow.id) === true);\n\n const renderEntryRow = (\n entryRow: (typeof entryRows)[number],\n pinnedZ: string,\n ) => {\n const cellsById = new Map(\n entryRow.getAllCells().map((cell) => [cell.column.id, cell]),\n );\n const committed = committedById.get(entryRow.id) === true;\n return (\n <div\n key={entryRow.id}\n role=\"row\"\n data-dg-part=\"entry-row\"\n data-row-id={entryRow.id}\n data-new\n data-committed={committed}\n // The same marker body rows carry once committed, so one selector\n // reaches everything parked in the draft store.\n data-draft={committed}\n className={classes.entryRow}\n >\n {orderedColumns.map((column) => {\n const cell = cellsById.get(column.id);\n const layout = layoutFor(column.id);\n const editable =\n cell !== undefined && isEntryCellEditable(entryRow, column, edit);\n return (\n <div\n key={column.id}\n role=\"cell\"\n data-column-id={column.id}\n data-align={getColumnAlign(column)}\n data-control-column={isControlColumn(column.id)}\n // A committed row re-opens where it is double-clicked, the\n // same gesture a body cell answers - and, like a body cell, a\n // cell that takes no edit answers nothing.\n onDoubleClick={\n committed && editable\n ? () =>\n edit.begin({\n rowId: entryRow.id,\n columnId: column.id,\n })\n : undefined\n }\n className={[\n classes.entryCell,\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: layout.pinnedAt === \"left\" ? layout.offset : undefined,\n right: layout.pinnedAt === \"right\" ? layout.offset : undefined,\n position: layout.pinnedAt ? \"sticky\" : undefined,\n zIndex: layout.pinnedAt ? pinnedZ : undefined,\n }}\n >\n {cell !== undefined && column.id === EDIT_COLUMN_ID ? (\n // The lane's cell - the entry row's controls.\n flexRender(cell.column.columnDef.cell, cell.getContext())\n ) : committed && cell !== undefined ? (\n // Entered, awaiting Save all: a value row through the\n // columns' own renderers, over the draft the memo above\n // fed this table.\n <span className={classes.cellContent}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </span>\n ) : editable && cell !== undefined ? (\n <TMDataGridCellEditor\n cell={cell}\n row={entryRow}\n takeSeedText={() => undefined}\n onClose={() => {}}\n inEntryBlock\n />\n ) : null}\n </div>\n );\n })}\n </div>\n );\n };\n\n return (\n <>\n {stickyRows.length > 0 && (\n <div\n ref={blockRef}\n role=\"rowgroup\"\n data-dg-entry-block\n className={classes.entryBlock}\n >\n {stickyRows.map((entryRow) =>\n renderEntryRow(entryRow, \"var(--dg-z-pinned-row-pinned-cell, 5)\"),\n )}\n </div>\n )}\n {flowRows.length > 0 && (\n <div\n role=\"rowgroup\"\n data-dg-entry-flow-block\n className={classes.entryFlowBlock}\n >\n {/* In flow, so a pinned cell stacks like a body row's, under the\n sticky blocks it scrolls past. */}\n {flowRows.map((entryRow) =>\n renderEntryRow(entryRow, \"var(--dg-z-pinned-cell, 2)\"),\n )}\n </div>\n )}\n </>\n );\n}\n","/**\n * What a running column resize drag paints, frame by frame.\n *\n * The grid's whole layout is one `grid-template-columns` on the grid element -\n * every row follows it through `subgrid` - so a drag only has to rewrite that\n * one string. Rendering the drag through React state instead costs a pass over\n * every mounted cell per pointer move, which is what makes a resize feel heavy\n * on a wide grid.\n *\n * This module computes the frame; `TMDataGridTable` writes it to the DOM and\n * TanStack commits the width into `columnSizing` when the pointer is released.\n */\n\n/** One entry of the grid's track list, paired with the column it sizes. */\nexport type TMDataGridColumnTrack = {\n id: string;\n /** The `grid-template-columns` entry - `120px` or `minmax(120px, 1fr)`. */\n track: string;\n /** The exact width where the track is exact, the floor where it is fluid. */\n minWidth: number;\n};\n\n/** TanStack's transient `columnResizing` state, narrowed to what a frame reads. */\nexport type TMDataGridResizeProgress = {\n isResizingColumn: string | false;\n columnSizingStart: Array<[string, number]>;\n deltaPercentage: number | null;\n};\n\n/** A column's declared bounds, as `column_getSize` reads them. */\nexport type TMDataGridSizeBounds = { minSize?: number; maxSize?: number };\n\n/** A sticky offset the drag has moved. */\nexport type TMDataGridOffsetPatch = {\n columnId: string;\n side: \"left\" | \"right\";\n offset: number;\n};\n\nexport type TMDataGridResizePreview = {\n gridTemplateColumns: string;\n minWidth: number;\n offsets: Array<TMDataGridOffsetPatch>;\n};\n\n/**\n * TanStack's own defaults, from `getDefaultColumnSizingColumnDef()`. Not\n * exported by the package, and the preview has to clamp exactly the way\n * `column_getSize` will once the width is committed - a preview that rounds\n * differently makes the column settle by a pixel when the pointer is released.\n */\nconst DEFAULT_MIN_SIZE = 20;\nconst DEFAULT_MAX_SIZE = Number.MAX_SAFE_INTEGER;\n\n/** The width `columnSizing` would hold if the drag ended on this delta. */\nfunction draggedWidth(\n startWidth: number,\n deltaPercentage: number,\n bounds: TMDataGridSizeBounds,\n): number {\n // Two decimals and the `max(…, 0)` are what `header_getResizeHandler`\n // commits; the clamp around it is what `column_getSize` applies on read.\n const dragged =\n Math.round(Math.max(startWidth + startWidth * deltaPercentage, 0) * 100) /\n 100;\n return Math.min(\n Math.max(bounds.minSize ?? DEFAULT_MIN_SIZE, dragged),\n bounds.maxSize ?? DEFAULT_MAX_SIZE,\n );\n}\n\nfunction* laneOffsets(\n lane: Array<string>,\n side: \"left\" | \"right\",\n widthOf: (columnId: string) => number,\n): Generator<TMDataGridOffsetPatch> {\n let offset = 0;\n for (const columnId of lane) {\n yield { columnId, side, offset };\n offset += widthOf(columnId);\n }\n}\n\n/**\n * The frame to paint for the drag in `progress`, or `null` when no drag is\n * running - which is also the answer for the first publish of a gesture, made\n * before the pointer has moved at all.\n *\n * `leftLane` and `rightLane` are the pinned lanes in the order the grid stacks\n * them: left to right, and outermost last on the right. Their offsets come\n * back only when the drag is resizing a pinned column, since nothing else\n * moves them.\n */\nexport function resizePreview({\n progress,\n tracks,\n boundsOf,\n leftLane,\n rightLane,\n}: {\n progress: TMDataGridResizeProgress;\n tracks: Array<TMDataGridColumnTrack>;\n boundsOf: (columnId: string) => TMDataGridSizeBounds;\n leftLane: Array<string>;\n rightLane: Array<string>;\n}): TMDataGridResizePreview | null {\n if (progress.isResizingColumn === false) return null;\n if (progress.columnSizingStart.length === 0) return null;\n\n const deltaPercentage = progress.deltaPercentage ?? 0;\n const widths = new Map<string, number>();\n for (const [columnId, startWidth] of progress.columnSizingStart) {\n widths.set(\n columnId,\n draggedWidth(startWidth, deltaPercentage, boundsOf(columnId)),\n );\n }\n\n const template: Array<string> = [];\n let minWidth = 0;\n for (const track of tracks) {\n const width = widths.get(track.id);\n template.push(width === undefined ? track.track : `${width}px`);\n minWidth += width ?? track.minWidth;\n }\n\n const inLane = (lane: Array<string>) => lane.some((id) => widths.has(id));\n const widthOf = (columnId: string) =>\n widths.get(columnId) ??\n tracks.find((track) => track.id === columnId)?.minWidth ??\n 0;\n\n return {\n gridTemplateColumns: template.join(\" \"),\n minWidth,\n offsets: [\n ...(inLane(leftLane) ? laneOffsets(leftLane, \"left\", widthOf) : []),\n ...(inLane(rightLane) ? laneOffsets(rightLane, \"right\", widthOf) : []),\n ],\n };\n}\n","import type { Cell, CellContext, Row } from \"@tanstack/react-table\";\nimport type { TMDataGridRowData } from \"../TMDataGridContext\";\nimport type { TMDataGridFeatures } from \"../useTMDataGrid\";\n\ntype ErasedCell = Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\ntype ErasedRow = Row<TMDataGridFeatures, TMDataGridRowData>;\ntype ErasedCellContext = CellContext<\n TMDataGridFeatures,\n TMDataGridRowData,\n unknown\n>;\n\n/**\n * The row internals the draft wrapper overrides. Private to table-core, but\n * load-bearing for it: `row.getValue` reads `_valuesCache` before running\n * `column.accessorFn(row.original, row.index)`, so owning fresh caches and a\n * draft `original` is what makes every accessor - key, function, dot path -\n * re-derive from the draft. Pinned by draftCellContext.test.ts, which is the\n * tripwire for a beta bump moving these.\n */\ntype RowInternals = {\n original: TMDataGridRowData;\n _valuesCache: Record<string, unknown>;\n _uniqueValuesCache: Record<string, unknown>;\n};\n\n/**\n * A cell render context whose values come from a row's edit draft instead of\n * `data` - how a parked draft is shown through the column's own `cell`\n * renderer.\n *\n * v9 constructs rows and cells as `Object.create(prototype)` instances whose\n * API methods dispatch on `this`, so a wrapper inheriting the real object but\n * owning `original` and empty value caches serves draft values from the same\n * code paths the real row uses. The context is hand-built rather than taken\n * from the wrapper's `getContext()`, which is memoized per instance and would\n * be inherited from the real cell.\n *\n * Limitation, accepted: instance-memoized traversals (`row.getAllCells()` and\n * friends) are inherited already-bound to the real row, so a renderer walking\n * `ctx.row` beyond `original` / `getValue()` / `renderValue()` sees committed\n * values. The documented renderer surface sees the draft.\n */\nexport function draftCellContext(\n cell: ErasedCell,\n draftValues: TMDataGridRowData,\n): ErasedCellContext {\n const draftRow = Object.create(cell.row) as ErasedRow;\n const internals = draftRow as unknown as RowInternals;\n internals.original = draftValues;\n internals._valuesCache = Object.create(null) as Record<string, unknown>;\n internals._uniqueValuesCache = Object.create(null) as Record<string, unknown>;\n\n const draftCell = Object.create(cell) as ErasedCell;\n (draftCell as { row: ErasedRow }).row = draftRow;\n\n return {\n table: cell.table,\n column: cell.column,\n row: draftRow,\n cell: draftCell,\n getValue: () => draftRow.getValue(cell.column.id),\n renderValue: () =>\n draftRow.getValue(cell.column.id) ??\n cell.table.options.renderFallbackValue ??\n null,\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 * There is then no rectangle, rather than a guessed replacement corner that\n * would copy cells the user never selected. The range itself is left alone:\n * clearing it here would discard a selection that returns as soon as the filter\n * is cleared.\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 lies 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, because a literal BOM is\n * invisible in a source file and easily deleted by accident.\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. This\n * export targets Excel, so opening correctly there takes priority over strict\n * CSV.\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 the caller can act on.\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 type { Row, RowData } from \"@tanstack/react-table\";\nimport type { TMDataGridFeatures, TMDataGridTable } from \"../useTMDataGrid\";\n\n/**\n * The rows pinned to one edge, resolved safely and in pin order.\n *\n * Not TanStack's `getTopRows()`: that resolves each pinned id with\n * `getRow(id, true)`, which throws once the row's data is gone - and pinned\n * ids outlive data. A delete, a server-side page swap, a refetch that comes\n * back without the row: any of these would take the whole grid down. Here a\n * stale id is skipped instead; it stays in state, harmless, and the row\n * returns to its edge if its data comes back.\n *\n * The semantics are TanStack's `keepPinnedRows: true`: a pinned row stays at\n * its edge even when a filter or the pager would have dropped it from the\n * body. Ids resolve against the pre-pagination model first - those rows carry\n * the live sort and filter context - with the core model as the fallback for\n * rows the filters removed. A leaf whose group is collapsed stays hidden,\n * as upstream does.\n */\nexport function readPinnedRows<TData extends RowData>(\n table: TMDataGridTable<TData>,\n position: \"top\" | \"bottom\",\n): Array<Row<TMDataGridFeatures, TData>> {\n const ids = table.store.state.rowPinning[position];\n if (ids.length === 0) return [];\n const visible = table.getPrePaginatedRowModel().rowsById;\n const all = table.getCoreRowModel().rowsById;\n const rows: Array<Row<TMDataGridFeatures, TData>> = [];\n for (const id of ids) {\n const row = visible[id] ?? all[id];\n if (row === undefined) continue;\n if (!row.getIsAllParentsExpanded()) continue;\n rows.push(row);\n }\n return rows;\n}\n","import type { RowData } from \"@tanstack/react-table\";\nimport {\n isTMDataGridFilterValue,\n type TMDataGridFilterOperator,\n} from \"./filterOperators\";\nimport type { TMDataGridTable } from \"../useTMDataGrid\";\n\n/** A matched slice of a cell's text, `start` inclusive to `end` exclusive. */\nexport type TMDataGridMatchRange = { start: number; end: number };\n\n/**\n * The operators whose match is a contiguous substring - the ones highlighting\n * can point at. Equality highlights nothing: marking the whole cell says\n * nothing the filter did not already say.\n */\nconst HIGHLIGHTABLE_OPERATORS: ReadonlyArray<TMDataGridFilterOperator> = [\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n];\n\n/**\n * Every needle that could highlight in a given column, keyed by column id -\n * the quick search for the columns it searches, plus any contains-family\n * column filter. `null` while nothing highlightable is active, which is the\n * common case and the cheap one.\n *\n * The fuzzy quick search still contributes its raw text: when the needle occurs\n * contiguously it is highlighted, and a typo-match with no contiguous\n * occurrence is not highlighted at all.\n */\nexport function buildMatchNeedles<TData extends RowData>(\n table: TMDataGridTable<TData>,\n): Map<string, ReadonlyArray<string>> | null {\n const state = table.store.state;\n const global =\n typeof state.globalFilter === \"string\" ? state.globalFilter.trim() : \"\";\n\n const byColumn = new Map<string, Array<string>>();\n for (const filter of state.columnFilters) {\n if (!isTMDataGridFilterValue(filter.value)) continue;\n const { operator, value } = filter.value;\n if (!HIGHLIGHTABLE_OPERATORS.includes(operator)) continue;\n if (typeof value !== \"string\" || value === \"\") continue;\n const needles = byColumn.get(filter.id) ?? [];\n needles.push(value);\n byColumn.set(filter.id, needles);\n }\n\n if (global === \"\" && byColumn.size === 0) return null;\n\n const map = new Map<string, ReadonlyArray<string>>();\n for (const column of table.getAllLeafColumns()) {\n const needles: Array<string> = [];\n if (global !== \"\" && column.getCanGlobalFilter()) needles.push(global);\n const own = byColumn.get(column.id);\n if (own !== undefined) needles.push(...own);\n if (needles.length > 0) map.set(column.id, needles);\n }\n return map.size > 0 ? map : null;\n}\n\n/**\n * Where the needles occur in the text, case-insensitively, merged where they\n * overlap or touch - so two needles covering \"St\" and \"tock\" come back as one\n * range rather than nested marks. `null` when nothing matches.\n */\nexport function findMatchRanges(\n text: string,\n needles: ReadonlyArray<string>,\n): Array<TMDataGridMatchRange> | null {\n const haystack = text.toLowerCase();\n const found: Array<TMDataGridMatchRange> = [];\n for (const needle of needles) {\n const lowered = needle.toLowerCase();\n if (lowered === \"\") continue;\n let index = haystack.indexOf(lowered);\n while (index !== -1) {\n found.push({ start: index, end: index + lowered.length });\n index = haystack.indexOf(lowered, index + 1);\n }\n }\n if (found.length === 0) return null;\n\n found.sort((a, b) => a.start - b.start || a.end - b.end);\n const merged: Array<TMDataGridMatchRange> = [];\n for (const range of found) {\n const last = merged.at(-1);\n if (last !== undefined && range.start <= last.end) {\n last.end = Math.max(last.end, range.end);\n } else {\n merged.push({ ...range });\n }\n }\n return merged;\n}\n","import { Checkbox, Loader, Menu, type MenuProps, Text } from \"@mantine/core\";\nimport {\n type Cell,\n type Column,\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 CSSProperties,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type UIEvent,\n useCallback,\n useEffect,\n useLayoutEffect,\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 {\n TMDataGridHeaderCell,\n type TMDataGridColumnMenuItemsRenderer,\n} from \"./TMDataGridHeaderCell\";\nimport {\n TMDataGridCellEditor,\n type TMDataGridCellEditorClose,\n} from \"./TMDataGridCellEditor\";\nimport { TMDataGridEntryRows } from \"./TMDataGridEntryRows\";\nimport { getColumnAlign, isControlColumn } from \"../core/columnUtils\";\nimport {\n resizePreview,\n type TMDataGridColumnTrack,\n} from \"../core/resizePreview\";\nimport { useSettledTableState } from \"../core/useSettledTableState\";\nimport { draftCellContext } from \"../core/draftCellContext\";\nimport {\n getEditFieldName,\n type TMDataGridEditState,\n} from \"../core/editEngine\";\nimport {\n getNextEditableCell,\n resolveCellMove,\n type TMDataGridCellPosition,\n} from \"../core/cellNavigation\";\nimport { FOCUSABLE_IN_CELL, focusEditorContent } from \"../core/editorFocus\";\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, hasMountedCells } from \"../core/autosize\";\nimport {\n getDisplayedRows,\n getSelectableRowIds,\n isPagingActive,\n resolveRowSelectionClick,\n} from \"../core/rowSelection\";\nimport { readPinnedRows } from \"../core/rowPinning\";\nimport { buildMatchNeedles, findMatchRanges } from \"../core/matchHighlight\";\nimport { ROW_NUMBER_COLUMN_ID } from \"./TMDataGridRowNumberColumn\";\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 * 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\n/**\n * The text with its matched slices wrapped in `<mark>` - or handed back\n * whole when nothing matches. Only ever called on string output; a renderer\n * returning its own elements never reaches this.\n */\nfunction withMatchHighlights(\n text: string,\n needles: ReadonlyArray<string>,\n): ReactNode {\n const ranges = findMatchRanges(text, needles);\n if (ranges === null) return text;\n const parts: Array<ReactNode> = [];\n let cursor = 0;\n for (const range of ranges) {\n if (range.start > cursor) parts.push(text.slice(cursor, range.start));\n parts.push(\n <mark key={range.start} className={classes.matchHighlight}>\n {text.slice(range.start, range.end)}\n </mark>,\n );\n cursor = range.end;\n }\n if (cursor < text.length) parts.push(text.slice(cursor));\n return parts;\n}\n\nfunction TMDataGridBodyCell({\n cell,\n rowHeight,\n layout,\n nav,\n editor,\n contentOverride,\n highlightNeedles,\n onFocus,\n onClick,\n onMouseDown,\n onMouseEnter,\n onDoubleClick,\n onContextMenu,\n}: {\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>;\n rowHeight: number;\n layout: TMDataGridColumnLayout;\n nav?: TMDataGridCellNav;\n /** The mounted editor, when this is the cell being edited. */\n editor?: ReactNode;\n /**\n * Replaces the column renderer's output - the row-number gutter, whose\n * value only the body knows. `undefined` means \"render normally\".\n */\n contentOverride?: ReactNode;\n /**\n * Needles to highlight in string output - see `enableMatchHighlighting`.\n * `undefined` almost always: only set while a highlightable filter is\n * active for this column.\n */\n highlightNeedles?: ReadonlyArray<string>;\n onFocus?: () => void;\n onClick?: (event: MouseEvent<HTMLDivElement>) => void;\n onMouseDown?: (event: MouseEvent<HTMLDivElement>) => void;\n onMouseEnter?: () => void;\n onDoubleClick?: (event: MouseEvent<HTMLDivElement>) => void;\n onContextMenu?: (event: MouseEvent<HTMLDivElement>) => void;\n}) {\n // The edit markers subscribe here, per cell, all to the one projection\n // store - so typing in an editor repaints the edited row's cells and\n // nothing else. Constant `false` everywhere while editing is off.\n const { table, edit } = useTMDataGridContext();\n const fieldName = getEditFieldName(cell.column);\n const cellRowId = cell.row.id;\n const isControl = isControlColumn(cell.column.id);\n const isDirty = useSelector(edit.store, (state) => {\n if (fieldName === null) return false;\n const projection = state.rows[cellRowId];\n return projection !== undefined && projection.dirtyFields.includes(fieldName);\n });\n const isInvalid = useSelector(edit.store, (state) => {\n if (fieldName === null) return false;\n const projection = state.rows[cellRowId];\n return projection !== undefined && projection.errorFields.includes(fieldName);\n });\n // The whole draft, not one field: a computed or custom renderer may read any\n // field off the row, so every data cell of a drafted row repaints together\n // when its draft moves - and only then, `values` being reference-stable\n // across meta-only form events. `undefined` everywhere else.\n const draftValues = useSelector(edit.store, (state) =>\n isControl ? undefined : state.rows[cellRowId]?.values,\n );\n return (\n <div\n // `gridcell` rather than `cell` is what tells a screen reader the arrow\n // keys move a cursor here, so it is set together with the tab stop rather\n // 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 // Both coordinates are always present, not only under cell selection:\n // autosize finds a column's mounted cells by the column id, and the pair\n // is how a test addresses one cell -\n // `[data-row-id=\"42\"][data-column-id=\"name\"]`. The cell-navigation\n // selectors also require `data-cell`, so they are unaffected.\n data-row-id={cell.row.id}\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 onClick={onClick}\n onMouseDown={onMouseDown}\n onMouseEnter={onMouseEnter}\n onDoubleClick={onDoubleClick}\n data-editing={editor !== undefined || undefined}\n data-dirty={isDirty || undefined}\n data-invalid={isInvalid || undefined}\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={isControl}\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 {editor ?? (\n <span className={classes.cellContent}>\n {(() => {\n // A row with a live form shows its draft, not `data`: the column's\n // own renderer over a context reading the form's values. The\n // drafts that outlive their editor - parked ones, cellConfirm's\n // kept ones - are the point; group cells are excluded because no\n // group row ever has a form.\n const draftContext =\n draftValues !== undefined &&\n contentOverride === undefined &&\n !cell.getIsPlaceholder() &&\n !cell.getIsAggregated()\n ? draftCellContext(cell, draftValues)\n : undefined;\n // Highlighting reproduces the *default* renderer, value then\n // `toString`, with the matched parts marked. A column with its own\n // `cell` is excluded: its renderer is not the default one, and the\n // grid does not modify a custom renderer's output.\n if (\n highlightNeedles !== undefined &&\n contentOverride === undefined &&\n !cell.getIsPlaceholder() &&\n !cell.getIsAggregated() &&\n cell.column.columnDef.cell === table.getDefaultColumnDef().cell\n ) {\n const value =\n draftContext !== undefined\n ? draftContext.renderValue()\n : cell.renderValue();\n if (typeof value === \"string\" || typeof value === \"number\") {\n return withMatchHighlights(String(value), highlightNeedles);\n }\n }\n if (draftContext !== undefined) {\n return flexRender(cell.column.columnDef.cell, draftContext);\n }\n return contentOverride ?? renderCellContent(cell);\n })()}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * The virtualized body rows, wrapped in the single Menu that serves all of them\n * when `renderRowContextMenu` 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 `renderRowContextMenu` 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 * The grid's own items for this menu: the cell copy and export items, under\n * `cellSelection: \"range\"`, and `null` otherwise.\n *\n * Placing it decides the order. Ignore it and the grid keeps today's\n * behavior, rendering its items above a divider and yours below.\n */\n internalItems: ReactNode;\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 TMDataGridRowContextMenuRenderer<TData extends RowData> = (\n args: TMDataGridRowContextMenuArgs<TData>,\n) => ReactNode;\n\n/**\n * What the `onCellClick` family receives - the cell with its row and column,\n * in the consumer's own row type, plus the pointer event.\n */\nexport type TMDataGridCellEventArgs<TData extends RowData> = {\n cell: Cell<TMDataGridFeatures, TData, unknown>;\n row: Row<TMDataGridFeatures, TData>;\n column: Column<TMDataGridFeatures, TData, unknown>;\n event: MouseEvent<HTMLElement>;\n};\n\n/**\n * Inline styles for a row. Widened to accept CSS variables, because setting\n * `--row-bg` is the supported way to colour a row - see {@link\n * TMDataGridTableProps.rowStyle}.\n */\nexport type TMDataGridRowStyle =\n | CSSProperties\n | (CSSProperties & Record<`--${string}`, string | number>);\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 * Called when a body cell is clicked. Composes, never suppresses: whatever\n * the click already does - selecting, highlighting, moving the cell cursor\n * - still happens. Group rows sit out the cell handlers the way they sit\n * out `onRowClick`, and for the same reason.\n */\n onCellClick?: (args: TMDataGridCellEventArgs<TData>) => void;\n /** As {@link onCellClick}; a double-click that opens an editor still does. */\n onCellDoubleClick?: (args: TMDataGridCellEventArgs<TData>) => void;\n /**\n * As {@link onCellClick}; `renderRowContextMenu` and the cell-selection menu still\n * open. To suppress the browser's own menu on a grid with neither, call\n * `event.preventDefault()` here.\n */\n onCellContextMenu?: (args: TMDataGridCellEventArgs<TData>) => void;\n /**\n * Class for a body row - a string, or a function of the row (group rows\n * included; test `row.getIsGrouped()` to skip them). Added after the grid's\n * own row class.\n */\n rowClassName?:\n | string\n | ((row: Row<TMDataGridFeatures, TData>) => string | undefined);\n /**\n * Inline style for a body row. To colour a row, set `--row-bg` rather than\n * `background`: the row's own background, its sticky pinned cells and the\n * cell-range tint all read that variable, and hover/selection/highlight\n * keep working on top of it - a raw `background` bypasses all of them.\n *\n * ```tsx\n * rowStyle={(row) =>\n * row.original.overdue ? { \"--row-bg\": \"var(--mantine-color-red-0)\" } : undefined\n * }\n * ```\n */\n rowStyle?:\n | TMDataGridRowStyle\n | ((row: Row<TMDataGridFeatures, TData>) => TMDataGridRowStyle | undefined);\n /**\n * Every second row takes `--dg-row-striped-bg`. Computed from the row's\n * position in the view - sorting and filtering restripe, and the stripes\n * stay put while the virtualizer mounts and unmounts rows.\n */\n striped?: boolean;\n /**\n * Called when the scroll *arrives* at an edge - once per arrival, not per\n * scroll event, and not on mount (the grid starts at the top-left edge).\n * For loading more rows as the end approaches, `onReachEnd` is the better\n * hook: it fires rows-early and latches per row count.\n */\n onScrollToTop?: () => void;\n /** As {@link onScrollToTop}, for the bottom edge. */\n onScrollToBottom?: () => void;\n /** As {@link onScrollToTop}, for the left edge. */\n onScrollToLeft?: () => void;\n /** As {@link onScrollToTop}, for the right edge. */\n onScrollToRight?: () => void;\n /**\n * Rendered centred in the body when the view is empty - the branded blank\n * slate. It takes over states 3 and 4 of the empty matrix (see the docs):\n * loading still shows the loader, and open entry rows still show only\n * themselves. `hasActiveFilters` says which emptiness this is - a filter\n * that matched nothing wants a \"clear filters\" invitation, a grid with no\n * data wants a \"create the first one\".\n */\n renderEmptyState?: (args: {\n hasActiveFilters: boolean;\n table: Table<TMDataGridFeatures, TData>;\n }) => ReactNode;\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 * renderRowContextMenu={({ 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 * `internalItems` is the grid's own half - place it to control the order,\n * ignore it and the grid keeps its items above a divider and yours below.\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 renderRowContextMenu?: TMDataGridRowContextMenuRenderer<TData>;\n /**\n * Replaces a column menu's contents, taking the grid's own items and\n * returning the full list.\n *\n * ```tsx\n * <TMDataGrid.Table\n * renderColumnMenuItems={({ column, internalItems }) => [\n * ...internalItems,\n * <Menu.Divider key=\"custom\" />,\n * <Menu.Item key=\"stats\" onClick={() => showStats(column.id)}>\n * Statistics\n * </Menu.Item>,\n * ]}\n * />\n * ```\n *\n * Returning an empty list leaves the column with no menu button, the same as\n * a column whose every feature is switched off.\n */\n renderColumnMenuItems?: TMDataGridColumnMenuItemsRenderer;\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 * Accessible name for the grid: what a screen reader announces on entry, and\n * what `getByRole(\"grid\", { name })` matches. Set it on any page holding more\n * than one grid; without it they are all announced as \"grid\".\n */\n \"aria-label\"?: string;\n /** As {@link \"aria-label\"}, pointing at an element that already names it. */\n \"aria-labelledby\"?: string;\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 work at any row count. Pagination is opt in through\n * `enablePagination`, or implied by `manualPagination`.\n */\nexport function TMDataGridTable<TData extends RowData = TMDataGridRowData>({\n onRowClick,\n onCellClick,\n onCellDoubleClick,\n onCellContextMenu,\n rowClassName,\n rowStyle,\n striped = false,\n onScrollToTop,\n onScrollToBottom,\n onScrollToLeft,\n onScrollToRight,\n renderEmptyState,\n renderRowContextMenu,\n renderColumnMenuItems,\n rowContextMenuProps,\n cellExport,\n onReachEnd,\n reachEndThreshold = 10,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n}: TMDataGridTableProps<TData>) {\n const {\n table,\n ui,\n edit,\n features,\n labels,\n rowHeight,\n controlSize,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n scrollerRef,\n } = useTMDataGridContext();\n\n // The body depends on every settled state slice (sorting, filters, paging,\n // sizing, visibility, selection). Not on the transient resize deltas: those\n // publish on every pointer move and the drag paints itself, see below.\n useSettledTableState(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 // Which cell has an editor open. The projection (dirty/error markers) is\n // subscribed per cell instead - see TMDataGridBodyCell.\n const editActive = useSelector(edit.store, (state) => state.active);\n // Row mode opens whole rows and any number of them at once, so which rows\n // are showing editors is the set of open forms, not the single active slot.\n const editOpenRowIds = useSelector(edit.store, (state) => state.openRowIds);\n const newRowCount = useSelector(edit.store, (state) => state.newRows.length);\n const deletedRowIds = useSelector(edit.store, (state) => state.deletedRowIds);\n // Rows carrying a dirty draft, for the row-level marker. Derived from the\n // same projections the cells subscribe to; the array's identity churns with\n // `openRowIds`' own per-publish churn, so this adds no new render class.\n const editDirtyRowIds = useSelector(edit.store, (state) =>\n state.openRowIds.filter(\n (id) => (state.rows[id]?.dirtyFields.length ?? 0) > 0,\n ),\n );\n // Rows parked in the draft store, waiting for Save. A separate marker from\n // `data-dirty`, which covers any row being typed into: after a partial save\n // these are what is left, so one selector highlights everything still\n // pending.\n const editDraftRowIds = useSelector(\n edit.store,\n (state) => state.committedRowIds,\n );\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 // Per-column highlight needles, or `null` while off or nothing is active -\n // the common case, costing one flag check per render.\n const matchNeedles = features.matchHighlighting\n ? buildMatchNeedles(table)\n : null;\n\n // The edge blocks. `getDisplayedRows` above has already taken these out of\n // the scrolling order; stale ids resolve to nothing - see readPinnedRows.\n const pinnedTopRows = features.rowPinning ? readPinnedRows(table, \"top\") : [];\n const pinnedBottomRows = features.rowPinning\n ? readPinnedRows(table, \"bottom\")\n : [];\n const pinnedRowCount = pinnedTopRows.length + pinnedBottomRows.length;\n\n // The row-number gutter's numbers: one pass over the view per render, only\n // while the lane exists. A cell cannot know its display position, so the\n // body hands each row its number - group rows get none (they are headings\n // over the rows being counted), and paging continues the count across\n // pages rather than restarting every page at 1.\n let rowNumberById: Map<string, number> | null = null;\n if (features.rowNumbers) {\n rowNumberById = new Map();\n let n = isPagingActive(table, features)\n ? table.store.state.pagination.pageIndex *\n table.store.state.pagination.pageSize\n : 0;\n for (const viewRow of rows) {\n if (!viewRow.getIsGrouped()) rowNumberById.set(viewRow.id, ++n);\n }\n }\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 each after the first rows are in the\n * DOM.\n *\n * The wait is required. The virtualizer measures its scroll element in an\n * effect and mounts its first rows in the render that follows, so on the\n * mounting commit this column has a header and no cells, and autosize would\n * fit the header alone and keep that width for the rest of the session. The\n * ids are therefore held in a set, and each one is dropped only once it has\n * been measured against mounted content.\n *\n * A ref rather than an effect dependency: a column is sized once per mount,\n * and only while no persisted or user width covers it - autosizing again on a\n * data change would fight a width the user has since dragged. Built from\n * every leaf column rather than the visible ones, so a column hidden at mount\n * is still sized when it is shown.\n */\n const pendingAutoSizeRef = useRef<Set<string> | null>(null);\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (container === null) return;\n pendingAutoSizeRef.current ??= new Set(\n table\n .getAllLeafColumns()\n .filter((column) => column.columnDef.meta?.autoSize === true)\n .map((column) => column.id),\n );\n const pending = pendingAutoSizeRef.current;\n if (pending.size === 0) return;\n\n for (const columnId of [...pending]) {\n if (columnId in table.store.state.columnSizing) {\n pending.delete(columnId);\n continue;\n }\n if (!hasMountedCells(container, columnId)) continue;\n autosizeColumn({ table, columnId, container });\n pending.delete(columnId);\n }\n });\n\n /**\n * The header's height, published as `--dg-header-height` for the entry\n * block to stick under - never measured otherwise (`top: 0` needs no\n * number). A ResizeObserver, mounted only while the block is in use: the\n * same discipline `renderDetails` applies to `measureElement`.\n */\n const gridElementRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (newRowCount === 0 && pinnedTopRows.length === 0) return;\n const grid = gridElementRef.current;\n if (grid === null) return;\n const headerRows = grid.querySelectorAll<HTMLElement>(\n \"[data-dg-header-row]\",\n );\n const measure = () => {\n let total = 0;\n for (const headerRow of headerRows) total += headerRow.offsetHeight;\n grid.style.setProperty(\"--dg-header-height\", `${total}px`);\n };\n measure();\n const observer = new ResizeObserver(measure);\n for (const headerRow of headerRows) observer.observe(headerRow);\n return () => observer.disconnect();\n }, [newRowCount, pinnedTopRows.length]);\n\n /**\n * The entry block's height, published as `--dg-entry-height` so the pinned\n * top block can stack under it - measured only while both blocks exist,\n * which is the only time the offset is anything but 0.\n */\n useEffect(() => {\n if (newRowCount === 0 || pinnedTopRows.length === 0) return;\n const grid = gridElementRef.current;\n if (grid === null) return;\n const entryBlock = grid.querySelector<HTMLElement>(\"[data-dg-entry-block]\");\n if (entryBlock === null) return;\n const measure = () =>\n grid.style.setProperty(\"--dg-entry-height\", `${entryBlock.offsetHeight}px`);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(entryBlock);\n return () => {\n observer.disconnect();\n grid.style.removeProperty(\"--dg-entry-height\");\n };\n }, [newRowCount, pinnedTopRows.length]);\n\n /**\n * The summary row's height, published as `--dg-summary-height` so the\n * pinned bottom block sticks above it rather than underneath it.\n */\n useEffect(() => {\n if (pinnedBottomRows.length === 0) return;\n const grid = gridElementRef.current;\n if (grid === null) return;\n const summaryRow = grid.querySelector<HTMLElement>(\n '[data-dg-part=\"summary-row\"]',\n );\n if (summaryRow === null) return;\n const measure = () =>\n grid.style.setProperty(\n \"--dg-summary-height\",\n `${summaryRow.offsetHeight}px`,\n );\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(summaryRow);\n return () => {\n observer.disconnect();\n grid.style.removeProperty(\"--dg-summary-height\");\n };\n }, [pinnedBottomRows.length]);\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 /**\n * A live `size` (or `meta.rowHeight`) change moves what `estimateSize`\n * answers, but the virtualizer's measurement cache does not list that option\n * among its dependencies - by its own docs, changing the estimate means\n * calling `measure()`. Without this the spacers keep the old height until\n * something else invalidates the cache, so the scroll range and the window\n * disagree with the rows actually painted.\n */\n const prevRowHeightRef = useRef(rowHeight);\n useEffect(() => {\n if (prevRowHeightRef.current === rowHeight) return;\n prevRowHeightRef.current = rowHeight;\n virtualizer.measure();\n }, [rowHeight, virtualizer]);\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 * `api.scrollToRow`, implemented where the virtualizer is.\n *\n * Registered in an effect rather than during render, and with no dependency\n * array so it re-registers on every one: the closure has to see this render's\n * `rows`, which sorting, filtering and paging all change. A grid whose Table\n * has unmounted leaves the hook's default behind, which answers `false`.\n */\n useEffect(() => {\n scrollerRef.current = ({ rowId, align = \"auto\" }) => {\n // Already parked at an edge, and outside the scrolling order - see\n // `getDisplayedRows`. Nothing to scroll, but the row *is* on screen, so\n // reporting failure would be the wrong answer.\n if (\n pinnedTopRows.some((row) => row.id === rowId) ||\n pinnedBottomRows.some((row) => row.id === rowId)\n ) {\n return true;\n }\n const index = rows.findIndex((row) => row.id === rowId);\n if (index < 0) return false;\n virtualizer.scrollToIndex(index, { align });\n return true;\n };\n return () => {\n scrollerRef.current = () => false;\n };\n });\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: Array<TMDataGridColumnTrack> = orderedColumns.map(\n (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 {\n id: column.id,\n track: `${column.getSize()}px`,\n minWidth: column.getSize(),\n };\n }\n return {\n id: column.id,\n track: `minmax(${minWidth}px, ${column.columnDef.meta?.flex ?? 1}fr)`,\n minWidth,\n };\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 /**\n * A running resize drag paints itself, straight onto the grid element.\n *\n * Every row sits on the grid's own column tracks through `subgrid`, so the\n * whole drag is one style write per frame. Letting the drag render instead -\n * `columnResizeMode: \"onChange\"`, which publishes a width on every pointer\n * move - costs a React pass over every mounted cell for each of those moves,\n * and the gesture turns choppy on a grid wide enough to be worth resizing.\n *\n * TanStack still owns the gesture and still commits the width into\n * `columnSizing` when the pointer is released; the render that follows lands\n * on the same numbers the last frame painted.\n */\n const previewRef = useRef<{\n tracks: Array<TMDataGridColumnTrack>;\n leftLane: Array<string>;\n rightLane: Array<string>;\n }>({ tracks: columnTracks, leftLane: [], rightLane: [] });\n useEffect(() => {\n previewRef.current = {\n tracks: columnTracks,\n leftLane: leftLeafColumns.map((column) => column.id),\n // Outermost last, the order the offsets above accumulate in.\n rightLane: [...rightLeafColumns].reverse().map((column) => column.id),\n };\n });\n useEffect(() => {\n const element = gridElementRef.current;\n if (!element) return;\n\n // Painted straight from the store's publish rather than on a frame of its\n // own: the browser already coalesces pointer moves to one per frame, and a\n // `requestAnimationFrame` stops firing altogether while the window is\n // occluded - which would leave the drag frozen under the pointer.\n let painted = \"\";\n const subscription = table.store.subscribe((state) => {\n const preview = resizePreview({\n progress: state.columnResizing,\n boundsOf: (columnId) => table.getColumn(columnId)?.columnDef ?? {},\n ...previewRef.current,\n });\n if (!preview || preview.gridTemplateColumns === painted) return;\n painted = preview.gridTemplateColumns;\n element.style.gridTemplateColumns = preview.gridTemplateColumns;\n element.style.minWidth = `${preview.minWidth}px`;\n // Only the pinned lanes, and only while the drag is resizing one of\n // them: their sticky offsets are the one measurement that does not\n // follow from the track list alone.\n for (const { columnId, side, offset } of preview.offsets) {\n for (const cell of element.querySelectorAll<HTMLElement>(\n `[data-column-id=\"${CSS.escape(columnId)}\"]`,\n )) {\n cell.style[side] = `${offset}px`;\n }\n }\n });\n return () => subscription.unsubscribe();\n }, [table]);\n\n // Pinned rows count as content: with every visible row pinned to an edge,\n // an empty-state message beside them would contradict what is on screen.\n const isEmpty = rows.length === 0 && pinnedRowCount === 0;\n // Which emptiness this is. The body already subscribes to the whole table\n // store, so these reads are reactive.\n const emptyGlobalFilter = table.store.state.globalFilter;\n const hasActiveFilters =\n table.store.state.columnFilters.length > 0 ||\n (typeof emptyGlobalFilter === \"string\"\n ? emptyGlobalFilter.trim() !== \"\"\n : emptyGlobalFilter != null);\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 // The value-or-function pair resolved per row, across the same erasure\n // crossing `onRowClick` makes.\n const rowClassNameFor = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n ): string | undefined =>\n typeof rowClassName === \"function\"\n ? rowClassName(row as unknown as Row<TMDataGridFeatures, TData>)\n : rowClassName;\n const rowStyleFor = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n ): CSSProperties | undefined =>\n typeof rowStyle === \"function\"\n ? rowStyle(row as unknown as Row<TMDataGridFeatures, TData>)\n : rowStyle;\n\n // The same erasure crossing `onRowClick` makes, once for all three cell\n // handlers.\n const cellEventArgs = (\n cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>,\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n event: MouseEvent<HTMLElement>,\n ): TMDataGridCellEventArgs<TData> =>\n ({\n cell,\n row,\n column: cell.column,\n event,\n }) as unknown as TMDataGridCellEventArgs<TData>;\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 // Cell editing - the gestures. The engine owns the forms; this component\n // owns where the editor opens from (keys, double-click) and where the\n // focus lands when it closes.\n // ---------------------------------------------------------------------------\n\n /** The pending type-to-edit seed, consumed by the editor host on mount. */\n const editSeedRef = useRef<string | undefined>(undefined);\n const takeEditSeed = () => {\n const seed = editSeedRef.current;\n editSeedRef.current = undefined;\n return seed;\n };\n\n /**\n * The row's first cell that edits, in visual order - where the caret goes\n * for a gesture that named no column, which is the edit lane's pencil.\n */\n const firstEditableColumnId = (rowId: string): string | null => {\n const row = rows.find((candidate) => candidate.id === rowId);\n if (row === undefined) return null;\n const cells = [\n ...row.getLeftVisibleCells(),\n ...row.getCenterVisibleCells(),\n ...row.getRightVisibleCells(),\n ];\n return (\n cells.find((cell) => edit.canEditCell(row, cell.column))?.column.id ??\n null\n );\n };\n\n /**\n * The `active` the caret has already been placed for. Identity, not value:\n * `beginOn` publishes a fresh object per gesture, so re-opening the same\n * cell is a new intent, while every later render for the same gesture - a\n * remount as the virtualizer scrolls among open rows - is not.\n */\n const placedEditCaretRef = useRef<TMDataGridEditState[\"active\"]>(null);\n\n /**\n * Puts the caret in the cell the open gesture named, once per gesture.\n * See `focusEditorContent` for where inside the editor it lands.\n *\n * A layout effect, ahead of the focused-cell effect below: the ring follows\n * the caret there rather than fighting it.\n */\n useLayoutEffect(() => {\n if (editActive === null) {\n placedEditCaretRef.current = null;\n return;\n }\n if (placedEditCaretRef.current === editActive) return;\n const container = scrollContainerRef.current;\n if (container === null) return;\n // The lane's pencil names no column - the row's first editable cell.\n const columnId =\n editActive.columnId ?? firstEditableColumnId(editActive.rowId);\n if (columnId === null) {\n placedEditCaretRef.current = editActive;\n return;\n }\n const editor = container.querySelector<HTMLElement>(\n `[data-dg-part=\"editor\"][data-row-id=\"${CSS.escape(editActive.rowId)}\"]` +\n `[data-column-id=\"${CSS.escape(columnId)}\"]`,\n );\n // Not mounted yet - the virtualizer is still bringing the row in. The\n // intent stays up, and the next render tries again.\n if (editor === null) return;\n placedEditCaretRef.current = editActive;\n focusEditorContent(editor);\n });\n\n /** DOM focus back onto a cell - after Escape, or a commit with nowhere to go. */\n const refocusCell = (position: TMDataGridCellPosition) => {\n const container = scrollContainerRef.current;\n if (container === null) return;\n wantsCellFocusRef.current = true;\n findCellElement(container, position)?.focus();\n };\n\n const openEditor = (position: TMDataGridCellPosition) => {\n if (cellSelection) ui.actions.setFocusedCell(position);\n // Row mode edits whole rows: any editable cell's open gesture opens all of\n // them, exactly as the lane's pencil does. The column still travels, as\n // the cell the caret belongs in - the one the gesture named. Dropping it\n // here sent the caret to the row's first editable cell instead, which the\n // focused-cell effect above then pulled back onto the cell just clicked,\n // leaving the row open with the caret in none of its editors.\n edit.begin({ rowId: position.rowId, columnId: position.columnId });\n };\n\n const handleEditorClose = (\n position: TMDataGridCellPosition,\n close: TMDataGridCellEditorClose,\n ) => {\n // Where the keyboard goes: Enter moves down, Tab to the next editable\n // cell (cellConfirm's deferring variants move the same way, draft kept) -\n // everything else, and a saved row, goes back to where the edit was.\n const move =\n close.via === \"enter\"\n ? \"down\"\n : close.via === \"tab\" || close.via === \"defer-tab\"\n ? 1\n : close.via === \"shift-tab\" || close.via === \"defer-shift-tab\"\n ? -1\n : null;\n if (move === null || features.editMode === \"row\") {\n refocusCell(position);\n return;\n }\n const rowIndex = rows.findIndex((row) => row.id === position.rowId);\n const columnIndex = orderedColumns.findIndex(\n (column) => column.id === position.columnId,\n );\n if (rowIndex < 0 || columnIndex < 0) {\n refocusCell(position);\n return;\n }\n if (move === \"down\") {\n if (rowIndex + 1 < rows.length) {\n moveFocusedCell({ rowIndex: rowIndex + 1, columnIndex });\n } else {\n refocusCell(position);\n }\n return;\n }\n const next = getNextEditableCell({\n from: { rowIndex, columnIndex },\n direction: move,\n rowCount: rows.length,\n columnCount: orderedColumns.length,\n isEditable: (coords) => {\n const row = rows[coords.rowIndex];\n const column = orderedColumns[coords.columnIndex];\n return (\n row !== undefined &&\n column !== undefined &&\n edit.canEditCell(row, column)\n );\n },\n });\n if (next !== null) moveFocusedCell(next);\n else refocusCell(position);\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 // Editing keys, ahead of the step-into pair - an editable cell's Enter\n // opens its editor, and only a non-editable cell's falls through to the\n // control it holds.\n const keyRow = rows[rowIndex];\n const keyColumn = orderedColumns[columnIndex];\n if (\n features.editing &&\n keyRow !== undefined &&\n keyColumn !== undefined &&\n edit.canEditCell(keyRow, keyColumn)\n ) {\n if (event.key === \"Enter\" || event.key === \"F2\") {\n event.preventDefault();\n openEditor({ rowId, columnId });\n return;\n }\n // The quick single-cell gestures - Delete-to-clear and type-to-edit -\n // sit out row mode, whose whole point is that nothing commits until\n // the row's explicit save.\n if (features.editMode !== \"row\") {\n // Clear-and-commit, without opening anything - the spreadsheet Delete.\n if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n void edit\n .clearCell(rowId, columnId)\n .then(() => refocusCell({ rowId, columnId }));\n return;\n }\n // Type-to-edit: a printable character opens the editor seeded with\n // itself. Space stays the row-selection key, modifiers stay shortcuts.\n if (\n event.key.length === 1 &&\n event.key !== \" \" &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.altKey\n ) {\n event.preventDefault();\n editSeedRef.current = event.key;\n openEditor({ rowId, columnId });\n return;\n }\n }\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 // An open editor outranks the ring, wherever it is. Row mode opens a whole\n // row from one gesture, so the caret legitimately sits in a cell other\n // than the one that gesture landed the ring on - the lane's pencil is the\n // plain case, focusing its own cell on the way to opening the row. Pulling\n // the caret back onto that cell would leave the row open with the caret in\n // none of its editors, and the user with nothing to type into.\n if (\n document.activeElement instanceof Element &&\n document.activeElement.closest('[data-dg-part=\"editor\"]') !== null\n ) {\n return;\n }\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 // `rowIndex < 0` is a pinned row: those sit out the cell range, so\n // moving the selection onto one would resolve to no rectangle at all\n // and drop the selection the user could still see at the edge.\n if (\n rowIndex >= 0 &&\n !isWithinBounds(selectionBounds, rowIndex, columnIndex)\n ) {\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 // The body list, then the edge blocks: pinning takes a row out of the\n // scrolling order, and unpinning is the first thing its menu exists to\n // offer, so a menu that could not resolve a pinned row would strand it\n // there. Searched in that order because the body holds nearly every row.\n const contextMenuRow =\n contextMenuTarget === null\n ? undefined\n : (rows.find((row) => row.id === contextMenuTarget.rowId) ??\n pinnedTopRows.find((row) => row.id === contextMenuTarget.rowId) ??\n pinnedBottomRows.find((row) => row.id === contextMenuTarget.rowId));\n\n const canRenderRowMenu =\n renderRowContextMenu !== undefined &&\n contextMenuTarget !== null &&\n contextMenuRow !== undefined &&\n !contextMenuRow.getIsGrouped();\n\n\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 consumer's half, built for the open row only - so the render prop runs\n * once per opened menu rather than once per mounted row. `null` back from it\n * means this row has no menu, which is also how the menu stays shut.\n *\n * `internalItems` is a getter, and reading it is the signal: a consumer who\n * touches it has taken the composition over, so the grid stops prepending\n * its own half. One who never mentions it gets today's behavior, the cell\n * items above a divider. The alternative - a second prop declaring intent -\n * asks people to say twice what the placement already says.\n *\n * The casts put back the concrete row type the context boundary erased - the\n * same crossing `onRowClick` makes.\n */\n let tookOverMenu = false;\n const rowMenuContent = canRenderRowMenu\n ? (renderRowContextMenu({\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 get internalItems() {\n tookOverMenu = true;\n return cellMenuContent;\n },\n }) ?? null)\n : null;\n\n /**\n * The two halves, in the order they apply to: the cells first, since the\n * right-click landed on one, then whatever the consumer offers for the row.\n * When the consumer takes the composition over, what they returned is the\n * entire menu.\n */\n const contextMenuContent = tookOverMenu\n ? rowMenuContent\n : cellMenuContent === null && rowMenuContent === null\n ? null\n : (\n <>\n {cellMenuContent}\n {cellMenuContent !== null && rowMenuContent !== null && (\n <Menu.Divider />\n )}\n {rowMenuContent}\n </>\n );\n\n /**\n * Which edges the scroll position is currently at. Seeded \"at top-left\",\n * which is where a grid mounts - so the callbacks report *arrivals*, and\n * mounting fires nothing.\n */\n const scrollEdgesRef = useRef({\n top: true,\n bottom: false,\n left: true,\n right: false,\n });\n const hasEdgeCallbacks =\n onScrollToTop !== undefined ||\n onScrollToBottom !== undefined ||\n onScrollToLeft !== undefined ||\n onScrollToRight !== undefined;\n\n /**\n * The context menu's dropdown is anchored to a fixed viewport point, so it\n * does not travel with the row when the body scrolls - and under\n * virtualization the row it belongs to may unmount entirely. It therefore\n * closes on scroll, as a desktop context menu does.\n *\n * The edge callbacks share the handler. Reading scroll offsets here costs\n * no layout; the 1px tolerance absorbs fractional offsets under browser\n * zoom, where a \"fully scrolled\" position can land at 799.5 of 800.\n */\n const handleScroll =\n contextMenuTarget || hasEdgeCallbacks\n ? (event: UIEvent<HTMLDivElement>) => {\n if (contextMenuTarget) closeContextMenu();\n if (!hasEdgeCallbacks) return;\n const el = event.currentTarget;\n const next = {\n top: el.scrollTop <= 1,\n bottom: el.scrollTop + el.clientHeight >= el.scrollHeight - 1,\n left: el.scrollLeft <= 1,\n right: el.scrollLeft + el.clientWidth >= el.scrollWidth - 1,\n };\n const previous = scrollEdgesRef.current;\n scrollEdgesRef.current = next;\n if (next.top && !previous.top) onScrollToTop?.();\n if (next.bottom && !previous.bottom) onScrollToBottom?.();\n if (next.left && !previous.left) onScrollToLeft?.();\n if (next.right && !previous.right) onScrollToRight?.();\n }\n : 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 ref={gridElementRef}\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-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n // Set while `meta.loading` is, whether or not the body has rows to\n // show - a refetch over existing rows is still a fetch, and a test\n // waiting for the grid to settle has nothing else to wait on.\n aria-busy={loading === true ? true : undefined}\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 +\n pinnedRowCount +\n headerGroups.length +\n (hasSummaryRow ? 1 : 0)\n }\n aria-colcount={orderedColumns.length}\n // Body rows the grid is currently showing - the page under\n // pagination, everything the filters left otherwise, edge blocks\n // included. Most of them are not in the DOM, so this is what a test\n // waits on rather than counting nodes.\n data-dg-row-count={rows.length + pinnedRowCount}\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 data-dg-header-row\n // The scrolled-under shadow belongs to the boundary between\n // header and body - the last header row, not every stacked\n // group row above it. See the stylesheet.\n data-dg-header-last={\n groupIndex === headerGroups.length - 1 || undefined\n }\n className={classes.headerRow}\n >\n {headerGroup.headers.map((header) => (\n <TMDataGridHeaderCell\n renderColumnMenuItems={renderColumnMenuItems}\n key={header.id}\n header={header}\n layout={layoutFor(header.column.id)}\n />\n ))}\n </div>\n ))}\n </div>\n\n {/* The entry block - new rows being typed, stuck under the header.\n Present only while `edit.addRow()` has open entries. */}\n {features.editing && newRowCount > 0 && (\n <TMDataGridEntryRows\n orderedColumns={orderedColumns}\n layoutFor={layoutFor}\n rowHeight={rowHeight}\n />\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 `renderRowContextMenu`.\n enabled={renderRowContextMenu !== undefined || cellRangeSelection}\n menuContent={contextMenuContent}\n menuProps={rowContextMenuProps}\n onContextMenu={handleContextMenu}\n onClose={closeContextMenu}\n >\n {(() => {\n /**\n * One renderer for every body row, wherever it sits: the\n * virtualized centre, or a pinned edge block. `viewIndex` is the\n * row's index in the scrolling view - `-1` for a pinned row,\n * which takes it out of striping, row measurement and the cell\n * range, all of which are statements about the scrolling order.\n * Scoped here rather than a component so the row keeps closing\n * over the body's handlers without threading them as props.\n */\n const renderBodyRow = (\n row: Row<TMDataGridFeatures, TMDataGridRowData>,\n viewIndex: number,\n ariaRowIndex: number,\n pinnedAt?: \"top\" | \"bottom\",\n ) => {\n const isGroupRow = row.getIsGrouped();\n const isInteractive = rowGesturesFor(row);\n const rowCells = [\n ...row.getLeftVisibleCells(),\n ...row.getCenterVisibleCells(),\n ...row.getRightVisibleCells(),\n ];\n // Row mode opens every editable cell of the row at once, and\n // rows accumulate: a second row opening leaves the first one\n // open, so every row holding a form shows its editors. Which of\n // them holds the caret is not decided here - see\n // placeEditCaret, which places it once per gesture.\n //\n // A parked row is not one of them. It keeps its form, so it is\n // still \"open\", but it has been decided: it renders its draft\n // through the column's own renderer until `begin` reopens it.\n const rowEditing =\n features.editMode === \"row\" &&\n editOpenRowIds.includes(row.id) &&\n !editDraftRowIds.includes(row.id);\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={row.id}\n role=\"row\"\n aria-rowindex={ariaRowIndex}\n data-dg-part=\"row\"\n data-row-id={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 why no second virtual item is needed.\n data-index={\n renderDetails && viewIndex >= 0 ? viewIndex : undefined\n }\n ref={\n renderDetails && viewIndex >= 0\n ? virtualizer.measureElement\n : undefined\n }\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 // Which edge block the row sits in, for styling hooks.\n data-pinned={pinnedAt}\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 // Marked deleted under draft: struck through and inert\n // until submitAll reports it, or the mark is toggled back.\n data-deleted={\n deletedRowIds.length > 0 && deletedRowIds.includes(row.id)\n }\n // Carrying a dirty draft - the row-level face of the cells'\n // own data-dirty markers, for row-scoped styling.\n data-dirty={\n editDirtyRowIds.length > 0 &&\n editDirtyRowIds.includes(row.id)\n }\n // Committed into the draft store, waiting for Save.\n data-draft={\n editDraftRowIds.length > 0 &&\n editDraftRowIds.includes(row.id)\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 // From the row's position in the whole view, so the stripes\n // survive the virtualizer's moving window - see the prop.\n data-striped={\n striped && viewIndex >= 0 ? viewIndex % 2 === 1 : undefined\n }\n className={[classes.bodyRow, rowClassNameFor(row)]\n .filter(Boolean)\n .join(\" \")}\n style={{\n minHeight: rowHeight,\n cursor: isInteractive ? \"pointer\" : undefined,\n ...rowStyleFor(row),\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 that too,\n // but would also stop cell values being copied, so it is\n // prevented on 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. `renderRowContextMenu` 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 (renderRowContextMenu && !isGroupRow) || cellRangeSelection\n ? () => {\n contextMenuRowRef.current = row.id;\n }\n : undefined\n }\n >\n {rowCells.map((cell, cellIndex) => {\n const isEditingCell =\n (editActive !== null &&\n editActive.rowId === row.id &&\n editActive.columnId === cell.column.id) ||\n (rowEditing && edit.canEditCell(row, cell.column));\n return (\n <TMDataGridBodyCell\n key={cell.id}\n cell={cell}\n rowHeight={rowHeight}\n layout={layoutFor(cell.column.id)}\n contentOverride={\n rowNumberById !== null &&\n cell.column.id === ROW_NUMBER_COLUMN_ID\n ? rowNumberById.get(row.id)\n : undefined\n }\n highlightNeedles={matchNeedles?.get(cell.column.id)}\n editor={\n isEditingCell ? (\n <TMDataGridCellEditor\n cell={cell}\n row={row}\n takeSeedText={takeEditSeed}\n onClose={(close) =>\n handleEditorClose(\n { rowId: row.id, columnId: cell.column.id },\n close,\n )\n }\n />\n ) : undefined\n }\n onClick={\n onCellClick && !isGroupRow\n ? (event) =>\n onCellClick(cellEventArgs(cell, row, event))\n : undefined\n }\n onDoubleClick={\n (features.editing || onCellDoubleClick) && !isGroupRow\n ? (event) => {\n onCellDoubleClick?.(\n cellEventArgs(cell, row, event),\n );\n if (!features.editing) return;\n if (!edit.canEditCell(row, cell.column)) return;\n openEditor({\n rowId: row.id,\n columnId: cell.column.id,\n });\n }\n : undefined\n }\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(rangeBounds, viewIndex, cellIndex)\n : isCellAt(focusedCell, row.id, cell.column.id),\n edges: boundsEdges(rangeBounds, viewIndex, cellIndex),\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 renderRowContextMenu || cellRangeSelection || onCellContextMenu\n ? (event) => {\n contextMenuColumnRef.current = cell.column.id;\n if (isGroupRow) return;\n onCellContextMenu?.(\n cellEventArgs(cell, row, event),\n );\n }\n : undefined\n }\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-dg-part=\"details\"\n data-row-id={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\n return (\n <>\n {/* The pinned edge blocks. Same sticky mechanics as the\n entry block - the *block* is the sticky element, its rows\n flow normally inside it. `role=\"presentation\"` keeps the\n wrapper out of the accessibility tree, so the rows stay\n direct children of the rowgroup. Inside the rowgroup so\n a right-click on a pinned row still opens the menu. */}\n {pinnedTopRows.length > 0 && (\n <div\n role=\"presentation\"\n data-dg-part=\"pinned-top\"\n className={classes.pinnedTopBlock}\n >\n {pinnedTopRows.map((row, index) =>\n renderBodyRow(\n row,\n -1,\n headerGroups.length + index + 1,\n \"top\",\n ),\n )}\n </div>\n )}\n\n {paddingTop > 0 && (\n <div\n aria-hidden\n style={{ gridColumn: \"1/-1\", height: paddingTop }}\n />\n )}\n\n {virtualItems.map((virtualItem) => {\n const row = rows[virtualItem.index];\n if (!row) return null;\n return renderBodyRow(\n row,\n virtualItem.index,\n virtualItem.index +\n headerGroups.length +\n pinnedTopRows.length +\n 1,\n );\n })}\n\n {paddingBottom > 0 && (\n <div\n aria-hidden\n style={{ gridColumn: \"1/-1\", height: paddingBottom }}\n />\n )}\n\n {pinnedBottomRows.length > 0 && (\n <div\n role=\"presentation\"\n data-dg-part=\"pinned-bottom\"\n className={classes.pinnedBottomBlock}\n >\n {pinnedBottomRows.map((row, index) =>\n renderBodyRow(\n row,\n -1,\n headerGroups.length +\n pinnedTopRows.length +\n rows.length +\n index +\n 1,\n \"bottom\",\n ),\n )}\n </div>\n )}\n </>\n );\n })()}\n </TMDataGridBodyRowGroup>\n\n {/* The empty matrix, one state at a time: loading wins (data is on\n its way, \"empty\" would be a lie), open entry rows show only\n themselves (a \"no rows\" under the row being typed reads as a\n contradiction), then the consumer's blank slate, then the two\n defaults - filtered-empty with its search icon, truly-empty as\n plain text, because only one of them is the user's own doing. */}\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 && newRowCount === 0 && (\n <div role=\"row\" className={classes.messageRow}>\n {renderEmptyState !== undefined ? (\n renderEmptyState({\n hasActiveFilters,\n table: table as unknown as Table<TMDataGridFeatures, TData>,\n })\n ) : hasActiveFilters ? (\n <>\n <SearchIcon size={40} stroke={1.4} opacity={0.4} />\n <Text span size={controlSize} c=\"dimmed\">\n {noResultsLabel}\n </Text>\n </>\n ) : (\n <Text span size={controlSize} c=\"dimmed\">\n {labels.noRows}\n </Text>\n )}\n </div>\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={\n rows.length + pinnedRowCount + headerGroups.length + 1\n }\n // Also what the height measurement above looks for. One\n // attribute serves both now that the part name *is* the\n // published contract rather than a testing-only alias.\n data-dg-part=\"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\n.summaryCount {\n white-space: nowrap;\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 { useSettledTableState } from \"../core/useSettledTableState\";\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 (\n <div data-dg-part=\"toolbar\" className={classes.toolbar}>\n {children}\n </div>\n );\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\" data-dg-part=\"loading\" 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 useSettledTableState(table.store);\n\n const shown = table.getRowCount();\n const total =\n table.options.meta?.totalRowCount ??\n table.getPreFilteredRowModel().rows.length;\n\n return (\n <Text\n span\n size={controlSize}\n c=\"dimmed\"\n className={classes.summaryCount}\n data-dg-part=\"summary-count\"\n >\n {children !== undefined ? children : `${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 data-dg-part=\"columns-button\"\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 // Also what the panel's click-away handler tests for, so that a click\n // here reads as a toggle rather than as a click outside.\n data-dg-part=\"filter-button\"\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 { TMDataGridDraftActions } from \"./TMDataGridDraftActions\";\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 /** Set on the root element. */\n id?: string;\n /**\n * Names this grid for tests. The grid names its own pieces with\n * `data-dg-part` rather than minting test ids, and those repeat across\n * grids - scope through this one and they stop colliding:\n *\n * ```ts\n * page.getByTestId(\"orders\").locator('[data-dg-part=\"row\"][data-row-id=\"42\"]')\n * ```\n *\n * See the Testing docs page for the full attribute contract.\n */\n \"data-testid\"?: string;\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 edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\n size = DEFAULT_TMDATAGRID_SIZE,\n children,\n className,\n style,\n id,\n \"data-testid\": testId,\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 edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\n size,\n rowHeight,\n controlSize: SIZE_CONTROL_SIZE[size],\n }),\n [\n table,\n ui,\n edit,\n features,\n labels,\n renderDetails,\n renderDetailsEstHeight,\n overscan,\n resetSettings,\n scrollToRow,\n scrollerRef,\n size,\n rowHeight,\n ],\n );\n\n return (\n <TMDataGridContextProvider value={api}>\n <div\n id={id}\n data-testid={testId}\n // The handle everything else scopes off - see the `data-testid` prop.\n data-dg-root\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 DraftActions: TMDataGridDraftActions,\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 { Input, RangeSlider } from \"@mantine/core\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport { operatorTakesRangeValue } from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for `number` columns: a range slider whose\n * bounds are seeded from the values present in the data, writing the\n * `between` pair. Pair it with `meta.filter.defaultOperator: \"between\"` so\n * the filter opens on it; any non-range operator falls back to the standard\n * input.\n */\nexport function DgRangeSliderFilter(args: TMDataGridFilterControlArgs) {\n const { column, operator, value, onChange, size, labels } = args;\n if (!operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n\n // Bounds from the faceted index - the min and max actually in the data.\n const numbers: number[] = [];\n for (const key of column.getFacetedUniqueValues().keys()) {\n const numeric = Number(key);\n if (Number.isFinite(numeric)) numbers.push(numeric);\n }\n const min = numbers.length > 0 ? Math.min(...numbers) : 0;\n const max = numbers.length > 0 ? Math.max(...numbers) : 100;\n\n const pair = Array.isArray(value) ? value : [\"\", \"\"];\n const lower = pair[0] === undefined || pair[0] === \"\" ? min : Number(pair[0]);\n const upper = pair[1] === undefined || pair[1] === \"\" ? max : Number(pair[1]);\n\n return (\n <Input.Wrapper label={labels.filterValue} size={size} w={180}>\n <RangeSlider\n size={size}\n mt={6}\n min={min}\n max={max}\n minRange={0}\n value={[\n Math.min(Math.max(lower, min), max),\n Math.min(Math.max(upper, min), max),\n ]}\n thumbFromLabel={labels.filterFrom}\n thumbToLabel={labels.filterTo}\n onChange={([nextLower, nextUpper]) =>\n onChange([String(nextLower), String(nextUpper)])\n }\n />\n </Input.Wrapper>\n );\n}\n","import { Group, TextInput } from \"@mantine/core\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport { operatorTakesRangeValue } from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for `date` columns: a From/To pair of\n * native date inputs writing the `between` pair - no `@mantine/dates`\n * involved, like the built-in date editor. Pair it with\n * `meta.filter.defaultOperator: \"between\"`; any non-range operator falls back\n * to the standard input.\n */\nexport function DgDateRangeFilter(args: TMDataGridFilterControlArgs) {\n const { operator, value, onChange, size, labels } = args;\n if (!operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n\n const pair: [string, string] = Array.isArray(value)\n ? [String(value[0] ?? \"\"), String(value[1] ?? \"\")]\n : [\"\", \"\"];\n\n return (\n <Group gap={4} wrap=\"nowrap\" align=\"flex-start\">\n <TextInput\n label={labels.filterFrom}\n size={size}\n w={88}\n type=\"date\"\n value={pair[0]}\n onChange={(event) => onChange([event.currentTarget.value, pair[1]])}\n />\n <TextInput\n label={labels.filterTo}\n size={size}\n w={88}\n type=\"date\"\n value={pair[1]}\n onChange={(event) => onChange([pair[0], event.currentTarget.value])}\n />\n </Group>\n );\n}\n","import { Autocomplete } from \"@mantine/core\";\nimport { resolveColumnOptions } from \"../../core/columnOptions\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport {\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for text-shaped columns: a free-text input\n * that also offers the values present in the data (or the column's declared\n * `meta.options`) as suggestions. Set or range operators fall back to the\n * standard input.\n */\nexport function DgAutocompleteFilter(args: TMDataGridFilterControlArgs) {\n const { column, table, operator, value, onChange, options, size, labels } =\n args;\n if (operatorTakesArrayValue(operator) || operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n const needsValue = operatorNeedsValue(operator);\n // `options` arrives pre-resolved only for declared or select-shaped\n // columns; on a plain string column the suggestions come from the faceted\n // values, resolved here.\n const suggestions =\n options.length > 0\n ? options\n : resolveColumnOptions({ table, column, fallback: \"faceted\" });\n\n return (\n <Autocomplete\n label={labels.filterValue}\n size={size}\n w={180}\n comboboxProps={{ withinPortal: false }}\n disabled={!needsValue}\n placeholder={needsValue ? labels.filterValuePlaceholder : \"\"}\n data={suggestions.map((option) => option.value)}\n limit={20}\n value={needsValue && typeof value === \"string\" ? value : \"\"}\n onChange={onChange}\n />\n );\n}\n","import { Input, SegmentedControl } from \"@mantine/core\";\nimport type { TMDataGridFilterControlArgs } from \"../../core/filterControls\";\nimport {\n operatorNeedsValue,\n operatorTakesArrayValue,\n operatorTakesRangeValue,\n} from \"../../core/filterOperators\";\nimport { TMDataGridFilterValueInput } from \"./TMDataGridFilterValueInput\";\n\n/**\n * A built-in `meta.filter.control` for `boolean` columns: an All / Yes / No\n * segmented control - All clears the value, which deactivates the filter.\n * Set or range operators fall back to the standard input.\n */\nexport function DgTriStateFilter(args: TMDataGridFilterControlArgs) {\n const { operator, value, onChange, size, labels } = args;\n if (operatorTakesArrayValue(operator) || operatorTakesRangeValue(operator)) {\n return <TMDataGridFilterValueInput {...args} />;\n }\n const needsValue = operatorNeedsValue(operator);\n const scalar = typeof value === \"string\" ? value : \"\";\n\n return (\n <Input.Wrapper label={labels.filterValue} size={size}>\n <SegmentedControl\n size={size}\n disabled={!needsValue}\n data={[\n { value: \"all\", label: labels.filterAll },\n { value: \"true\", label: labels.booleanTrue },\n { value: \"false\", label: labels.booleanFalse },\n ]}\n value={scalar === \"true\" || scalar === \"false\" ? scalar : \"all\"}\n onChange={(next) => onChange(next === \"all\" ? \"\" : next)}\n />\n </Input.Wrapper>\n );\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 between: \"är mellan\",\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 LAYOUT\",\n columnsResetHint:\n \"Återställer kolumnernas synlighet, ordning, bredder, fästning och gruppering\",\n rowNumberColumnLabel: \"Radnummer\",\n noRows: \"Inga rader att visa\",\n\n filterColumn: \"Kolumn\",\n filterOperator: \"Operator\",\n filterValue: \"Värde\",\n filterValuePlaceholder: \"Filtervärde\",\n filterFrom: \"Från\",\n filterTo: \"Till\",\n filterAll: \"Alla\",\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 editCell: (column) => `Redigera ${column}`,\n confirmEdit: \"Spara\",\n cancelEdit: \"Avbryt\",\n editColumnLabel: \"Redigera\",\n editRow: \"Redigera rad\",\n saveRow: \"Spara rad\",\n cancelRowEdit: \"Avbryt redigering\",\n editRowErrors: \"Åtgärda de markerade cellerna\",\n saveAllEdits: (rows) => (rows === 1 ? \"Spara 1 rad\" : `Spara ${rows} rader`),\n discardAllEdits: \"Förkasta\",\n editRowsStillOpen: (rows) =>\n rows === 1 ? \"1 rad redigeras fortfarande\" : `${rows} rader redigeras fortfarande`,\n confirmNewRow: \"Lägg till rad\",\n discardNewRow: \"Släng ny rad\",\n deleteRow: \"Ta bort rad\",\n restoreRow: \"Återställ rad\",\n revertRow: \"Ångra ändringar\",\n rowStateNew: \"Ny rad\",\n rowStateEdited: \"Ändrad rad\",\n rowStateDeleted: \"Markerad för borttagning\",\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 *\n * Every data row counts once. Grouping builds its group rows from this model\n * rather than into it, so a grouped grid totals its records, not its records\n * plus their subtotals; a tree counts parents and children alike.\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 // `flatRows`, not `rows`: the filtered model nests under `getSubRows`, and\n // the top-level array would total a tree's roots and drop every child.\n // Grouping does not nest it - the group rows are built from this model, not\n // held in it - so a grouped grid is unaffected either way.\n const rows = erased.getFilteredRowModel().flatRows;\n // Leaf and child rows are the same set here: this is already every row.\n return aggregationFns[fn](columnId, rows, rows);\n}\n"],"mappings":"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"}
|