feat(data-grid): improve transpose view record location and last-column alignment
This commit is contained in:
4 files changed
+198
-23
No files matched your search
@@ -7,6 +7,7 @@ import {
|
||||
minTransposeFieldWidth,
|
||||
shouldAutoTransposeSingleRow,
|
||||
transposeAnchorRowIndex,
|
||||
transposeEndAlignmentSpacerWidth,
|
||||
transposeFieldWidth,
|
||||
transposeScrollLeftForRecord,
|
||||
transposeRecordWidthsForDensity,
|
||||
@@ -107,6 +108,39 @@ describe("dataGridTranspose density widths", () => {
|
||||
});
|
||||
|
||||
describe("transpose record scrolling", () => {
|
||||
it("aligns the fifth record at the start while nearest keeps an already-visible record in place", () => {
|
||||
const endSpacerWidth = transposeEndAlignmentSpacerWidth({
|
||||
viewportWidth: 1200,
|
||||
pinnedWidth: 104,
|
||||
lastRecordWidth: 168,
|
||||
});
|
||||
|
||||
expect(endSpacerWidth).toBe(928);
|
||||
expect(
|
||||
transposeScrollLeftForRecord({
|
||||
recordIndex: 4,
|
||||
totalRecords: 5,
|
||||
viewportWidth: 1200,
|
||||
pinnedWidth: 104,
|
||||
recordWidth: 168,
|
||||
currentScrollLeft: 0,
|
||||
alignment: "start",
|
||||
endSpacerWidth,
|
||||
}),
|
||||
).toBe(672);
|
||||
expect(
|
||||
transposeScrollLeftForRecord({
|
||||
recordIndex: 4,
|
||||
totalRecords: 5,
|
||||
viewportWidth: 1200,
|
||||
pinnedWidth: 104,
|
||||
recordWidth: 168,
|
||||
currentScrollLeft: 0,
|
||||
endSpacerWidth,
|
||||
}),
|
||||
).toBe(0);
|
||||
});
|
||||
|
||||
it("uses the scroll position after the sticky field for virtualization", () => {
|
||||
expect(
|
||||
visibleTransposeRecordWindow({
|
||||
@@ -147,6 +181,42 @@ describe("transpose record scrolling", () => {
|
||||
}),
|
||||
).toBe(450);
|
||||
});
|
||||
|
||||
it("uses the end spacer to align a variable-width final record exactly at the start", () => {
|
||||
const recordOffsets = [0, 500, 596, 692];
|
||||
const endSpacerWidth = transposeEndAlignmentSpacerWidth({
|
||||
viewportWidth: 300,
|
||||
pinnedWidth: 100,
|
||||
lastRecordWidth: 96,
|
||||
});
|
||||
|
||||
expect(endSpacerWidth).toBe(104);
|
||||
expect(
|
||||
transposeScrollLeftForRecord({
|
||||
recordIndex: 2,
|
||||
totalRecords: 3,
|
||||
viewportWidth: 300,
|
||||
pinnedWidth: 100,
|
||||
recordWidth: 230,
|
||||
recordOffsets,
|
||||
currentScrollLeft: 0,
|
||||
alignment: "start",
|
||||
endSpacerWidth,
|
||||
}),
|
||||
).toBe(596);
|
||||
expect(
|
||||
transposeScrollLeftForRecord({
|
||||
recordIndex: 2,
|
||||
totalRecords: 3,
|
||||
viewportWidth: 300,
|
||||
pinnedWidth: 100,
|
||||
recordWidth: 230,
|
||||
recordOffsets,
|
||||
currentScrollLeft: 596,
|
||||
endSpacerWidth,
|
||||
}),
|
||||
).toBe(596);
|
||||
});
|
||||
});
|
||||
|
||||
describe("dataGridTranspose field metadata", () => {
|
||||
|
||||
@@ -166,6 +166,16 @@ export interface TransposeScrollLeftOptions {
|
||||
recordWidth: number;
|
||||
recordOffsets?: readonly number[];
|
||||
currentScrollLeft?: number;
|
||||
alignment?: TransposeScrollAlignment;
|
||||
endSpacerWidth?: number;
|
||||
}
|
||||
|
||||
export type TransposeScrollAlignment = "start" | "nearest";
|
||||
|
||||
export interface TransposeEndAlignmentSpacerOptions {
|
||||
viewportWidth: number;
|
||||
pinnedWidth: number;
|
||||
lastRecordWidth: number;
|
||||
}
|
||||
|
||||
export interface TransposeRecordIndexesForModeOptions {
|
||||
@@ -339,6 +349,11 @@ export function transposeFieldWidth(columns: string[], options: TransposeFieldWi
|
||||
return Math.min(maxWidth, Math.max(minWidth, Math.ceil(longest * charWidth + padding)));
|
||||
}
|
||||
|
||||
export function transposeEndAlignmentSpacerWidth(options: TransposeEndAlignmentSpacerOptions): number {
|
||||
const recordViewportWidth = Math.max(0, options.viewportWidth - options.pinnedWidth);
|
||||
return Math.max(0, recordViewportWidth - Math.max(0, options.lastRecordWidth));
|
||||
}
|
||||
|
||||
export function transposeScrollLeftForRecord(options: TransposeScrollLeftOptions): number {
|
||||
if (options.recordWidth <= 0 || options.totalRecords <= 0) return 0;
|
||||
const recordIndex = Math.max(0, Math.min(options.totalRecords - 1, options.recordIndex));
|
||||
@@ -348,8 +363,8 @@ export function transposeScrollLeftForRecord(options: TransposeScrollLeftOptions
|
||||
const recordsWidth = offsets ? offsets[options.totalRecords] : options.totalRecords * options.recordWidth;
|
||||
const recordViewportWidth = Math.max(0, options.viewportWidth - options.pinnedWidth);
|
||||
const currentScrollLeft = Math.max(0, options.currentScrollLeft ?? recordStart);
|
||||
const desired = recordStart < currentScrollLeft ? recordStart : recordEnd > currentScrollLeft + recordViewportWidth ? recordEnd - recordViewportWidth : currentScrollLeft;
|
||||
const totalWidth = options.pinnedWidth + recordsWidth;
|
||||
const desired = options.alignment === "start" ? recordStart : recordStart < currentScrollLeft ? recordStart : recordEnd > currentScrollLeft + recordViewportWidth ? recordEnd - recordViewportWidth : currentScrollLeft;
|
||||
const totalWidth = options.pinnedWidth + recordsWidth + Math.max(0, options.endSpacerWidth ?? 0);
|
||||
const maxScrollLeft = Math.max(0, totalWidth - options.viewportWidth);
|
||||
return Math.max(0, Math.min(desired, maxScrollLeft));
|
||||
}
|
||||
Reference in new issue
Block a user