@jielga/tmdatagrid 2.0.0-beta.7 → 2.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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_1459c_1{align-items:center;gap:var(--mantine-spacing-xs);padding:6px var(--mantine-spacing-xs);flex-shrink:0;min-height:42px;display:flex}._toolbarSpacer_1459c_10{flex:1}._summaryCount_1459c_14{white-space:nowrap}
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_1npmp_2{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}._scrollContainer_1npmp_10{flex:1;min-height:0;position:relative;overflow:auto;container-type:inline-size}._grid_1npmp_21{display:grid}._headerRow_1npmp_27{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-header,6);display:grid;position:sticky;top:0}._headerRow_1npmp_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_1npmp_27[data-dg-header-last]:after{animation:linear both _dg-header-shadow_1npmp_1;animation-timeline:scroll();animation-range:0 24px}}@keyframes _dg-header-shadow_1npmp_1{0%{opacity:0}to{opacity:1}}._bodyRow_1npmp_76{--row-bg:var(--mantine-color-body);grid-column:1/-1;grid-template-columns:subgrid;align-items:stretch;display:grid}._bodyRow_1npmp_76[data-striped=true]{--row-bg:var(--dg-row-striped-bg)}._bodyRow_1npmp_76:hover{--row-bg:var(--mantine-color-default-hover)}._bodyRow_1npmp_76[data-grouped=true]{--row-bg:var(--dg-row-group-bg)}._bodyRow_1npmp_76[data-context-menu=true]{--row-bg:var(--mantine-color-default-hover)}._bodyRow_1npmp_76[data-selected-bg=true]{--row-bg:var(--dg-row-selected-bg)}._bodyRow_1npmp_76[data-highlighted=true]{--row-bg:var(--dg-row-highlight-bg)}._bodyRow_1npmp_76[data-selects-on-click=true]{-webkit-user-select:none;user-select:none}._bodyRow_1npmp_76:focus-visible{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._bodyCell_1npmp_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_1npmp_143[data-control-column=true]{padding:0}._grid_1npmp_21[data-range-dragging]{-webkit-user-select:none;user-select:none}._bodyCell_1npmp_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_1npmp_143[data-edge-top=true]{--dg-edge-top:var(--mantine-primary-color-filled)}._bodyCell_1npmp_143[data-edge-bottom=true]{--dg-edge-bottom:var(--mantine-primary-color-filled)}._bodyCell_1npmp_143[data-edge-left=true]{--dg-edge-left:var(--mantine-primary-color-filled)}._bodyCell_1npmp_143[data-edge-right=true]{--dg-edge-right:var(--mantine-primary-color-filled)}._bodyCell_1npmp_143[data-focused=true]{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._cellContent_1npmp_141{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._bodyCell_1npmp_143[data-editing]{padding:0 calc(var(--dg-padding) / 2)}._cellEditor_1npmp_243{align-items:center;gap:2px;width:100%;min-width:0;display:flex}._cellEditorActions_1npmp_252{flex:none;align-items:center;display:flex}._bodyCell_1npmp_143[data-dirty],._bodyCell_1npmp_143[data-invalid]{position:relative}._bodyCell_1npmp_143[data-dirty]:after,._bodyCell_1npmp_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_1npmp_143[data-invalid]:after{border-top-color:var(--mantine-color-error);border-right-color:var(--mantine-color-error)}._bodyCell_1npmp_143[data-align=right]{justify-content:flex-end}._bodyCell_1npmp_143[data-align=center]{justify-content:center}._bodyCell_1npmp_143[data-align=left] ._cellContent_1npmp_141{flex:auto}._detailsCell_1npmp_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_1npmp_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_1npmp_76[data-deleted=true]{opacity:.55;text-decoration:line-through}._bodyRow_1npmp_76[data-deleted=true] ._bodyCell_1npmp_143:not([data-control-column=true]){pointer-events:none}._entryBlock_1npmp_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_1npmp_362,._entryFlowBlock_1npmp_371{grid-column:1/-1;grid-template-columns:subgrid;display:grid}._pinnedTopBlock_1npmp_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_1npmp_384>:last-child>[role=cell]{border-bottom:2px solid var(--mantine-color-default-border)}._pinnedBottomBlock_1npmp_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_1npmp_397>:first-child>[role=cell]{border-top:2px solid var(--mantine-color-default-border)}._entryCell_1npmp_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_1npmp_410[data-control-column=true]{justify-content:center;padding:0}._entryRow_1npmp_362[data-committed=true] ._entryCell_1npmp_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_1npmp_362[data-committed=true] ._entryCell_1npmp_410[data-control-column=true]{padding:0}._rowStateIndicator_1npmp_440{width:22px;height:22px;color:var(--mantine-color-dimmed);flex:none;justify-content:center;align-items:center;display:inline-flex}._rowStateIndicator_1npmp_440[data-error]{color:var(--mantine-color-error)}._entryCell_1npmp_410[data-align=right]{justify-content:flex-end}._entryCell_1npmp_410[data-align=center]{justify-content:center}._matchHighlight_1npmp_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_1npmp_478{grid-column:1/-1;grid-template-columns:subgrid;z-index:var(--dg-z-summary-row,4);display:grid;position:sticky;bottom:0}._summaryCell_1npmp_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_1npmp_487[data-control-column=true]{padding:0}._summaryCell_1npmp_487[data-align=right]{justify-content:flex-end}._summaryCell_1npmp_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_1459c_1{align-items:center;gap:var(--mantine-spacing-xs);padding:6px var(--mantine-spacing-xs);flex-shrink:0;min-height:42px;display:flex}._toolbarSpacer_1459c_10{flex:1}._summaryCount_1459c_14{white-space:nowrap}
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.7",
3
+ "version": "2.0.0-beta.8",
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",
@@ -61,6 +61,7 @@
61
61
  "build:lib": "vite build --config vite.lib.config.ts && tsc -p tsconfig.lib.json && rolldown -c rolldown.dts.config.mjs",
62
62
  "lint": "oxlint",
63
63
  "check:style": "node scripts/check-house-style.mjs",
64
+ "check:skills": "node scripts/intent.mjs validate",
64
65
  "test": "vitest run",
65
66
  "test:watch": "vitest",
66
67
  "preview": "vite preview",
@@ -16,7 +16,7 @@ description: >
16
16
  metadata:
17
17
  type: core
18
18
  library: '@jielga/tmdatagrid'
19
- library_version: '2.0.0-beta.7'
19
+ library_version: '2.0.0-beta.8'
20
20
  sources:
21
21
  - 'Jielga/TMDataGrid:src/docs/styling.md'
22
22
  - 'Jielga/TMDataGrid:src/docs/toolbar.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.7'
17
+ library_version: '2.0.0-beta.8'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:src/docs/cell-selection.md'
20
20
  - 'Jielga/TMDataGrid:src/tmdatagrid/core/cellNavigation.ts'
@@ -16,7 +16,7 @@ description: >
16
16
  metadata:
17
17
  type: core
18
18
  library: '@jielga/tmdatagrid'
19
- library_version: '2.0.0-beta.7'
19
+ library_version: '2.0.0-beta.8'
20
20
  sources:
21
21
  - 'Jielga/TMDataGrid:src/docs/columns.md'
22
22
  - 'Jielga/TMDataGrid:src/docs/column-layout.md'
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: core
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.0.0-beta.7'
18
+ library_version: '2.0.0-beta.8'
19
19
  sources:
20
20
  - 'Jielga/TMDataGrid:src/docs/pagination.md'
21
21
  - 'Jielga/TMDataGrid:src/docs/scrolling.md'
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.0.0-beta.7'
21
+ library_version: '2.0.0-beta.8'
22
22
  sources:
23
23
  - 'Jielga/TMDataGrid:src/docs/editing.md'
24
24
  - 'Jielga/TMDataGrid:src/docs/query-builder.md'
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: core
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.0.0-beta.7'
18
+ library_version: '2.0.0-beta.8'
19
19
  sources:
20
20
  - 'Jielga/TMDataGrid:src/docs/filtering.md'
21
21
  - 'Jielga/TMDataGrid:src/docs/quick-search.md'
@@ -11,7 +11,7 @@ description: >
11
11
  metadata:
12
12
  type: core
13
13
  library: '@jielga/tmdatagrid'
14
- library_version: '2.0.0-beta.7'
14
+ library_version: '2.0.0-beta.8'
15
15
  sources:
16
16
  - 'Jielga/TMDataGrid:src/docs/getting-started.md'
17
17
  - 'Jielga/TMDataGrid:src/docs/anatomy.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.7'
17
+ library_version: '2.0.0-beta.8'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:src/docs/grouping.md'
20
20
  - 'Jielga/TMDataGrid:src/docs/summary-row.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.7'
17
+ library_version: '2.0.0-beta.8'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:src/docs/use-tm-data-grid.md'
20
20
  - 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
@@ -17,7 +17,7 @@ description: >
17
17
  metadata:
18
18
  type: core
19
19
  library: '@jielga/tmdatagrid'
20
- library_version: '2.0.0-beta.7'
20
+ library_version: '2.0.0-beta.8'
21
21
  sources:
22
22
  - 'Jielga/TMDataGrid:src/docs/row-selection.md'
23
23
  - 'Jielga/TMDataGrid:src/docs/row-interaction.md'
@@ -10,7 +10,7 @@ description: >
10
10
  metadata:
11
11
  type: core
12
12
  library: '@jielga/tmdatagrid'
13
- library_version: '2.0.0-beta.7'
13
+ library_version: '2.0.0-beta.8'
14
14
  sources:
15
15
  - 'Jielga/TMDataGrid:src/docs/server-side.md'
16
16
  - 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
@@ -11,7 +11,7 @@ description: >
11
11
  metadata:
12
12
  type: core
13
13
  library: '@jielga/tmdatagrid'
14
- library_version: '2.0.0-beta.7'
14
+ library_version: '2.0.0-beta.8'
15
15
  sources:
16
16
  - 'Jielga/TMDataGrid:src/docs/testing.md'
17
17
  - 'Jielga/TMDataGrid:src/tmdatagrid/components/TMDataGrid.tsx'
@@ -210,13 +210,14 @@ export function TMDataGridEntryRows({
210
210
  data-align={getColumnAlign(column)}
211
211
  data-control-column={isControlColumn(column.id)}
212
212
  // A committed row re-opens where it is double-clicked, the
213
- // same gesture a body cell answers.
213
+ // same gesture a body cell answers - and, like a body cell, a
214
+ // cell that takes no edit answers nothing.
214
215
  onDoubleClick={
215
- committed && !isControlColumn(column.id)
216
+ committed && editable
216
217
  ? () =>
217
218
  edit.begin({
218
219
  rowId: entryRow.id,
219
- columnId: editable ? column.id : null,
220
+ columnId: column.id,
220
221
  })
221
222
  : undefined
222
223
  }
@@ -1,10 +1,10 @@
1
1
  import { ActionIcon, Group, Select, Text, Tooltip } from "@mantine/core";
2
2
  import type { RowData } from "@tanstack/react-table";
3
- import { useSelector } from "@tanstack/react-store";
4
3
  import { useMemo, type ReactNode } from "react";
5
4
  import classes from "./TMDataGridFooter.module.css";
6
5
  import { useTMDataGridContext } from "../TMDataGridContext";
7
6
  import { getGridCapabilities } from "../core/capabilities";
7
+ import { useSettledTableState } from "../core/useSettledTableState";
8
8
  import { isPagingActive } from "../core/rowSelection";
9
9
  import { ChevronLeftIcon, ChevronRightIcon } from "./icons";
10
10
  import type { TMDataGridTable } from "../useTMDataGrid";
@@ -122,7 +122,7 @@ function PaginationPageSize({
122
122
  pageSizeOptions: ReadonlyArray<number>;
123
123
  }) {
124
124
  const { table, features, labels, controlSize } = useTMDataGridContext();
125
- useSelector(table.store);
125
+ useSettledTableState(table.store);
126
126
  const paging = isPagingActive(table, features);
127
127
  const { pageSize } = table.store.state.pagination;
128
128
  // A page size restored from storage, or set through `initialState`, need not
@@ -163,7 +163,7 @@ function PaginationPageSize({
163
163
 
164
164
  function PaginationRange() {
165
165
  const { table, features, labels, controlSize } = useTMDataGridContext();
166
- useSelector(table.store);
166
+ useSettledTableState(table.store);
167
167
  const paging = isPagingActive(table, features);
168
168
  const { pageIndex, pageSize } = table.store.state.pagination;
169
169
  const total = table.getRowCount();
@@ -184,7 +184,7 @@ function PaginationRange() {
184
184
 
185
185
  function PaginationPager() {
186
186
  const { table, features, labels } = useTMDataGridContext();
187
- useSelector(table.store);
187
+ useSettledTableState(table.store);
188
188
  const paging = isPagingActive(table, features);
189
189
 
190
190
  return (
@@ -250,7 +250,7 @@ export function TMDataGridFooter({
250
250
  renderPagination,
251
251
  }: TMDataGridFooterProps) {
252
252
  const { table, features, labels } = useTMDataGridContext();
253
- useSelector(table.store);
253
+ useSettledTableState(table.store);
254
254
 
255
255
  // Bound once per option list rather than per render, so the controls keep
256
256
  // their identity and the elements they render keep theirs.
@@ -133,6 +133,9 @@ export function TMDataGridHeaderCell({
133
133
  (filter) => filter.id === column.id && isFilterActive(filter.value),
134
134
  );
135
135
  const isResizing = resizingColumnId === column.id;
136
+ // Any column, not just this one: a resize elsewhere must not leave a
137
+ // neighbouring header ready to start a native drag under the pointer.
138
+ const isAnyResizing = resizingColumnId !== false;
136
139
  const pinnedAt = layout.pinnedAt;
137
140
 
138
141
  // Every affordance below mirrors a TanStack capability check, so switching a
@@ -222,6 +225,43 @@ export function TMDataGridHeaderCell({
222
225
  if (container) autosizeColumn({ table, columnId: column.id, container });
223
226
  }
224
227
 
228
+ /**
229
+ * Writes the width this header's columns are rendered with into
230
+ * `columnSizing`, for the ones that have no width there yet.
231
+ *
232
+ * An unresized column is a fluid (`fr`) track: it renders at whatever share
233
+ * of the grid it is given, while `column.getSize()` keeps reporting the
234
+ * declared `size`. Anything that switches a column to exact pixels has to
235
+ * close that gap first, or the column jumps from the width on screen to the
236
+ * declared one.
237
+ *
238
+ * Under a held pointer that jump is more than cosmetic: it slides the
239
+ * divider out from under the cursor onto the neighbouring header, where the
240
+ * browser starts a native column-move drag instead. That drag swallows the
241
+ * `mouseup` the resize listens for, so the resize keeps running after the
242
+ * button is released.
243
+ */
244
+ function freezeRenderedWidths() {
245
+ const container = cellRef.current?.closest<HTMLElement>(
246
+ "[data-dg-scroll-container]",
247
+ );
248
+ if (!container) return;
249
+ const sizing = table.store.state.columnSizing;
250
+ const frozen: Record<string, number> = {};
251
+ for (const leaf of header.getLeafHeaders()) {
252
+ const id = leaf.column.id;
253
+ if (id in sizing) continue;
254
+ const width = container
255
+ .querySelector<HTMLElement>(
256
+ `[role="columnheader"][data-column-id="${CSS.escape(id)}"]`,
257
+ )
258
+ ?.getBoundingClientRect().width;
259
+ if (width) frozen[id] = Math.round(width);
260
+ }
261
+ if (Object.keys(frozen).length === 0) return;
262
+ table.setColumnSizing((previous) => ({ ...previous, ...frozen }));
263
+ }
264
+
225
265
  /**
226
266
  * Pinned columns are positioned with `getStart()` / `getAfter()`, which sum
227
267
  * `column.getSize()`. Fluid (`fr`) columns don't report their rendered width
@@ -229,15 +269,7 @@ export function TMDataGridHeaderCell({
229
269
  * keeps the column looking the same and keeps the offsets exact.
230
270
  */
231
271
  function setPinned(position: "left" | "right" | false) {
232
- if (position && !(column.id in table.store.state.columnSizing)) {
233
- const width = cellRef.current?.getBoundingClientRect().width;
234
- if (width) {
235
- table.setColumnSizing((prev) => ({
236
- ...prev,
237
- [column.id]: Math.round(width),
238
- }));
239
- }
240
- }
272
+ if (position) freezeRenderedWidths();
241
273
  column.pin(position);
242
274
  // `pin("right")` appends, which would leave the column outside the edit
243
275
  // lane. Normalising after the pin rather than writing the lane by hand
@@ -514,10 +546,12 @@ export function TMDataGridHeaderCell({
514
546
  : undefined
515
547
  }
516
548
  className={cellClass}
517
- // Dropped while a resize is running, so that dragging the separator
518
- // resizes the column instead of starting to move it. The resize handler
519
- // records the column on mousedown, before the first pointer move.
520
- draggable={canReorder && !isResizing}
549
+ // Dropped while any column is resizing, so that dragging the separator
550
+ // resizes the column instead of starting to move it - and so that a
551
+ // header the divider passes under cannot start a move of its own. The
552
+ // resize handler records the column on mousedown, before the first
553
+ // pointer move.
554
+ draggable={canReorder && !isAnyResizing}
521
555
  onDragStart={canReorder ? handleDragStart : undefined}
522
556
  onDragEnd={canReorder ? handleDragEnd : undefined}
523
557
  onDragOver={isDropTarget ? handleDragOver : undefined}
@@ -671,15 +705,26 @@ export function TMDataGridHeaderCell({
671
705
  // Keeps a drag that starts on the separator from being picked up by
672
706
  // the draggable header around it.
673
707
  draggable={false}
708
+ // The drag starts from `column.getSize()`, so the rendered width has
709
+ // to be in `columnSizing` before the handler reads it - otherwise
710
+ // the first pointer move snaps a fluid column to its declared size.
674
711
  onMouseDown={
675
712
  canResize
676
713
  ? (event) => {
677
714
  suppressSortRef.current = true;
715
+ freezeRenderedWidths();
716
+ header.getResizeHandler()(event);
717
+ }
718
+ : undefined
719
+ }
720
+ onTouchStart={
721
+ canResize
722
+ ? (event) => {
723
+ freezeRenderedWidths();
678
724
  header.getResizeHandler()(event);
679
725
  }
680
726
  : undefined
681
727
  }
682
- onTouchStart={canResize ? header.getResizeHandler() : undefined}
683
728
  onClick={(event) => event.stopPropagation()}
684
729
  // The spreadsheet gesture: double-click the divider, the column
685
730
  // fits its content. Same measurement as the menu item.
@@ -422,16 +422,16 @@
422
422
  justify-content: center;
423
423
  }
424
424
 
425
- /* A confirmed entry row - entered, awaiting Save all. It reads as a value
425
+ /* A committed entry row - entered, awaiting Save all. It reads as a value
426
426
  row: text padding, the body's border weight, and the "new" tint instead of
427
427
  the editing underline. */
428
- .entryRow[data-confirmed="true"] .entryCell {
428
+ .entryRow[data-committed="true"] .entryCell {
429
429
  padding: 0 var(--dg-padding);
430
430
  border-bottom: 1px solid var(--mantine-color-default-border);
431
431
  background-color: var(--dg-row-new-bg, var(--mantine-color-body));
432
432
  }
433
433
 
434
- .entryRow[data-confirmed="true"] .entryCell[data-control-column="true"] {
434
+ .entryRow[data-committed="true"] .entryCell[data-control-column="true"] {
435
435
  padding: 0;
436
436
  }
437
437
 
@@ -35,6 +35,11 @@ import {
35
35
  } from "./TMDataGridCellEditor";
36
36
  import { TMDataGridEntryRows } from "./TMDataGridEntryRows";
37
37
  import { getColumnAlign, isControlColumn } from "../core/columnUtils";
38
+ import {
39
+ resizePreview,
40
+ type TMDataGridColumnTrack,
41
+ } from "../core/resizePreview";
42
+ import { useSettledTableState } from "../core/useSettledTableState";
38
43
  import { draftCellContext } from "../core/draftCellContext";
39
44
  import {
40
45
  getEditFieldName,
@@ -726,9 +731,10 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
726
731
  scrollerRef,
727
732
  } = useTMDataGridContext();
728
733
 
729
- // The body depends on every state slice (sorting, filters, paging, sizing,
730
- // visibility, selection), so it subscribes to the whole table store.
731
- useSelector(table.store);
734
+ // The body depends on every settled state slice (sorting, filters, paging,
735
+ // sizing, visibility, selection). Not on the transient resize deltas: those
736
+ // publish on every pointer move and the drag paints itself, see below.
737
+ useSettledTableState(table.store);
732
738
  // The active row lives in the chrome store, so it needs its own subscription.
733
739
  const highlightedRowId = useSelector(ui, (state) => state.highlightedRowId);
734
740
  // As does the focused cell. Selected separately from the row above so a grid
@@ -1082,19 +1088,26 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1082
1088
  // Pinned columns are always exact: their sticky offsets come from
1083
1089
  // `getStart()` / `getAfter()`, which sum `getSize()` and cannot see an `fr`.
1084
1090
  const columnSizing = table.store.state.columnSizing;
1085
- const columnTracks = orderedColumns.map((column) => {
1086
- const isFixed = column.columnDef.minSize === column.columnDef.maxSize;
1087
- const isResized = column.id in columnSizing;
1088
- const isPinned = column.getIsPinned() !== false;
1089
- const minWidth = column.columnDef.minSize ?? 80;
1090
- if (isFixed || isResized || isPinned) {
1091
- return { track: `${column.getSize()}px`, minWidth: column.getSize() };
1092
- }
1093
- return {
1094
- track: `minmax(${minWidth}px, ${column.columnDef.meta?.flex ?? 1}fr)`,
1095
- minWidth,
1096
- };
1097
- });
1091
+ const columnTracks: Array<TMDataGridColumnTrack> = orderedColumns.map(
1092
+ (column) => {
1093
+ const isFixed = column.columnDef.minSize === column.columnDef.maxSize;
1094
+ const isResized = column.id in columnSizing;
1095
+ const isPinned = column.getIsPinned() !== false;
1096
+ const minWidth = column.columnDef.minSize ?? 80;
1097
+ if (isFixed || isResized || isPinned) {
1098
+ return {
1099
+ id: column.id,
1100
+ track: `${column.getSize()}px`,
1101
+ minWidth: column.getSize(),
1102
+ };
1103
+ }
1104
+ return {
1105
+ id: column.id,
1106
+ track: `minmax(${minWidth}px, ${column.columnDef.meta?.flex ?? 1}fr)`,
1107
+ minWidth,
1108
+ };
1109
+ },
1110
+ );
1098
1111
  const gridTemplateColumns = columnTracks.map((c) => c.track).join(" ");
1099
1112
  const gridMinWidth = columnTracks.reduce((sum, c) => sum + c.minWidth, 0);
1100
1113
 
@@ -1142,6 +1155,65 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1142
1155
  const layoutFor = (columnId: string) =>
1143
1156
  columnLayout.get(columnId) ?? UNPINNED_LAYOUT;
1144
1157
 
1158
+ /**
1159
+ * A running resize drag paints itself, straight onto the grid element.
1160
+ *
1161
+ * Every row sits on the grid's own column tracks through `subgrid`, so the
1162
+ * whole drag is one style write per frame. Letting the drag render instead -
1163
+ * `columnResizeMode: "onChange"`, which publishes a width on every pointer
1164
+ * move - costs a React pass over every mounted cell for each of those moves,
1165
+ * and the gesture turns choppy on a grid wide enough to be worth resizing.
1166
+ *
1167
+ * TanStack still owns the gesture and still commits the width into
1168
+ * `columnSizing` when the pointer is released; the render that follows lands
1169
+ * on the same numbers the last frame painted.
1170
+ */
1171
+ const previewRef = useRef<{
1172
+ tracks: Array<TMDataGridColumnTrack>;
1173
+ leftLane: Array<string>;
1174
+ rightLane: Array<string>;
1175
+ }>({ tracks: columnTracks, leftLane: [], rightLane: [] });
1176
+ useEffect(() => {
1177
+ previewRef.current = {
1178
+ tracks: columnTracks,
1179
+ leftLane: leftLeafColumns.map((column) => column.id),
1180
+ // Outermost last, the order the offsets above accumulate in.
1181
+ rightLane: [...rightLeafColumns].reverse().map((column) => column.id),
1182
+ };
1183
+ });
1184
+ useEffect(() => {
1185
+ const element = gridElementRef.current;
1186
+ if (!element) return;
1187
+
1188
+ // Painted straight from the store's publish rather than on a frame of its
1189
+ // own: the browser already coalesces pointer moves to one per frame, and a
1190
+ // `requestAnimationFrame` stops firing altogether while the window is
1191
+ // occluded - which would leave the drag frozen under the pointer.
1192
+ let painted = "";
1193
+ const subscription = table.store.subscribe((state) => {
1194
+ const preview = resizePreview({
1195
+ progress: state.columnResizing,
1196
+ boundsOf: (columnId) => table.getColumn(columnId)?.columnDef ?? {},
1197
+ ...previewRef.current,
1198
+ });
1199
+ if (!preview || preview.gridTemplateColumns === painted) return;
1200
+ painted = preview.gridTemplateColumns;
1201
+ element.style.gridTemplateColumns = preview.gridTemplateColumns;
1202
+ element.style.minWidth = `${preview.minWidth}px`;
1203
+ // Only the pinned lanes, and only while the drag is resizing one of
1204
+ // them: their sticky offsets are the one measurement that does not
1205
+ // follow from the track list alone.
1206
+ for (const { columnId, side, offset } of preview.offsets) {
1207
+ for (const cell of element.querySelectorAll<HTMLElement>(
1208
+ `[data-column-id="${CSS.escape(columnId)}"]`,
1209
+ )) {
1210
+ cell.style[side] = `${offset}px`;
1211
+ }
1212
+ }
1213
+ });
1214
+ return () => subscription.unsubscribe();
1215
+ }, [table]);
1216
+
1145
1217
  // Pinned rows count as content: with every visible row pinned to an edge,
1146
1218
  // an empty-state message beside them would contradict what is on screen.
1147
1219
  const isEmpty = rows.length === 0 && pinnedRowCount === 0;
@@ -5,6 +5,7 @@ import classes from "./TMDataGridToolbar.module.css";
5
5
  import { TMDataGridColumnsPanel } from "./TMDataGridColumnsPanel";
6
6
  import { useTMDataGridContext } from "../TMDataGridContext";
7
7
  import { getGridCapabilities } from "../core/capabilities";
8
+ import { useSettledTableState } from "../core/useSettledTableState";
8
9
  import { isFilterActive } from "../core/filterOperators";
9
10
  import { BurgerIcon, FilterIcon } from "./icons";
10
11
  import { openColumnFilter } from "../useTMDataGrid";
@@ -52,7 +53,7 @@ export function TMDataGridLoadingIndicator() {
52
53
  */
53
54
  export function TMDataGridSummaryCount({ children }: { children?: ReactNode }) {
54
55
  const { table, controlSize } = useTMDataGridContext();
55
- useSelector(table.store);
56
+ useSettledTableState(table.store);
56
57
 
57
58
  const shown = table.getRowCount();
58
59
  const total =