feat(ui): add Badge interactive states - #1965
MartinS-git wants to merge 9 commits into
Conversation
…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> Signed-off-by: MartinS-git <info@eyepic.de>
Set `interactive` to render the badge as a `<button>` with hover, focus, active, and disabled states. Active state uses `ring-inset` (box-shadow) instead of `border` to avoid layout shift when toggling between interactive and non-interactive. Use `disabled` to disable the button. Signed-off-by: MartinS-git <info@eyepic.de>
🦋 Changeset detectedLatest commit: b689f7e The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
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 |
|
There was a problem hiding this comment.
🟡 Changes recommended
Remove the unrelated changeset and restore variant fallback handling.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds opt-in interactive button behavior, disabled states, styling, stories, and tests to the Badge component.
Changes:
- Added interactive/disabled Badge behavior and state styling.
- Added interactive stories and unit tests.
- Added a Badge changeset and an unrelated SideNavigation changeset.
File summaries
| File | Summary |
|---|---|
packages/ui-components/src/components/Badge/Badge.test.tsx |
Tests rendering, disabled behavior, and click handling. |
packages/ui-components/src/components/Badge/Badge.stories.tsx |
Adds interactive state stories. |
packages/ui-components/src/components/Badge/Badge.component.tsx |
Implements interactive Badge behavior. Moderate issue (2 votes): preserve fallback handling for unknown variants. |
.changeset/sidenavigation-on-toggle.md |
Unrelated SideNavigation release note. Moderate issue (3 votes): remove it or include the corresponding implementation. |
.changeset/badge-interactive-states.md |
Documents the Badge minor release. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The sidenavigation-on-toggle changeset was pulled in via rebase from aprevious session. The SideNavigation code is already on main; the changeset file does not belong in this Badge PR. Signed-off-by: Martin Schulze <info@eyepic.de>
Remove the boolean interactive prop. Badge now auto-detects its element type: onClick renders a button, href renders an anchor, neither a span. Restore variant fallback handling dropped in prior refactoring. Disabled anchors lose href, gain aria-disabled and tabIndex=-1. Update stories and tests accordingly. Signed-off-by: MartinS-git <info@eyepic.de>
…e on <a> Move shared active tokens (ring-1, ring-inset, text-theme-highest) from badgeActiveVariantStyles into badgeInteractiveBaseStyles. Each variant entry now only holds its specific ring color. Replace jn:disabled:* pseudo-class tokens (which don't work on <a>) with an explicit conditional applied to both button and anchor branches. Add tabIndex=-1 assertion to disabled anchor test and AsLinkDisabled story. Signed-off-by: MartinS-git <info@eyepic.de>
- extract VALID_ICON_NAMES as module-level constant to avoid Set rebuild on every render - use children ?? text instead of || to correctly handle falsy children values - remove dead ?? fallbacks in class string (variant keys are always present) Signed-off-by: MartinS-git <info@eyepic.de>
… missing Badge variant tests Signed-off-by: MartinS-git <info@eyepic.de>
There was a problem hiding this comment.
🔵 Needs a closer look
Restore variant fallbacks in Badge.component.tsx to prevent missing styles for unexpected runtime values.
Review details
Suppressed comments (1)
packages/ui-components/src/components/Badge/Badge.component.tsx:142
- The variant fallback is still missing here (and on the next line): runtime values outside the TypeScript union now interpolate as
undefined, so the badge loses its default background and interactive active styling. This was the behavior regression called out previously; preserve the old fallback for both style maps.
${badgeVariantStyles[variant]}
${isInteractive ? `${badgeInteractiveBaseStyles} ${badgeActiveVariantStyles[variant]}` : ""}
- Files reviewed: 4/4 changed files
- Comments generated: 0 new
- Review effort level: Lite
…iveVariantStyles Signed-off-by: MartinS-git <info@eyepic.de>
Signed-off-by: MartinS-git <info@eyepic.de>
Summary
Adds interactive states to the
Badgecomponent. PassonClickto render the badge as a<button>, orhrefto render it as an<a>element — consistent with theonClick/hrefpattern used across other Juno components (e.g.SideNavigationItem). Without either prop, Badge renders as a non-interactive<span>.Changes
Badge.component.tsx: Replaceinteractiveprop withonClick/hreffor element auto-detection. Restore variant fallback handling (?? badgeVariantStyles["default"]) dropped in prior refactoring. Disabled<a>elements: removehref, addaria-disabledandtabIndex=-1. Fix disabled state: removecursor-not-allowedwhich was rendered dead bypointer-events-none.Badge.stories.tsx: ReplaceInteractive*stories withAsButton,AsButtonDisabled,AsLink, and per-variant button stories. Remove deadparameters.text(was a no-op; component props belong inargs).Badge.test.tsx: Rewritedescribe("Interactive")block to testonClick-triggered<button>rendering andhref-triggered<a>rendering. Added tests for disabled anchor behavior. Added missing variant tests forwarning,danger, anderror..changeset/badge-interactive-states.md: Minor version bump for@cloudoperators/juno-ui-components.Why
ring-insetinstead ofborderfor the active stateUsing
bordercaused a 2px layout shift when toggling between interactive and non-interactive (border takes layout space).ring-insetrenders as an insetbox-shadow— no layout impact, no size change on non-interactive badges.Test plan
pnpm --filter @cloudoperators/juno-ui-components test