Skip to content

feat(ui): add onToggle callback to SideNavigationGroup and SideNavigationItem#1803

Open
edda wants to merge 4 commits into
mainfrom
edda/sidenavigation-on-toggle
Open

feat(ui): add onToggle callback to SideNavigationGroup and SideNavigationItem#1803
edda wants to merge 4 commits into
mainfrom
edda/sidenavigation-on-toggle

Conversation

@edda

@edda edda commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds onToggle?: (isOpen: boolean) => void to SideNavigationGroup and SideNavigationItem. The callback fires whenever the user clicks the toggle affordance, with the next open state.
  • For SideNavigationGroup the whole row is the toggle, so onToggle fires on any click of the group. For SideNavigationItem only the chevron is the toggle — the label keeps its existing onClick/href navigation behavior unchanged.
  • The existing open prop semantics are preserved: it still seeds the initial state and re-syncs the internal state when the parent re-renders with a new value. No breaking changes — consumers that don't pass onToggle see identical behavior to today.

This is the same soft-control pattern already used by Panel and Modal in this library and lets parents implement use cases like "auto-open the group containing the active route while preserving any groups the user has manually closed" (the Aurora Dashboard use case from the issue).

Closes #1799.

Test plan

  • pnpm vitest run in packages/ui-components for SideNavigation* suites — 47/47 passing, including 13 new tests:
    • Group: onToggle fires with true/false, internal state still toggles without callback, open prop re-sync still works.
    • Item: onToggle fires from the chevron with the next state; label clicks do not fire onToggle (only onClick); disabled items don't fire onToggle; internal state still toggles without callback; open prop re-sync still works.
  • pnpm --filter @cloudoperators/juno-ui-components typecheck clean.
  • pnpm --filter @cloudoperators/juno-ui-components lint clean.
  • Storybook stories added: Controlled example for both components demonstrating the parent-owned-state pattern. Verify visually in Storybook.
  • Reviewer to verify the new Controlled stories in Storybook behave as expected.

Notes

  • The component-level interface SideNavigationItemProps now uses Omit<HTMLAttributes<HTMLElement>, "onToggle"> to avoid colliding with the DOM ToggleEvent handler type on HTMLAttributes. Our onToggle(isOpen: boolean) is a domain-level callback, not a DOM event handler.
  • Includes a changeset entry (minor).

…tionItem

Adds an `onToggle(isOpen)` callback to both components that fires whenever
the user expands or collapses the section. Lets parents observe (and
optionally drive) the open state without changing the existing `open` prop
behavior. Closes #1799.

Signed-off-by: Esther Schmitz <esther.schmitz@sap.com>
Copilot AI review requested due to automatic review settings June 29, 2026 18:48
@edda edda requested review from a team and franzheidl as code owners June 29, 2026 18:48
@changeset-bot

changeset-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4694f3f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@cloudoperators/juno-ui-components Minor
@cloudoperators/juno-app-carbon Patch
@cloudoperators/juno-app-doop Patch
@cloudoperators/juno-app-example Patch
@cloudoperators/juno-app-greenhouse Patch
@cloudoperators/juno-app-heureka Patch
@cloudoperators/juno-app-supernova Patch
@cloudoperators/juno-app-template Patch
@cloudoperators/juno-messages-provider Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

🚀 View preview at
https://cloudoperators.github.io/juno/pr-preview/pr-1803/

Built to branch gh-pages at 2026-06-29 19:38 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an onToggle(isOpen: boolean) callback to SideNavigationGroup and SideNavigationItem to let consumers observe (and optionally drive) expand/collapse behavior while preserving the existing “internal state seeded by open and re-synced on prop changes” semantics.

Changes:

  • Added onToggle?: (isOpen: boolean) => void to SideNavigationGroup and SideNavigationItem and call it with the next open state on user toggles.
  • Added Vitest coverage for onToggle, disabled behavior, and open re-sync behavior.
  • Added Storybook “Controlled” examples demonstrating parent-owned open state.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/ui-components/src/components/SideNavigationItem/SideNavigationItem.component.tsx Adds onToggle prop and triggers it from the chevron toggle handler; updates prop typings.
packages/ui-components/src/components/SideNavigationGroup/SideNavigationGroup.component.tsx Adds onToggle prop and triggers it from the group row click handler; updates prop typings.
packages/ui-components/src/components/SideNavigationItem/SideNavigationItem.test.tsx Adds tests for item onToggle, label-vs-chevron behavior, disabled behavior, and open re-sync.
packages/ui-components/src/components/SideNavigationGroup/SideNavigationGroup.test.tsx Adds tests for group onToggle, internal toggling without callback, and open re-sync.
packages/ui-components/src/components/SideNavigationItem/SideNavigationItem.stories.tsx Adds “Controlled” story demonstrating parent-managed open via onToggle.
packages/ui-components/src/components/SideNavigationGroup/SideNavigationGroup.stories.tsx Adds “Controlled” story demonstrating parent-managed open via onToggle.
.changeset/sidenavigation-on-toggle.md Adds a minor changeset documenting the new callback behavior.

edda added 3 commits June 29, 2026 20:58
Clarify the `open` JSDoc on both components so it reflects the
seed-and-resync semantics rather than implying strict React control,
and query the label button in the SideNavigationItem onToggle test by
accessible name instead of position to make the test robust to DOM
changes.

Signed-off-by: Esther Schmitz <esther.schmitz@sap.com>
… stories

Storybook v8/v9 dropped the implicit `on*` action inference, so handlers
were no longer being logged in the Actions panel for these stories. Add
explicit `fn()` spies as default args for `onToggle` (and `onClick` on
the Item story) so the Actions panel reflects user interactions, while
the Controlled stories keep their real state-based handlers.

Signed-off-by: Esther Schmitz <esther.schmitz@sap.com>
…n items

Wrap nested onToggle handlers with `action("onToggle")` so the Actions
panel logs toggle events for nested items/groups. The Storybook `fn()`
spy only auto-routes to the panel when bound via `args`; inline JSX
props need the explicit `action()` helper.

Signed-off-by: Esther Schmitz <esther.schmitz@sap.com>
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.

[Feature](ui): Make SideNavigationGroup a Controlled Component

2 participants