FN-6764: make research and insights tablet layouts full width
Research and Insights now reflow at tablet widths to avoid cut-off content while preserving mobile and desktop behavior. - Add tablet-specific full-width Research layout rules with shrink-safe reader/history containers. - Add tablet-specific Insights layout rules that stack the category rail above the detail pane. - Cover Research and Insights responsive CSS contracts across desktop, mobile, and tablet tiers. Files changed: packages/dashboard/app/components/InsightsView.css | 67 ++++++++++++++++++++++ packages/dashboard/app/components/ResearchView.css | 47 +++++++++++++++ .../app/components/__tests__/InsightsView.test.tsx | 20 +++++++ .../app/components/__tests__/ResearchView.test.tsx | 13 +++++ 4 files changed, 147 insertions(+) Fusion-Task-Id: FN-6764 Fusion-Task-Lineage: ed528038-e69b-4794-9885-fb3b5f47b3ed
This commit is contained in:
@@ -613,3 +613,70 @@
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:InsightsView 2026-06-20-00:34:
|
||||
Insights tablets at 769px–1024px were inheriting the desktop fixed category sidebar, which squeezed the detail pane inside the .project-content flex chain. Stack the category rail above the detail pane and keep both panes shrinkable so long insight content cannot force horizontal cut-off.
|
||||
*/
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
.insights-view {
|
||||
flex: 1;
|
||||
inline-size: 100%;
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.insights-view-header {
|
||||
min-inline-size: 0;
|
||||
}
|
||||
|
||||
.insights-view-title {
|
||||
flex: 1 1 auto;
|
||||
min-inline-size: 0;
|
||||
}
|
||||
|
||||
.insights-view-actions {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.insights-body {
|
||||
flex-direction: column;
|
||||
inline-size: 100%;
|
||||
min-width: 0;
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.insights-sidebar {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
min-inline-size: 0;
|
||||
border-right: none;
|
||||
border-bottom: var(--btn-border-width) solid var(--border);
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.insights-category-list {
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.insights-category-list > li {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.insights-category-item {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.insights-detail {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,3 +293,50 @@
|
||||
min-height: calc(var(--space-lg) * 2 + var(--space-sm));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:ResearchView 2026-06-20-00:33:
|
||||
Research tablets at 769px–1024px were inheriting the desktop two-column grid, leaving the reader cramped inside the .project-content flex chain. Reflow to one full-width column while preserving internal history and reader scroll containers so the document itself does not overflow horizontally.
|
||||
*/
|
||||
@media (min-width: 769px) and (max-width: 1024px) {
|
||||
.research-view {
|
||||
flex: 1;
|
||||
inline-size: 100%;
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.research-view__layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
inline-size: 100%;
|
||||
min-width: 0;
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.research-view__sidebar,
|
||||
.research-view__reader,
|
||||
.research-view__sidebar-content,
|
||||
.research-view__reader-content {
|
||||
min-width: 0;
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
}
|
||||
|
||||
.research-view__sidebar {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.research-view__reader {
|
||||
flex: 1 1 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.research-view__history {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
||||
import { loadAllAppCss, loadAllAppCssBaseOnly } from "../../test/cssFixture";
|
||||
import { InsightsView } from "../InsightsView";
|
||||
|
||||
// Mock the useInsights hook
|
||||
@@ -1351,4 +1352,23 @@ describe("InsightsView", () => {
|
||||
expect(dismiss2Button).toBeDisabled(); // All actions disabled when any is in-flight
|
||||
});
|
||||
});
|
||||
|
||||
describe("responsive CSS contracts", () => {
|
||||
it("FN-6764: adds a tablet full-width reflow without regressing desktop or mobile tiers", () => {
|
||||
const baseCss = loadAllAppCssBaseOnly();
|
||||
const css = loadAllAppCss();
|
||||
|
||||
expect(baseCss).toMatch(/\.insights-body\s*\{[^}]*display:\s*flex;[^}]*overflow:\s*hidden;[^}]*\}/);
|
||||
expect(baseCss).toMatch(/\.insights-sidebar\s*\{[^}]*width:\s*calc\(var\(--space-2xl\)\s*\*\s*7\s*\+\s*var\(--space-lg\)\);[^}]*flex-shrink:\s*0;[^}]*overflow-y:\s*auto;[^}]*\}/);
|
||||
expect(baseCss).toMatch(/\.insights-detail\s*\{[^}]*flex:\s*1;[^}]*min-width:\s*0;[^}]*overflow-y:\s*auto;[^}]*\}/);
|
||||
|
||||
expect(css).toMatch(/@media[^{]*\(max-width:\s*768px\)[^{]*\{[\s\S]*?\.insights-body\s*\{[^}]*flex-direction:\s*column;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(max-width:\s*768px\)[^{]*\{[\s\S]*?\.insights-sidebar\s*\{[^}]*width:\s*100%;[^}]*border-right:\s*none;[^}]*overflow-x:\s*auto;[^}]*overflow-y:\s*hidden;[^}]*\}/);
|
||||
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.insights-view\s*\{[^}]*inline-size:\s*100%;[^}]*min-inline-size:\s*0;[^}]*overflow:\s*hidden;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.insights-body\s*\{[^}]*flex-direction:\s*column;[^}]*inline-size:\s*100%;[^}]*min-width:\s*0;[^}]*min-inline-size:\s*0;[^}]*overflow:\s*hidden;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.insights-sidebar\s*\{[^}]*width:\s*100%;[^}]*min-width:\s*0;[^}]*min-inline-size:\s*0;[^}]*border-right:\s*none;[^}]*border-bottom:\s*var\(--btn-border-width\)\s+solid\s+var\(--border\);[^}]*overflow-x:\s*auto;[^}]*overflow-y:\s*hidden;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.insights-detail\s*\{[^}]*flex:\s*1\s+1\s+0;[^}]*min-width:\s*0;[^}]*min-inline-size:\s*0;[^}]*overflow-y:\s*auto;[^}]*\}/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -561,4 +561,17 @@ describe("ResearchView", () => {
|
||||
expect(css).toMatch(/@media[^{]*\(max-width:\s*768px\)[^{]*\{[\s\S]*?\.research-view__layout\s*\{[^}]*display:\s*flex;[^}]*flex-direction:\s*column;[^}]*overflow:\s*visible;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(max-width:\s*768px\)[^{]*\{[\s\S]*?\.research-view__history\s*\{[^}]*overflow:\s*visible;[^}]*\}/);
|
||||
});
|
||||
|
||||
it("FN-6764: adds a tablet full-width reflow without regressing desktop or mobile tiers", () => {
|
||||
const baseCss = loadAllAppCssBaseOnly();
|
||||
const css = loadAllAppCss();
|
||||
|
||||
expect(baseCss).toMatch(/\.research-view__layout\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)\s*minmax\(0,\s*2fr\);[^}]*overflow:\s*hidden;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(max-width:\s*768px\)[^{]*\{[\s\S]*?\.research-view__layout\s*\{[^}]*display:\s*flex;[^}]*flex-direction:\s*column;[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\);[^}]*overflow:\s*visible;[^}]*\}/);
|
||||
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.research-view\s*\{[^}]*inline-size:\s*100%;[^}]*min-inline-size:\s*0;[^}]*overflow:\s*hidden;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.research-view__layout\s*\{[^}]*display:\s*flex;[^}]*flex-direction:\s*column;[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\);[^}]*min-width:\s*0;[^}]*min-inline-size:\s*0;[^}]*overflow:\s*hidden;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.research-view__reader\s*\{[^}]*flex:\s*1\s+1\s+0;[^}]*overflow:\s*auto;[^}]*\}/);
|
||||
expect(css).toMatch(/@media[^{]*\(min-width:\s*769px\)\s*and\s*\(max-width:\s*1024px\)[^{]*\{[\s\S]*?\.research-view__history\s*\{[^}]*overflow:\s*auto;[^}]*\}/);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user