Skip to content

feat(CNavGroup): controlled visibility, onVisibleChange and context-based accordion#459

Merged
mrholek merged 1 commit into
mainfrom
feat/nav-group-controlled-visible
Jun 11, 2026
Merged

feat(CNavGroup): controlled visibility, onVisibleChange and context-based accordion#459
mrholek merged 1 commit into
mainfrom
feat/nav-group-controlled-visible

Conversation

@mrholek

@mrholek mrholek commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

Reworks the sidebar nav group so it works either uncontrolled (the toggler manages its own state) or controlled (the parent owns visible), and replaces the positional idx / recursiveClone coordination with a context-based accordion using stable ids.

What changes

  • onVisibleChange + controlled mode. A group is controlled when visible and onVisibleChange are provided together. The toggler then only requests a change and the group follows the prop, so a rejected collapse keeps it open—no desync. Used on its own, visible still acts as the default-open state and the group stays fully toggleable (backward compatible).
  • Context-based accordion with stable useId chains. Groups no longer rely on CSidebarNav cloning children to inject a positional dotted idx. Each group derives a stable id chain through React context, so coordination works through wrappers, fragments and Children.map, and the duplicated logic in CSidebarNav is gone.
  • Consistent accordion for controlled groups. When another branch opens, a controlled group requests its own close through onVisibleChange (the parent decides—collapse it, or keep it open if it must stay expanded).
  • Robust active-link detection. CNavLink now observes the link's class with a MutationObserver, so client-side navigation reopens the active section. The previous effect missed route changes that didn't change className.
  • Accessibility. The toggler gets aria-expanded.

Notes

  • CNavGroup no longer takes the internal idx prop, and CSidebarNavContext changes shape (both were internal, not part of the public API).
  • The sidebar nav is a one-open-per-level accordion; two sibling groups marked visible resolve to a single open branch.

Docs

Adds a "Controlled navigation group" example to the Sidebar page and refreshes the main sidebar example.

Tests

CNavGroup.spec.tsx covers uncontrolled toggling, controlled reject, accordion close on sibling open (accept vs. locked), nested default-open groups staying independently toggleable, the toggler render function, and active-link auto-open.

…ased accordion

Rework the sidebar nav group so it works either uncontrolled (the toggler manages its
own state) or controlled (the parent owns `visible` via `onVisibleChange`), and replace
the positional `idx`/`recursiveClone` coordination with a context-based accordion.

- Add `onVisibleChange`. A group is controlled when `visible` and `onVisibleChange` are
  provided together; the toggler then only requests a change and the group follows the
  prop, so a rejected collapse keeps it open (no desync). On its own, `visible` still acts
  as the default-open state and the group stays toggleable.
- Coordinate groups through React context with stable `useId` chains instead of cloning
  children to inject positional `idx`. This works through wrappers, fragments and
  `Children.map`, and removes the duplicated logic in CSidebarNav.
- A controlled group now closes when another branch opens by requesting the change through
  `onVisibleChange`, keeping the accordion consistent.
- Detect active nav links with a MutationObserver on the link's class, so client-side
  navigation reopens the active section (the previous effect missed route changes that
  did not change `className`).
- Add `aria-expanded` on the toggler.

Docs: add a "Controlled navigation group" example and refresh the sidebar example.
@mrholek mrholek merged commit 09a80f2 into main Jun 11, 2026
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.

1 participant