fix(frontend): left-align the sidebar nav items on the mobile drawer
The nav buttons defaulted to centered for the desktop icon rail and were flipped back by `[data-state="expanded"]`. That attribute tracks the desktop open state, while the mobile drawer runs off `openMobile`, so on a phone the labels rendered but the override never matched: 新建对话 and 我的报告 floated mid-drawer while every other row sat flush left. Left alignment is the base layer now, correct for both the drawer and the expanded desktop sidebar, and centering moved into the >=768px collapsed block beside the rest of the rail rules. That was the only top-level `[data-state=...]` selector left in the stylesheet. personal-report-entry asserted `justify-content: center` on the report button, which is the defect itself; the value is updated and the rest of that assertion stands. BUG-438. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
This commit is contained in:
co-authored by
Claude Opus 5
parent
3cecb25f42
commit
d02fa8bbf3
@@ -211,9 +211,12 @@ test("entry is global in the sidebar and absent from the active session header",
|
||||
assert.match(pageSource, /onOpenReports=\{\(\) => router\.push\("\/reports"\)\}/);
|
||||
assert.doesNotMatch(pageSource, /window\.location\.assign\("\/reports"\)/);
|
||||
assert.doesNotMatch(pageSource, /GeneratePersonalReportButton|reportEntryVisible|reportEvidenceState/);
|
||||
// Was `justify-content: center`, which is what put 我的报告 in the middle of
|
||||
// the mobile drawer (BUG-438). The base layer is left-aligned now; centering
|
||||
// moved into the >=768px collapsed rail, locked by sidebar-contract.
|
||||
assert.match(
|
||||
globalStyles,
|
||||
/\.report-nav-button \{[^}]*display: flex;[^}]*align-items: center;[^}]*justify-content: center;/,
|
||||
/\.report-nav-button \{[^}]*display: flex;[^}]*align-items: center;[^}]*justify-content: flex-start;/,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -10,6 +10,32 @@ const globalStyles = readProjectFile("src/app/globals.css");
|
||||
|
||||
const cssBlock = (selector: string) => cssDeclarations(selector, globalStyles);
|
||||
|
||||
/** The base-layer rule only — media-query copies of a selector are indented. */
|
||||
const topLevelRule = (selector: string) => {
|
||||
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
const hit = globalStyles.match(new RegExp(`^${escaped}\\s*\\{([^}]*)\\}`, "m"));
|
||||
assert.ok(hit, `no base-layer rule for ${selector}`);
|
||||
return hit[1];
|
||||
};
|
||||
|
||||
test("sidebar nav items read left-aligned everywhere; centering is the desktop rail only", () => {
|
||||
// `data-state` tracks the DESKTOP open state, so it cannot decide layout on
|
||||
// the mobile drawer — that drawer is always expanded no matter what the
|
||||
// desktop rail is doing. Centering as the base layer, flipped back by a
|
||||
// `[data-state="expanded"]` override, left 新建对话 / 我的报告 floating in
|
||||
// the middle of the drawer on phones while every other row sat flush left.
|
||||
for (const selector of [".new-chat", ".report-nav-button"]) {
|
||||
assert.match(topLevelRule(selector), /justify-content:\s*flex-start/);
|
||||
assert.doesNotMatch(topLevelRule(selector), /justify-content:\s*center/);
|
||||
}
|
||||
assert.doesNotMatch(globalStyles, /\[data-state="expanded"\][^{]*\.(?:new-chat|report-nav-button)/);
|
||||
// The rail lives at >=768px, beside the other collapsed-state rules.
|
||||
assert.match(
|
||||
globalStyles,
|
||||
/@media\s*\(min-width:\s*768px\)[\s\S]*\[data-state="collapsed"\]\s+\.new-chat,\s*\[data-state="collapsed"\]\s+\.report-nav-button\s*\{[^}]*justify-content:\s*center/,
|
||||
);
|
||||
});
|
||||
|
||||
test("provides the generic composable sidebar primitive", () => {
|
||||
assert.equal(existsSync(projectFile("src/components/ui/sidebar.tsx")), true);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user