From ca30e8ff2db3ce67cf24100523e541d105936dc3 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Mon, 29 Jun 2026 01:44:35 +0800 Subject: [PATCH] fix(grid): expand auto-fit column width --- .../composables/useDataGridColumnResize.ts | 4 ++- apps/desktop/src/lib/dataGridColumnWidth.ts | 15 ++++++--- .../app-tests/dataGridColumnWidth.test.ts | 33 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 packages/app-tests/dataGridColumnWidth.test.ts diff --git a/apps/desktop/src/composables/useDataGridColumnResize.ts b/apps/desktop/src/composables/useDataGridColumnResize.ts index a10b52380..c6c151732 100644 --- a/apps/desktop/src/composables/useDataGridColumnResize.ts +++ b/apps/desktop/src/composables/useDataGridColumnResize.ts @@ -1,6 +1,6 @@ import { ref, computed, watch, type ComputedRef, type Ref } from "vue"; import { useElementSize } from "@vueuse/core"; -import { calculateDataGridColumnWidth, DATA_GRID_COL_MIN_WIDTH, DATA_GRID_SAMPLE_ROWS } from "@/lib/dataGridColumnWidth"; +import { calculateDataGridColumnWidth, DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT, DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, DATA_GRID_COL_MIN_WIDTH, DATA_GRID_SAMPLE_ROWS } from "@/lib/dataGridColumnWidth"; type CellValue = string | number | boolean | null; @@ -78,6 +78,8 @@ export function useDataGridColumnResize(options: UseDataGridColumnResizeOptions) columnWidths.value[colIdx] = calculateDataGridColumnWidth({ columnName: colName, sampleValues: sampleColumnValues(colIdx), + maxWidth: DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, + valueTextLimit: DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT, }); } diff --git a/apps/desktop/src/lib/dataGridColumnWidth.ts b/apps/desktop/src/lib/dataGridColumnWidth.ts index 2f9745c09..1a179d24a 100644 --- a/apps/desktop/src/lib/dataGridColumnWidth.ts +++ b/apps/desktop/src/lib/dataGridColumnWidth.ts @@ -2,10 +2,13 @@ type CellValue = string | number | boolean | null; export const DATA_GRID_COL_MIN_WIDTH = 60; export const DATA_GRID_COL_MAX_WIDTH = 400; +export const DATA_GRID_COL_AUTO_FIT_MAX_WIDTH = 1200; export const DATA_GRID_CHAR_WIDTH = 8; export const DATA_GRID_HEADER_CONTROL_WIDTH = 80; export const DATA_GRID_CELL_PADDING = 28; export const DATA_GRID_SAMPLE_ROWS = 50; +export const DATA_GRID_VALUE_TEXT_LIMIT = 60; +export const DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT = 160; function estimateTextWidth(text: string, padding: number): number { return text.length * DATA_GRID_CHAR_WIDTH + padding; @@ -16,16 +19,18 @@ function displaySampleValue(value: CellValue): string | null { return typeof value === "object" ? JSON.stringify(value) : String(value); } -export function calculateDataGridColumnWidth(options: { columnName: string; sampleValues: readonly CellValue[] }): number { - let maxWidth = estimateTextWidth(options.columnName, DATA_GRID_HEADER_CONTROL_WIDTH); +export function calculateDataGridColumnWidth(options: { columnName: string; sampleValues: readonly CellValue[]; maxWidth?: number; valueTextLimit?: number }): number { + const maxAllowedWidth = options.maxWidth ?? DATA_GRID_COL_MAX_WIDTH; + const valueTextLimit = options.valueTextLimit ?? DATA_GRID_VALUE_TEXT_LIMIT; + let maxContentWidth = estimateTextWidth(options.columnName, DATA_GRID_HEADER_CONTROL_WIDTH); for (const value of options.sampleValues.slice(0, DATA_GRID_SAMPLE_ROWS)) { const text = displaySampleValue(value); if (text == null) continue; - const displayLen = Math.min(text.length, 60); + const displayLen = Math.min(text.length, valueTextLimit); const width = displayLen * DATA_GRID_CHAR_WIDTH + DATA_GRID_CELL_PADDING; - if (width > maxWidth) maxWidth = width; + if (width > maxContentWidth) maxContentWidth = width; } - return Math.max(DATA_GRID_COL_MIN_WIDTH, Math.min(DATA_GRID_COL_MAX_WIDTH, Math.round(maxWidth))); + return Math.max(DATA_GRID_COL_MIN_WIDTH, Math.min(maxAllowedWidth, Math.round(maxContentWidth))); } diff --git a/packages/app-tests/dataGridColumnWidth.test.ts b/packages/app-tests/dataGridColumnWidth.test.ts new file mode 100644 index 000000000..01a90ac0d --- /dev/null +++ b/packages/app-tests/dataGridColumnWidth.test.ts @@ -0,0 +1,33 @@ +import { expect, test } from "vitest"; +import { calculateDataGridColumnWidth, DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT, DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, DATA_GRID_COL_MAX_WIDTH } from "../../apps/desktop/src/lib/dataGridColumnWidth.ts"; + +test("default data grid column width remains compact for long values", () => { + const width = calculateDataGridColumnWidth({ + columnName: "description", + sampleValues: ["x".repeat(120)], + }); + + expect(width).toBe(DATA_GRID_COL_MAX_WIDTH); +}); + +test("auto-fit data grid column width expands long values beyond default width", () => { + const width = calculateDataGridColumnWidth({ + columnName: "description", + sampleValues: ["x".repeat(120)], + maxWidth: DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, + valueTextLimit: DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT, + }); + + expect(width).toBeGreaterThan(DATA_GRID_COL_MAX_WIDTH); +}); + +test("auto-fit data grid column width stays bounded for very long values", () => { + const width = calculateDataGridColumnWidth({ + columnName: "description", + sampleValues: ["x".repeat(1000)], + maxWidth: DATA_GRID_COL_AUTO_FIT_MAX_WIDTH, + valueTextLimit: DATA_GRID_AUTO_FIT_VALUE_TEXT_LIMIT, + }); + + expect(width).toBe(DATA_GRID_COL_AUTO_FIT_MAX_WIDTH); +});