Skip to content

Improve class-tree expand feedback and animation - #531

Open
matthewhorridge wants to merge 1 commit into
ncbo:masterfrom
matthewhorridge:improve-class-tree-expand-feedback
Open

Improve class-tree expand feedback and animation#531
matthewhorridge wants to merge 1 commit into
ncbo:masterfrom
matthewhorridge:improve-class-tree-expand-feedback

Conversation

@matthewhorridge

Copy link
Copy Markdown

Improve class-tree expand feedback and animation

Expanding a node in the Classes-tab hierarchy is a server round-trip that can
take a second or more. During that time the UI gave no feedback on the clicked
node (the chevron only flipped once the response arrived), and the loading
placeholder was a centred, padded block that opened a large gap and pushed the
sibling nodes down. This makes expansion feel clunky and unresponsive.

This is a front-end change only — the underlying fetch latency is unchanged.

Changes

Optimistic expand feedback.

  • On clicking a collapsed node's chevron, the simple-tree controller adds
    .tree-expanding to the <li>, which rotates and pulses the chevron
    immediately instead of only flipping once the response lands, and shows a
    compact loading cue.
  • The class is cleared when the children list is actually inserted, watched via
    a MutationObserver — children arrive by Turbo Stream, which emits no
    turbo:frame-load on the target frame, so a frame-event hook wouldn't fire.
  • An 8s timeout backstop guarantees the class can never persist (and the chevron
    can't pulse forever) if children never arrive — e.g. a leaf-like node, a
    request error, or a click that triggers no load.

Compact loading indicator.

  • The per-node loading block was my-auto mx-auto p-3 — centred and padded — so
    it opened a large gap and shoved siblings down while loading. It now renders as
    a small, indent-aligned inline cue under the node label, so nothing jumps.

Slide-in animation.

  • Arriving children slide in briefly so an expanded subtree feels continuous
    rather than popping into place. A prefers-reduced-motion query disables the
    transitions and animations.

Not included

  • The ~1–3s per-node fetch latency itself is a backend concern (child-fetch
    speed / caching) and is out of scope here; these changes make the wait feel
    responsive rather than making it shorter.

Files

  • app/javascript/controllers/simple_tree_controller.js — optimistic feedback +
    observer-based clearing + timeout backstop.
  • app/assets/stylesheets/tree.scss — chevron transition/flip, compact loader,
    slide-in, reduced-motion guard.

Testing

Verified on the BCIO Classes tree against a live backend: clicking a chevron
immediately rotates/pulses it and shows the compact loader; the state clears the
moment children are inserted; re-collapsing/expanding an already-loaded subtree
is unaffected (instant toggle path).

Expanding a node in the Classes-tab hierarchy is a server round-trip that
can take a second or more, during which the UI gave no feedback on the
clicked node and the loading placeholder shoved siblings around. Three
front-end improvements (the underlying fetch latency is unchanged):

- Optimistic expand feedback: on clicking a collapsed node's chevron, the
  simple-tree controller adds `.tree-expanding` to the <li>, which rotates
  and pulses the chevron immediately (instead of only flipping once the
  response lands) and shows a compact loading cue. The class is cleared
  when the children list is inserted (watched via MutationObserver, since
  children arrive by Turbo Stream and emit no turbo:frame-load), with an
  8s timeout backstop so a node can never pulse forever if children never
  arrive (leaf-like node / error / click that triggers no load).
- Compact, indent-aligned loading indicator: the per-node "loading" block
  was centre-aligned and padded, opening a large gap that pushed sibling
  nodes down. It now renders as a small inline cue under the label.
- Slide-in animation for arriving children, so an expanded subtree feels
  continuous rather than popping in. A prefers-reduced-motion query
  disables the transitions/animations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jvendetti jvendetti self-assigned this Jul 25, 2026
@jvendetti

Copy link
Copy Markdown
Member

@matthewhorridge thanks for the PR - I tested locally and the new behavior looks really nice!

One small comment - Claude's review pointed out that the slide-in animation never fires:

The slide-in animation selector appears to never match — likely dead CSS.
tree.scss:57 animates .simpleTree turbo-frame[id$="_childs"] > ul, but no frame with an _childs id ever directly contains a <ul>

Worth fixing, or just dropping that bullet from the description?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants