Unify top panel header styling

This commit is contained in:
2026-08-05 16:48:27 +02:00
parent 4a985f101f
commit a83b9b3ab9
5 changed files with 19 additions and 6 deletions
+1
View File
@@ -40,6 +40,7 @@ This project replaces the Excel/VBA workflow named `Catalog maker - 20` with a N
- Multi-column panels must use a shared collapse pattern: collapsing a panel removes its grid track, lets the adjacent workspace expand, preserves an accessible expand/collapse control, and stacks predictably on mobile.
- When the left sidebar is closed on desktop, its open control keeps a dedicated narrow rail; it must not be positioned inside the secondary product-details panel. On mobile, the rail collapses and the control may overlay the stacked layout.
- Top headers for the sidebar, secondary panel and main workspace must use one shared fixed height so the columns align visually across the application.
- All top panel headers must use the shared `panel-header` component class, including identical background, border, typography, spacing and dark/light theme behavior. Do not style `Catalog controls`, `Product details` or `Main workspace` headers independently.
- Panel collapse/open controls must use the shared `panel-control-button` style; do not create separate visual variants for `X`, chevrons or future panel toggles.
- Verify shared panel-control styling through computed browser styles, not only by checking class names.
- Use Playwright to inspect the rendered result after every visual change at desktop and narrow viewport sizes.
+3 -3
View File
@@ -17,7 +17,7 @@
<button class="sidebar-overlay" id="sidebarOverlay" type="button" aria-label="Close sidebar"></button>
<aside class="control-panel sidebar-drawer" id="sidebarDrawer" aria-label="Catalog controls">
<div class="sidebar-drawer-header">
<div class="panel-header sidebar-drawer-header">
<span class="sidebar-drawer-title">Catalog controls</span>
<button class="sidebar-close-button panel-control-button" id="sidebarCloseButton" type="button" aria-label="Close sidebar" title="Close sidebar">
<svg class="sidebar-icon" aria-hidden="true"><use href="/icons.svg#close"></use></svg>
@@ -97,7 +97,7 @@
</aside>
<section class="product-panel secondary-panel" aria-label="Product details">
<div class="column-header">
<div class="panel-header column-header">
<span>Product details</span>
<button class="column-toggle" id="secondaryPanelToggle" type="button" aria-expanded="true" aria-controls="fieldGrid" aria-label="Collapse product details" title="Collapse product details"></button>
</div>
@@ -105,7 +105,7 @@
</section>
<section class="data-panel main-workspace" aria-label="Catalog workspace">
<div class="column-header workspace-header">
<div class="panel-header column-header workspace-header">
<span>Main workspace</span>
<button class="column-toggle" id="mainWorkspaceToggle" type="button" aria-expanded="true" aria-controls="variantGrid" aria-label="Collapse main workspace" title="Collapse main workspace"></button>
</div>
+1 -1
View File
File diff suppressed because one or more lines are too long
+5 -2
View File
@@ -46,7 +46,7 @@
.catalog-screen.secondary-collapsed { --secondary-track: 44px; }
.catalog-screen.workspace-collapsed { --workspace-track: 44px; }
.sidebar-drawer { @apply fixed inset-y-0 left-0 z-40 flex w-72 min-h-screen flex-col gap-1.5 overflow-y-auto bg-slate-900 p-1.5 text-[11px] text-slate-200 shadow-xl transition-transform duration-200 ease-out; }
.sidebar-drawer-header { @apply box-border flex h-7 min-h-7 items-center justify-between border-b border-slate-700 py-0; }
.panel-header, .sidebar-drawer-header, .column-header { @apply box-border flex h-7 min-h-7 items-center justify-between gap-1 border-b border-slate-700 bg-slate-900 px-1 text-[10px] font-semibold uppercase tracking-wide text-slate-300; }
.sidebar-drawer-title { @apply px-1 text-[10px] font-semibold uppercase tracking-wide text-slate-400; }
.sidebar-close-button, .sidebar-open-button { @apply inline-flex h-7 w-7 items-center justify-center rounded border border-slate-700 bg-slate-800 text-slate-200 shadow-sm transition hover:border-slate-500 hover:bg-slate-700; }
.sidebar-close-button .sidebar-icon, .sidebar-open-button .sidebar-icon { @apply h-4 w-4; }
@@ -115,7 +115,7 @@
.mapping-source-status.is-bad { @apply bg-red-100 text-red-700; }
.mapping-source-status.is-muted { @apply bg-slate-200 text-slate-600; }
.secondary-panel { @apply min-w-0 border-r border-slate-400 bg-slate-300; }
.column-header { @apply box-border flex h-7 min-h-7 items-center justify-between gap-1 border-b border-slate-400 px-1 text-[10px] font-semibold uppercase tracking-wide text-slate-600; }
.column-header { @apply min-w-0; }
.column-toggle { @apply inline-flex h-5 w-5 shrink-0 items-center justify-center rounded border border-slate-400 bg-white text-sm leading-none text-slate-700 shadow-sm transition hover:border-slate-500 hover:bg-slate-200 focus:outline-none focus:ring-2 focus:ring-catalog-focus/25; }
.secondary-panel .field-grid { @apply overflow-hidden; }
.secondary-collapsed .secondary-panel .column-header { @apply h-full flex-col justify-start py-1; writing-mode: vertical-rl; }
@@ -222,6 +222,9 @@
html:not(.dark) .sidebar-drawer-header,
html:not(.dark) .sidebar-footer { @apply border-slate-300; }
html:not(.dark) .sidebar-drawer-title { @apply text-slate-500; }
html:not(.dark) .panel-header,
html:not(.dark) .sidebar-drawer-header,
html:not(.dark) .column-header { @apply border-slate-300 bg-slate-100 text-slate-700; }
html:not(.dark) .sidebar-close-button,
html:not(.dark) .sidebar-open-button,
html:not(.dark) .drawer-trigger,
+9
View File
@@ -81,6 +81,15 @@ test("uses one shared height for the top panel headers", async ({ page }) => {
expect(new Set(heights).size).toBe(1);
});
test("uses one shared visual style for the top panel headers", async ({ page }) => {
await page.goto("/");
const styles = await page.locator(".panel-header").evaluateAll((elements) => elements.map((element) => {
const style = getComputedStyle(element);
return [style.height, style.backgroundColor, style.borderBottomColor, style.fontSize, style.fontWeight, style.paddingLeft, style.paddingRight];
}));
expect(new Set(styles.map((style) => JSON.stringify(style))).size).toBe(1);
});
test("uses one shared visual style for panel controls", async ({ page }) => {
await page.goto("/");
const styles = await page.locator("#sidebarCloseButton, #secondaryPanelToggle, #mainWorkspaceToggle").evaluateAll((elements) => elements.map((element) => {