fix(grid): expand auto-fit column width
This commit is contained in:
parent
2d2284a0ef
commit
ca30e8ff2d
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
Loading…
Reference in New Issue