fix: isolate limit-pool fixed layout to 1440+ breakpoints

Keep the 1600 no-overflow table, but restore natural column widths
and horizontal scrolling at 1280 and 390 so cells are readable.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
MS-01-Codex
2026-08-20 04:04:59 +08:00
co-authored by Cursor multica-agent
parent f67100929b
commit 6ab910eeea
2 changed files with 77 additions and 36 deletions
+35 -27
View File
@@ -2220,27 +2220,11 @@
} }
#limitPool #limitTable { #limitPool #limitTable {
min-width: 0; min-width: var(--table-wide);
width: 100%; width: 100%;
table-layout: fixed; table-layout: auto;
}
#limitPool #limitTable thead th {
width: auto;
min-width: 0;
}
#limitPool #limitTable thead th.row-number {
width: 36px;
}
#limitPool.redesigned-pool-view .pool-table-card.tbl-wrap {
overflow-x: hidden;
overflow-y: auto;
} }
#limitPool #limitTable.tbl thead th, #limitPool #limitTable.tbl thead th,
@@ -2259,20 +2243,44 @@
padding: 0 8px; padding: 0 8px;
} }
#limitPool #limitTable .reason-column { @media (min-width: 1440px) {
min-width: 0; #limitPool #limitTable {
min-width: 0;
overflow: hidden; table-layout: fixed;
}
white-space: nowrap; #limitPool #limitTable thead th {
} width: auto;
#limitPool #limitTable .pool-reason-cell { min-width: 0;
overflow: hidden; }
text-overflow: ellipsis; #limitPool #limitTable thead th.row-number {
width: 36px;
}
white-space: nowrap; #limitPool.redesigned-pool-view .pool-table-card.tbl-wrap {
overflow-x: hidden;
overflow-y: auto;
}
#limitPool #limitTable .reason-column {
min-width: 0;
overflow: hidden;
white-space: nowrap;
}
#limitPool #limitTable .pool-reason-cell {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
} }
#brokenTable, #brokenTable,
+42 -9
View File
@@ -3222,28 +3222,52 @@ test("merged header keeps date, detail fields and 13 pool columns after dual-rev
expect(await page.locator("#dataDateMetric").evaluate((node) => Boolean(node.closest(".metric-wide")))).toBe(false); expect(await page.locator("#dataDateMetric").evaluate((node) => Boolean(node.closest(".metric-wide")))).toBe(false);
await page.keyboard.press("Escape"); await page.keyboard.press("Escape");
await page.setViewportSize({ width: 1600, height: 1000 }); const measurePoolTable = () => {
await page.locator('[data-view="limitPool"]').first().click(); const wrap = document.querySelector("#limitPool .pool-table-card");
const tableFit = await page.evaluate(() => { const table = document.querySelector("#limitTable");
const card = document.querySelector("#limitPool .pool-table-card");
const reason = document.querySelector("#limitTable .reason-column"); const reason = document.querySelector("#limitTable .reason-column");
const reasonCell = document.querySelector("#limitTable .pool-reason-cell"); const reasonCell = document.querySelector("#limitTable .pool-reason-cell");
const headerCell = document.querySelector("#limitPool .data-table thead th"); const headerCell = document.querySelector("#limitPool .data-table thead th");
const rowCell = document.querySelector("#limitPool .data-table tbody td"); const rowCell = document.querySelector("#limitPool .data-table tbody td");
const cells = [...document.querySelectorAll("#limitTable tbody td")];
const numberCells = [...document.querySelectorAll("#limitTable tbody td.num, #limitTable tbody td.number")];
const header = document.querySelector(".app-header"); const header = document.querySelector(".app-header");
const headerStyle = headerCell ? getComputedStyle(headerCell) : null; const headerStyle = headerCell ? getComputedStyle(headerCell) : null;
const rowStyle = rowCell ? getComputedStyle(rowCell) : null; const rowStyle = rowCell ? getComputedStyle(rowCell) : null;
const widths = cells.map((cell) => cell.getBoundingClientRect().width);
const numberWidths = numberCells.map((cell) => cell.getBoundingClientRect().width);
return { return {
cardOverflow: card.scrollWidth - card.clientWidth, tableLayout: table ? getComputedStyle(table).tableLayout : "",
reasonVisible: reason.getBoundingClientRect().right <= card.getBoundingClientRect().right + 1, columnCount: document.querySelectorAll("#limitTable thead th").length,
reasonText: reason.textContent.trim(), minCellWidth: widths.length ? Math.min(...widths) : 0,
minNumberWidth: numberWidths.length ? Math.min(...numberWidths) : 0,
wrapOverflow: wrap ? wrap.scrollWidth - wrap.clientWidth : 0,
tableWidth: table ? table.getBoundingClientRect().width : 0,
wrapWidth: wrap ? wrap.getBoundingClientRect().width : 0,
cardOverflow: wrap ? wrap.scrollWidth - wrap.clientWidth : 0,
reasonVisible: Boolean(reason && wrap && reason.getBoundingClientRect().right <= wrap.getBoundingClientRect().right + 1),
reasonText: reason ? reason.textContent.trim() : "",
reasonTitle: reasonCell?.getAttribute("title") || "", reasonTitle: reasonCell?.getAttribute("title") || "",
headerOverflow: header.scrollWidth - header.clientWidth, headerOverflow: header ? header.scrollWidth - header.clientWidth : 0,
headerHeight: headerStyle ? Number.parseFloat(headerStyle.height) : 0, headerHeight: headerStyle ? Number.parseFloat(headerStyle.height) : 0,
headerFont: headerStyle ? Number.parseFloat(headerStyle.fontSize) : 0, headerFont: headerStyle ? Number.parseFloat(headerStyle.fontSize) : 0,
rowHeight: rowStyle ? Number.parseFloat(rowStyle.height) : 0, rowHeight: rowStyle ? Number.parseFloat(rowStyle.height) : 0,
}; };
}); };
const pool1280 = await page.evaluate(measurePoolTable);
expect(pool1280.columnCount).toBe(13);
expect(pool1280.tableLayout).toBe("auto");
expect(pool1280.minCellWidth).toBeGreaterThanOrEqual(40);
expect(pool1280.minNumberWidth).toBeGreaterThanOrEqual(50);
expect(pool1280.wrapOverflow).toBeGreaterThan(0);
expect(pool1280.reasonTitle).toContain("板块龙头连板打开空间");
expect(pool1280.headerHeight).toBe(36);
expect(pool1280.rowHeight).toBeGreaterThanOrEqual(40);
await page.setViewportSize({ width: 1600, height: 1000 });
await page.locator('[data-view="limitPool"]').first().click();
const tableFit = await page.evaluate(measurePoolTable);
expect(tableFit.reasonText).toContain("涨停原因"); expect(tableFit.reasonText).toContain("涨停原因");
expect(tableFit.reasonVisible).toBe(true); expect(tableFit.reasonVisible).toBe(true);
expect(tableFit.cardOverflow).toBeLessThanOrEqual(1); expect(tableFit.cardOverflow).toBeLessThanOrEqual(1);
@@ -3252,6 +3276,8 @@ test("merged header keeps date, detail fields and 13 pool columns after dual-rev
expect(tableFit.headerHeight).toBe(36); expect(tableFit.headerHeight).toBe(36);
expect(tableFit.headerFont).toBe(12.5); expect(tableFit.headerFont).toBe(12.5);
expect(tableFit.rowHeight).toBeGreaterThanOrEqual(40); expect(tableFit.rowHeight).toBeGreaterThanOrEqual(40);
expect(tableFit.tableLayout).toBe("fixed");
expect(tableFit.columnCount).toBe(13);
await page.locator('[data-view="heavenView"]').first().click(); await page.locator('[data-view="heavenView"]').first().click();
await expect(page.locator(".app-header .overview-strip")).toBeHidden(); await expect(page.locator(".app-header .overview-strip")).toBeHidden();
@@ -3259,6 +3285,13 @@ test("merged header keeps date, detail fields and 13 pool columns after dual-rev
await page.setViewportSize({ width: 390, height: 844 }); await page.setViewportSize({ width: 390, height: 844 });
await page.locator('[data-view="limitPool"]').first().click({ force: true }); await page.locator('[data-view="limitPool"]').first().click({ force: true });
const pool390 = await page.evaluate(measurePoolTable);
expect(pool390.columnCount).toBe(13);
expect(pool390.tableLayout).toBe("auto");
expect(pool390.minCellWidth).toBeGreaterThanOrEqual(40);
expect(pool390.minNumberWidth).toBeGreaterThanOrEqual(50);
expect(pool390.wrapOverflow).toBeGreaterThan(0);
expect(pool390.reasonTitle).toContain("板块龙头连板打开空间");
await page.locator("#mobileMarketViewSelect").selectOption("sentimentCycleView"); await page.locator("#mobileMarketViewSelect").selectOption("sentimentCycleView");
await page.locator("#overviewToggle").click(); await page.locator("#overviewToggle").click();
const mobileDetail = await page.locator(".tape-detail").innerText(); const mobileDetail = await page.locator(".tape-detail").innerText();