refactor(frontend): migrate dashboard tabbar to createTabStrip + drop overflow (#1464 step 1)
The dashboard's tab strip now runs on the shared createTabStrip (@hive/shared/tabs.js) — the third and final consumer of #1464 step 1 (after logs + the agent window selector). - activateTab is reduced to the per-tab side-effects only (body.dataset.activeTab, the selection-bar gate, the lazy-loads); createTabStrip owns the active tab/pane toggle + aria-selected + hash routing, calling activateTab via onShow. Panes switch via the `hidden` attribute (was a `.tab-pane-active` class) — the markup carries `hidden` so there's no flash before the script runs. - the responsive overflow menu is DROPPED per the design call (move panes to their own pages rather than hide them in a dropdown). Removes ~150 lines: updateTabbarOverflow, closeOverflowMenu, the click/keydown handlers, the ResizeObserver + MutationObserver, and syncTabFromHash. S3TT1NGS is a regular strip tab now (no data-overflow). - CSS: .tab.active becomes .tab.hive-tab--active; pane visibility is now .tab-pane[hidden] { display: none }; the overflow dropdown styles are gone. Count pills (setTabCount/refreshTabCounts) are unchanged. Behaviour-preserving except the deliberate overflow removal; aria-selected is now standardised on the tabs.
This commit is contained in:
parent
0680f87d3d
commit
2ec06f07ed
3 changed files with 37 additions and 320 deletions
|
|
@ -85,7 +85,7 @@ body.dashboard-shell {
|
|||
color: var(--purple);
|
||||
background: color-mix(in srgb, var(--purple) 6%, transparent);
|
||||
}
|
||||
.tabbar .tab.active {
|
||||
.tabbar .tab.hive-tab--active {
|
||||
color: var(--purple);
|
||||
border-color: var(--purple-dim);
|
||||
background: var(--bg);
|
||||
|
|
@ -112,109 +112,11 @@ body.dashboard-shell {
|
|||
color: var(--red);
|
||||
}
|
||||
|
||||
/* Overflowed tabs are hidden from the bar (moved to the ⋮ dropdown). */
|
||||
.tabbar .tab[data-overflow="default"],
|
||||
.tabbar .tab.tab-overflowed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ── overflow ⋮ button + dropdown ────────────────────────── */
|
||||
.tabbar-overflow {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto; /* push to the far right */
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tabbar-overflow-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px 4px 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 1.2em;
|
||||
line-height: 1;
|
||||
padding: 0.3em 0.5em;
|
||||
cursor: pointer;
|
||||
transition: color 0.15s, background 0.15s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tabbar-overflow-btn:hover {
|
||||
color: var(--purple);
|
||||
background: color-mix(in srgb, var(--purple) 6%, transparent);
|
||||
}
|
||||
.tabbar-overflow-btn.tabbar-overflow-active {
|
||||
color: var(--purple);
|
||||
border-color: var(--purple-dim);
|
||||
}
|
||||
|
||||
.tabbar-overflow-dropdown {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: calc(100% + 2px);
|
||||
z-index: 100;
|
||||
background: var(--bg-elev);
|
||||
border: 1px solid var(--purple-dim);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0.3em 0;
|
||||
min-width: 12em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tabbar-overflow-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.6em;
|
||||
width: 100%;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--fg);
|
||||
font-family: inherit;
|
||||
font-size: 0.88em;
|
||||
letter-spacing: 0.05em;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
padding: 0.45em 1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tabbar-overflow-item:hover {
|
||||
background: var(--border);
|
||||
color: var(--purple);
|
||||
}
|
||||
.tabbar-overflow-item-active {
|
||||
color: var(--purple);
|
||||
}
|
||||
|
||||
.tabbar-overflow-badge {
|
||||
display: inline-block;
|
||||
background: var(--purple-dim);
|
||||
color: var(--purple);
|
||||
border-radius: 999px;
|
||||
padding: 0 0.5em;
|
||||
min-width: 1.4em;
|
||||
text-align: center;
|
||||
font-size: 0.82em;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tabbar-overflow-badge.tab-count-attn {
|
||||
background: color-mix(in srgb, var(--red) 22%, transparent);
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
/* Tab pane visibility — show only the active one. The .tab-pane-active
|
||||
class is set by tabs.js based on the URL hash; default (no hash)
|
||||
resolves to SW4RM. */
|
||||
.tab-pane { display: none; }
|
||||
.tab-pane.tab-pane-active { display: block; }
|
||||
/* Tab pane visibility — createTabStrip (@hive/shared/tabs.js) sets the
|
||||
`hidden` attribute on every inactive pane (resolved from the URL hash;
|
||||
default — no hash — is SW4RM). Only the active pane stays visible. */
|
||||
.tab-pane[hidden] { display: none; }
|
||||
|
||||
/* FL0W is a separate page (`/flow.html`) — its full-viewport
|
||||
styling lives in flow.css. */
|
||||
|
|
|
|||
Loading…
Reference in a new issue