mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-11 01:03:51 +08:00
🐛 fix(datagrid): 修复最小列宽下筛选与排序控件隐藏
This commit is contained in:
@@ -90,6 +90,7 @@ describe('DataGridColumnTitle', () => {
|
||||
expect(markup).toContain('主键 ID');
|
||||
expect(markup).toContain('flex-direction:column');
|
||||
expect(markup).toContain('align-items:flex-start');
|
||||
expect(markup).toContain('display:inline-flex;width:100%;max-width:100%;min-width:0;overflow:hidden');
|
||||
});
|
||||
|
||||
it('keeps column metadata tooltip readable in light theme', () => {
|
||||
@@ -187,6 +188,8 @@ describe('DataGridColumnTitle', () => {
|
||||
expect(markup).toContain('data-grid-column-filter-active="true"');
|
||||
expect(markup).toContain('data-grid-column-filter-popover="true"');
|
||||
expect(markup).toContain('flex:1 1 auto');
|
||||
expect(markup).toContain('display:inline-flex;flex:1 1 auto;max-width:100%;min-width:0;overflow:hidden');
|
||||
expect(markup).toContain('width:100%');
|
||||
expect(markup).toContain('Filter status');
|
||||
expect(markup).toContain('value="active"');
|
||||
});
|
||||
|
||||
@@ -258,7 +258,9 @@ const DataGridColumnTitle: React.FC<DataGridColumnTitleProps> = ({
|
||||
styles={{ root: { maxWidth: 640 } }}
|
||||
{...(!darkMode ? { color: 'rgba(0, 0, 0, 0.82)' } : {})}
|
||||
>
|
||||
<span style={{ display: 'inline-flex', maxWidth: '100%' }}>{titleNode}</span>
|
||||
<span style={{ display: 'inline-flex', width: '100%', maxWidth: '100%', minWidth: 0, overflow: 'hidden' }}>
|
||||
{titleNode}
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
})();
|
||||
@@ -483,15 +485,16 @@ const DataGridColumnTitle: React.FC<DataGridColumnTitleProps> = ({
|
||||
<span
|
||||
className="gn-v2-column-title-shell"
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
display: 'flex',
|
||||
// 顶对齐:有无注释时标题块高度不同,center 会让筛选图标上下错位
|
||||
alignItems: 'flex-start',
|
||||
gap: 4,
|
||||
width: '100%',
|
||||
maxWidth: '100%',
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<span style={{ display: 'inline-flex', flex: '1 1 auto', minWidth: 0 }}>
|
||||
<span style={{ display: 'inline-flex', flex: '1 1 auto', maxWidth: '100%', minWidth: 0, overflow: 'hidden' }}>
|
||||
{titleWithOptionalTooltip}
|
||||
</span>
|
||||
<Popover
|
||||
|
||||
@@ -176,12 +176,12 @@ describe('useDataGridColumnResize interaction cleanup', () => {
|
||||
expect(fakeWindow.listenerCount('blur')).toBe(0);
|
||||
});
|
||||
|
||||
it('clamps manual data column resizing to the shared 80px minimum', () => {
|
||||
it('clamps manual data column resizing to the shared 120px minimum', () => {
|
||||
beginResize();
|
||||
|
||||
act(() => fakeDocument.dispatch('mouseup', { clientX: 0 }));
|
||||
|
||||
expectLastWidthUpdate(80);
|
||||
expectLastWidthUpdate(120);
|
||||
});
|
||||
|
||||
it('cancels pending RAF and gate work without committing when unmounted mid-resize', () => {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { resolveDataTableColumnWidth } from '../utils/dataGridDisplay';
|
||||
import {
|
||||
MIN_DATA_TABLE_COLUMN_WIDTH,
|
||||
resolveDataTableColumnWidth,
|
||||
} from '../utils/dataGridDisplay';
|
||||
import { calculateAutoFitColumnWidth } from './dataGridAutoWidth';
|
||||
import { DEFAULT_GRID_MONO_FONT_FAMILY, GONAVI_ROW_NUMBER_COLUMN_KEY } from './DataGridCore';
|
||||
|
||||
const ROW_NUMBER_DEFAULT_WIDTH = 36;
|
||||
const ROW_NUMBER_MIN_WIDTH = 28;
|
||||
const ROW_NUMBER_MAX_WIDTH = 120;
|
||||
const DATA_COLUMN_MIN_WIDTH = 80;
|
||||
|
||||
type UseDataGridColumnResizeContext = Record<string, any>;
|
||||
type ColumnResizeListeners = {
|
||||
@@ -110,7 +112,7 @@ export const useDataGridColumnResize = (ctx: UseDataGridColumnResizeContext) =>
|
||||
const finalClientX = Number.isFinite(clientX) ? clientX as number : latestClientX ?? dragState.startX;
|
||||
const deltaX = finalClientX - dragState.startX;
|
||||
const isRowNumberColumn = dragState.key === GONAVI_ROW_NUMBER_COLUMN_KEY;
|
||||
const minWidth = isRowNumberColumn ? ROW_NUMBER_MIN_WIDTH : DATA_COLUMN_MIN_WIDTH;
|
||||
const minWidth = isRowNumberColumn ? ROW_NUMBER_MIN_WIDTH : MIN_DATA_TABLE_COLUMN_WIDTH;
|
||||
const maxWidth = isRowNumberColumn ? ROW_NUMBER_MAX_WIDTH : Number.POSITIVE_INFINITY;
|
||||
const newWidth = Math.min(maxWidth, Math.max(minWidth, dragState.startWidth + deltaX));
|
||||
setColumnWidthsRef.current((prev: Record<string, number>) => ({ ...prev, [dragState.key]: newWidth }));
|
||||
@@ -216,7 +218,7 @@ export const useDataGridColumnResize = (ctx: UseDataGridColumnResizeContext) =>
|
||||
valueTexts: displayData.slice(0, 200).map((row: any) => row?.[key]),
|
||||
measureHeaderText: (text) => measureTextWidth(text, `600 ${font}`),
|
||||
measureCellText: (text) => measureTextWidth(text, `400 ${font}`),
|
||||
minWidth: 40,
|
||||
minWidth: MIN_DATA_TABLE_COLUMN_WIDTH,
|
||||
maxWidth: 600,
|
||||
defaultWidth: densityParams.defaultColumnWidth,
|
||||
});
|
||||
@@ -249,7 +251,7 @@ export const useDataGridColumnResize = (ctx: UseDataGridColumnResizeContext) =>
|
||||
measureHeaderText: buildAutoFitMeasurer(headerEl ?? null, `600 ${densityParams.dataFontSize}px ${DEFAULT_GRID_MONO_FONT_FAMILY}`),
|
||||
measureCellText: buildAutoFitMeasurer(sampleCell ?? null, `400 ${densityParams.dataFontSize}px ${DEFAULT_GRID_MONO_FONT_FAMILY}`),
|
||||
defaultWidth,
|
||||
minWidth: DATA_COLUMN_MIN_WIDTH,
|
||||
minWidth: MIN_DATA_TABLE_COLUMN_WIDTH,
|
||||
maxWidth: Math.max(720, Math.floor(containerWidth * 0.85)),
|
||||
});
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ describe('dataGridDisplay helpers', () => {
|
||||
|
||||
it('keeps manual column widths ahead of density defaults', () => {
|
||||
expect(resolveDataTableColumnWidth({ manualWidth: 320, density: 'compact' })).toBe(320);
|
||||
expect(resolveDataTableColumnWidth({ manualWidth: undefined, density: 'compact' })).toBe(100);
|
||||
expect(resolveDataTableColumnWidth({ manualWidth: 80, density: 'comfortable' })).toBe(120);
|
||||
expect(resolveDataTableColumnWidth({ manualWidth: undefined, density: 'compact' })).toBe(120);
|
||||
});
|
||||
|
||||
it('uses subtle themed vertical border colors and transparent when disabled', () => {
|
||||
|
||||
@@ -26,6 +26,9 @@ export const MIN_DATA_TABLE_FONT_SIZE = 10;
|
||||
export const MAX_DATA_TABLE_FONT_SIZE = 18;
|
||||
export const MIN_SIDEBAR_TREE_FONT_SIZE = 10;
|
||||
export const MAX_SIDEBAR_TREE_FONT_SIZE = 18;
|
||||
// Keep enough room for the column title, filter trigger, sorter and resize handle.
|
||||
// Default, manual and auto-fit widths must all preserve this invariant.
|
||||
export const MIN_DATA_TABLE_COLUMN_WIDTH = 120;
|
||||
|
||||
type DensityOptionTranslator = (key: string) => string;
|
||||
|
||||
@@ -148,10 +151,10 @@ export const resolveDataTableColumnWidth = ({
|
||||
density: DataTableDensity | null | undefined;
|
||||
}): number => {
|
||||
if (typeof manualWidth === 'number' && Number.isFinite(manualWidth) && manualWidth > 0) {
|
||||
return manualWidth;
|
||||
return Math.max(MIN_DATA_TABLE_COLUMN_WIDTH, manualWidth);
|
||||
}
|
||||
|
||||
return resolveDataTableDefaultColumnWidth(density);
|
||||
return Math.max(MIN_DATA_TABLE_COLUMN_WIDTH, resolveDataTableDefaultColumnWidth(density));
|
||||
};
|
||||
|
||||
export const resolveDataTableVerticalBorderColor = ({
|
||||
|
||||
@@ -4331,15 +4331,25 @@ body[data-ui-version="v2"] .gn-v2-data-grid .gn-v2-table-designer.is-embedded .a
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .ant-table-thead .ant-table-column-title {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
font-size: var(--gn-data-table-font-size, var(--gn-font-size-mono, 12px));
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .ant-table-thead .ant-table-column-sorters {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
min-height: 0 !important;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .ant-table-thead .ant-table-column-sorter {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .ant-table-thead > tr > th.is-single-line-title {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
@@ -4350,9 +4360,11 @@ body[data-ui-version="v2"] .gn-v2-data-grid .ant-table-thead > tr > th.is-single
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .sortable-header-cell-drag-handle {
|
||||
box-sizing: border-box;
|
||||
min-height: 48px !important;
|
||||
align-items: flex-start !important;
|
||||
padding: 3px 8px !important;
|
||||
padding-right: 12px !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-data-grid .sortable-header-cell-drag-handle > div {
|
||||
|
||||
Reference in New Issue
Block a user