Skip to content

Assess sidebar selection continuity #10253

Description

@saphid

Assess a shared selection surface between thread rows, scoped to route selection with interruption and reduced motion. Check existing PRs #9431, #9424, #9967 and existing autoAnimate; avoid duplicate or competing row animation.

Requested by Alex after the T3 UI motion audit. First record an independent Astra-medium accept/revise/reject verdict with source evidence. Accepted changes should end in small focused PRs; do not implement a rejected suggestion.

Use the installed shadcn-motion-ui skill and Human Interface Craft guidelines (feedback, relationship, continuity, accessibility, signature moments). Consult current official docs, reuse local primitives, verify installed API compatibility and add exact source references. Respect native platforms, reduced motion, interruptions, responsiveness, focus, and performance. No continuous repaint loops or framework rewrites.

Acceptance:

  • Independent assessment and overlap check recorded.
  • Accepted scope implemented and focused checks pass, or rejection/dependency documented.
  • Best-effort independent cross-provider review recorded.
  • Real before/after motion evidence and PR linked, with any missing evidence disclosed as a draft-readiness gap.

Do not change live user data, the dirty primary checkout, existing Stash worktree, or unrelated work. No merge or deployment is requested.

Activity

  1. saphid commented on Sep 6, 2026

    @saphid
    ContributorAuthor

    Independent Astra-medium verdict: reject the proposed traveling selection surface for now.

    At base eee05575ebd514db36f61d7eb05d2258a10c96bd, apps/web/src/components/Sidebar.tsx:1182–1200 already reserves distinct surfaces for active route, multi-selection, unsent draft, and hover, in that priority order. Route activation (:4051) is not a row moving: the previously active thread stays in place. The list already animates structural changes with 150 ms autoAnimate (:3596–3599). A shared traveling highlight would imply movement across intervening threads during rapid keyboard navigation and requires additional handling for offscreen routes and separated shelves.

    Overlap checked: #9431 owns pin flight and animation suppression, #9424 owns hover surfaces and active/selected priority, #9967 owns compact/custom row geometry. All edit Sidebar.tsx. Clean main has no Motion dependency. Introducing shared-layout machinery here has no demonstrated usability benefit sufficient to justify another overlapping animation system. A subtle instantaneous route surface remains clear during repeated navigation.

    This follows Human Interface Craft p10 §14/15 (meaningful relationships, repeated-use speed), p11 §16 (keyboard and exposed state), p13 §23 (ordinary actions familiar). Motion shared layout explains matching visual identity, but does not establish that this interaction needs it. No code, worktree, PR, or runtime proof claimed for this rejected suggestion. Reconsider with a concrete observed selection-tracking problem after the existing sidebar PRs settle.

  2. juliusmarminge commented on Sep 6, 2026

    @juliusmarminge
    Member

    Triage

    Motion-audit assessment ticket (not a user bug): should thread rows share a traveling selection surface for route changes, with interruption and reduced motion, without competing with existing row animation?

    Verdict: reject the traveling selection surface. The requester already recorded an independent Astra-medium reject (comment). I checked the same main (eee05575ebd514db36f61d7eb05d2258a10c96bd) and agree. No code or PR.

    What already exists

    Route selection is not a row moving. The previous thread stays put; the destination row gets the active surface in place.

    Sidebar.tsx already reserves one surface model, in priority order:

    1. Route active — bg-sidebar-row-active (isActive={routeThreadKey === threadKey} at L4051)
    2. Multi-select — bg-sidebar-row-selected
    3. Unsent draft
    4. Hover (or receded hover)

    Draft session rows use the same active/draft split (L572). Search results keep a second highlight (isHighlighted vs isRouteActive, L1814–L1827) so keyboard listbox focus and the open thread stay distinct.

    Structural list motion is already present: the inbox <ul> uses FormKit autoAnimate at 150 ms ease-out (L3596–L3598). Clean main has @formkit/auto-animate only — no Motion / layoutId dependency.

    Collapsed shelves already special-case route continuity without animation: a snoozed or paged settled thread reached by route is pulled into the visible tail so the highlight and affordances stay reachable (L2387–L2446).

    Why a shared traveling surface is the wrong model here

    The list is not a homogeneous row track. One autoAnimated <ul> mixes draft block, a nested pinned DndContext/<ul>, a pin divider, inbox rows, and snoozed/settled headers (L4114–L4230). A layoutId highlight would travel across those non-row siblings, or disappear when the destination is in the nested pinned list.

    Keyboard route changes skip intervening rows: prev/next traversal and Cmd/Ctrl+1–9 jump (L3520–L3562). During rapid repeats the highlight would sweep over threads the user did not visit. Offscreen destinations and collapsed shelves would need extra measurement, scroll coordination, and interruption — none of which is a demonstrated usability problem.

    A subtle instantaneous route surface stays truthful during repeated navigation (Human Interface Craft: meaningful relationships, repeated-use speed, exposed keyboard state). Motion shared layout describes matching visual identity; it does not establish that this interaction needs it. AGENTS.md already treats extra motion as a performance risk.

    Clients: this surface is web/desktop (Sidebar.tsx). Native mobile is a separate React Native list — out of scope and not a reason to add shared-layout machinery on web.

    Overlap (do not compete)

    All three named PRs are open, all edit Sidebar.tsx:

    PR Owns Why it conflicts
    #9431 Pin flight + animation suppression (dnd, compact, snoozed/settled cleanup) Second row-motion system on the same list
    #9424 Project-colored hover; active/selected/draft stay above hover Shared highlight would recast the surface priority that PR is tightening
    #9967 Compact / custom row geometry (variable height, up to three rows) Traveling highlight must retarget changing row boxes

    Pin flight is not on main (sidebarPinMotion exists only on #9431). Introducing Motion shared-layout here would be a third animation stack (autoAnimate + pin flight + layoutId) with no measured benefit.

    Siblings #10248–#10255 are separate motion-audit scopes, not duplicates of this one.

    Next step

    Close as wontfix. Do not implement. Remaining acceptance items (implementation, cross-provider review, before/after captures) do not apply to a rejected addition.

    Reconsider only after #9431 / #9424 / #9967 settle and there is a concrete observed selection-tracking problem (e.g. users losing the active row during keyboard traversal). A new ticket should describe that failure, not re-propose shared layout in the abstract.

  3. added
    via-triageFiled through npx t3 triage
    enhancementRequested improvement or new capability.
    wontfixThis will not be worked on
    on Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequested improvement or new capability.via-triageFiled through npx t3 triagewontfixThis will not be worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions