fix(FN-1894): add base and mobile CSS for .mailbox-view full-page layout

- Add .mailbox-view base styles for full-page layout with flexbox and inset edges
- Add mobile responsive styles for .mailbox-view within 768px breakpoint
- Add MailboxView component test covering layout rendering and mobile behavior
This commit is contained in:
Fusion
2026-04-16 06:33:37 -07:00
committed by gsxdsm
parent e0266565f3
commit da432d515c
2 changed files with 102 additions and 3 deletions

View File

@@ -479,4 +479,100 @@ describe("MailboxView", () => {
expect(screen.getByText("Test Agent 1")).toBeDefined();
expect(screen.getByText("Test Agent 2")).toBeDefined();
});
describe("mobile layout CSS regressions", () => {
it("defines .mailbox-view base flex layout with min-height: 0", async () => {
const fs = await import("fs");
const path = await import("path");
const cssPath = path.resolve(__dirname, "../../styles.css");
const css = fs.readFileSync(cssPath, "utf-8");
const viewBlockMatch = css.match(/\.mailbox-view\s*\{([^}]*)\}/);
expect(viewBlockMatch).toBeTruthy();
const viewBlock = viewBlockMatch![1];
expect(viewBlock).toContain("display: flex;");
expect(viewBlock).toContain("flex-direction: column;");
expect(viewBlock).toContain("height: 100%;");
expect(viewBlock).toContain("min-height: 0;");
expect(viewBlock).toContain("overflow: hidden;");
});
it("keeps mobile .mailbox-view overrides in the dedicated media-query section", async () => {
const fs = await import("fs");
const path = await import("path");
const cssPath = path.resolve(__dirname, "../../styles.css");
const css = fs.readFileSync(cssPath, "utf-8");
const sectionStart = css.indexOf("/* ── Mailbox — Mobile");
expect(sectionStart).toBeGreaterThan(-1);
const sectionEnd = css.indexOf("/* ── Message Composer", sectionStart);
expect(sectionEnd).toBeGreaterThan(sectionStart);
const mailboxMobileSection = css.slice(sectionStart, sectionEnd);
expect(mailboxMobileSection).toContain("@media (max-width: 768px)");
// Verify .mailbox-view selectors are in mobile section
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-header");
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-tabs");
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-content");
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-compose-fab");
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-empty");
});
it("uses mobile-specific values for .mailbox-view content and FAB", async () => {
const fs = await import("fs");
const path = await import("path");
const cssPath = path.resolve(__dirname, "../../styles.css");
const css = fs.readFileSync(cssPath, "utf-8");
const sectionStart = css.indexOf("/* ── Mailbox — Mobile");
expect(sectionStart).toBeGreaterThan(-1);
const sectionEnd = css.indexOf("/* ── Message Composer", sectionStart);
const mailboxMobileSection = css.slice(sectionStart, sectionEnd);
// Content should have max-height: none (not modal's calc)
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-content");
// Match descendant selector: .mailbox-view followed by space, then .mailbox-content
const contentRuleMatch = mailboxMobileSection.match(/\.mailbox-view\s+\.mailbox-content\s*\{[^}]*\}/);
expect(contentRuleMatch).toBeTruthy();
expect(contentRuleMatch![0]).toContain("max-height: none");
// Content should have padding-bottom accounting for mobile nav
expect(contentRuleMatch![0]).toContain("padding-bottom");
// FAB should account for mobile nav height
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-compose-fab");
const fabRuleMatch = mailboxMobileSection.match(/\.mailbox-view\s+\.mailbox-compose-fab\s*\{[^}]*\}/);
expect(fabRuleMatch).toBeTruthy();
expect(fabRuleMatch![0]).toContain("--mobile-nav-height");
expect(fabRuleMatch![0]).toContain("safe-area-inset-bottom");
expect(fabRuleMatch![0]).toContain("--standalone-bottom-gap");
});
it("renders structural elements that mobile CSS targets", async () => {
mockFetchInbox.mockResolvedValue({
messages: [mockMessage],
unreadCount: 1,
});
const { container } = render(<MailboxView {...defaultProps} />);
// Verify root element with data-testid
expect(screen.getByTestId("mailbox-view")).toBeDefined();
// Verify header
const header = container.querySelector(".mailbox-header");
expect(header).toBeTruthy();
// Verify tabs
const tabs = container.querySelector(".mailbox-tabs");
expect(tabs).toBeTruthy();
// Verify content
const content = container.querySelector(".mailbox-content");
expect(content).toBeTruthy();
});
});
});

View File

@@ -26886,6 +26886,7 @@ html .column.drag-over * {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
overflow: hidden;
}
@@ -27007,8 +27008,10 @@ html .column.drag-over * {
}
.mailbox-view .mailbox-content {
padding: var(--space-md);
max-height: none;
padding: var(--space-md);
/* Account for mobile nav bar at bottom */
padding-bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap) + var(--space-lg));
}
.mailbox-view .mailbox-message-detail-header {
@@ -27038,8 +27041,8 @@ html .column.drag-over * {
}
.mailbox-view .mailbox-compose-fab {
bottom: calc(16px + var(--mobile-nav-height, 44px) + env(safe-area-inset-bottom, 0px));
right: 16px;
bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap) + var(--space-lg));
right: var(--space-lg);
}
.mailbox-view .mailbox-empty {