feat(plan): complete sticky actions — pin toolstrip + badges on scroll#510
Merged
backnotprop merged 2 commits intomainfrom Apr 7, 2026
Merged
feat(plan): complete sticky actions — pin toolstrip + badges on scroll#510backnotprop merged 2 commits intomainfrom
backnotprop merged 2 commits intomainfrom
Conversation
The sticky actions setting previously only pinned the action button cluster on the right side of the plan card. The annotation toolstrip (selection mode + editor mode toggles) and the left-side badges (repo / branch / plan-diff) scrolled away, forcing users to scroll back to the top of long plans to switch modes or jump into diff view. Adds a ghost sticky header lane that pins the toolstrip and badges on the same horizontal plane as the already-sticky action buttons once the user scrolls past the top of the document. Top-of-document rendering is unchanged. - Extract the badge cluster into a reusable `DocBadges` component with `column` / `row` layouts so the card's absolute cluster and the ghost bar share the same markup. - Add a `compact` prop to `AnnotationToolstrip` that disables hover expansion (only the active button shows its label) and hides the help link, for use inside the ghost bar. - Introduce `StickyHeaderLane`: a zero-height sticky wrapper with an absolute-positioned bar that fades + slides in via IntersectionObserver on a sentinel. Uses a 72px top rootMargin so the bar only materializes after the real toolstrip has scrolled off. - Hidden in plan-diff, archive, and linked-doc modes, and gated by the existing `stickyActionsEnabled` preference. For provenance purposes, this commit was AI assisted.
Iteration on the sticky header lane addressing review feedback and
in-browser testing across viewport sizes:
- Mobile (<640px): the bar now drops to its own full-width row at
top: 52px, directly below the action buttons row. Two stacked
horizontal lanes — no horizontal collision possible. The toolstrip
switches to icon-only on mobile so the diff badges fit alongside.
- sm-md (640-1023px): bar shares the top: 12px lane with action
buttons, capped at `max-w-[calc(100%-340px)]` to clear the short-
label action button cluster (Attachments + Comment + Copy ≈ 320px).
- lg+ (1024px+): same shared-lane behavior, cap raised to 400px to
clear the full-label cluster.
- Bar is `inline-flex` (content-width), not flex (full bounding-box
width), so the chrome wraps tightly to the toolstrip + badges and
doesn't extend visually past where it needs to.
- Add `inert` to the bar when not stuck — removes the hidden subtree
from the tab order entirely so keyboard users don't land on
invisible duplicate controls before reaching the real toolstrip.
- Add `iconOnly` prop to AnnotationToolstrip; passed via JS-driven
matchMedia('(max-width: 639px)') in StickyHeaderLane. Active button
expansion is preserved on sm+ so users still see the current mode
label there.
- Bump action button label breakpoint md → lg in Viewer so "Comment"
and "Copy" stay short labels until 1024px, giving the action button
cluster more breathing room on tablet/laptop widths.
For provenance purposes, this commit was AI assisted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
stickyActionsEnabledsetting only pinned the right-side action button cluster. The annotation toolstrip (selection mode + editor mode toggles) and the left-side badges (repo / branch / plan-diff) scrolled away, forcing users to scroll back to the top of long plans to switch modes or jump into diff view.This PR adds a ghost sticky header lane that pins the toolstrip and badges on the same horizontal plane as the already-sticky action buttons once the user scrolls past the top of the document.
top: 12px, containing the full toolstrip (in compact mode — only the active mode shows its label) and a row-layout badge cluster, sized to leave the right side of the lane clear for the existing action buttons.stickyActionsEnabledis off.Implementation highlights
DocBadgesextracted fromViewer.tsxso the card's absolute cluster and the ghost bar share the same markup via alayout: 'column' | 'row'prop. No JSX duplication.AnnotationToolstripgets acompactprop — the same component renders in both locations, just with hover-expansion disabled and the help link hidden.StickyHeaderLaneis a zero-height sticky wrapper with an absolute-positioned bar inside it, so it never pushes content down at top of doc. AnIntersectionObserverwithrootMargin: '72px 0 0 0'delays the trigger until the real toolstrip has actually scrolled off, avoiding a brief double-header.prefers-reduced-motion.Viewer.tsxis untouched — same DOM, same classes, sameisStuckchrome behavior.Test plan
mainpixel-for-pixel (toolstrip above card, badges absolute top-left, action buttons float-right, no ghost bar visible)PlanDiffBadgecorrectly toggles plan-diff view on resubmitted plansprefers-reduced-motion: reducedrops the slide, keeps opacity