Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions packages/layout-engine/layout-engine/src/layout-table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ describe('layoutTableBlock', () => {
const boundaries = fragments[0].metadata?.columnBoundaries;
expect(boundaries).toBeDefined();

// All columns should have minWidth >= 25 (absolute minimum)
// Keep a fixed floor so resize constraints always allow shrinking.
boundaries?.forEach((boundary) => {
expect(boundary.minWidth).toBeGreaterThanOrEqual(25);
expect(boundary.minWidth).toBe(10);
});
});

Expand Down Expand Up @@ -602,8 +602,7 @@ describe('layoutTableBlock', () => {

const boundaries = fragments[0].metadata?.columnBoundaries;
expect(boundaries).toHaveLength(1);
expect(boundaries![0].minWidth).toBeGreaterThanOrEqual(25);
expect(boundaries![0].minWidth).toBeLessThanOrEqual(200);
expect(boundaries![0].minWidth).toBe(10);
});

it('should handle very wide column (> 200px)', () => {
Expand All @@ -628,8 +627,7 @@ describe('layoutTableBlock', () => {
});

const boundaries = fragments[0].metadata?.columnBoundaries;
// Min width should be capped at 200px
expect(boundaries![0].minWidth).toBe(200);
expect(boundaries![0].minWidth).toBe(10);
});

it('should handle very narrow column (< 25px)', () => {
Expand All @@ -654,8 +652,7 @@ describe('layoutTableBlock', () => {
});

const boundaries = fragments[0].metadata?.columnBoundaries;
// Min width should be at least 25px
expect(boundaries![0].minWidth).toBe(25);
expect(boundaries![0].minWidth).toBe(10);
});

it('should handle empty columnWidths array', () => {
Expand Down Expand Up @@ -707,8 +704,7 @@ describe('layoutTableBlock', () => {
});

const boundaries = fragments[0].metadata?.columnBoundaries;
// Should default to minimum 25px for negative widths
expect(boundaries![0].minWidth).toBe(25);
expect(boundaries![0].minWidth).toBe(10);
});

it('should handle zero measured width', () => {
Expand All @@ -733,8 +729,7 @@ describe('layoutTableBlock', () => {
});

const boundaries = fragments[0].metadata?.columnBoundaries;
// Should default to minimum 25px for zero width
expect(boundaries![0].minWidth).toBe(25);
expect(boundaries![0].minWidth).toBe(10);
});

it('should handle multiple columns with varying widths', () => {
Expand All @@ -760,12 +755,9 @@ describe('layoutTableBlock', () => {
});

const boundaries = fragments[0].metadata?.columnBoundaries;
// Column 0: 10px -> should be 25px (minimum)
expect(boundaries![0].minWidth).toBe(25);
// Column 1: 100px -> should be 100px (within range)
expect(boundaries![1].minWidth).toBe(100);
// Column 2: 500px -> should be 200px (capped)
expect(boundaries![2].minWidth).toBe(200);
boundaries?.forEach((boundary) => {
expect(boundary.minWidth).toBe(10);
});
});
});

Expand Down
22 changes: 8 additions & 14 deletions packages/layout-engine/layout-engine/src/layout-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,15 @@ function resolveTableFrame(
/**
* Calculate minimum width for a table column.
*
* The resize overlay uses this value to enforce drag constraints.
* We derive it from the measured column width and clamp to a practical range.
* Uses a conservative minimum of 10px per column to match PM's
* columnResizing behavior.
*
* @param measuredWidth - Current measured column width in pixels
* @returns Minimum width in pixels, clamped to [25, 200]
* @returns Minimum width in pixels (10px)
*/
function calculateColumnMinWidth(measuredWidth: number): number {
const MIN_WIDTH = 25;
const MAX_WIDTH = 200;
function calculateColumnMinWidth(): number {
const DEFAULT_MIN_WIDTH = 10; // Minimum usable column width in pixels

if (!Number.isFinite(measuredWidth) || measuredWidth <= 0) {
return MIN_WIDTH;
}

return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, measuredWidth));
return DEFAULT_MIN_WIDTH;
}

/**
Expand All @@ -210,7 +204,7 @@ function calculateColumnMinWidth(measuredWidth: number): number {
* Edge cases handled:
* - Empty columnWidths array: Returns empty array (no boundaries)
* - Single column: Returns one boundary with proper min/max constraints
* - Very wide/narrow columns: Handled by calculateColumnMinWidth
* - Very wide/narrow columns: Supported with a fixed resize floor
*
* @param measure - Table measurement containing column widths
* @returns Array of column boundary metadata, one per column
Expand All @@ -221,7 +215,7 @@ function generateColumnBoundaries(measure: TableMeasure): TableColumnBoundary[]

for (let i = 0; i < measure.columnWidths.length; i++) {
const width = measure.columnWidths[i];
const minWidth = calculateColumnMinWidth(width);
const minWidth = calculateColumnMinWidth();

const boundary = {
index: i,
Expand Down
Loading