Skip to content

Conversation

yihuiliao
Copy link
Member

Closes

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

🧢 Your Project:

@rspbot
Copy link

rspbot commented Oct 10, 2025

@rspbot
Copy link

rspbot commented Oct 10, 2025

@rspbot
Copy link

rspbot commented Oct 10, 2025

@rspbot
Copy link

rspbot commented Oct 10, 2025

if (parent) {
// siblings must exist because our original node exists
let siblings = state.collection.getChildren?.(parent.key)!;
let siblings = getDirectChildren(parent as CollectionNode<T>, state.collection as Collection<CollectionNode<T>>);
Copy link
Member Author

Choose a reason for hiding this comment

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

we used to use the getChildren method from TreeCollection but now that we've changed it to get ALL the descendants of a parent node instead of its immediate descendants, we can't use that anymore. i decided to make a new function called getDirectChildren which is essentially the same code as what getChildren was before

let {flattenedRows, keyMap, itemCount} = flattenTree<T>(collection, {expandedKeys});
this.flattenedRows = flattenedRows;
let {collection, lastExpandedKeys, expandedKeys} = opts;
let {keyMap, itemCount} = flattenTree<T>(collection, {expandedKeys});
Copy link
Member Author

Choose a reason for hiding this comment

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

i've removed flattenedRows from TreeCollection since we've moved away from the flattened structure but i didn't feel entirely comfortable removing flattenTree entirely since we use it to build the keyMap and modify the nodes (like the levels and index). but if we do wanna rework it, im happy to do it in a follow-up unless we'd like the changes in this PR

return this.keyMap.get(key) || null;
}

at(idx: number) {
Copy link
Member Author

Choose a reason for hiding this comment

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

obviously, this was a lot easier when we had flattenedRows because we could just index it but now we don't have a nice array to index. getKeyAfter will get the next visible row from the top and we just iterate however many times idx is

if you're wondering why we don't just use getKeyAfter that's already built into TreeCollection...continue reading...

let [expandedKeys, setExpandedKeys] = useControlledState(
propExpandedKeys ? convertExpanded(propExpandedKeys) : undefined,
propDefaultExpandedKeys ? convertExpanded(propDefaultExpandedKeys) : new Set(),
propExpandedKeys ? new Set(propExpandedKeys) : undefined,
Copy link
Member Author

Choose a reason for hiding this comment

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

ended up getting rid of convertExpanded because i was running into a type error where expandedKeys could either be a Set or string but since propExpandedKeys/propDefaultExpandedKeys are type Iterable<Key> and cannot be set to all, there wasn't any way expandedKeys would ever be a string

}

if ((this.expandedKeys.has(node.key) || node.type !== 'item') && node.firstChildKey != null) {
return node.firstChildKey;
Copy link
Member Author

Choose a reason for hiding this comment

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

should getKeyAfter include content nodes or should it skip them?

in this case, if the node is included in expandedKeys, we'll look at its firstChildKey which will be a TreeItemContent node. however, this caused issues in DropTargetKeyboardNavigation so we check if the node is a content node and if it is, we check its nextKey. however, we could deal with that here but depends on what we want to do

@yihuiliao yihuiliao changed the title wip: tree section feat: add support for tree sections Oct 10, 2025
@yihuiliao yihuiliao marked this pull request as ready for review October 10, 2025 23:20
@rspbot
Copy link

rspbot commented Oct 10, 2025

@rspbot
Copy link

rspbot commented Oct 10, 2025

## API Changes

react-aria-components

/react-aria-components:GridListSectionProps

-GridListSectionProps <T> {
-  aria-label?: string
-  children?: ReactNode | (T) => ReactElement
-  className?: string = 'react-aria-GridListSection'
-  dependencies?: ReadonlyArray<any>
-  id?: Key
-  items?: Iterable<T>
-  style?: CSSProperties
-  value?: T
-}

/react-aria-components:TreeHeader

+TreeHeader {
+  UNTYPED
+}

/react-aria-components:TreeSection

+TreeSection <T extends {}> {
+  aria-label?: string
+  children?: ReactNode | ({}) => ReactElement
+  className?: string
+  dependencies?: ReadonlyArray<any>
+  id?: Key
+  items?: Iterable<{}>
+  style?: CSSProperties
+  value?: {}
+}

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