fix(grid): keep column names fully visible

This commit is contained in:
t8y2 committed 2026-07-17 08:39:16 +08:00
1 parent 6193f8b860
commit 51f87976b4
5 files changed
+84 -15

No files matched your search

@@ -3,20 +3,28 @@ import { describe, expect, it } from "vitest";
import { DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, DATA_GRID_COL_MIN_WIDTH } from "@/lib/dataGrid/dataGridColumnWidth";
import { DATA_GRID_ROW_NUM_WIDTH, resizeDataGridColumnWidth, useDataGridColumnResize } from "@/composables/useDataGridColumnResize";
function createResizeState(options: { columns: string[]; rows: Array<Array<string | number | boolean | null>>; columnIndexes?: number[]; density?: "compact" | "standard" | "comfortable"; compactColumnHeaderActions?: boolean }) {
function createResizeState(options: { columns: string[]; rows: Array<Array<string | number | boolean | null>>; columnIndexes?: number[]; density?: "compact" | "standard" | "comfortable"; compactColumnHeaderActions?: boolean; headerTextWidth?: number }) {
const compact = ref(options.compactColumnHeaderActions ?? true);
const headerTextWidth = ref(options.headerTextWidth);
const headerMeasurementKey = ref(0);
const state = useDataGridColumnResize({
columns: computed(() => options.columns),
sourceRows: computed(() => options.rows),
columnIndexes: computed(() => options.columnIndexes ?? options.columns.map((_, index) => index)),
density: ref(options.density ?? "standard"),
compactColumnHeaderActions: computed(() => compact.value),
measureHeaderText: () => headerTextWidth.value,
headerMeasurementKey,
});
return {
...state,
setCompact(v: boolean) {
compact.value = v;
},
setHeaderTextWidth(width: number) {
headerTextWidth.value = width;
headerMeasurementKey.value += 1;
},
};
}
@@ -109,7 +117,25 @@ describe("useDataGridColumnResize", () => {
expect(widthNonCompact).toBeGreaterThan(widthCompact);
});
it("compact mode bases width on field name only, capping long names", () => {
it("recalculates column widths when rendered header font metrics change", async () => {
const state = createResizeState({
columns: ["AMOUNT"],
rows: [[1]],
density: "comfortable",
compactColumnHeaderActions: true,
headerTextWidth: 54,
});
state.initColumnWidths();
expect(state.columnWidths.value[0]).toBe(113);
state.setHeaderTextWidth(70);
await nextTick();
expect(state.columnWidths.value[0]).toBe(129);
});
it("compact mode bases width on field name without truncating long names", () => {
// 短字段名:列宽=字段名宽度,值不参与撑宽
const short = createResizeState({
columns: ["id"],
@@ -132,16 +158,16 @@ describe("useDataGridColumnResize", () => {
// 9×7+45=108
expect(mid.columnWidths.value[0]).toBe(108);
// 过长字段名:截断到边界
const capped = createResizeState({
// 过长字段名:字段名仍完整展示,不受内容宽度上限影响
const longName = createResizeState({
columns: ["x".repeat(70)],
rows: [["a"]],
density: "compact",
compactColumnHeaderActions: true,
});
capped.initColumnWidths();
// 70×7+45=535 > maxWidth 480 → 480
expect(capped.columnWidths.value[0]).toBe(480);
longName.initColumnWidths();
// 70×7+45=535,紧凑模式只限制内容,不限制字段名
expect(longName.columnWidths.value[0]).toBe(535);
});
it("comfortable mode uses percentile to ignore outlier values", () => {
@@ -16,10 +16,12 @@ export interface UseDataGridColumnResizeOptions {
columnIndexes: ComputedRef<number[]>;
density: Ref<ColumnWidthDensity>;
compactColumnHeaderActions: ComputedRef<boolean>;
measureHeaderText?: (text: string) => number | undefined;
headerMeasurementKey?: Ref<unknown>;
}
export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions) {
const { columns, sourceRows, columnIndexes, density, compactColumnHeaderActions } = options;
const { columns, sourceRows, columnIndexes, density, compactColumnHeaderActions, measureHeaderText } = options;
const columnWidths = ref<number[]>([]);
let isResizing = false;
@@ -55,6 +57,7 @@ export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions)
sampleValues: sampleColumnValues(colIdx),
density: density.value,
compactColumnHeaderActions: compactColumnHeaderActions.value,
headerTextWidth: measureHeaderText?.(colName),
});
});
}
@@ -114,6 +117,7 @@ export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions)
density: density.value,
compactColumnHeaderActions: compactColumnHeaderActions.value,
includeValues: true,
headerTextWidth: measureHeaderText?.(colName),
});
}
@@ -139,7 +143,7 @@ export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions)
() => columnIndexes.value.join("\0"),
() => initColumnWidths(),
);
watch([density, compactColumnHeaderActions], () => initColumnWidths(true));
watch([density, compactColumnHeaderActions, () => options.headerMeasurementKey?.value], () => initColumnWidths(true));
return {
columnWidths,