facebook / facebook/astryx

[RFC] Progressive disclosure for long nested navigation

Open
#5,910 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
13.2k
Forks
1.1k
Avg merge
1d 14h
Merged PRs (30d)
669

Description

## Problem Statement

Products with nested navigation can accumulate enough child destinations that
expanding one parent makes the side navigation long and difficult to scan. The
common desired interaction is to show an initial window of children, then let
the user reveal more in place without replacing the children already shown.

Astryx `SideNavItem` supports nested children and whole-group collapse, but it
does not provide a progressive middle state. A consumer can slice its children
before rendering, but then it owns a second visibility model alongside the
navigation component: reveal count, selected-item visibility, focus behavior,
hidden-count messaging, and resets when the collection changes.

This RFC is a demand signal and an ownership question, not a request for a
specific prop. Would Astryx be interested in owning progressive disclosure for
long nested navigation collections? If so, should it belong to `SideNavItem`,
to a collection primitive that navigation components can share, or to an
official composition recipe?

## Evidence of Demand

Apache Maka has a public use case in its **By project** navigation. A project
can accumulate many tasks, and expanding it currently renders every task. The
project discussed initially showing five tasks, revealing ten more per
activation, retaining the total-count badge, and automatically revealing the
active task:

- https://github.com/apache/maka/discussions/4357
- https://github.com/apache/maka/discussions/4357#discussioncomment-18222317

That discussion also records an important constraint: the product does not
want to build a second custom navigation implementation beside Astryx just to
obtain this behavior.

The broader interaction appears in products that keep long collections
scannable through cumulative **Show more** controls rather than page
replacement. The exact initial size and reveal step are product decisions; the
reusable need is coordinating partial visibility with selection, navigation,
and accessibility semantics.

## Why Existing Components Don't Cover This

- `SideNavItem` can expose all children or collapse the entire child group. It
has no partial, repeatedly advanced state.
- `TreeList` similarly models node expansion, not an initial child window with
cumulative reveal.
- `OverflowList` measures horizontal space and moves overflowed items out of
the visible list; it is not a vertical, user-advanced collection.
- `Collapsible` is binary whole-section disclosure.
- `MoreMenu` moves hidden destinations into a menu instead of preserving their
place in the navigation hierarchy.
- `Pagination` replaces one page with another instead of accumulating visible
items.

Consumer-side slicing can reproduce the visual result, but every consumer must
then decide how to reveal a selected item outside the current window, preserve
focus when the collection changes, expose the hidden count, and integrate the
control with collapsed and mobile SideNav modes. That repeated behavioral work
is the gap this RFC is asking Astryx to evaluate.

## Rough Approaches Considered

These are ownership directions rather than API proposals:

1. `SideNavItem` owns progressive disclosure for its nested children.
2. A reusable collection-disclosure primitive owns the visible window and can
be composed by `SideNavItem` and potentially other list components.
3. Astryx documents and tests an official composition recipe while leaving the
state in the consumer.

The Maka use case would choose an initial count of five and a reveal step of
ten, but those values should not become universal component defaults without
broader evidence.

## Accessibility Considerations

This is navigation with expandable groups, so the disclosure control must not
silently become another destination. The design should determine and document:

- whether the control is a button and how it relates to the child group;
- how its accessible name communicates the number of hidden items;
- where focus remains after additional items appear;
- how an active or selected child outside the window becomes visible;
- what happens when filtering or collection updates shrink the visible range;
- how SideNav keyboard behavior, collapsed-rail mode, and mobile drawer mode
remain intact.

If this is generalized to `TreeList`, partial DOM collections also need correct
set position and size semantics. For ordinary navigation, the disclosure
pattern should remain the baseline rather than introducing tree-widget keyboard
semantics unnecessarily.

## Performance Considerations

Progressive disclosure bounds the initial number of rendered child rows and
reduces mount and layout work for collections in the tens or hundreds. It is
not virtualization: if the user reveals everything, the DOM still grows to the
full collection. Truly unbounded data would still require windowing or
server-side pagination, which is outside this RFC.

An Astryx-owned behavior should avoid hidden measurement copies of the whole
collection when the caller already provides an explicit item-count window.

If maintainers agree that this belongs in Astryx, I would be happy to help with
the follow-up research, specification work, and implementation after the
component ownership and interaction model are agreed.

## Pre-submission Checklist

- [x] I have read the [Contributing guide](https://github.com/facebook/astryx/wiki/Contributing)
- [x] I have read the [API Conventions](https://github.com/facebook/astryx/wiki/API-Conventions)
- [x] I have checked that existing Astryx components cannot compose to solve this without consumer-owned navigation behavior
- [x] This is a general-purpose UI pattern (not specific to one product)

_Drafted with OpenAI Codex at the contributor's direction and reviewed by the
contributor of record._

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the existing SideNavItem, TreeList, OverflowList, Collapsible, MoreMenu, and Pagination components described in the RFC; no source file or test is named. Done is not yet defined: maintainers first need to agree whether ownership belongs in SideNavItem, a reusable primitive, or a documented composition, along with the interaction and accessibility model.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
accessibility, design, frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.