facebook / facebook/astryx

TreeList: allow customizing the expand/collapse indicator icon (e.g. folder open/closed for file trees)

Open
#4,131 0 comments 0 reactions 0 assignees View on GitHub
component enhancement
Dominant language
TypeScript
Stars
13k
Forks
1.1k
Avg merge
1d 15h
Merged PRs (30d)
690

Description

## Summary

Allow customizing the expand/collapse indicator icon on `TreeList` rows. Today the indicator is hardcoded to a rotating `chevronRight`, so patterns like a **file/folder tree** — where an expandable node should show a closed-folder icon when collapsed and an open-folder icon when expanded — aren't expressible.

## Motivation

- A folder tree is one of the most common TreeList use cases, and the folder-open / folder-closed icon swap is the expected visual language for it.
- More generally, teams want the expand affordance to match their domain (folders, categories, org nodes) rather than a generic chevron.
- `startContent` already lets you put an icon *before the label*, but it doesn't control the **expand/collapse indicator** itself, which is a separate, hardcoded element.

## Current behavior

In `TreeListItem.tsx` the indicator is fixed:

```ts
const chevronIcon = (

{getIcon('chevronRight')}

);
```

There is no prop to override it, and the collapsed/expanded states are expressed only by rotating the same chevron.

## Proposed API

Add a way to supply a custom indicator, ideally state-aware so collapsed vs. expanded can be distinct icons (not just a rotation). A render-prop keeps it flexible and avoids a rotation assumption:

```tsx

hasChildren
? (isExpanded ? : )
:
}
/>
```

Open to a simpler shape if preferred (e.g. `expandIcon` / `collapseIcon` props). Key requirements:

- Distinguish **collapsed vs expanded** icons (folder-closed / folder-open), not just a rotated single icon.
- Optionally distinguish **leaf** nodes (no children) so a folder tree can render a file/leaf icon in the indicator slot.
- Default stays the current chevron — this is opt-in.
- Preserve the existing a11y wiring: the toggle button keeps `aria-expanded`, `aria-label`, roving-tabindex behavior, and `data-tree-toggle` regardless of the icon rendered inside it.

## Notes

- Should the rotation animation be suppressed automatically when a custom state-aware icon is provided (so an open-folder icon isn't also rotated)? Probably yes.
- Per-item override vs. tree-level render prop — a tree-level `renderExpandIcon` covers the folder case cleanly; per-item could come later if needed.

## Environment

- Component: `TreeList` (`@astryxdesign/core`), `packages/core/src/TreeList/TreeListItem.tsx`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.