@jielga/tmdatagrid 2.0.0-beta.0 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -34
- package/dist/index.d.ts +164 -102
- package/dist/index.js +2060 -1705
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/skills/appearance/SKILL.md +37 -34
- package/skills/cell-selection/SKILL.md +19 -19
- package/skills/columns/SKILL.md +9 -9
- package/skills/data/SKILL.md +53 -53
- package/skills/editing/SKILL.md +152 -311
- package/skills/editing/references/common-mistakes.md +177 -0
- package/skills/editing/references/editing-api.md +56 -28
- package/skills/editing/references/editors-and-validation.md +26 -19
- package/skills/filtering/SKILL.md +51 -50
- package/skills/getting-started/SKILL.md +10 -10
- package/skills/grouping/SKILL.md +41 -43
- package/skills/options/SKILL.md +4 -4
- package/skills/rows/SKILL.md +59 -59
- package/skills/rows/references/rows-api.md +7 -7
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +11 -10
- package/src/tmdatagrid/components/TMDataGrid.module.css +13 -1
- package/src/tmdatagrid/components/TMDataGridCellEditor.tsx +20 -8
- package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +29 -18
- package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +5 -8
- package/src/tmdatagrid/components/TMDataGridEditActions.tsx +2 -2
- package/src/tmdatagrid/components/TMDataGridEditColumn.tsx +246 -86
- package/src/tmdatagrid/components/TMDataGridEntryRows.tsx +176 -77
- package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +11 -6
- package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +9 -5
- package/src/tmdatagrid/components/TMDataGridTable.module.css +47 -3
- package/src/tmdatagrid/components/TMDataGridTable.tsx +101 -40
- package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +1 -1
- package/src/tmdatagrid/components/icons.ts +1 -0
- package/src/tmdatagrid/core/autosize.ts +30 -6
- package/src/tmdatagrid/core/capabilities.ts +15 -5
- package/src/tmdatagrid/core/cellExport.ts +6 -7
- package/src/tmdatagrid/core/cellNavigation.ts +2 -2
- package/src/tmdatagrid/core/cellRange.ts +6 -6
- package/src/tmdatagrid/core/columnOrdering.ts +30 -1
- package/src/tmdatagrid/core/columnUtils.ts +14 -0
- package/src/tmdatagrid/core/draftCellContext.ts +68 -0
- package/src/tmdatagrid/core/editEngine.ts +111 -37
- package/src/tmdatagrid/core/filterOperators.ts +6 -6
- package/src/tmdatagrid/core/labels.ts +13 -1
- package/src/tmdatagrid/core/labelsSv.ts +4 -0
- package/src/tmdatagrid/core/matchHighlight.ts +3 -3
- package/src/tmdatagrid/core/persistence.ts +3 -3
- package/src/tmdatagrid/core/rowSelection.ts +3 -3
- package/src/tmdatagrid/index.ts +3 -1
- package/src/tmdatagrid/useTMDataGrid.tsx +141 -99
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
._root_1e2oi_8[data-size=xs]{--dg-row-height:34px;--dg-header-height:32px;--dg-font-size:var(--mantine-font-size-xs);--dg-padding:6px}._root_1e2oi_8[data-size=sm]{--dg-row-height:42px;--dg-header-height:38px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:8px}._root_1e2oi_8[data-size=md]{--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px}._root_1e2oi_8[data-size=lg]{--dg-row-height:62px;--dg-header-height:52px;--dg-font-size:var(--mantine-font-size-md);--dg-padding:14px}._root_1e2oi_8[data-size=xl]{--dg-row-height:72px;--dg-header-height:60px;--dg-font-size:var(--mantine-font-size-lg);--dg-padding:18px}._root_1e2oi_8{--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-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(--mantine-radius-md);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}}._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}._tableWrapper_15qzd_2{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}._scrollContainer_15qzd_10{flex:1;min-height:0;position:relative;overflow:auto;container-type:inline-size}._grid_15qzd_21{display:grid}._headerRow_15qzd_27{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-header,6);display:grid;position:sticky;top:0}._headerRow_15qzd_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_15qzd_27[data-dg-header-last]:after{animation:linear both _dg-header-shadow_15qzd_1;animation-timeline:scroll();animation-range:0 24px}}@keyframes _dg-header-shadow_15qzd_1{0%{opacity:0}to{opacity:1}}._bodyRow_15qzd_76{--row-bg:var(--mantine-color-body);grid-column:1/-1;grid-template-columns:subgrid;align-items:stretch;display:grid}._bodyRow_15qzd_76[data-striped=true]{--row-bg:var(--dg-row-striped-bg)}._bodyRow_15qzd_76:hover{--row-bg:var(--mantine-color-default-hover)}._bodyRow_15qzd_76[data-grouped=true]{--row-bg:var(--dg-row-group-bg)}._bodyRow_15qzd_76[data-context-menu=true]{--row-bg:var(--mantine-color-default-hover)}._bodyRow_15qzd_76[data-selected-bg=true]{--row-bg:var(--dg-row-selected-bg)}._bodyRow_15qzd_76[data-highlighted=true]{--row-bg:var(--dg-row-highlight-bg)}._bodyRow_15qzd_76[data-selects-on-click=true]{-webkit-user-select:none;user-select:none}._bodyRow_15qzd_76:focus-visible{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._bodyCell_15qzd_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_15qzd_143[data-control-column=true]{padding:0}._grid_15qzd_21[data-range-dragging]{-webkit-user-select:none;user-select:none}._bodyCell_15qzd_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_15qzd_143[data-edge-top=true]{--dg-edge-top:var(--mantine-primary-color-filled)}._bodyCell_15qzd_143[data-edge-bottom=true]{--dg-edge-bottom:var(--mantine-primary-color-filled)}._bodyCell_15qzd_143[data-edge-left=true]{--dg-edge-left:var(--mantine-primary-color-filled)}._bodyCell_15qzd_143[data-edge-right=true]{--dg-edge-right:var(--mantine-primary-color-filled)}._bodyCell_15qzd_143[data-focused=true]{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._cellContent_15qzd_141{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._bodyCell_15qzd_143[data-editing]{padding:0 calc(var(--dg-padding) / 2)}._cellEditor_15qzd_243{align-items:center;gap:2px;width:100%;min-width:0;display:flex}._cellEditorActions_15qzd_252{flex:none;align-items:center;display:flex}._bodyCell_15qzd_143[data-dirty],._bodyCell_15qzd_143[data-invalid]{position:relative}._bodyCell_15qzd_143[data-dirty]:after,._bodyCell_15qzd_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_15qzd_143[data-invalid]:after{border-top-color:var(--mantine-color-error);border-right-color:var(--mantine-color-error)}._bodyCell_15qzd_143[data-align=right]{justify-content:flex-end}._bodyCell_15qzd_143[data-align=center]{justify-content:center}._bodyCell_15qzd_143[data-align=left] ._cellContent_15qzd_141{flex:auto}._detailsCell_15qzd_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_15qzd_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_15qzd_76[data-deleted=true]{opacity:.55;pointer-events:none;text-decoration:line-through}._entryBlock_15qzd_347{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_15qzd_356{grid-column:1/-1;grid-template-columns:subgrid;display:grid}._pinnedTopBlock_15qzd_369{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_15qzd_369>:last-child>[role=cell]{border-bottom:2px solid var(--mantine-color-default-border)}._pinnedBottomBlock_15qzd_382{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_15qzd_382>:first-child>[role=cell]{border-top:2px solid var(--mantine-color-default-border)}._entryCell_15qzd_395{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_15qzd_395[data-control-column=true]{justify-content:center;padding:0}._entryCell_15qzd_395[data-align=right]{justify-content:flex-end}._entryCell_15qzd_395[data-align=center]{justify-content:center}._matchHighlight_15qzd_422{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_15qzd_434{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-summary-row,4);display:grid;position:sticky;bottom:0}._summaryCell_15qzd_443{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_15qzd_443[data-control-column=true]{padding:0}._summaryCell_15qzd_443[data-align=right]{justify-content:flex-end}._summaryCell_15qzd_443[data-align=center]{justify-content:center}._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_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}
|
|
2
2
|
/*$vite$:1*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jielga/tmdatagrid",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "A React data grid built on TanStack Table v9 and Mantine - always virtualized, with resizable, reorderable, sortable, filterable, hideable and pinnable columns.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@ description: >
|
|
|
16
16
|
metadata:
|
|
17
17
|
type: core
|
|
18
18
|
library: '@jielga/tmdatagrid'
|
|
19
|
-
library_version: '2.0.0-beta.
|
|
19
|
+
library_version: '2.0.0-beta.2'
|
|
20
20
|
sources:
|
|
21
21
|
- 'Jielga/TMDataGrid:src/docs/styling.md'
|
|
22
22
|
- 'Jielga/TMDataGrid:src/docs/toolbar.md'
|
|
@@ -44,13 +44,15 @@ and selects the size of every Mantine control the grid renders.
|
|
|
44
44
|
| `xl` | 72px | 60px | `lg` | 18px |
|
|
45
45
|
|
|
46
46
|
Row height is also required by the virtualizer **as a number**, so it cannot be
|
|
47
|
-
defined in CSS alone. For a height outside the scale set `meta.rowHeight
|
|
48
|
-
the variable. `SIZE_ROW_HEIGHT` is the exported source of these
|
|
47
|
+
defined in CSS alone. For a height outside the scale, set `meta.rowHeight`
|
|
48
|
+
rather than the variable. `SIZE_ROW_HEIGHT` is the exported source of these
|
|
49
|
+
values.
|
|
49
50
|
|
|
50
51
|
## CSS variables
|
|
51
52
|
|
|
52
53
|
`style` accepts custom properties and `className` reaches the same element from
|
|
53
|
-
a stylesheet. Both are per instance
|
|
54
|
+
a stylesheet. Both are per instance, so a grid can be themed without a
|
|
55
|
+
provider.
|
|
54
56
|
|
|
55
57
|
```tsx
|
|
56
58
|
<TMDataGrid
|
|
@@ -62,17 +64,17 @@ a stylesheet. Both are per instance - a grid is themed without a provider.
|
|
|
62
64
|
|
|
63
65
|
**Metrics:** `--dg-row-height`, `--dg-header-height`, `--dg-summary-height`,
|
|
64
66
|
`--dg-entry-height`, `--dg-font-size`, `--dg-padding`. All default from `size`.
|
|
65
|
-
The generated lanes are
|
|
67
|
+
The generated lanes are excluded from padding: they are fixed 36px tracks that
|
|
66
68
|
centre their control.
|
|
67
69
|
|
|
68
|
-
**Colours:** `--row-bg` (one row's own background
|
|
70
|
+
**Colours:** `--row-bg` (one row's own background; set this, never
|
|
69
71
|
`background`), `--dg-row-selected-bg`, `--dg-row-highlight-bg`,
|
|
70
72
|
`--dg-row-striped-bg`, `--dg-row-group-bg`, `--dg-match-highlight-bg`,
|
|
71
73
|
`--dg-header-shadow-color`.
|
|
72
74
|
|
|
73
75
|
**Layout internals:** `--dg-sticky-edge-range` (`20px`), the `--dg-edge-*`
|
|
74
|
-
markers the grid sets on cell-range borders, and the `--dg-z-*` stacking
|
|
75
|
-
|
|
76
|
+
markers the grid sets on cell-range borders, and the `--dg-z-*` stacking order.
|
|
77
|
+
Change those only to place something of your own between two layers.
|
|
76
78
|
|
|
77
79
|
One stylesheet import, once, anywhere:
|
|
78
80
|
|
|
@@ -87,7 +89,8 @@ two, never both.
|
|
|
87
89
|
## Layout
|
|
88
90
|
|
|
89
91
|
The grid fills the box you give it and scrolls inside it. It does not size
|
|
90
|
-
itself to its content
|
|
92
|
+
itself to its content, because a virtualized grid has no content height to
|
|
93
|
+
measure.
|
|
91
94
|
|
|
92
95
|
```tsx
|
|
93
96
|
<div style={{ display: "flex", flexDirection: "column", height: "100vh" }}>
|
|
@@ -97,16 +100,15 @@ itself to its content - a virtualized grid has no content height to measure.
|
|
|
97
100
|
</div>
|
|
98
101
|
```
|
|
99
102
|
|
|
100
|
-
`minHeight: 0` is
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
`minHeight: 0` is required: a flex item's default `min-height: auto` will not
|
|
104
|
+
shrink below its content, so without it the grid grows past the viewport instead
|
|
105
|
+
of scrolling.
|
|
103
106
|
|
|
104
107
|
## Toolbar
|
|
105
108
|
|
|
106
|
-
The toolbar is a flex row
|
|
107
|
-
|
|
108
|
-
and `TMDataGrid.Spacer` pushes what follows to the right.
|
|
109
|
-
layout system.
|
|
109
|
+
The toolbar is a flex row. There is no slots API and no `actions` prop: your
|
|
110
|
+
buttons sit beside the built-in ones because they are all children of the same
|
|
111
|
+
element, and `TMDataGrid.Spacer` pushes what follows to the right.
|
|
110
112
|
|
|
111
113
|
```tsx
|
|
112
114
|
<TMDataGrid.Toolbar>
|
|
@@ -121,11 +123,11 @@ layout system.
|
|
|
121
123
|
```
|
|
122
124
|
|
|
123
125
|
Each built-in renders nothing when its feature is off, so a read-only grid needs
|
|
124
|
-
no conditionals: `FilterButton` under `enableColumnFilters: false`
|
|
125
|
-
|
|
126
|
+
no conditionals: `FilterButton` under `enableColumnFilters: false` renders
|
|
127
|
+
nothing at all.
|
|
126
128
|
|
|
127
|
-
A button of your own reads the grid from context
|
|
128
|
-
labels, controlSize, resetSettings }`:
|
|
129
|
+
A button of your own reads the grid from context, which returns
|
|
130
|
+
`{ table, ui, features, labels, controlSize, resetSettings }`:
|
|
129
131
|
|
|
130
132
|
```tsx
|
|
131
133
|
import {
|
|
@@ -148,9 +150,9 @@ function ExportButton() {
|
|
|
148
150
|
}
|
|
149
151
|
```
|
|
150
152
|
|
|
151
|
-
`getGridCapabilities(table, features)`
|
|
153
|
+
`getGridCapabilities(table, features)` returns `canSortAny`, `canFilterAny`,
|
|
152
154
|
`canHideAny`, `canPinAny`, `canReorderAny`, `canGroupAny`, `canSelectRows`,
|
|
153
|
-
`canPaginate` and `canSearch`. `getColumnCapabilities(column, features)`
|
|
155
|
+
`canPaginate` and `canSearch`. `getColumnCapabilities(column, features)` returns
|
|
154
156
|
the same for one column as `canSort`, `canFilter`, `canHide`, `canPin`,
|
|
155
157
|
`canResize`, `canReorder` and `canGroup`.
|
|
156
158
|
|
|
@@ -158,13 +160,13 @@ the same for one column as `canSort`, `canFilter`, `canHide`, `canPin`,
|
|
|
158
160
|
|
|
159
161
|
`features` comes back from `useTMDataGrid` and is re-derived from the options
|
|
160
162
|
object on every render. It is required **in addition to** TanStack's `getCanX()`
|
|
161
|
-
methods because it is what makes the result reactive
|
|
163
|
+
methods because it is what makes the result reactive. `column.getCanSort()` is a
|
|
162
164
|
method call on a column object whose identity survives an options change, so
|
|
163
165
|
under the React Compiler that call is memoized and a grid whose `enableSorting`
|
|
164
|
-
|
|
166
|
+
changed to `false` would carry on rendering sort indicators. `features` supplies
|
|
165
167
|
a value that changes; `getCanX()` still decides the outcome.
|
|
166
168
|
|
|
167
|
-
The same rule applies
|
|
169
|
+
The same rule applies elsewhere in your application: read state through
|
|
168
170
|
`useSelector(table.store, …)` and options through `features`, rather than
|
|
169
171
|
calling methods on a long-lived object.
|
|
170
172
|
|
|
@@ -180,8 +182,8 @@ import { TMDATAGRID_LABELS_SV } from "@jielga/tmdatagrid";
|
|
|
180
182
|
const grid = useTMDataGrid({ data, columns, labels: TMDATAGRID_LABELS_SV });
|
|
181
183
|
```
|
|
182
184
|
|
|
183
|
-
Labels that carry a value are functions, so
|
|
184
|
-
its grammar
|
|
185
|
+
Labels that carry a value are functions, so each language can place the value
|
|
186
|
+
where its grammar requires:
|
|
185
187
|
|
|
186
188
|
```tsx
|
|
187
189
|
const labels = {
|
|
@@ -190,10 +192,10 @@ const labels = {
|
|
|
190
192
|
} satisfies TMDataGridLabelsOverride;
|
|
191
193
|
```
|
|
192
194
|
|
|
193
|
-
`TMDataGridLabels` is the full dictionary type,
|
|
194
|
-
translation a
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
`TMDataGridLabels` is the full dictionary type, so a missing key in a new
|
|
196
|
+
translation is a compile error. The resolved dictionary comes back as
|
|
197
|
+
`grid.labels` and from `useTMDataGridContext().labels`, so a component of your
|
|
198
|
+
own uses the same strings as the built-in parts.
|
|
197
199
|
|
|
198
200
|
## Common mistakes
|
|
199
201
|
|
|
@@ -229,7 +231,7 @@ Source: `src/docs/styling.md` (Layout).
|
|
|
229
231
|
### HIGH Setting `--dg-row-height` to change density
|
|
230
232
|
|
|
231
233
|
The virtualizer needs the row height as a number, and takes it from
|
|
232
|
-
`meta.rowHeight` or `size
|
|
234
|
+
`meta.rowHeight` or `size`, not from the variable. Setting the variable alone
|
|
233
235
|
leaves the measurement and the render disagreeing, so rows overlap or gaps open
|
|
234
236
|
as you scroll.
|
|
235
237
|
|
|
@@ -266,8 +268,9 @@ Source: `src/docs/toolbar.md` (Why `features` is a second argument).
|
|
|
266
268
|
|
|
267
269
|
### MEDIUM An inline `labels` object
|
|
268
270
|
|
|
269
|
-
The
|
|
270
|
-
literal is a new object every render.
|
|
271
|
+
The grid re-renders when the labels object changes identity, and an inline
|
|
272
|
+
literal is a new object on every render. Define it at module scope, or memoize
|
|
273
|
+
it.
|
|
271
274
|
|
|
272
275
|
Wrong:
|
|
273
276
|
|
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.0.0-beta.
|
|
17
|
+
library_version: '2.0.0-beta.2'
|
|
18
18
|
sources:
|
|
19
19
|
- 'Jielga/TMDataGrid:src/docs/cell-selection.md'
|
|
20
20
|
- 'Jielga/TMDataGrid:src/tmdatagrid/core/cellNavigation.ts'
|
|
@@ -24,9 +24,9 @@ sources:
|
|
|
24
24
|
|
|
25
25
|
# TMDataGrid - Cell selection
|
|
26
26
|
|
|
27
|
-
A cell cursor the arrow keys
|
|
28
|
-
and a Ctrl+C that pastes into Excel as cells rather than as one
|
|
29
|
-
default.
|
|
27
|
+
A cell cursor moved with the arrow keys, a rectangle of cells that can be
|
|
28
|
+
dragged out, and a Ctrl+C that pastes into Excel as cells rather than as one
|
|
29
|
+
string. Off by default.
|
|
30
30
|
|
|
31
31
|
```tsx
|
|
32
32
|
const grid = useTMDataGrid({ data, columns, cellSelection: "range" });
|
|
@@ -38,15 +38,15 @@ const grid = useTMDataGrid({ data, columns, cellSelection: "range" });
|
|
|
38
38
|
| `"single"` | One focused cell, moved with the arrow keys |
|
|
39
39
|
| `"range"` | As `"single"`, plus a rectangle, Ctrl+C and the export menu |
|
|
40
40
|
|
|
41
|
-
Setting `
|
|
41
|
+
Setting `editing` defaults `cellSelection` to `"single"`, since editing
|
|
42
42
|
navigates by cursor. An explicit `cellSelection` always wins.
|
|
43
43
|
|
|
44
44
|
Turning it on changes three things about the body:
|
|
45
45
|
|
|
46
46
|
- The tab stop moves from the row to a cell, so the whole grid is **one** Tab
|
|
47
|
-
stop and the arrow keys
|
|
47
|
+
stop and the arrow keys move within it.
|
|
48
48
|
- The grid reports itself as a `grid` of `gridcell`s rather than a `table` of
|
|
49
|
-
`cell`s, which
|
|
49
|
+
`cell`s, which tells a screen reader those keys are live.
|
|
50
50
|
- The focused cell takes `data-focused`, selected ones `data-selected` and
|
|
51
51
|
`data-edge-*`.
|
|
52
52
|
|
|
@@ -97,10 +97,11 @@ cell works either way.
|
|
|
97
97
|
## Where the selection lives
|
|
98
98
|
|
|
99
99
|
`ui.state.focusedCell` is a `{ rowId, columnId }` pair, and `ui.state.cellRange`
|
|
100
|
-
is two of them
|
|
101
|
-
sorting, filtering and column reordering
|
|
102
|
-
instead of leaving it over whatever
|
|
103
|
-
corner is filtered away paints nothing, and
|
|
100
|
+
is two of them: the anchor and the moving corner. They hold **ids rather than
|
|
101
|
+
indices**, so sorting, filtering and column reordering move the selection with
|
|
102
|
+
the cells instead of leaving it over whatever took those positions. A range
|
|
103
|
+
whose corner is filtered away paints nothing, and returns when the filter is
|
|
104
|
+
cleared.
|
|
104
105
|
|
|
105
106
|
```tsx
|
|
106
107
|
const focusedCell = useSelector(grid.ui, (state) => state.focusedCell);
|
|
@@ -111,11 +112,10 @@ grid.ui.actions.setFocusedCell({ rowId: "42", columnId: "salary" });
|
|
|
111
112
|
One rectangle at a time; Ctrl+drag for a second, disjoint block is not
|
|
112
113
|
supported.
|
|
113
114
|
|
|
114
|
-
The generated lanes (checkbox, tree, details) are part of the selection
|
|
115
|
-
take the tint and the outline so the block stays a rectangle
|
|
116
|
-
*exported*,
|
|
117
|
-
nothing else has nothing to copy, and the Copy and Export items
|
|
118
|
-
disabled.
|
|
115
|
+
The generated lanes (checkbox, tree, details) are part of the selection: they
|
|
116
|
+
take the tint and the outline so the block stays a rectangle. They are never
|
|
117
|
+
*exported*, because they hold controls rather than values. A block covering
|
|
118
|
+
nothing else has nothing to copy, and the Copy and Export items are disabled.
|
|
119
119
|
|
|
120
120
|
## Copy and export
|
|
121
121
|
|
|
@@ -130,7 +130,7 @@ below a divider, so nothing is lost by turning cell selection on.
|
|
|
130
130
|
|
|
131
131
|
The CSV is written for a Nordic Excel: a `sep=;` first line, a UTF-8 BOM, CRLF
|
|
132
132
|
endings, semicolons between fields and a comma as the decimal mark. That
|
|
133
|
-
combination
|
|
133
|
+
combination opens straight into columns with å ä ö intact.
|
|
134
134
|
|
|
135
135
|
```tsx
|
|
136
136
|
<TMDataGrid.Table
|
|
@@ -179,7 +179,7 @@ Source: `src/docs/cell-selection.md` (One tab stop).
|
|
|
179
179
|
|
|
180
180
|
The grid reports `grid` and `gridcell` once cell selection is on, so a test or a
|
|
181
181
|
query written against `getByRole("cell")` stops resolving the moment the option
|
|
182
|
-
is set - including when `
|
|
182
|
+
is set - including when `editing` turns it on implicitly.
|
|
183
183
|
|
|
184
184
|
Source: `src/docs/cell-selection.md`, and the `testing` skill.
|
|
185
185
|
|
|
@@ -218,7 +218,7 @@ Source: `src/docs/cell-selection.md` (Copy and export).
|
|
|
218
218
|
|
|
219
219
|
| Name | Kind | Type | Default | What it does |
|
|
220
220
|
| --- | --- | --- | --- | --- |
|
|
221
|
-
| `cellSelection` | Option | `"none" \| "single" \| "range"` | `"none"`, or `"single"` under `
|
|
221
|
+
| `cellSelection` | Option | `"none" \| "single" \| "range"` | `"none"`, or `"single"` under `editing` | Turns the cursor, and the rectangle, on. |
|
|
222
222
|
| `onFocusedCellChange` | Callback | `(cell \| null) => void` | – | Follows the cursor. |
|
|
223
223
|
| `cellExport` | Table prop | `TMDataGridCellExportOptions` | Nordic Excel | Separator, decimal mark, headers, file name. |
|
|
224
224
|
| `ui.state.focusedCell` | UI state | `{ rowId, columnId } \| null` | `null` | The cursor. |
|
package/skills/columns/SKILL.md
CHANGED
|
@@ -16,7 +16,7 @@ description: >
|
|
|
16
16
|
metadata:
|
|
17
17
|
type: core
|
|
18
18
|
library: '@jielga/tmdatagrid'
|
|
19
|
-
library_version: '2.0.0-beta.
|
|
19
|
+
library_version: '2.0.0-beta.2'
|
|
20
20
|
sources:
|
|
21
21
|
- 'Jielga/TMDataGrid:src/docs/columns.md'
|
|
22
22
|
- 'Jielga/TMDataGrid:src/docs/column-layout.md'
|
|
@@ -69,9 +69,9 @@ column model.
|
|
|
69
69
|
| `filter` | `TMDataGridColumnFilterOptions` | – | How this column filters. See below. |
|
|
70
70
|
| `edit` | `TMDataGridColumnEditOptions` | – | How this column is edited. See below. |
|
|
71
71
|
|
|
72
|
-
What the column **is** stays flat; what
|
|
73
|
-
|
|
74
|
-
which is why they are
|
|
72
|
+
What the column **is** stays flat; what the filter panel and the edit engine do
|
|
73
|
+
with it sits in their namespaces. `type` and `options` are read by both stages,
|
|
74
|
+
which is why they are in neither.
|
|
75
75
|
|
|
76
76
|
`meta.filter`:
|
|
77
77
|
|
|
@@ -99,7 +99,7 @@ meta: {
|
|
|
99
99
|
```
|
|
100
100
|
|
|
101
101
|
`enableOrdering` lives in `meta` because column ordering is the one feature
|
|
102
|
-
TanStack defines no column option for. `meta.edit` only acts once `
|
|
102
|
+
TanStack defines no column option for. `meta.edit` only acts once `editing` is
|
|
103
103
|
set: see the `editing` skill. `meta.filter` belongs to the `filtering` skill.
|
|
104
104
|
|
|
105
105
|
### Column types
|
|
@@ -246,7 +246,7 @@ asks for it.
|
|
|
246
246
|
| Checkbox | `SELECT_COLUMN_ID` | Selection is on and the mode has checkboxes |
|
|
247
247
|
| Tree | `GROUP_COLUMN_ID` | A column is grouped |
|
|
248
248
|
| Details | `DETAILS_COLUMN_ID` | `renderDetails` is set |
|
|
249
|
-
| Edit | `EDIT_COLUMN_ID` | Row mode,
|
|
249
|
+
| Edit | `EDIT_COLUMN_ID` | Row mode, draft mode, or `editing.onRowDelete` |
|
|
250
250
|
|
|
251
251
|
They are structural: fixed width, no column menu, and they cannot be sorted,
|
|
252
252
|
filtered, resized, re-pinned or moved. The checkbox lane anchors the left pinned
|
|
@@ -350,10 +350,10 @@ columnHelper.accessor("priority", { header: "Priority", sortFn: byRank });
|
|
|
350
350
|
Source: `@tanstack/table-core` `rowSortingFeature.types.d.ts`, and
|
|
351
351
|
`src/tmdatagrid/useTMDataGrid.tsx` (the registered `sortFns`).
|
|
352
352
|
|
|
353
|
-
### MEDIUM
|
|
353
|
+
### MEDIUM Expecting autosize to measure every row
|
|
354
354
|
|
|
355
355
|
Autosizing fits the **mounted** rows plus overscan, not every row, because
|
|
356
|
-
virtualization
|
|
356
|
+
virtualization leaves the rest with no DOM to measure. A column autosized at the
|
|
357
357
|
top of a long list can be too narrow for a value further down.
|
|
358
358
|
|
|
359
359
|
Source: `src/docs/column-layout.md` (Autosizing).
|
|
@@ -387,7 +387,7 @@ Source: `src/docs/column-layout.md` (Regions).
|
|
|
387
387
|
| `isColumnReorderable` | Export | `(column, features) => boolean` | – | Whether this column may move at all. |
|
|
388
388
|
| `autosizeColumn` | Export | `({ table, columnId, container }) => void` | – | Fits a column to its mounted content. |
|
|
389
389
|
| `measureColumnContentWidth` | Export | `(args) => number` | – | The measurement behind it. |
|
|
390
|
-
| `getColumnLabel` · `getColumnType` · `getColumnDefaultOperator` · `isControlColumn` | Exports | – | – | What the
|
|
390
|
+
| `getColumnLabel` · `getColumnType` · `getColumnDefaultOperator` · `isControlColumn` | Exports | – | – | What the built-in controls read off a column. |
|
|
391
391
|
| `SELECT_COLUMN_ID` · `GROUP_COLUMN_ID` · `DETAILS_COLUMN_ID` · `EDIT_COLUMN_ID` · `ROW_NUMBER_COLUMN_ID` | Exports | ids | – | The generated lanes. |
|
|
392
392
|
| `TMDataGrid.ColumnsButton` · `TMDataGrid.ColumnsPanel` | Components | – | – | Manage columns, and Reset layout. |
|
|
393
393
|
|
package/skills/data/SKILL.md
CHANGED
|
@@ -15,7 +15,7 @@ description: >
|
|
|
15
15
|
metadata:
|
|
16
16
|
type: core
|
|
17
17
|
library: '@jielga/tmdatagrid'
|
|
18
|
-
library_version: '2.0.0-beta.
|
|
18
|
+
library_version: '2.0.0-beta.2'
|
|
19
19
|
sources:
|
|
20
20
|
- 'Jielga/TMDataGrid:src/docs/pagination.md'
|
|
21
21
|
- 'Jielga/TMDataGrid:src/docs/scrolling.md'
|
|
@@ -28,8 +28,8 @@ sources:
|
|
|
28
28
|
## Pagination
|
|
29
29
|
|
|
30
30
|
**Off by default.** The grid renders every filtered and sorted row and relies on
|
|
31
|
-
virtualization, which handles any row count
|
|
32
|
-
|
|
31
|
+
virtualization, which handles any row count. Paging is not needed for
|
|
32
|
+
performance. Three modes:
|
|
33
33
|
|
|
34
34
|
```tsx
|
|
35
35
|
// 1. None (default). TMDataGrid.Footer renders nothing.
|
|
@@ -50,12 +50,12 @@ const grid = useTMDataGrid({
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Initial page size is 25, through `initialState.pagination`. `enablePagination`
|
|
53
|
-
is
|
|
53
|
+
is defined by the grid rather than by TanStack, and is the only grid option that
|
|
54
54
|
defaults to off.
|
|
55
55
|
|
|
56
56
|
`TMDataGrid.Footer` takes a `renderPagination` slot handed three things: the
|
|
57
|
-
`state` the pager shows, the `actions` it can take, and `Controls
|
|
58
|
-
|
|
57
|
+
`state` the pager shows, the `actions` it can take, and `Controls`, the built-in
|
|
58
|
+
pieces, already wired.
|
|
59
59
|
|
|
60
60
|
```tsx
|
|
61
61
|
<TMDataGrid.Footer
|
|
@@ -74,35 +74,34 @@ built-in pieces, already wired.
|
|
|
74
74
|
/>
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
`Controls.PageSize`, `Controls.Range` and `Controls.Pager` are
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
suspended pager
|
|
77
|
+
`Controls.PageSize`, `Controls.Range` and `Controls.Pager` are what the default
|
|
78
|
+
footer renders, in that order, so a custom layout can keep the parts it wants
|
|
79
|
+
instead of rebuilding them. They behave exactly as before, including greying out
|
|
80
|
+
under a suspended pager.
|
|
81
81
|
|
|
82
82
|
`state` carries `pageIndex`, `pageSize`, `pageCount`, `rowCount`,
|
|
83
83
|
`canPreviousPage`, `canNextPage`, `from`, `to` and `isPagingActive`. `actions`
|
|
84
84
|
carries `setPageIndex`, `setPageSize`, `previousPage`, `nextPage`, `firstPage`
|
|
85
85
|
and `lastPage`. `getTMDataGridPaginationApi(table)` returns the same
|
|
86
|
-
`{ state, actions }` outside the Footer
|
|
87
|
-
context, so
|
|
86
|
+
`{ state, actions }` outside the Footer. `Controls` is bound to the grid
|
|
87
|
+
context, so those components work only inside the slot.
|
|
88
88
|
|
|
89
|
-
Grouping suspends the pager
|
|
90
|
-
`Grouped · all N rows`. `isPagingActive(table, features)` is the live state
|
|
91
|
-
whether the pager is slicing anything right now
|
|
89
|
+
Grouping suspends the pager: it greys out and the range becomes
|
|
90
|
+
`Grouped · all N rows`. `isPagingActive(table, features)` is the live state,
|
|
91
|
+
whether the pager is slicing anything right now, while
|
|
92
92
|
`getGridCapabilities(...).canPaginate` is the configuration. The two differ
|
|
93
|
-
|
|
93
|
+
while a grouping is active.
|
|
94
94
|
|
|
95
95
|
## Scrolling
|
|
96
96
|
|
|
97
|
-
Virtualization is **always on**. There is no flag
|
|
98
|
-
|
|
99
|
-
are ever mounted.
|
|
97
|
+
Virtualization is **always on**. There is no flag and no threshold: only the
|
|
98
|
+
rows within the viewport plus a small overscan are mounted.
|
|
100
99
|
|
|
101
|
-
`overscan` (default `6`) is the
|
|
100
|
+
`overscan` (default `6`) is the only setting: raise it if a fast scroll flashes
|
|
102
101
|
blank rows, lower it when rows are expensive. Row height comes from
|
|
103
102
|
`meta.rowHeight`, or from `size` when that is not set, and rows are **fixed
|
|
104
|
-
height**, so the virtualizer's estimate is exact and the scrollbar
|
|
105
|
-
Row details are the exception: a row showing a panel is measured after it
|
|
103
|
+
height**, so the virtualizer's estimate is exact and the scrollbar does not
|
|
104
|
+
drift. Row details are the exception: a row showing a panel is measured after it
|
|
106
105
|
mounts.
|
|
107
106
|
|
|
108
107
|
```tsx
|
|
@@ -117,20 +116,21 @@ const grid = useTMDataGrid({
|
|
|
117
116
|
grid.scrollToRow({ rowId: "42", align: "center" });
|
|
118
117
|
```
|
|
119
118
|
|
|
120
|
-
`scrollToRow` exists because the row may not be mounted,
|
|
121
|
-
`element.scrollIntoView()` cannot
|
|
122
|
-
`"end"` or `"auto"`. `scrollerRef` is the scroll
|
|
119
|
+
`scrollToRow` exists because the target row may not be mounted, and
|
|
120
|
+
`element.scrollIntoView()` cannot find an element that is not rendered. `align`
|
|
121
|
+
is `"start"`, `"center"`, `"end"` or `"auto"`. `scrollerRef` is the scroll
|
|
122
|
+
container itself.
|
|
123
123
|
|
|
124
124
|
`TMDataGrid.Table` reports arrivals at each edge - `onScrollToTop`,
|
|
125
125
|
`onScrollToBottom`, `onScrollToLeft`, `onScrollToRight` - firing **once** on
|
|
126
|
-
arrival rather than on every scroll event. For loading more rows
|
|
127
|
-
`onReachEnd` (the `server-side` skill): it fires
|
|
128
|
-
|
|
126
|
+
arrival rather than on every scroll event. For loading more rows use
|
|
127
|
+
`onReachEnd` (the `server-side` skill) instead: it fires a number of rows before
|
|
128
|
+
the bottom, and latches per row count so a pending fetch is not requested twice.
|
|
129
129
|
|
|
130
|
-
Two depth cues are scroll-driven animations on the compositor, with no
|
|
131
|
-
listener and no React render: a shadow under the sticky header once rows
|
|
132
|
-
beneath it, and a band beside a pinned lane while it is
|
|
133
|
-
|
|
130
|
+
Two depth cues are scroll-driven animations run on the compositor, with no
|
|
131
|
+
scroll listener and no React render: a shadow under the sticky header once rows
|
|
132
|
+
scroll beneath it, and a band beside a pinned lane while it is covering
|
|
133
|
+
content.
|
|
134
134
|
|
|
135
135
|
## Empty states
|
|
136
136
|
|
|
@@ -138,12 +138,12 @@ There are four ways to have nothing to show, and an empty body shows exactly one
|
|
|
138
138
|
of them, in this order:
|
|
139
139
|
|
|
140
140
|
1. **Loading** - `meta.loading` is true: a centred loader. A grid that is
|
|
141
|
-
fetching never
|
|
142
|
-
2. **Entry rows** - an open entry row from `edit.addRow()`:
|
|
143
|
-
|
|
141
|
+
fetching never reports itself as empty.
|
|
142
|
+
2. **Entry rows** - an open entry row from `edit.addRow()`: the entry block
|
|
143
|
+
only, with no message beside the form.
|
|
144
144
|
3. **`renderEmptyState`** - your node, centred where the message would be.
|
|
145
|
-
4. **Filtered-empty** - a filter or search is active: `labels.noResults`,
|
|
146
|
-
|
|
145
|
+
4. **Filtered-empty** - a filter or search is active: `labels.noResults`, since
|
|
146
|
+
clearing the filter will bring rows back.
|
|
147
147
|
5. **Truly-empty** - no data at all: `labels.noRows`.
|
|
148
148
|
|
|
149
149
|
`renderEmptyState` replaces the last two with one render prop, and
|
|
@@ -163,12 +163,12 @@ of them, in this order:
|
|
|
163
163
|
/>
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
An empty grid is
|
|
167
|
-
|
|
166
|
+
An empty grid is a good place to offer the action that fills it, such as
|
|
167
|
+
clearing the filters or creating the first record.
|
|
168
168
|
|
|
169
169
|
The body's loading state only appears while the grid is **empty**. A
|
|
170
|
-
server-driven grid refetching with rows still on screen keeps showing them
|
|
171
|
-
`TMDataGrid.LoadingIndicator`
|
|
170
|
+
server-driven grid refetching with rows still on screen keeps showing them.
|
|
171
|
+
`TMDataGrid.LoadingIndicator` covers that case: a small spinner while
|
|
172
172
|
`meta.loading` is true. `TMDataGrid.SummaryCount` shows visible rows out of
|
|
173
173
|
total, where the total is `meta.totalRowCount` when provided and the pre-filtered
|
|
174
174
|
count otherwise.
|
|
@@ -178,17 +178,17 @@ count otherwise.
|
|
|
178
178
|
### CRITICAL Turning pagination on to make a large grid fast
|
|
179
179
|
|
|
180
180
|
Virtualization is already unconditional, so paging a 200 000-row grid changes
|
|
181
|
-
nothing about rendering cost
|
|
182
|
-
|
|
181
|
+
nothing about rendering cost. It only changes how users navigate. Enable it when
|
|
182
|
+
they should move page by page, not for performance.
|
|
183
183
|
|
|
184
184
|
Source: `src/docs/pagination.md`, `src/docs/scrolling.md`.
|
|
185
185
|
|
|
186
186
|
### CRITICAL A variable row height
|
|
187
187
|
|
|
188
188
|
The virtualizer needs one number, and rows are fixed height so the scrollbar
|
|
189
|
-
stays
|
|
189
|
+
stays accurate. Styling a taller row through CSS leaves the measurement and the
|
|
190
190
|
render disagreeing: rows overlap or gaps open as you scroll, and the effect
|
|
191
|
-
depends on scroll position, so it
|
|
191
|
+
depends on scroll position, so it appears intermittent.
|
|
192
192
|
|
|
193
193
|
Wrong:
|
|
194
194
|
|
|
@@ -215,16 +215,16 @@ Correct:
|
|
|
215
215
|
grid.scrollToRow({ rowId: "4000", align: "center" });
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
-
`scrollToRow` returns `false` when the row is not in the current view
|
|
219
|
-
out, on another page, or an id matching no row
|
|
218
|
+
`scrollToRow` returns `false` when the row is not in the current view (filtered
|
|
219
|
+
out, on another page, or an id matching no row) and nothing scrolled.
|
|
220
220
|
|
|
221
221
|
Source: `src/docs/scrolling.md` (Scrolling to a row).
|
|
222
222
|
|
|
223
223
|
### HIGH Loading more rows from `onScrollToBottom`
|
|
224
224
|
|
|
225
|
-
It fires at the very bottom, so the
|
|
226
|
-
fetch. `onReachEnd` fires rows
|
|
227
|
-
fetch is
|
|
225
|
+
It fires at the very bottom, so the user waits at the end of the list for the
|
|
226
|
+
fetch. `onReachEnd` fires a number of rows earlier and latches per row count, so
|
|
227
|
+
a pending fetch is not requested twice.
|
|
228
228
|
|
|
229
229
|
Source: `src/docs/scrolling.md` (Edge callbacks).
|
|
230
230
|
|
|
@@ -249,7 +249,7 @@ Source: `src/docs/loading-and-empty.md` (Counting what is there).
|
|
|
249
249
|
|
|
250
250
|
### MEDIUM Rendering an empty message while data is loading
|
|
251
251
|
|
|
252
|
-
The order exists so a fetching grid never
|
|
252
|
+
The order exists so a fetching grid never reports itself as empty. A hand-rolled
|
|
253
253
|
`data.length === 0 ? <Empty /> : <Grid />` outside the grid flashes "No rows to
|
|
254
254
|
show" on every load.
|
|
255
255
|
|
|
@@ -281,7 +281,7 @@ Source: `src/docs/pagination.md` (Grouping suspends it).
|
|
|
281
281
|
| `TMDataGrid.Footer` | Component | `pageSizeOptions`, `pagination` | `[10, 25, 50, 100]` | The footer bar. Renders nothing when paging is off. |
|
|
282
282
|
| `Footer` `renderPagination` | Slot | `({ state, actions, Controls }) => ReactNode` | Built-in pager | Replaces the pager, and hands over its pieces. |
|
|
283
283
|
| `getTMDataGridPaginationApi` | Export | `(table) => { state, actions }` | – | The pager API, outside the Footer. |
|
|
284
|
-
| `TMDataGridPaginationState` · `TMDataGridPaginationActions` · `TMDataGridPaginationControls` | Exports | types | – | The three
|
|
284
|
+
| `TMDataGridPaginationState` · `TMDataGridPaginationActions` · `TMDataGridPaginationControls` | Exports | types | – | The three parts of the slot argument. |
|
|
285
285
|
| `isPagingActive` | Export | `(table, features) => boolean` | – | Whether the pager is slicing anything right now. |
|
|
286
286
|
| `overscan` | Option | `number` | `6` | Rows kept mounted beyond each edge of the viewport. |
|
|
287
287
|
| `meta.rowHeight` | Option | `number` | From `size` | Row height in pixels. The virtualizer needs a number. |
|
|
@@ -289,7 +289,7 @@ Source: `src/docs/pagination.md` (Grouping suspends it).
|
|
|
289
289
|
| `scrollerRef` | Hook return | `RefObject<HTMLDivElement>` | – | The scroll container. |
|
|
290
290
|
| `onScrollToTop` · `onScrollToBottom` · `onScrollToLeft` · `onScrollToRight` | Table props | `() => void` | – | Fire once on arriving at that edge. |
|
|
291
291
|
| `TMDataGridScrollAlign` | Export | `"start" \| "center" \| "end" \| "auto"` | – | The `align` argument. |
|
|
292
|
-
| `meta.loading` | Option | `boolean` | `false` | A fetch is in flight.
|
|
292
|
+
| `meta.loading` | Option | `boolean` | `false` | A fetch is in flight. Takes precedence over every empty message. |
|
|
293
293
|
| `meta.noResultsLabel` | Option | `string` | `labels.noResults` | The filtered-empty message, without a render prop. |
|
|
294
294
|
| `meta.totalRowCount` | Option | `number` | Pre-filtered count | The total `SummaryCount` reports. |
|
|
295
295
|
| `renderEmptyState` | Table prop | `({ hasActiveFilters, table }) => ReactNode` | – | Replaces both built-in empty messages. |
|