@jielga/tmdatagrid 2.0.0-beta.2 → 2.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +5 -212
  2. package/dist/index.d.ts +1664 -632
  3. package/dist/index.js +5226 -3223
  4. package/dist/index.js.map +1 -1
  5. package/dist/styles.css +1 -1
  6. package/docs/anatomy.md +102 -0
  7. package/docs/cell-selection.md +154 -0
  8. package/docs/column-layout.md +204 -0
  9. package/docs/columns.md +262 -0
  10. package/docs/components.md +304 -0
  11. package/docs/editing.md +603 -0
  12. package/docs/editors.md +250 -0
  13. package/docs/export.md +326 -0
  14. package/docs/filtering.md +358 -0
  15. package/docs/getting-started.md +123 -0
  16. package/docs/grouping.md +165 -0
  17. package/docs/loading-and-empty.md +92 -0
  18. package/docs/localization.md +79 -0
  19. package/docs/menu.md +143 -0
  20. package/docs/pagination.md +144 -0
  21. package/docs/persistence.md +111 -0
  22. package/docs/portfolio-rebalancer.md +94 -0
  23. package/docs/query-builder.md +175 -0
  24. package/docs/quick-search.md +83 -0
  25. package/docs/row-details.md +113 -0
  26. package/docs/row-interaction.md +148 -0
  27. package/docs/row-pinning.md +132 -0
  28. package/docs/row-selection.md +134 -0
  29. package/docs/row-styling.md +133 -0
  30. package/docs/scrolling.md +111 -0
  31. package/docs/server-query.md +246 -0
  32. package/docs/server-side.md +206 -0
  33. package/docs/sorting.md +101 -0
  34. package/docs/styling.md +126 -0
  35. package/docs/summary-row.md +76 -0
  36. package/docs/testing.md +309 -0
  37. package/docs/toolbar.md +161 -0
  38. package/docs/use-tm-data-grid.md +361 -0
  39. package/package.json +21 -45
  40. package/skills/appearance/SKILL.md +70 -17
  41. package/skills/cell-selection/SKILL.md +70 -76
  42. package/skills/columns/SKILL.md +131 -32
  43. package/skills/data/SKILL.md +100 -23
  44. package/skills/editing/SKILL.md +217 -96
  45. package/skills/editing/references/common-mistakes.md +111 -24
  46. package/skills/editing/references/editing-api.md +63 -39
  47. package/skills/editing/references/editors-and-validation.md +77 -19
  48. package/skills/filtering/SKILL.md +148 -40
  49. package/skills/getting-started/SKILL.md +18 -16
  50. package/skills/grouping/SKILL.md +32 -15
  51. package/skills/options/SKILL.md +39 -9
  52. package/skills/rows/SKILL.md +22 -18
  53. package/skills/server-side/SKILL.md +170 -17
  54. package/skills/testing/SKILL.md +10 -7
  55. package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +7 -19
  56. package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +7 -1
  57. package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +39 -23
  58. package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +106 -38
  59. package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
  60. package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
  61. package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +4 -4
  62. package/src/components/TMDataGridDraftActions.tsx +307 -0
  63. package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +58 -50
  64. package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +150 -115
  65. package/src/components/TMDataGridExportPicker.module.css +77 -0
  66. package/src/components/TMDataGridExportPicker.tsx +234 -0
  67. package/src/components/TMDataGridFilterPanel.module.css +54 -0
  68. package/src/components/TMDataGridFilterPanel.tsx +348 -0
  69. package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +7 -5
  70. package/src/components/TMDataGridFilterSurface.module.css +54 -0
  71. package/src/components/TMDataGridFilterSurface.tsx +167 -0
  72. package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -13
  73. package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +4 -3
  74. package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +10 -0
  75. package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +100 -28
  76. package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
  77. package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
  78. package/src/components/TMDataGridMenu.tsx +354 -0
  79. package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +12 -7
  80. package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +90 -67
  81. package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +678 -156
  82. package/src/components/TMDataGridToolbar.module.css +21 -0
  83. package/src/components/TMDataGridToolbar.tsx +181 -0
  84. package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
  85. package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
  86. package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
  87. package/src/components/editors/TMDataGridNumberEditor.tsx +70 -0
  88. package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
  89. package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
  90. package/src/{tmdatagrid/components → components}/editors/editorShared.ts +17 -31
  91. package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
  92. package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
  93. package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
  94. package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
  95. package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
  96. package/src/components/filters/controlLayout.ts +32 -0
  97. package/src/components/filters/filterControlFor.ts +65 -0
  98. package/src/{tmdatagrid/components → components}/icons.ts +1 -0
  99. package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
  100. package/src/components/useHideableColumns.ts +52 -0
  101. package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
  102. package/src/{tmdatagrid/core → core}/capabilities.ts +14 -6
  103. package/src/{tmdatagrid/core → core}/columnOptions.ts +46 -0
  104. package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
  105. package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
  106. package/src/core/controlledState.ts +179 -0
  107. package/src/core/controlledStateSync.ts +108 -0
  108. package/src/core/deletedRows.ts +34 -0
  109. package/src/core/dom.ts +74 -0
  110. package/src/core/editEngine.ts +2476 -0
  111. package/src/{tmdatagrid/core → core}/editorFocus.ts +8 -4
  112. package/src/core/export.ts +843 -0
  113. package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
  114. package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
  115. package/src/core/filterSurface.ts +99 -0
  116. package/src/{tmdatagrid/core → core}/labels.ts +66 -8
  117. package/src/{tmdatagrid/core → core}/labelsSv.ts +26 -3
  118. package/src/core/pageReset.ts +120 -0
  119. package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
  120. package/src/core/resizePreview.ts +141 -0
  121. package/src/core/summary.ts +59 -0
  122. package/src/core/useSettledTableState.ts +36 -0
  123. package/src/{tmdatagrid/index.ts → index.ts} +75 -12
  124. package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +734 -135
  125. package/src/useTMDataGridExport.ts +78 -0
  126. package/src/tmdatagrid/components/TMDataGridEditActions.tsx +0 -162
  127. package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
  128. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
  129. package/src/tmdatagrid/components/TMDataGridToolbar.module.css +0 -12
  130. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -162
  131. package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +0 -40
  132. package/src/tmdatagrid/core/cellExport.ts +0 -320
  133. package/src/tmdatagrid/core/editEngine.ts +0 -1006
  134. package/src/tmdatagrid/core/summary.ts +0 -35
  135. /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
  136. /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
  137. /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
  138. /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
  139. /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
  140. /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
  141. /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
  142. /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
  143. /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
  144. /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
  145. /package/src/{tmdatagrid/core → core}/grouping.ts +0 -0
  146. /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
  147. /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
  148. /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
  149. /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
  150. /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
