Skip to content

tree: emit TreeEvent on expand/collapse#2454

Open
jayson-saavylab wants to merge 2 commits into
longbridge:mainfrom
SaavyLab:feat/tree-expansion-events
Open

tree: emit TreeEvent on expand/collapse#2454
jayson-saavylab wants to merge 2 commits into
longbridge:mainfrom
SaavyLab:feat/tree-expansion-events

Conversation

@jayson-saavylab

Copy link
Copy Markdown

(No associated issue - small additive enhancement)

Description

Add explicit TreeEvent to TreeState so consumers can react to expand/collapse changes without maintaining a shadow copy of expansion state.

For lazy-loading trees (file browsers, database explorers, remote object browsers), consumers currently need to cx.observe(&tree_state, ...) and diff the entire expansion set after every notify.

With this change, consumers can subscribe directly:

cx.subscribe(&tree_state, |this, _, event: &TreeEvent, cx| {
    if let TreeEvent::Expanded(id) = event {
        this.load_children_for(id.as_ref(), cx);
    }
});

Break Changes

Fully additive. Existing cx.observe(&tree_state, ...) consumers continue to work unchanged.

How to Test

cargo test -p gpui-component tree

Four new tests were added:

  • test_emits_expanded_event - toggling a collapsed folder emits TreeEvent::Expanded(id)
  • test_emits_collapsed_event - toggling an expanded folder emits TreeEvent::Collapsed(id)
  • test_set_items_does_not_emit_expansion_events - rebuilding the tree via set_items() is silent
  • test_event_carries_item_id - event payload is TreeItem.id, not row index

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • [N/A] Tested macOS, Windows and Linux platforms performance (if the change is platform-specific) (not platform specific)

AI Assistance Disclosure

🤖 Parts of this PR were generated with AI assistance and subsequently reviewed, tested, and refactored by a human to match the project's existing code style and patterns. Specifically:

  • The TreeEvent enum and EventEmitter implementation were drafted with AI, then aligned to match the existing TableEvent / SliderEvent patterns in the crate.
  • The test cases were AI-generated and then verified by running the full gpui-component test suite (219 tests pass, including the 4 new ones).

@jayson-saavylab jayson-saavylab marked this pull request as ready for review June 10, 2026 04:28
@madcodelife

madcodelife commented Jun 10, 2026

Copy link
Copy Markdown
Member

Thanks for the PR!

One small detail though: If you use set_selected_item to select a node hidden under collapsed folders, it bypasses toggle_expand so no TreeEvent::Expanded is emitted — a lazy-loading subscriber would never load children for folders expanded this way.

@huacnlee huacnlee changed the title feat(tree): emit TreeEvent on expand/collapse tree: emit TreeEvent on expand/collapse Jun 10, 2026
@jayson-saavylab

Copy link
Copy Markdown
Author

Thanks for the PR!

One small detail though: If you use set_selected_item to select a node hidden under collapsed folders, it bypasses toggle_expand so no TreeEvent::Expanded is emitted — a lazy-loading subscriber would never load children for folders expanded this way.

Hey thanks for the feedback, this should be resolved now! set_selected_item now routes ancestor expansion through the event-emitting path, so hidden folders fire TreeEvent::Expanded when revealed. I also reversed the ancestor iteration so events fire root -> leaf, which is the order a lazy-loading subscriber would like

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