LearnNewsExamplesServices
Frontmatter
id18015
titleFocus-hidden toolbar actions leave a gap in the action rail
stateClosed
labels
bugdesignaitestingarchitecturecore
assigneesneo-opus-vega
createdAtSep 1, 2026, 11:15 AM
updatedAtSep 1, 2026, 2:37 PM
githubUrlhttps://github.com/neomjs/neo/issues/18015
authorneo-gpt-emmy
commentsCount0
parentIssue17836
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[x] 18014 Complete the default DockLayout action rail in Workstation
closedAtSep 1, 2026, 2:37 PM

Focus-hidden toolbar actions leave a gap in the action rail

Closed Backlog/active-chunk-19 bugdesignaitestingarchitecturecore
neo-gpt-emmy
neo-gpt-emmy commented on Sep 1, 2026, 11:15 AM

Context

Epic #17836's DockLayouts goal requires focus-gated middle actions without an empty rail gap. The operator resolved both sides of the trade:

  • an action not offered by showOnFocus must consume no space;
  • focus-driven tab-overflow repartition is acceptable: “totally worth it.”

Fresh Workstation measurement found two inactive 24px actions reserving a 48px hole. The behavior came from resources/scss/src/toolbar/Base.scss: visibility: hidden preserved their boxes.

The Problem

Changing that rule to display: none removes the gap, but a collapsed action reports an all-zero DOM rect. Neo.tab.plugin.Overflow reads action rect position as well as size; treating a collapsed rect as the start of the action cluster makes the cluster consume the full strip. In the 843px dock fixture, every tab but one moved into overflow.

The correct contract is simpler than the initial ticket prescription: collapsed actions are absent from layout and absent from Overflow's action measurement. Focus may legitimately change the tab partition.

The Architectural Reality

  • toolbar.Base#applyContextualActionState() retains the stable action instance and owns aria-hidden, inert, and tabIndex.
  • .neo-toolbar-action-context-inactive owns physical layout participation.
  • Overflow#getActionItems() owns which rendered actions reduce the tab strip extent; collapsed actions cannot supply meaningful position or size.
  • The overflow contribution remains first and outside the tab collection; the active tab remains directly visible by the existing packing invariant.

The Fix

  1. Collapse context-inactive actions out of layout without replacing their component instances.
  2. Exclude context-inactive/collapsed actions from Overflow action-rect measurement.
  3. Update source comments to state the accepted focus-time repartition.
  4. Invert the existing focus-geometry witness and pin the zero-rect exclusion with its own mutation control.

Contract Ledger

Target Surface Authority Behavior Fallback Docs Evidence
inactive showOnFocus action operator ruling + #17874 focus gate zero layout extent; same inert/aria-hidden instance persistent action unchanged toolbar JSDoc/SCSS four-theme component geometry
Overflow action measurement rendered-layout truth collapsed actions excluded; visible actions measured normally no visible actions ⇒ zero action extent Overflow JSDoc direct-tab partition + filter mutation
DockLayouts consumer Epic #17836 / #18014 no 48px gap; overflow may repartition on focus active tab remains visible existing dock docs #18014 Workstation acceptance

Decision Record impact

aligned-with ADR 0029 §2.4 and Epic #17836; supersedes only #17874's hidden-representation row. No model, operation, or wire change.

Acceptance Criteria

  • A context-inactive action has no DOM box while retaining the same component identity and accessibility state.
  • Focus reveals that same instance; leaving focus collapses it again.
  • Overflow excludes collapsed actions from position/extent measurement; an all-zero rect cannot consume the strip.
  • The 843px dock fixture retains its expected direct tabs after the action collapses; the active-tab invariant remains intact.
  • Overflow remains the first action contribution and the engine action ordering remains intact.
  • Four-theme focus geometry and DockPopOut ordering witnesses are green.
  • Mutation controls independently red when (a) visibility: hidden is restored and (b) the collapsed-action exclusion is removed.
  • #18014 carries the final Workstation screenshot/action acceptance after this engine prerequisite lands.

Out of Scope

  • Default Dock action membership, reload/pop-out behavior, or Workstation cache adoption (#18014).
  • Changing focus ownership or containsFocus observation.
  • Restyling pane chrome or changing overflow menu content.

Avoided Traps

  • Only switch to display: none. Zero rects poison positional overflow measurement.
  • Preserve invisible boxes. Retains the operator-reported gap.
  • Preserve a focus-stable partition at any cost. Explicitly rejected by the operator.
  • Hard-code 24px. Generic actions and orientations are not a fixed-size invariant.

Related

Parent: #17836. Product consumer: #18014. Precedents: #17874/#17875 and #17951/#17960.

Origin Session ID: 309a78d7-2d95-4f23-bdfc-69d2ae393a5d

Retrieval Hint: query_raw_memories("showOnFocus collapsed action zero rect Overflow position measurement")

— Emmy (GPT-5.6 Sol Ultra, Codex), incorporating Vega's measured one-line regression and the operator's repartition ruling.