- ._root_1wvkg_8[data-size=xs]{--dg-row-height:34px;--dg-header-height:32px;--dg-font-size:var(--mantine-font-size-xs);--dg-padding:6px}._root_1wvkg_8[data-size=sm]{--dg-row-height:42px;--dg-header-height:38px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:8px}._root_1wvkg_8[data-size=md]{--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px}._root_1wvkg_8[data-size=lg]{--dg-row-height:62px;--dg-header-height:52px;--dg-font-size:var(--mantine-font-size-md);--dg-padding:14px}._root_1wvkg_8[data-size=xl]{--dg-row-height:72px;--dg-header-height:60px;--dg-font-size:var(--mantine-font-size-lg);--dg-padding:18px}._root_1wvkg_8{--dg-radius:var(--mantine-radius-md);--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px;--dg-row-selected-bg:var(--mantine-primary-color-light);--dg-row-highlight-bg:var(--mantine-primary-color-light-hover);--dg-row-group-bg:var(--mantine-color-body);--dg-row-striped-bg:color-mix(in srgb, var(--mantine-color-text) 3.5%, var(--mantine-color-body));--dg-row-new-bg:color-mix(in srgb, var(--mantine-color-green-6) 8%, var(--mantine-color-body));--dg-z-pinned-cell:2;--dg-z-focused-cell:3;--dg-z-pinned-row:4;--dg-z-pinned-row-pinned-cell:5;--dg-z-summary-row:4;--dg-z-summary-pinned-cell:5;--dg-z-header:6;--dg-z-header-pinned-cell:7;text-align:left;border:1px solid var(--mantine-color-default-border);border-radius:var(--dg-radius);background-color:var(--mantine-color-body);flex-direction:column;min-height:0;display:flex;overflow:hidden}._columnsPanel_1492o_1{flex-direction:column;width:280px;display:flex}._columnsPanelSearch_1492o_7{padding:var(--mantine-spacing-sm)}._columnsPanelList_1492o_11{gap:var(--mantine-spacing-sm);padding:0 var(--mantine-spacing-sm) var(--mantine-spacing-sm);flex-direction:column;display:flex}._columnsPanelFooter_1492o_18{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-sm);padding:var(--mantine-spacing-sm);border-top:1px solid var(--mantine-color-default-border);display:flex}._detailsToggle_n39tz_3{width:100%;height:100%;color:inherit;justify-content:center;align-items:center;display:flex}._detailsToggle_n39tz_3:hover ._chevron_n39tz_12{color:var(--mantine-color-text)}._chevron_n39tz_12{color:var(--mantine-color-dimmed);align-items:center;transition:transform .12s;display:flex}._chevron_n39tz_12[data-expanded=true]{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){._chevron_n39tz_12{transition:none}}._tableWrapper_uqiy9_2{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}._scrollContainer_uqiy9_10{flex:1;min-height:0;position:relative;overflow:auto;container-type:inline-size}._grid_uqiy9_21{display:grid}._headerRow_uqiy9_27{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-header,6);display:grid;position:sticky;top:0}._headerRow_uqiy9_27[data-dg-header-last]:after{content:"";pointer-events:none;background:linear-gradient(to bottom, var(--dg-header-shadow-color,#00000024), transparent);opacity:0;height:6px;position:absolute;inset:100% 0 auto}@supports (animation-timeline:scroll()){._headerRow_uqiy9_27[data-dg-header-last]:after{animation:linear both _dg-header-shadow_uqiy9_1;animation-timeline:scroll();animation-range:0 24px}}@keyframes _dg-header-shadow_uqiy9_1{0%{opacity:0}to{opacity:1}}._bodyRow_uqiy9_76{--row-bg:var(--mantine-color-body);grid-column:1/-1;grid-template-columns:subgrid;align-items:stretch;display:grid}._bodyRow_uqiy9_76[data-striped=true]{--row-bg:var(--dg-row-striped-bg)}._bodyRow_uqiy9_76:hover{--row-bg:var(--mantine-color-default-hover)}._bodyRow_uqiy9_76[data-grouped=true]{--row-bg:var(--dg-row-group-bg)}._bodyRow_uqiy9_76[data-context-menu=true]{--row-bg:var(--mantine-color-default-hover)}._bodyRow_uqiy9_76[data-selected-bg=true]{--row-bg:var(--dg-row-selected-bg)}._bodyRow_uqiy9_76[data-highlighted=true]{--row-bg:var(--dg-row-highlight-bg)}._bodyRow_uqiy9_76[data-selects-on-click=true]{-webkit-user-select:none;user-select:none}._bodyRow_uqiy9_76:focus-visible{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._bodyCell_uqiy9_143{padding:0 var(--dg-padding);border-bottom:1px solid var(--mantine-color-default-border);background-color:var(--row-bg);font-size:var(--dg-font-size);align-items:center;display:flex}._bodyCell_uqiy9_143[data-control-column=true]{padding:0}._grid_uqiy9_21[data-range-dragging]{-webkit-user-select:none;user-select:none}._bodyCell_uqiy9_143[data-selected=true]{background-color:color-mix(in srgb, var(--mantine-primary-color-filled) 14%, var(--row-bg));--dg-edge-top:transparent;--dg-edge-bottom:transparent;--dg-edge-left:transparent;--dg-edge-right:transparent;box-shadow:inset 0 1px 0 0 var(--dg-edge-top), inset 0 -1px 0 0 var(--dg-edge-bottom), inset 1px 0 0 0 var(--dg-edge-left), inset -1px 0 0 0 var(--dg-edge-right)}._bodyCell_uqiy9_143[data-edge-top=true]{--dg-edge-top:var(--mantine-primary-color-filled)}._bodyCell_uqiy9_143[data-edge-bottom=true]{--dg-edge-bottom:var(--mantine-primary-color-filled)}._bodyCell_uqiy9_143[data-edge-left=true]{--dg-edge-left:var(--mantine-primary-color-filled)}._bodyCell_uqiy9_143[data-edge-right=true]{--dg-edge-right:var(--mantine-primary-color-filled)}._bodyCell_uqiy9_143[data-focused=true]{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._cellContent_uqiy9_141{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._bodyCell_uqiy9_143[data-editing]{padding:0 calc(var(--dg-padding) / 2)}._cellEditor_uqiy9_243{align-items:center;gap:2px;width:100%;min-width:0;display:flex}._cellEditorActions_uqiy9_252{flex:none;align-items:center;display:flex}._bodyCell_uqiy9_143[data-dirty],._bodyCell_uqiy9_143[data-invalid]{position:relative}._bodyCell_uqiy9_143[data-dirty]:after,._bodyCell_uqiy9_143[data-invalid]:after{content:"";border:5px solid #0000;border-top-color:var(--mantine-primary-color-filled);border-right-color:var(--mantine-primary-color-filled);position:absolute;top:0;right:0}._bodyCell_uqiy9_143[data-invalid]:after{border-top-color:var(--mantine-color-error);border-right-color:var(--mantine-color-error)}._bodyCell_uqiy9_143[data-align=right]{justify-content:flex-end}._bodyCell_uqiy9_143[data-align=center]{justify-content:center}._bodyCell_uqiy9_143[data-align=left] ._cellContent_uqiy9_141{flex:auto}._detailsCell_uqiy9_303{border-bottom:1px solid var(--mantine-color-default-border);background-color:var(--row-bg);padding:var(--dg-padding);-webkit-user-select:text;user-select:text;cursor:auto;grid-column:1/-1}._messageRow_uqiy9_15{justify-content:center;justify-self:start;align-items:center;gap:var(--mantine-spacing-xs);width:100cqi;padding:var(--mantine-spacing-xl);flex-direction:column;grid-column:1/-1;display:flex;position:sticky;left:0}._bodyRow_uqiy9_76[data-deleted=true]{opacity:.55;text-decoration:line-through}._bodyRow_uqiy9_76[data-deleted=true] ._bodyCell_uqiy9_143:not([data-control-column=true]){pointer-events:none}._entryBlock_uqiy9_353{grid-column:1/-1;grid-template-columns:subgrid;top:var(--dg-header-height,0px);z-index:var(--dg-z-pinned-row,4);display:grid;position:sticky}._entryRow_uqiy9_362,._entryFlowBlock_uqiy9_371{grid-column:1/-1;grid-template-columns:subgrid;display:grid}._pinnedTopBlock_uqiy9_384{grid-column:1/-1;grid-template-columns:subgrid;top:calc(var(--dg-header-height,0px) + var(--dg-entry-height,0px));z-index:var(--dg-z-pinned-row,4);display:grid;position:sticky}._pinnedTopBlock_uqiy9_384>:last-child>[role=cell]{border-bottom:2px solid var(--mantine-color-default-border)}._pinnedBottomBlock_uqiy9_397{grid-column:1/-1;grid-template-columns:subgrid;bottom:var(--dg-summary-height,0px);z-index:var(--dg-z-pinned-row,4);display:grid;position:sticky}._pinnedBottomBlock_uqiy9_397>:first-child>[role=cell]{border-top:2px solid var(--mantine-color-default-border)}._entryCell_uqiy9_410{padding:0 calc(var(--dg-padding) / 2);border-bottom:2px solid var(--mantine-primary-color-filled);background-color:var(--mantine-color-body);font-size:var(--dg-font-size);align-items:center;display:flex}._entryCell_uqiy9_410[data-control-column=true]{justify-content:center;padding:0}._entryRow_uqiy9_362[data-confirmed=true] ._entryCell_uqiy9_410{padding:0 var(--dg-padding);border-bottom:1px solid var(--mantine-color-default-border);background-color:var(--dg-row-new-bg,var(--mantine-color-body))}._entryRow_uqiy9_362[data-confirmed=true] ._entryCell_uqiy9_410[data-control-column=true]{padding:0}._rowStateIndicator_uqiy9_440{width:22px;height:22px;color:var(--mantine-color-dimmed);flex:none;justify-content:center;align-items:center;display:inline-flex}._rowStateIndicator_uqiy9_440[data-error]{color:var(--mantine-color-error)}._entryCell_uqiy9_410[data-align=right]{justify-content:flex-end}._entryCell_uqiy9_410[data-align=center]{justify-content:center}._matchHighlight_uqiy9_466{background-color:var(--dg-match-highlight-bg,var(--lightningcss-light,var(--mantine-color-yellow-2))var(--lightningcss-dark,#fab00559));color:inherit;border-radius:2px}._summaryRow_uqiy9_478{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-summary-row,4);display:grid;position:sticky;bottom:0}._summaryCell_uqiy9_487{padding:0 var(--dg-padding);border-top:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);font-size:var(--dg-font-size);align-items:center;font-weight:600;display:flex}._summaryCell_uqiy9_487[data-control-column=true]{padding:0}._summaryCell_uqiy9_487[data-align=right]{justify-content:flex-end}._summaryCell_uqiy9_487[data-align=center]{justify-content:center}._groupToggle_1954o_4{width:100%;min-width:0;font-size:var(--dg-font-size);color:inherit;align-items:center;gap:6px;display:flex}._chevron_1954o_14{color:var(--mantine-color-dimmed);flex:none;align-items:center;transition:transform .12s;display:flex}._chevron_1954o_14[data-expanded=true]{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){._chevron_1954o_14{transition:none}}._groupLabel_1954o_34{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}._groupCount_1954o_44{color:var(--mantine-color-dimmed);font-variant-numeric:tabular-nums;flex:none}._filterPanel_izakx_4{top:calc(var(--dg-header-height) + 2px);left:var(--mantine-spacing-md);z-index:5;padding:var(--mantine-spacing-sm);border-radius:var(--mantine-radius-md);border:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);box-shadow:var(--mantine-shadow-md);position:absolute}._filterRow_izakx_16{align-items:flex-end;gap:var(--mantine-spacing-xs);display:flex}._filterPanelHeader_izakx_22{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-md);padding-bottom:var(--mantine-spacing-xs);display:flex}._filterPanelFooter_izakx_30{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-md);display:flex}._filterPills_14wl0_3{align-items:center;gap:var(--mantine-spacing-xs);flex-wrap:wrap;display:flex}._filterPills_14wl0_3 ._pill_14wl0_15{background-color:var(--lightningcss-light,var(--mantine-color-gray-1))var(--lightningcss-dark,var(--mantine-color-dark-5));color:var(--lightningcss-light,var(--mantine-color-black))var(--lightningcss-dark,var(--mantine-color-dark-0));border:1px solid var(--lightningcss-light,var(--mantine-color-gray-3))var(--lightningcss-dark,var(--mantine-color-dark-3))}._pillLabel_14wl0_27{font:inherit;color:inherit;cursor:pointer}._pillLabel_14wl0_27:hover{text-decoration:underline}._footer_te0a3_1{justify-content:flex-end;align-items:center;gap:var(--mantine-spacing-lg);padding:4px var(--mantine-spacing-sm);border-top:1px solid var(--mantine-color-default-border);flex-shrink:0;min-height:48px;display:flex}._footer_te0a3_1[data-paging-suspended=true]{opacity:.55}._stickyLeft_1vw51_16:after,._stickyRight_1vw51_17:after{content:"";pointer-events:none;width:8px;position:absolute;top:0;bottom:0}._stickyLeft_1vw51_16:after{background:linear-gradient(90deg,var(--lightningcss-light,#00000012)var(--lightningcss-dark,#00000042),var(--lightningcss-light,#00000006)var(--lightningcss-dark,#00000017) 45%,#0000);left:100%}._stickyRight_1vw51_17:after{background:linear-gradient(270deg,var(--lightningcss-light,#00000012)var(--lightningcss-dark,#00000042),var(--lightningcss-light,#00000006)var(--lightningcss-dark,#00000017) 45%,#0000);right:100%}@supports (animation-timeline:scroll()){._stickyLeft_1vw51_16:after,._stickyRight_1vw51_17:after{--dg-sticky-edge-range:20px;opacity:0;animation-timing-function:linear;animation-fill-mode:both;animation-timeline:scroll(inline)}._stickyLeft_1vw51_16:after{animation-name:_stickyEdgeIn_1vw51_1;animation-range:0 var(--dg-sticky-edge-range)}._stickyRight_1vw51_17:after{animation-name:_stickyEdgeOut_1vw51_1;animation-range:calc(100% - var(--dg-sticky-edge-range)) 100%}}@keyframes _stickyEdgeIn_1vw51_1{0%{opacity:0}to{opacity:1}}@keyframes _stickyEdgeOut_1vw51_1{0%{opacity:1}to{opacity:0}}._headerCell_188ed_1{padding:0 var(--dg-padding);min-width:0;min-height:var(--dg-header-height);font-weight:600;font-size:var(--dg-font-size);background-color:var(--mantine-color-body);border-bottom:1px solid var(--mantine-color-default-border);-webkit-user-select:none;user-select:none;align-items:center;gap:2px;display:flex;position:relative}._headerCell_188ed_1[data-align=right]{justify-content:flex-end}._headerCell_188ed_1[data-align=center]{justify-content:center}._headerCell_188ed_1[data-control-column=true]{padding:0}._headerCellFiltered_188ed_35 ._headerTitle_188ed_35{color:var(--mantine-primary-color-filled)}._headerTitle_188ed_35{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}._headerCell_188ed_1[data-align=right] ._headerTitle_188ed_35{text-align:right}._headerCell_188ed_1[data-align=center] ._headerTitle_188ed_35{justify-content:center;display:flex}._headerActions_188ed_58{flex-shrink:0;align-items:center;gap:0;margin-left:auto;display:flex}._headerCell_188ed_1[data-align=right] ._headerActions_188ed_58{order:-1;margin-left:0;margin-right:auto}._headerAction_188ed_58{display:none}._headerCell_188ed_1:hover ._headerAction_188ed_58,._headerCell_188ed_1:focus-within ._headerAction_188ed_58,._headerAction_188ed_58[data-pinned-visible=true]{display:flex}._headerCellSortable_188ed_87{cursor:pointer}._sortAction_188ed_93[data-sorted=false]{opacity:.55}._sortAction_188ed_93[data-sorted=false]:hover{opacity:1}._sortIndex_188ed_103{color:var(--mantine-color-dimmed);text-align:center;min-width:10px;font-size:10px;font-weight:600;line-height:1}._headerCellDragging_188ed_115{opacity:.4}._headerCellDropBefore_188ed_119:before,._headerCellDropAfter_188ed_120:before{content:"";background-color:var(--mantine-primary-color-filled);z-index:5;pointer-events:none;width:2px;position:absolute;top:0;bottom:0}._headerCellDropBefore_188ed_119:before{left:0}._headerCellDropAfter_188ed_120:before{right:0}._columnSeparator_188ed_140{z-index:1;justify-content:center;width:10px;height:50%;display:flex;position:absolute;top:25%;right:0;transform:translate(50%)}._columnSeparatorResizable_188ed_152{cursor:col-resize;touch-action:none}._columnSeparator_188ed_140:after{content:"";background-color:#0000;width:1px;height:100%;transition:background-color .12s,width .12s}._headerCell_188ed_1:hover ._columnSeparator_188ed_140:after,._headerCell_188ed_1:focus-within ._columnSeparator_188ed_140:after{background-color:var(--mantine-color-default-border)}._columnSeparatorResizable_188ed_152:hover:after,._columnSeparatorActive_188ed_175:after{background-color:var(--mantine-primary-color-filled);width:2px}._menuItemActive_188ed_181{background-color:var(--mantine-color-default-hover);font-weight:600}._toolbar_4my8t_1{align-items:center;gap:var(--mantine-spacing-xs);padding:6px var(--mantine-spacing-xs);flex-shrink:0;min-height:42px;display:flex}._toolbarSpacer_4my8t_10{flex:1}
1
+ ._root_1kqd2_8[data-size=xs]{--dg-row-height:34px;--dg-header-height:32px;--dg-font-size:var(--mantine-font-size-xs);--dg-padding:6px}._root_1kqd2_8[data-size=sm]{--dg-row-height:42px;--dg-header-height:38px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:8px}._root_1kqd2_8[data-size=md]{--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px}._root_1kqd2_8[data-size=lg]{--dg-row-height:62px;--dg-header-height:52px;--dg-font-size:var(--mantine-font-size-md);--dg-padding:14px}._root_1kqd2_8[data-size=xl]{--dg-row-height:72px;--dg-header-height:60px;--dg-font-size:var(--mantine-font-size-lg);--dg-padding:18px}._root_1kqd2_8{--dg-radius:var(--mantine-radius-md);--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px;--dg-row-selected-bg:var(--mantine-primary-color-light);--dg-row-highlight-bg:var(--mantine-primary-color-light-hover);--dg-row-group-bg:var(--mantine-color-body);--dg-row-striped-bg:color-mix(in srgb, var(--mantine-color-text) 3.5%, var(--mantine-color-body));--dg-row-new-bg:color-mix(in srgb, var(--mantine-color-green-6) 8%, var(--mantine-color-body));--dg-z-focused-cell:1;--dg-z-pinned-cell:2;--dg-z-pinned-focused-cell:3;--dg-z-pinned-row:4;--dg-z-pinned-row-pinned-cell:5;--dg-z-summary-row:4;--dg-z-summary-pinned-cell:5;--dg-z-header:6;--dg-z-header-pinned-cell:7;text-align:left;border:1px solid var(--mantine-color-default-border);border-radius:var(--dg-radius);background-color:var(--mantine-color-body);flex-direction:column;min-height:0;display:flex;overflow:hidden}._columnsPanel_a5do5_1{flex-direction:column;width:280px;display:flex}._columnsPanelSearch_a5do5_7{padding:var(--mantine-spacing-sm)}._columnsPanelList_a5do5_11{gap:var(--mantine-spacing-sm);padding:var(--mantine-spacing-sm);flex-direction:column;display:flex}._columnsPanelSearch_a5do5_7+* ._columnsPanelList_a5do5_11{padding-top:0}._columnsPanelFooter_a5do5_22{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-sm);padding:var(--mantine-spacing-sm);border-top:1px solid var(--mantine-color-default-border);display:flex}._detailsToggle_n39tz_3{width:100%;height:100%;color:inherit;justify-content:center;align-items:center;display:flex}._detailsToggle_n39tz_3:hover ._chevron_n39tz_12{color:var(--mantine-color-text)}._chevron_n39tz_12{color:var(--mantine-color-dimmed);align-items:center;transition:transform .12s;display:flex}._chevron_n39tz_12[data-expanded=true]{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){._chevron_n39tz_12{transition:none}}._tableWrapper_bdal6_2{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}._tableWrapper_bdal6_2[data-dg-filter-sidebar]{flex-direction:row}._scrollContainer_bdal6_17{flex:1;min-width:0;min-height:0;position:relative;overflow:auto;container-type:inline-size}._grid_bdal6_29{align-content:start;min-height:100%;display:grid}._tabGuard_bdal6_44{outline:none;width:0;height:0;position:absolute;overflow:hidden}._headerRow_bdal6_54{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-header,6);display:grid;position:sticky;top:0}._bodyRow_bdal6_63{--row-bg:var(--mantine-color-body);grid-column:1/-1;grid-template-columns:subgrid;align-items:stretch;display:grid}._bodyRow_bdal6_63[data-striped=true]{--row-bg:var(--dg-row-striped-bg)}._bodyRow_bdal6_63[data-new=true]{--row-bg:var(--dg-row-new-bg,var(--mantine-color-body))}._bodyRow_bdal6_63:hover{--row-bg:var(--mantine-color-default-hover)}._bodyRow_bdal6_63[data-grouped=true]{--row-bg:var(--dg-row-group-bg)}._bodyRow_bdal6_63[data-context-menu=true]{--row-bg:var(--mantine-color-default-hover)}._bodyRow_bdal6_63[data-selected-bg=true]{--row-bg:var(--dg-row-selected-bg)}._bodyRow_bdal6_63[data-highlighted=true]{--row-bg:var(--dg-row-highlight-bg)}._bodyRow_bdal6_63[data-selects-on-click=true]{-webkit-user-select:none;user-select:none}._bodyRow_bdal6_63:focus-visible{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._bodyCell_bdal6_137{padding:0 var(--dg-padding);border-bottom:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);background-image:linear-gradient(var(--row-bg), var(--row-bg));font-size:var(--dg-font-size);align-items:center;display:flex}._bodyCell_bdal6_137[data-control-column=true]{padding:0}._grid_bdal6_29[data-range-dragging]{-webkit-user-select:none;user-select:none}._bodyCell_bdal6_137[data-selected=true]{--dg-range-tint:color-mix(in srgb, var(--mantine-primary-color-filled) 14%, var(--row-bg));background-image:linear-gradient(var(--dg-range-tint), var(--dg-range-tint));--dg-edge-top:transparent;--dg-edge-bottom:transparent;--dg-edge-left:transparent;--dg-edge-right:transparent;box-shadow:inset 0 1px 0 0 var(--dg-edge-top), inset 0 -1px 0 0 var(--dg-edge-bottom), inset 1px 0 0 0 var(--dg-edge-left), inset -1px 0 0 0 var(--dg-edge-right)}._bodyCell_bdal6_137[data-edge-top=true]{--dg-edge-top:var(--mantine-primary-color-filled)}._bodyCell_bdal6_137[data-edge-bottom=true]{--dg-edge-bottom:var(--mantine-primary-color-filled)}._bodyCell_bdal6_137[data-edge-left=true]{--dg-edge-left:var(--mantine-primary-color-filled)}._bodyCell_bdal6_137[data-edge-right=true]{--dg-edge-right:var(--mantine-primary-color-filled)}._bodyCell_bdal6_137[data-focused=true]{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._cellContent_bdal6_135{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._bodyCell_bdal6_137[data-editing]{padding:0 calc(var(--dg-padding) / 2)}._cellEditor_bdal6_244{align-items:center;gap:2px;width:100%;min-width:0;display:flex}._cellEditorField_bdal6_254{flex:auto;align-items:center;min-width:0;display:flex}._cellEditorActions_bdal6_262{flex:none;align-items:center;display:flex}._bodyCell_bdal6_137[data-dirty],._bodyCell_bdal6_137[data-invalid],._entryCell_bdal6_275[data-invalid]{position:relative}._bodyCell_bdal6_137[data-dirty]:after,._bodyCell_bdal6_137[data-invalid]:after,._entryCell_bdal6_275[data-invalid]:after{content:"";border:5px solid #0000;border-top-color:var(--mantine-primary-color-filled);border-right-color:var(--mantine-primary-color-filled);position:absolute;top:0;right:0}._bodyCell_bdal6_137[data-invalid]:after,._entryCell_bdal6_275[data-invalid]:after{border-top-color:var(--mantine-color-error);border-right-color:var(--mantine-color-error)}._bodyCell_bdal6_137[data-align=right]{justify-content:flex-end}._bodyCell_bdal6_137[data-align=center]{justify-content:center}._bodyCell_bdal6_137[data-align=left] ._cellContent_bdal6_135{flex:auto}._detailsCell_bdal6_317{border-bottom:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);background-image:linear-gradient(var(--row-bg), var(--row-bg));padding:var(--dg-padding);-webkit-user-select:text;user-select:text;cursor:auto;grid-column:1/-1}._messageRow_bdal6_23{justify-content:center;justify-self:start;align-items:center;gap:var(--mantine-spacing-xs);width:100cqi;padding:var(--mantine-spacing-xl);flex-direction:column;grid-column:1/-1;display:flex;position:sticky;left:0}._bodyRow_bdal6_63[data-deleted=true]{opacity:.55;text-decoration:line-through}._bodyRow_bdal6_63[data-deleted=true] ._bodyCell_bdal6_137:not([data-control-column=true]){pointer-events:none}._entryBlock_bdal6_369{grid-column:1/-1;grid-template-columns:subgrid;top:var(--dg-header-height,0px);z-index:var(--dg-z-pinned-row,4);display:grid;position:sticky}._entryRow_bdal6_378{grid-column:1/-1;grid-template-columns:subgrid;display:grid}._pinnedTopBlock_bdal6_391{grid-column:1/-1;grid-template-columns:subgrid;top:calc(var(--dg-header-height,0px) + var(--dg-entry-height,0px));z-index:var(--dg-z-pinned-row,4);display:grid;position:sticky}._pinnedTopBlock_bdal6_391>:last-child>[role=cell]{border-bottom:2px solid var(--mantine-color-default-border)}._pinnedBottomBlock_bdal6_404{grid-column:1/-1;grid-template-columns:subgrid;bottom:var(--dg-summary-height,0px);z-index:var(--dg-z-pinned-row,4);display:grid;position:sticky}._pinnedBottomBlock_bdal6_404>:first-child>[role=cell]{border-top:2px solid var(--mantine-color-default-border)}._entryCell_bdal6_275{padding:0 calc(var(--dg-padding) / 2);border-bottom:2px solid var(--mantine-primary-color-filled);background-color:var(--mantine-color-body);font-size:var(--dg-font-size);align-items:center;display:flex}._entryCell_bdal6_275[data-control-column=true]{justify-content:center;padding:0}._entryRow_bdal6_378[data-committed=true] ._entryCell_bdal6_275{padding:0 var(--dg-padding);border-bottom:1px solid var(--mantine-color-default-border);background-image:linear-gradient(var(--dg-row-new-bg,transparent), var(--dg-row-new-bg,transparent))}._entryRow_bdal6_378[data-committed=true] ._entryCell_bdal6_275[data-control-column=true]{padding:0}._rowStateIndicator_bdal6_453{width:22px;height:22px;color:var(--mantine-color-dimmed);flex:none;justify-content:center;align-items:center;display:inline-flex}._rowStateIndicator_bdal6_453[data-error]{color:var(--mantine-color-error)}._entryCell_bdal6_275[data-align=right]{justify-content:flex-end}._entryCell_bdal6_275[data-align=center]{justify-content:center}._matchHighlight_bdal6_479{background-color:var(--dg-match-highlight-bg,var(--lightningcss-light,var(--mantine-color-yellow-2))var(--lightningcss-dark,#fab00559));color:inherit;border-radius:2px}._summaryRow_bdal6_500{grid-column:1/-1;grid-template-columns:subgrid;top:calc(100% - var(--dg-summary-height,0px));z-index:var(--dg-z-summary-row,4);display:grid;position:sticky;bottom:0}._summaryCell_bdal6_510{padding:0 var(--dg-padding);border-top:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);font-size:var(--dg-font-size);align-items:center;font-weight:600;display:flex}._summaryCell_bdal6_510[data-control-column=true]{padding:0}._summaryCell_bdal6_510[data-align=right]{justify-content:flex-end}._summaryCell_bdal6_510[data-align=center]{justify-content:center}._groupToggle_1954o_4{width:100%;min-width:0;font-size:var(--dg-font-size);color:inherit;align-items:center;gap:6px;display:flex}._chevron_1954o_14{color:var(--mantine-color-dimmed);flex:none;align-items:center;transition:transform .12s;display:flex}._chevron_1954o_14[data-expanded=true]{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){._chevron_1954o_14{transition:none}}._groupLabel_1954o_34{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}._groupCount_1954o_44{color:var(--mantine-color-dimmed);font-variant-numeric:tabular-nums;flex:none}._filterPanel_wm77f_4{gap:var(--mantine-spacing-xs);flex-direction:column;display:flex}._filterRow_wm77f_12{align-items:flex-end;gap:var(--mantine-spacing-xs);display:flex}._filterRow_wm77f_12[data-layout=stacked]{align-items:end;gap:6px var(--mantine-spacing-xs);padding:var(--mantine-spacing-xs);border:1px solid var(--mantine-color-default-border);border-radius:var(--mantine-radius-sm);grid-template-columns:1fr auto;display:grid}._filterRow_wm77f_12[data-layout=stacked] ._filterRemove_wm77f_32{grid-area:1/2}._filterRow_wm77f_12[data-layout=stacked] ._filterColumnSlot_wm77f_37{grid-area:1/1;min-width:0}._filterRow_wm77f_12[data-layout=stacked] ._filterOperatorSlot_wm77f_43,._filterRow_wm77f_12[data-layout=stacked] ._filterValueSlot_wm77f_44{grid-column:1/-1;min-width:0}._filterPanelFooter_wm77f_49{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-md);display:flex}._filterPills_14wl0_3{align-items:center;gap:var(--mantine-spacing-xs);flex-wrap:wrap;display:flex}._filterPills_14wl0_3 ._pill_14wl0_15{background-color:var(--lightningcss-light,var(--mantine-color-gray-1))var(--lightningcss-dark,var(--mantine-color-dark-5));color:var(--lightningcss-light,var(--mantine-color-black))var(--lightningcss-dark,var(--mantine-color-dark-0));border:1px solid var(--lightningcss-light,var(--mantine-color-gray-3))var(--lightningcss-dark,var(--mantine-color-dark-3))}._pillLabel_14wl0_27{font:inherit;color:inherit;cursor:pointer}._pillLabel_14wl0_27:hover{text-decoration:underline}._footer_te0a3_1{justify-content:flex-end;align-items:center;gap:var(--mantine-spacing-lg);padding:4px var(--mantine-spacing-sm);border-top:1px solid var(--mantine-color-default-border);flex-shrink:0;min-height:48px;display:flex}._footer_te0a3_1[data-paging-suspended=true]{opacity:.55}._stickyLeft_1jwnm_16:after,._stickyRight_1jwnm_17:after{content:"";pointer-events:none;width:8px;position:absolute;top:0;bottom:0}._stickyLeft_1jwnm_16:after{background:linear-gradient(90deg,var(--lightningcss-light,#00000012)var(--lightningcss-dark,#00000042),var(--lightningcss-light,#00000006)var(--lightningcss-dark,#00000017) 45%,#0000);left:100%}._stickyRight_1jwnm_17:after{background:linear-gradient(270deg,var(--lightningcss-light,#00000012)var(--lightningcss-dark,#00000042),var(--lightningcss-light,#00000006)var(--lightningcss-dark,#00000017) 45%,#0000);right:100%}@supports (animation-timeline:scroll()){._stickyLeft_1jwnm_16:after,._stickyRight_1jwnm_17:after{--dg-sticky-edge-range:20px;opacity:0;animation-timing-function:linear;animation-fill-mode:both;animation-timeline:scroll(inline)}._stickyLeft_1jwnm_16:after{animation-name:_stickyEdgeIn_1jwnm_1;animation-range:0 var(--dg-sticky-edge-range)}._stickyRight_1jwnm_17:after{animation-name:_stickyEdgeOut_1jwnm_1;animation-range:calc(100% - var(--dg-sticky-edge-range)) 100%}}@keyframes _stickyEdgeIn_1jwnm_1{0%{opacity:0}to{opacity:1}}@keyframes _stickyEdgeOut_1jwnm_1{0%{opacity:1}to{opacity:0}}._headerBoundary_1jwnm_120:after{content:"";pointer-events:none;background:linear-gradient(to bottom, var(--dg-header-shadow-color,#00000024), transparent);opacity:0;height:6px;position:absolute;inset:100% 0 auto}@supports (animation-timeline:scroll()){._headerBoundary_1jwnm_120:after{animation:linear both _dgHeaderShadow_1jwnm_1;animation-timeline:scroll();animation-range:0 24px}}@keyframes _dgHeaderShadow_1jwnm_1{0%{opacity:0}to{opacity:1}}._surfaceHeader_10bcx_5{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-md);padding-bottom:var(--mantine-spacing-xs);display:flex}._filterPopup_10bcx_18{top:calc(var(--dg-header-stack-height,var(--dg-header-height)) + 2px);left:var(--mantine-spacing-md);z-index:var(--dg-z-filter-popup,20);padding:var(--mantine-spacing-sm);border-radius:var(--mantine-radius-md);border:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);box-shadow:var(--mantine-shadow-md);position:absolute}._filterSidebar_10bcx_33{min-width:0;padding:var(--mantine-spacing-sm);background-color:var(--mantine-color-body);border-left:1px solid var(--mantine-color-default-border);flex-direction:column;flex:none;display:flex}._filterSidebar_10bcx_33[data-side=left]{border-left:none;border-right:1px solid var(--mantine-color-default-border);order:-1}._filterSidebarBody_10bcx_51{flex:1;min-height:0}._headerFilterRow_h1geg_9{grid-column:1/-1;grid-template-columns:subgrid;top:var(--dg-header-height);z-index:var(--dg-z-header,6);display:grid;position:sticky}._headerFilterCell_h1geg_18{min-width:0;padding:calc(var(--dg-padding) / 2);background-color:var(--mantine-color-body);border-bottom:1px solid var(--mantine-color-default-border);align-items:center;gap:2px;display:flex;overflow:hidden}._headerFilterCell_h1geg_18[data-control-column=true]{padding:0}._headerFilterValue_h1geg_39{flex:1;min-width:0}._headerFilterOperator_h1geg_44{flex:none}._operatorItemActive_h1geg_48{color:var(--mantine-primary-color-filled);font-weight:600}._headerCell_apk7q_1{padding:0 var(--dg-padding);min-width:0;min-height:var(--dg-header-height);font-weight:600;font-size:var(--dg-font-size);background-color:var(--mantine-color-body);border-bottom:1px solid var(--mantine-color-default-border);-webkit-user-select:none;user-select:none;align-items:center;gap:2px;display:flex;position:relative}._headerCell_apk7q_1[data-align=right]{justify-content:flex-end}._headerCell_apk7q_1[data-align=center]{justify-content:center}._headerCell_apk7q_1[data-control-column=true]{padding:0}._headerCellFiltered_apk7q_35 ._headerTitle_apk7q_35{color:var(--mantine-primary-color-filled)}._headerTitle_apk7q_35{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}._headerCell_apk7q_1[data-align=right] ._headerTitle_apk7q_35{text-align:right}._headerCell_apk7q_1[data-align=center] ._headerTitle_apk7q_35{justify-content:center;display:flex}._headerActions_apk7q_58{flex-shrink:0;align-items:center;gap:0;margin-left:auto;display:flex}._headerCell_apk7q_1[data-align=right] ._headerActions_apk7q_58{order:-1;margin-left:0;margin-right:auto}._headerAction_apk7q_58{display:none}._headerCell_apk7q_1:hover ._headerAction_apk7q_58,._headerCell_apk7q_1:focus-within ._headerAction_apk7q_58,._headerAction_apk7q_58[data-pinned-visible=true]{display:flex}._headerCellSortable_apk7q_87{cursor:pointer}._sortAction_apk7q_93[data-sorted=false]{opacity:.55}._sortAction_apk7q_93[data-sorted=false]:hover{opacity:1}._sortIndex_apk7q_103{color:var(--mantine-color-dimmed);text-align:center;min-width:10px;font-size:10px;font-weight:600;line-height:1}._headerCellDragging_apk7q_115{opacity:.4}._headerCellDropBefore_apk7q_119:before,._headerCellDropAfter_apk7q_120:before{content:"";background-color:var(--mantine-primary-color-filled);z-index:5;pointer-events:none;width:2px;position:absolute;top:0;bottom:0}._headerCellDropBefore_apk7q_119:before{left:0}._headerCellDropAfter_apk7q_120:before{right:0}._columnSeparator_apk7q_140{z-index:1;justify-content:center;width:10px;height:50%;display:flex;position:absolute;top:25%;right:0;transform:translate(50%)}._headerCell_apk7q_1:last-child ._columnSeparator_apk7q_140{justify-content:flex-end;transform:none}._columnSeparatorResizable_apk7q_162{cursor:col-resize;touch-action:none}._columnSeparator_apk7q_140:after{content:"";background-color:#0000;width:1px;height:100%;transition:background-color .12s,width .12s}._headerCell_apk7q_1:hover ._columnSeparator_apk7q_140:after,._headerCell_apk7q_1:focus-within ._columnSeparator_apk7q_140:after{background-color:var(--mantine-color-default-border)}._columnSeparatorResizable_apk7q_162:hover:after,._columnSeparatorActive_apk7q_185:after{background-color:var(--mantine-primary-color-filled);width:2px}._menuItemActive_apk7q_191{background-color:var(--mantine-color-default-hover);font-weight:600}._toolbar_gwk05_1{align-items:center;gap:var(--mantine-spacing-xs);padding:6px var(--mantine-spacing-xs);flex-shrink:0;min-height:42px;display:flex}._toolbar_gwk05_1[data-with-bottom-border]{border-bottom:1px solid var(--mantine-color-default-border)}._toolbarSpacer_gwk05_15{flex:1}._summaryCount_gwk05_19{white-space:nowrap}._title_199r2_1{font-weight:500}._list_199r2_5{border:1px solid var(--mantine-color-default-border);border-radius:var(--mantine-radius-default);flex-direction:column;display:flex;overflow:hidden}._listHeader_199r2_13{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-sm);padding:var(--mantine-spacing-xs) var(--mantine-spacing-sm);background-color:var(--mantine-color-default-hover);border-bottom:1px solid var(--mantine-color-default-border);display:flex}._headerLabel_199r2_23{cursor:pointer;font-weight:500}._rows_199r2_28{padding:calc(var(--mantine-spacing-xs) / 2) 0;flex-direction:column;display:flex}._row_199r2_28{padding:0 var(--mantine-spacing-sm)}._row_199r2_28:hover{background-color:var(--mantine-color-default-hover)}._rowBody_199r2_45{align-items:center}._rowLabelWrapper_199r2_49{flex:1;min-width:0}._rowLabel_199r2_49{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-sm);padding-block:calc(var(--mantine-spacing-xs) * .75);cursor:pointer;display:flex}._rowText_199r2_63{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._rowHint_199r2_69{font-size:var(--mantine-font-size-xs);color:var(--mantine-color-dimmed);flex:none}._empty_199r2_75{padding:var(--mantine-spacing-xs) var(--mantine-spacing-sm)}
2
2
  /*$vite$:1*/
@@ -0,0 +1,102 @@
1
+ # Grid anatomy
2
+
3
+ A grid is a tree of components inside the `TMDataGrid` wrapper. Parts are
4
+ opt-in: a grid containing only `<TMDataGrid.Table />` has no toolbar, footer or
5
+ search. Add the built-in parts you need, configure them, or add components of
6
+ your own.
7
+
8
+ `useTMDataGrid` returns the props `TMDataGrid` takes:
9
+
10
+ ```tsx
11
+ const grid = useTMDataGrid({ data, columns });
12
+
13
+ <TMDataGrid {...grid} style={{ flex: 1, minHeight: 0 }} size="xs">
14
+ <TMDataGrid.Toolbar>
15
+ <TMDataGrid.Search />
16
+ <TMDataGrid.Spacer />
17
+ <TMDataGrid.FilterButton />
18
+ <TMDataGrid.Menu>
19
+ <TMDataGrid.Menu.Columns />
20
+ </TMDataGrid.Menu>
21
+ </TMDataGrid.Toolbar>
22
+ <TMDataGrid.Table />
23
+ <TMDataGrid.Footer />
24
+ </TMDataGrid>
25
+ ```
26
+
27
+ ## The parts
28
+
29
+ Every component below reads the grid from context and must be rendered inside
30
+ `TMDataGrid`.
31
+
32
+ | Component | What it is | Documented on |
33
+ | ----------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------- |
34
+ | `TMDataGrid.Table` | The scrollable surface: header, virtualized body, filter panel | This page |
35
+ | `TMDataGrid.Toolbar` | A flex row above the grid | [Toolbar](/docs/toolbar) |
36
+ | `TMDataGrid.Footer` | The pager bar below it | [Pagination](/docs/pagination) |
37
+ | `TMDataGrid.Search` | Quick search input | [Quick search](/docs/quick-search) |
38
+ | `TMDataGrid.FilterButton` · `.FilterPanel` | The filter UI | [Filtering](/docs/filtering) |
39
+ | `TMDataGrid.FilterPills` | Active filters as pills. Also exported as `TMDataGridFilterPills` | [Filtering](/docs/filtering#tmdatagridfilterpills) |
40
+ | `TMDataGrid.Menu` · `.ColumnsPanel` | The burger menu, and the column chooser | [Grid menu](/docs/menu) |
41
+ | `TMDataGrid.Spacer` | Pushes following toolbar items right | [Toolbar](/docs/toolbar) |
42
+ | `TMDataGrid.LoadingIndicator` · `.SummaryCount` | Fetch spinner, and the row count | [Loading and empty states](/docs/loading-and-empty) |
43
+ | `TMDataGrid.DraftActions` | Save and Discard for pending edits. Also exported as `TMDataGridDraftActions` | [Editing](/docs/editing#the-draft-store) |
44
+
45
+ `FilterPills` is the exception: it takes the grid as an `api` prop and can be
46
+ rendered outside `TMDataGrid`, since an active-filter strip often sits above
47
+ the grid it describes.
48
+
49
+ The parts that can be rendered outside the grid are exported under both
50
+ spellings - `TMDataGrid.FilterPills` and `TMDataGridFilterPills` are the same
51
+ component, and so are the `Search` and `DraftActions` pairs. Every other part
52
+ is reached only through the `TMDataGrid` object.
53
+
54
+ ## `TMDataGrid.Table`
55
+
56
+ The scrollable surface: the header, the virtualized body and the filter panel.
57
+ Pass the row type so the handlers are typed:
58
+
59
+ ```tsx
60
+ <TMDataGrid.Table<Employee> onRowClick={(row) => open(row.original.id)} />
61
+ ```
62
+
63
+ Its props, and those of `TMDataGrid` itself, are listed once, on
64
+ [Components and hooks](/docs/components#tmdatagridtable). This page says what
65
+ each part is and which page documents it; that page says what every prop does.
66
+
67
+ Set `aria-label` on any page holding more than one grid: it is what a screen
68
+ reader announces on entry, and what `getByRole("grid", { name })` matches.
69
+
70
+ ### Which rows it renders
71
+
72
+ With pagination off (the default) rows come from
73
+ `getPrePaginatedRowModel()`: every filtered and sorted row, virtualized. With
74
+ pagination on they come from `getPaginatedRowModel()`, so a
75
+ [`manualPagination`](/docs/server-side) grid renders exactly the page the server
76
+ returned.
77
+
78
+ ## What the hook returns
79
+
80
+ `useTMDataGrid` returns the table instance, the UI store, the edit engine, the
81
+ resolved labels and the feature flags, along with `resetSettings`,
82
+ `scrollToRow` and the details options it passes through to the Table. The
83
+ [complete list, with types](/docs/components#usetmdatagrid), is on Components
84
+ and hooks; the [options it takes](/docs/use-tm-data-grid) are their own page.
85
+
86
+ Read state through TanStack Store's
87
+ [`useSelector(table.store, …)`](https://tanstack.com/store/latest/docs/framework/react/reference)
88
+ rather than calling methods on `table`. The table identity is stable across
89
+ renders, so the React Compiler caches a bare method call and the component
90
+ stops updating.
91
+
92
+ ## Reference
93
+
94
+ | Name | Kind | Type | Default | What it does |
95
+ | ------------------------------------------------------------------------------------ | --------- | ------------------------------ | ------- | ---------------------------------------------------- |
96
+ | `useTMDataGrid` | Hook | `(options) => TMDataGridApi` | – | Creates the grid's table, UI state and edit engine. |
97
+ | `TMDataGrid` | Component | – | – | The root element. Provides the grid through context. |
98
+ | `TMDataGrid.Table` | Component | – | – | Header, virtualized body and filter panel. |
99
+ | `data-testid` | Prop | `string` | – | Names the grid for tests. |
100
+ | `aria-label` · `aria-labelledby` | Props | `string` | – | The grid's accessible name. |
101
+ | `useTMDataGridContext` | Hook | `() => TMDataGridContextValue` | – | The grid, from inside any child. |
102
+ | `TMDataGridApi` · `TMDataGridTable` · `TMDataGridUiStore` · `TMDataGridFeatureFlags` | Exports | types | – | The hook's result and its parts. |
@@ -0,0 +1,154 @@
1
+ # Cell selection and copy
2
+
3
+ A cell cursor moved with the arrow keys, a rectangle of cells that can be
4
+ dragged out, and Ctrl+C that pastes into Excel as cells rather than as one
5
+ string. Off by default; `cellSelection` turns it on.
6
+
7
+ ```tsx
8
+ const grid = useTMDataGrid({ data, columns, cellSelection: "range" });
9
+ ```
10
+
11
+ | Mode | What it gives |
12
+ | ---- | ------------- |
13
+ | `"none"` | Nothing. The default |
14
+ | `"single"` | One focused cell, moved with the arrow keys |
15
+ | `"range"` | As `"single"`, plus a rectangle of cells, Ctrl+C and the export menu |
16
+
17
+ ```demo
18
+ file: cells/CellSelection.tsx
19
+ hint: Tab into the grid, then arrows to move · Shift+arrows or drag to select a block. However many cells it holds, the whole grid is one tab stop.
20
+ ```
21
+
22
+ Turning it on changes three things about the body:
23
+
24
+ - The tab stop moves from the row to a cell, so the whole grid is **one** Tab
25
+ stop and the arrow keys move within it.
26
+ - The grid reports itself as a `grid` of `gridcell`s rather than a `table` of
27
+ `cell`s, which is what tells a screen reader the arrow keys are live.
28
+ - The focused cell takes `data-focused`, and the selected ones `data-selected`
29
+ and `data-edge-*`, which the stylesheet styles.
30
+
31
+ ## Keys and keyboard shortcuts
32
+
33
+ | Key | Does |
34
+ | --- | --- |
35
+ | Arrows | Moves one cell. Clamped at the edges; no wrapping |
36
+ | Shift+arrows | Extends the rectangle from its anchor (`"range"`) |
37
+ | PageUp / PageDown | Moves one viewport of rows |
38
+ | Home / End | First / last cell of the row |
39
+ | Ctrl+Home / Ctrl+End | First / last cell of the grid |
40
+ | Enter or F2 | Steps into the cell, to its checkbox, link or button |
41
+ | Escape | Steps back out, or drops the rectangle to the focused cell |
42
+ | Space | Selects the row, as a row click does under `selectionMode: "row"` |
43
+ | Ctrl+C | Copies the selection as tab-separated text |
44
+ | Ctrl+V | Not handled. The grid never writes cells from the clipboard |
45
+
46
+ There is no paste and no fill handle: values arrive through a cell editor or
47
+ through [`edit.addRows`](/docs/editing#adding-and-deleting-rows), which is the
48
+ path for importing a block of rows at once.
49
+
50
+ A [cell editor](/docs/editing) takes over Enter and F2 when editing is on.
51
+ Otherwise they focus the first control in the cell, and the arrow keys stop
52
+ moving the cursor while focus is inside it.
53
+
54
+ ## One tab stop
55
+
56
+ The body is one tab stop in each direction.
57
+ Tab from a cell leaves the grid and Shift+Tab leaves it backwards, however many
58
+ rows are mounted and whatever those rows hold.
59
+
60
+ A control inside a body cell needs no `tabIndex`.
61
+ Enter or F2 steps into the cell and onto its first control, Escape steps back
62
+ out to the cell, and Space selects the row from any of its cells without
63
+ stepping in.
64
+
65
+ Once the focus is on a control, Tab walks the rest of that row's controls - its
66
+ open editors, the buttons in its cells, and on an open row the edit lane's save
67
+ and cancel.
68
+ Past the row's last control the cursor moves to the next row's first cell, and
69
+ Shift+Tab before its first control moves to the previous row's last cell;
70
+ neither opens the row it lands on.
71
+ From the last row, Tab leaves the grid.
72
+
73
+ Header controls are unaffected: the header row is not part of cell navigation,
74
+ so Tab is the only way to its sort buttons and menus.
75
+
76
+ ## Where the selection lives
77
+
78
+ `ui.state.focusedCell` is a `{ rowId, columnId }` pair, and `ui.state.cellRange`
79
+ is two of them: the anchor and the moving corner. They hold **ids rather than
80
+ indices**, so sorting, filtering and column reordering move the selection with
81
+ the cells instead of leaving it over whatever took those positions. A range
82
+ whose corner is filtered away is not shown, and returns when the filter is
83
+ cleared.
84
+
85
+ Move either with `ui.actions.setFocusedCell` / `setCellRange`, follow them with
86
+ `onFocusedCellChange`, or read them with TanStack Store's
87
+ [`useSelector`](https://tanstack.com/store/latest/docs/framework/react/reference):
88
+
89
+ ```tsx
90
+ const focusedCell = useSelector(grid.ui, (state) => state.focusedCell);
91
+ ```
92
+
93
+ One rectangle at a time. Ctrl+drag for a second, disjoint block is not
94
+ supported.
95
+
96
+ ### System lanes
97
+
98
+ The generated lanes (checkbox, tree, details) are part of the selection. They
99
+ take the tint and the outline, so the block stays a rectangle and the arrow keys
100
+ still reach the checkbox. They are never exported. A block covering nothing else
101
+ has nothing to copy, and the Copy and Export items are disabled.
102
+
103
+ ## Copy and export
104
+
105
+ Ctrl+C puts the selected block on the clipboard as tab-separated text with CRLF
106
+ between rows, the format Excel, Sheets and Numbers all write themselves, so a
107
+ paste lands in cells rather than in one column. Values only: no header row, the
108
+ same as Excel's own copy.
109
+
110
+ ```demo
111
+ file: cells/CopyAndExport.tsx
112
+ hint: Select a block and press Ctrl+C. It pastes into Excel as cells, not as one string.
113
+ ```
114
+
115
+ Right-clicking inside the selection opens a menu with **Copy**, **Export cells**
116
+ and an **Include headers** toggle. A right-click outside it moves the
117
+ selection there first, as a spreadsheet does. Your own
118
+ [`renderRowContextMenu`](/docs/row-interaction#context-menus) items are appended
119
+ below a divider, so turning cell selection on removes nothing. Those three items are also what that slot's `internalItems` contains.
120
+
121
+ ### The file
122
+
123
+ **Export cells** writes the rectangle in the grid's export format, by default a CSV for a Nordic Excel: a `sep=;` first line, a UTF-8 BOM, CRLF endings, semicolons between fields and a comma as the decimal mark.
124
+ The format, the file name and the header row are the grid's `exportOptions`; the formats, `meta.exportValue` and `meta.enableExport` are on [Export](/docs/export).
125
+
126
+ ```tsx
127
+ const grid = useTMDataGrid({
128
+ data,
129
+ columns,
130
+ cellSelection: "range",
131
+ exportOptions: { format: csvFormat(), fileName: "employees" },
132
+ });
133
+ ```
134
+
135
+ What is written is the cell's **value**, not what it renders, for the file and for Ctrl+C alike.
136
+ Ctrl+C writes numbers with the format's decimal mark, so what is pasted matches what is exported.
137
+
138
+ Exporting every filtered row rather than the rectangle is `TMDataGrid.Menu.Export` and `useTMDataGridExport`, on [Export](/docs/export).
139
+
140
+ ## Reference
141
+
142
+ | Name | Kind | Type | Default | What it does |
143
+ | --- | --- | --- | --- | --- |
144
+ | `cellSelection` | Option | `"none" \| "single" \| "range"` | `"none"` | Turns the cell cursor, and the rectangle, on. |
145
+ | `onFocusedCellChange` | Callback | `(cell \| null) => void` | – | Follows the cursor. |
146
+ | `exportOptions` | Option | `TMDataGridExportOptions` | `DEFAULT_EXPORT_OPTIONS` | Format, file name and header row of the Export cells item. See [Export](/docs/export). |
147
+ | `ui.state.focusedCell` | UI state | `{ rowId, columnId } \| null` | `null` | The cursor. |
148
+ | `ui.state.cellRange` | UI state | `{ anchor, focus } \| null` | `null` | The rectangle's two corners. |
149
+ | `ui.actions.setFocusedCell` · `setCellRange` | UI actions | – | – | Move either from your own code. |
150
+ | `toClipboardText` · `writeClipboardText` | Exports | – | – | The pieces behind Ctrl+C. |
151
+ | `buildExportData` | Export | `({ table, rows, bounds }) => TMDataGridExportData` | – | The rectangle's values, with `bounds`. |
152
+ | `labels.copy` · `labels.exportCells` · `labels.includeHeaders` · `labels.cellCount` | Labels | – | – | The menu's strings. |
153
+ | `data-focused` | Data attribute | – | – | On the focused cell. |
154
+ | `data-edge-top` · `-bottom` · `-left` · `-right` | Data attributes | – | – | On cells at the rectangle's border. |
@@ -0,0 +1,204 @@
1
+ # Visibility, pinning, ordering and size
2
+
3
+ Four things a user can change about the layout of the grid, and one button that
4
+ resets them. All four write state that
5
+ [persists](/docs/use-tm-data-grid#persist) together, so a grid comes back
6
+ arranged the way it was left.
7
+
8
+ ```demo
9
+ file: columns/ColumnLayout.tsx
10
+ hint: Drag a header to reorder · pin or hide from a column menu · drag a divider to resize, or double-click it to fit the content.
11
+ ```
12
+
13
+ ## Hiding
14
+
15
+ **Hide column** in any column menu, and the column chooser for the whole list at once: a search field, one checkbox per column, show/hide all, and **Reset layout**.
16
+ The chooser is `TMDataGrid.Menu.Columns` in the [grid menu](/docs/menu), **Manage columns** in every column menu (a submenu of the same items), and `TMDataGrid.ColumnsPanel` as plain controls for a host that is not a menu.
17
+
18
+ `enableHiding: false` removes all of it; on a column it removes that column's
19
+ menu item and leaves it out of the panel, which lists what can be hidden and
20
+ nothing else. Show/hide all covers the same list, so a column switched off this
21
+ way keeps whatever visibility it was given. The state is TanStack's
22
+ `columnVisibility`.
23
+
24
+ The generated lanes are all `enableHiding: false` and never appear in the
25
+ panel. Each follows the feature that adds it rather than a setting of its own.
26
+
27
+ ## Pinning
28
+
29
+ **Pin to left** and **Pin to right** are in each column menu. The current
30
+ position is marked, and choosing it again unpins. Pinned columns are sticky
31
+ within the scroll container. The boundary is marked with a divider and a short
32
+ gradient band, which fades in only while it is covering content.
33
+
34
+ Headers, cells and grid tracks are ordered left, centre, right from the same
35
+ source, so pinning does not change a column's position relative to its group.
36
+
37
+ A pinned column also becomes fixed-width, since sticky offsets cannot be
38
+ computed from an `fr` value. The grid writes the column's rendered width into
39
+ `columnSizing` as it is pinned, so nothing jumps.
40
+
41
+ To start pinned, set `initialState.columnPinning`. The slice is TanStack's
42
+ full `ColumnPinningState`, so a partial does not compile - name both sides.
43
+ A column pinned at mount has no rendered width to store, so it takes its
44
+ `size` - TanStack's default of `150` where none is set - and `minSize` does
45
+ not apply. Give such a column an explicit `size`:
46
+
47
+ ```tsx
48
+ columnHelper.accessor("registration", { header: "Registration", size: 220 });
49
+
50
+ initialState: { columnPinning: { start: ["registration"], end: [] } }
51
+ ```
52
+
53
+ The generated lanes stay outside both pinned lanes: pinning a column right puts
54
+ it to the left of the edit lane, so the row's Save, Cancel and Delete remain
55
+ last in the row.
56
+
57
+ ## Ordering
58
+
59
+ Drag a column header sideways to move it. The header being dragged dims, and a
60
+ bar marks the edge the column will land against. **Move left** and **Move
61
+ right** in the column menu do the same one step at a time, without a pointer.
62
+ Both move the header, its cells and its filter entry together.
63
+
64
+ ```tsx
65
+ const grid = useTMDataGrid({ data, columns, enableColumnOrdering: false });
66
+ ```
67
+
68
+ `enableColumnOrdering` is defined by the grid rather than by TanStack, which
69
+ ships the ordering state and APIs but no `enable` option. The per-column form is
70
+ `meta.enableOrdering`.
71
+
72
+ ### Regions
73
+
74
+ A column can only move **within its own pinned region**; a header in another
75
+ region does not accept the drop. This follows TanStack's ordering pipeline:
76
+ pinning splits the grid into left, centre and right, then `columnOrder`
77
+ sequences the centre while `columnPinning.start` and `.end` sequence the
78
+ pinned lanes. Unpin a column first to move it out of one.
79
+
80
+ A neighbour that cannot be moved blocks the move; it is not stepped over. The
81
+ checkbox column sets `meta.enableOrdering: false`, so nothing can be placed in
82
+ front of it.
83
+
84
+ Columns inside a header group cannot be moved either, in either direction:
85
+ `columnOrder` sequences leaf columns, so moving one would leave the group header
86
+ spanning columns that no longer belong to it.
87
+
88
+ ### Moving from your own code
89
+
90
+ ```tsx
91
+ import { moveColumn, moveColumnByStep } from "@jielga/tmdatagrid";
92
+
93
+ moveColumn({ table, columnId: "salary", targetId: "age", side: "before" });
94
+ moveColumnByStep({ table, columnId: "salary", direction: 1 });
95
+ ```
96
+
97
+ Both are no-ops for a move that is not allowed, including one across regions.
98
+ `getStepTargetColumn({ table, columnId, direction })` returns the column a step
99
+ would swap with, or `null` at the edge of a region. The menu items use it to
100
+ decide whether to disable themselves.
101
+
102
+ ### State
103
+
104
+ Ordering writes `columnOrder` as the **complete** leaf order, including hidden
105
+ and pinned columns, so a column keeps its position when it is later shown or
106
+ unpinned. Moving a pinned column also rewrites its `columnPinning` array. A
107
+ column added to the definitions later is not in the stored order and is appended
108
+ at the end until it is moved.
109
+
110
+ ## Sizing
111
+
112
+ Columns are fluid by default. Each track is `minmax(minSize, flex fr)`.
113
+
114
+ | Column option | Effect |
115
+ | --- | --- |
116
+ | `minSize` | Minimum width, and the column's contribution to the grid minimum width. Defaults to `80`. |
117
+ | `meta.flex` | Share of the remaining width. Defaults to `1`. |
118
+ | `minSize === maxSize` | Fixed width. The column is never fluid. |
119
+ | `size` | Applied once the column becomes fixed by resizing or pinning. |
120
+
121
+ Drag a divider to resize. A column switches to a fixed pixel width the moment
122
+ it is resized or pinned, and the width is stored in `columnSizing`. The drag
123
+ starts from the width the column is rendered with, and the grid paints it on
124
+ its own column tracks while the pointer moves; the width reaches `columnSizing`
125
+ when the pointer is released. `columnResizeMode: "onChange"` publishes it on
126
+ every move instead, at the cost of a render of the grid for each one.
127
+
128
+ ### Autosizing
129
+
130
+ Double-click a column's resize divider to size it to its widest mounted
131
+ content. **Autosize column** in the column menu does the same without a
132
+ pointer, and `meta.autoSize: true` runs it once after the first rows render,
133
+ unless a persisted or user-set width already applies to the column.
134
+
135
+ **Mounted content only.** Under virtualization the unmounted rows cannot be
136
+ measured, so the width fits the visible window plus overscan. The result is
137
+ clamped to `minSize`/`maxSize` and written into `columnSizing`, so it persists
138
+ with the other widths and a later drag overrides it.
139
+
140
+ `meta.autoSize` waits for content: on a grid whose rows are fetched, the first
141
+ render has a header and no cells, so the column is sized on the render its
142
+ first cells appear in.
143
+
144
+ `autosizeColumn({ table, columnId, container })` is exported for menus and
145
+ consumer code; `container` is the grid's scroll container, or any ancestor of
146
+ the column's cells.
147
+
148
+ ## The column menu
149
+
150
+ Everything above is reachable from a column's menu, and
151
+ `renderColumnMenuItems` on `TMDataGrid.Table` sets what is in it. It receives
152
+ the items the grid would have rendered and returns the list to render:
153
+
154
+ ```tsx
155
+ <TMDataGrid.Table<Employee>
156
+ renderColumnMenuItems={({ column, internalItems }) => [
157
+ ...internalItems,
158
+ <Menu.Divider key="stats-divider" />,
159
+ <Menu.Item key="stats" onClick={() => showStats(column.id)}>
160
+ Column statistics
161
+ </Menu.Item>,
162
+ ]}
163
+ />
164
+ ```
165
+
166
+ `internalItems` is the built-in list in order, dividers included. Returning it
167
+ unchanged gives the default menu, splicing around it extends the menu, and
168
+ returning something else replaces it. An empty list removes the menu button.
169
+
170
+ It runs for every column that has a menu, so branch on `column.id` for a
171
+ per-column menu. A trailing divider is dropped automatically.
172
+
173
+ ## Reset the layout
174
+
175
+ `resetSettings()` from the hook clears visibility, order, pinning and widths in
176
+ one call. The columns panel offers it as **Reset layout**.
177
+
178
+ ```tsx
179
+ const { resetSettings } = useTMDataGrid({ data, columns });
180
+ ```
181
+
182
+ ## Reference
183
+
184
+ | Name | Kind | Type | Default | What it does |
185
+ | --- | --- | --- | --- | --- |
186
+ | `enableHiding` | Table option | `boolean` | `true` | Also a column option. `false` removes hiding entirely. |
187
+ | `enableColumnPinning` | Table option | `boolean` | `true` | `false` removes the pin menu items. |
188
+ | `enablePinning` | Column option | `boolean` | `true` | `false` for one column. |
189
+ | `enableColumnOrdering` | Option | `boolean` | `true` | Header dragging and the move menu items. Grid-defined. |
190
+ | `meta.enableOrdering` | Column meta | `boolean` | `true` | `false` keeps one column where it is. |
191
+ | `enableColumnResizing` | Table option | `boolean` | `true` | `false` leaves the divider as a separator only. |
192
+ | `enableResizing` | Column option | `boolean` | `true` | `false` for one column. |
193
+ | `meta.flex` | Column meta | `number` | `1` | Share of the remaining width. |
194
+ | `meta.autoSize` | Column meta | `boolean` | `false` | Autosize once, on the render the column's first cells appear in. |
195
+ | `minSize` / `maxSize` / `size` | Column options | `number` | `80` / – / – | Width bounds, and the fixed width once one applies. |
196
+ | `renderColumnMenuItems` | Table prop | `({ column, table, internalItems }) => ReactNode[]` | – | The column menu's contents. An empty list removes the button. |
197
+ | `resetSettings` | Hook return | `() => void` | – | Clears visibility, order, pinning and widths. |
198
+ | `moveColumn` | Export | `({ table, columnId, targetId, side }) => void` | – | Moves a column beside another. |
199
+ | `moveColumnByStep` | Export | `({ table, columnId, direction }) => void` | – | Moves it one place. |
200
+ | `getStepTargetColumn` | Export | `(args) => Column \| null` | – | What a step would swap with, or `null` at a region edge. |
201
+ | `keepGeneratedColumnsOutermost` | Export | `(columnPinning) => ColumnPinningState` | – | Puts the generated lanes back on the outside of both pinned lanes. The grid runs it after every pin. |
202
+ | `getColumnRegion` | Export | `(column) => "start" \| "center" \| "end"` | – | Which pinned region a column is in. |
203
+ | `autosizeColumn` | Export | `({ table, columnId, container }) => void` | – | Fits a column to its mounted content. |
204
+ | `TMDataGrid.Menu.Columns` · `TMDataGrid.ColumnsPanel` | Components | – | – | The column chooser, as menu items and as plain controls. See [Grid menu](/docs/menu). |