@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.
- package/README.md +5 -212
- package/dist/index.d.ts +1664 -632
- package/dist/index.js +5226 -3223
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/anatomy.md +102 -0
- package/docs/cell-selection.md +154 -0
- package/docs/column-layout.md +204 -0
- package/docs/columns.md +262 -0
- package/docs/components.md +304 -0
- package/docs/editing.md +603 -0
- package/docs/editors.md +250 -0
- package/docs/export.md +326 -0
- package/docs/filtering.md +358 -0
- package/docs/getting-started.md +123 -0
- package/docs/grouping.md +165 -0
- package/docs/loading-and-empty.md +92 -0
- package/docs/localization.md +79 -0
- package/docs/menu.md +143 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +111 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +175 -0
- package/docs/quick-search.md +83 -0
- package/docs/row-details.md +113 -0
- package/docs/row-interaction.md +148 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +134 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +111 -0
- package/docs/server-query.md +246 -0
- package/docs/server-side.md +206 -0
- package/docs/sorting.md +101 -0
- package/docs/styling.md +126 -0
- package/docs/summary-row.md +76 -0
- package/docs/testing.md +309 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +21 -45
- package/skills/appearance/SKILL.md +70 -17
- package/skills/cell-selection/SKILL.md +70 -76
- package/skills/columns/SKILL.md +131 -32
- package/skills/data/SKILL.md +100 -23
- package/skills/editing/SKILL.md +217 -96
- package/skills/editing/references/common-mistakes.md +111 -24
- package/skills/editing/references/editing-api.md +63 -39
- package/skills/editing/references/editors-and-validation.md +77 -19
- package/skills/filtering/SKILL.md +148 -40
- package/skills/getting-started/SKILL.md +18 -16
- package/skills/grouping/SKILL.md +32 -15
- package/skills/options/SKILL.md +39 -9
- package/skills/rows/SKILL.md +22 -18
- package/skills/server-side/SKILL.md +170 -17
- package/skills/testing/SKILL.md +10 -7
- package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +7 -19
- package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +7 -1
- package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +39 -23
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +106 -38
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
- package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +4 -4
- package/src/components/TMDataGridDraftActions.tsx +307 -0
- package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +58 -50
- package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +150 -115
- package/src/components/TMDataGridExportPicker.module.css +77 -0
- package/src/components/TMDataGridExportPicker.tsx +234 -0
- package/src/components/TMDataGridFilterPanel.module.css +54 -0
- package/src/components/TMDataGridFilterPanel.tsx +348 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +7 -5
- package/src/components/TMDataGridFilterSurface.module.css +54 -0
- package/src/components/TMDataGridFilterSurface.tsx +167 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -13
- package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +4 -3
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +10 -0
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +100 -28
- package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
- package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
- package/src/components/TMDataGridMenu.tsx +354 -0
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +12 -7
- package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +90 -67
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +678 -156
- package/src/components/TMDataGridToolbar.module.css +21 -0
- package/src/components/TMDataGridToolbar.tsx +181 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
- package/src/components/editors/TMDataGridNumberEditor.tsx +70 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/editorShared.ts +17 -31
- package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
- package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
- package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
- package/src/components/filters/controlLayout.ts +32 -0
- package/src/components/filters/filterControlFor.ts +65 -0
- package/src/{tmdatagrid/components → components}/icons.ts +1 -0
- package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
- package/src/components/useHideableColumns.ts +52 -0
- package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
- package/src/{tmdatagrid/core → core}/capabilities.ts +14 -6
- package/src/{tmdatagrid/core → core}/columnOptions.ts +46 -0
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/controlledState.ts +179 -0
- package/src/core/controlledStateSync.ts +108 -0
- package/src/core/deletedRows.ts +34 -0
- package/src/core/dom.ts +74 -0
- package/src/core/editEngine.ts +2476 -0
- package/src/{tmdatagrid/core → core}/editorFocus.ts +8 -4
- package/src/core/export.ts +843 -0
- package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
- package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
- package/src/core/filterSurface.ts +99 -0
- package/src/{tmdatagrid/core → core}/labels.ts +66 -8
- package/src/{tmdatagrid/core → core}/labelsSv.ts +26 -3
- package/src/core/pageReset.ts +120 -0
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/core/resizePreview.ts +141 -0
- package/src/core/summary.ts +59 -0
- package/src/core/useSettledTableState.ts +36 -0
- package/src/{tmdatagrid/index.ts → index.ts} +75 -12
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +734 -135
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/components/TMDataGridEditActions.tsx +0 -162
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
- package/src/tmdatagrid/components/TMDataGridToolbar.module.css +0 -12
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -162
- package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +0 -40
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- package/src/tmdatagrid/core/editEngine.ts +0 -1006
- package/src/tmdatagrid/core/summary.ts +0 -35
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
- /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
- /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
- /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
- /package/src/{tmdatagrid/core → core}/grouping.ts +0 -0
- /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
- /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*/
|
package/docs/anatomy.md
ADDED
|
@@ -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). |
|