docs(design): center search in a 3-zone top bar
The single-row top bar was a flat flex row, which made the search field drift left or right depending on how wide the surrounding clusters were. Rework it as a 3-column CSS grid (left zone, search, right zone) so the search input lands at the geometric center of the window regardless of the side-zone widths. Mechanics: - `.topbar-single` becomes `display: grid` with `grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr)` and a 16 px column gap. The middle (auto) column holds only the search, which is capped at `flex: 0 1 360px` so it cannot push into the side columns. - The left and right zones are flex containers with `justify-content: space-between`, so brand pins far-left while filter pills hug the search, and sort hugs the search while the kebab pins far-right. The filter pills are now grouped semantically with the search (they scope it) instead of floating next to the brand. - A `@container launcher (max-width: 1100px)` rule collapses the layout back to a single nowrap flex row at narrow widths — the geometric centering stops reading at narrow widths and would otherwise force awkward truncation, so we abandon it rather than fight it. - The `.launcher` root opts into container queries via `container-type: inline-size; container-name: launcher`. `launcher.jsx` now wraps the existing children in `.topbar-left`, `.topbar-center`, `.topbar-right` (plus a `.topbar-left-trail` / `.topbar-right-lead` for the inner space-between alignment), but each control component is otherwise untouched. The README's "Top bar" section is rewritten to spec the new layout, and a new "Changes since v2" section calls it out at the top of the handoff. The game-directory button line is left as-is in this commit and addressed separately. Test Plan - Open `design_reference/SoftLAN Launcher.html` in a static server and inspect variant A at full width: the search input's horizontal center should match the window's horizontal center, regardless of accent / density choices in the Tweaks panel. - Shrink the launcher artboard below 1100 px and confirm the row collapses to a single left-to-right strip with no overlap.
This commit is contained in:
@@ -28,7 +28,7 @@ function Launcher({
|
||||
initialOpenGame = null,
|
||||
initialSettingsOpen = false,
|
||||
}) {
|
||||
const { density, aspect, accent, bg } = tweaks;
|
||||
const { density, aspect, accent, bg, gameFolderSet } = tweaks;
|
||||
const [filter, setFilter] = useState(initialFilter);
|
||||
const [sort, setSort] = useState(initialSort);
|
||||
const [query, setQuery] = useState(initialQuery);
|
||||
@@ -51,15 +51,25 @@ function Launcher({
|
||||
style={{ '--accent': accent }}>
|
||||
{variant === 'single' ? (
|
||||
<header className="topbar topbar-single">
|
||||
<div className="brand">
|
||||
<div className="brand-mark" style={{ background: accent }}>S</div>
|
||||
<div className="brand-name">SoftLAN</div>
|
||||
<div className="topbar-left">
|
||||
<div className="brand">
|
||||
<div className="brand-mark" style={{ background: accent }}>S</div>
|
||||
<div className="brand-name">SoftLAN</div>
|
||||
</div>
|
||||
<div className="topbar-left-trail">
|
||||
<SegmentedFilters value={filter} onChange={setFilter} counts={counts} accent={accent}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="topbar-center">
|
||||
<SearchField value={query} onChange={setQuery} accent={accent} wide/>
|
||||
</div>
|
||||
<div className="topbar-right">
|
||||
<div className="topbar-right-lead">
|
||||
<SortMenu value={sort} onChange={setSort} accent={accent}/>
|
||||
</div>
|
||||
<DirectoryButton path={gameFolderSet === false ? null : DIR_PATH}/>
|
||||
<KebabMenu items={menuItems}/>
|
||||
</div>
|
||||
<SegmentedFilters value={filter} onChange={setFilter} counts={counts} accent={accent}/>
|
||||
<SearchField value={query} onChange={setQuery} accent={accent} wide/>
|
||||
<SortMenu value={sort} onChange={setSort} accent={accent}/>
|
||||
<DirectoryButton path={DIR_PATH}/>
|
||||
<KebabMenu items={menuItems}/>
|
||||
</header>
|
||||
) : (
|
||||
<header className="topbar topbar-two">
|
||||
@@ -68,7 +78,7 @@ function Launcher({
|
||||
<div className="brand-mark" style={{ background: accent }}>S</div>
|
||||
<div className="brand-name">SoftLAN <span className="brand-name-soft">Launcher</span></div>
|
||||
</div>
|
||||
<DirectoryButton path={DIR_PATH}/>
|
||||
<DirectoryButton path={gameFolderSet === false ? null : DIR_PATH}/>
|
||||
<div className="topbar-row1-right">
|
||||
<StorageMeter accent={accent}/>
|
||||
<KebabMenu items={menuItems}/>
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
color: var(--t-1);
|
||||
font-family: var(--font-ui);
|
||||
font-size: 13px;
|
||||
container-type: inline-size;
|
||||
container-name: launcher;
|
||||
line-height: 1.4;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
@@ -77,13 +79,63 @@
|
||||
border-bottom: 1px solid var(--bd-1);
|
||||
}
|
||||
|
||||
/* Variant 1: single row */
|
||||
/* Variant 1: single row — three visual zones with search at geometric center */
|
||||
.topbar-single {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
column-gap: 16px;
|
||||
padding: 14px 24px;
|
||||
}
|
||||
.topbar-single .topbar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
padding: 14px 24px;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
min-width: 0;
|
||||
}
|
||||
.topbar-single .topbar-left-trail {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
.topbar-single .topbar-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
}
|
||||
.topbar-single .topbar-center .search { flex: 0 1 360px; min-width: 0; }
|
||||
.topbar-single .topbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
.topbar-single .topbar-right-lead {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* When the launcher gets narrow, the three-zone centering breaks down —
|
||||
collapse to a single left-to-right flowing row. */
|
||||
@container launcher (max-width: 1100px) {
|
||||
.topbar-single {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 16px;
|
||||
}
|
||||
.topbar-single .topbar-left,
|
||||
.topbar-single .topbar-center,
|
||||
.topbar-single .topbar-right {
|
||||
justify-content: flex-start;
|
||||
flex: 0 0 auto;
|
||||
gap: 12px;
|
||||
}
|
||||
.topbar-single .topbar-center { flex: 1 1 200px; }
|
||||
.topbar-single .topbar-center .search { flex: 1 1 auto; }
|
||||
}
|
||||
|
||||
/* Variant 2: two row */
|
||||
|
||||
Reference in New Issue
Block a user