Skip to content

🪢 feat: Collapse Activity Folds From Their Rails - #16637

Merged
danny-avila merged 3 commits into
devfrom
danny-avila/glyph-tool-collapse-ui-d88498
Oct 1, 2026
Merged

danny-avila merged 3 commits into
devfrom
danny-avila/glyph-tool-collapse-ui-d88498

Conversation

@danny-avila

Copy link
Copy Markdown
Collaborator

Summary

An open activity fold (a phase card or a tool group) draws a hairline down the left of its rows, but the line is decoration only: closing a long fold means scrolling back up to its header. This makes the rail a collapse control, the way Reddit's thread lines work.

Bringing the pointer near an open fold's rail lights the line, and the header's glyph turns into a ⊖ knob, so the reader sees which fold will close before clicking. Clicking anywhere in the 24px inset beside the rows collapses that fold. If the header has scrolled out of view, it is brought back first. Nested rails work independently: a tool group's rail sits inside its phase's rows, so hovering it marks and closes only the group.

The header button stays the one control for keyboard and screen-reader users. The rail is a pointer shortcut, hidden from assistive tech and never focused.

How it works

rail.tsx holds the pieces both folds share. The rail lives in the panel and the knob in the header, so they share a tiny external store rather than state on the fold. A hover repaints only the header glyph, not every row under the fold.

ToolCallGroup / ActivityPhaseGroup
├── header  → <RailGlyph hover>{glyph}</RailGlyph>    # ⊖ while the rail is hovered
└── panel   → FOLD_RAIL_CLASSES wrapper ("relative pl-6")
    └── <FoldRail hover onCollapse={handleRailCollapse}/>  # absolute, w-6, hairline at 11px
  • FOLD_RAIL_CLASSES drops its before: pseudo-element hairline; FoldRail draws the same line (same position, border-medium, text-secondary on hover) inside a hit area that fills the inset.
  • handleRailCollapse does nothing once the fold is closed: the rail stays drawn while the panel animates shut, so a second click must not reopen it.
  • revealFoldHeader scrolls the card to its start when its header is pinned (sticky phase header), otherwise brings the header just into view.
  • The failed-row stripe sits over the rail's hit area, so it gets before:pointer-events-none.

Type of change

  • Feature

Testing

Mock e2e lane (activity-fold.spec.ts, Chromium, memory Mongo). On the failed-reply scenario, the test hovers the group rail and the phase rail and checks that exactly one knob shows, in the hovered fold's header, and that the line colour changes. Clicking the group rail closes only the group; clicking the phase rail closes the phase.

Tested environments/configuration:

  • Browser: Chromium (Playwright), light theme
  • Provider/model: mock endpoint Mock Provider F

Automated tests:

  • Added __tests__/rail.test.tsx (header reveal, knob dropped on unmount under the pointer)
  • Rail hover/collapse cases in ToolCallGroup.test.tsx and ActivityPhaseGroup.test.tsx; each fails with its guard removed
  • Extended e2e/specs/mock/activity-fold.spec.ts
  • Content suites run: rail, ToolCallGroup, ActivityPhaseGroup, ProgressText, LiveParity, ContentParts.integration (336 passed)

Hovering an open fold's rail lights the line and swaps the header's glyph for a collapse knob; clicking the rail collapses that fold and brings its header back into view.
Copilot AI balanced review requested due to automatic review settings October 1, 2026 19:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Collapsed retained panels can preserve stale hover state, nested headers can remain obscured, and multi-icon headers shift on hover.

Review effort: Balanced
Findings: 3 Medium severity

Open (3)
What changed in this PR

Adds pointer-accessible rails for collapsing activity phases and tool groups.

Changes:

  • Introduces shared rail hover, glyph, collapse, and header-reveal behavior.
  • Integrates rails into nested activity folds and preserves failed-row interactions.
  • Adds unit and end-to-end coverage.
File Description
e2e/​specs/​mock/​activity-fold.spec.ts Tests nested rail hover and collapse behavior.
client/​src/​components/​Chat/​Messages/​Content/​ToolCallGroup.tsx Adds tool-group rail controls.
client/​src/​components/​Chat/​Messages/​Content/​rows.ts Moves rail rendering out of shared CSS.
client/​src/​components/​Chat/​Messages/​Content/​rail.tsx Implements shared rail behavior.
client/​src/​components/​Chat/​Messages/​Content/​ProgressText.tsx Allows rail interaction through failure stripes.
client/​src/​components/​Chat/​Messages/​Content/​ActivityPhaseGroup.tsx Adds phase rail controls.
client/​src/​components/​Chat/​Messages/​Content/​__tests__/​ToolCallGroup.test.tsx Covers tool-group rail collapse.
client/​src/​components/​Chat/​Messages/​Content/​__tests__/​rail.test.tsx Tests shared rail lifecycle and scrolling.
client/​src/​components/​Chat/​Messages/​Content/​__tests__/​ActivityPhaseGroup.test.tsx Covers phase rail collapse.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread client/src/components/Chat/Messages/Content/rail.tsx Outdated
Comment thread client/src/components/Chat/Messages/Content/rail.tsx Outdated
Comment thread client/src/components/Chat/Messages/Content/rail.tsx Outdated
@codegraph-librechat codegraph-librechat Bot added the 🗺️ Chat UI Shell codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) label Oct 1, 2026
@lia-by-librechat

Copy link
Copy Markdown
Contributor

Review head: a8c1694. Preserves glyph layout during rail hover, clears hover for retained collapsed bodies and closed parent phases, and reveals nested group headers below the sticky phase header. Includes unit and browser regressions.

@lia-by-librechat

Copy link
Copy Markdown
Contributor

Review head: 9deef1d. Adds the host message’s existing toolbar scroll inset to phase and nested-group header reveals. Browser regressions now retain space below the fold and verify both revealed headers are pointer-accessible. Prior glyph-layout and retained-hover fixes remain included.

@danny-avila
danny-avila marked this pull request as ready for review October 1, 2026 20:33
@codegraph-librechat codegraph-librechat Bot added the 🗺️ Agent Chat UI codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) label Oct 1, 2026
@danny-avila
danny-avila merged commit e689243 into dev Oct 1, 2026
30 checks passed
@danny-avila
danny-avila deleted the danny-avila/glyph-tool-collapse-ui-d88498 branch October 1, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗺️ Agent Chat UI codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ Chat UI Shell codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants