Skip to content

feat(ui): add Badge interactive states - #1965

Open
MartinS-git wants to merge 9 commits into
mainfrom
interactive-badge
Open

MartinS-git wants to merge 9 commits into
mainfrom
interactive-badge

Conversation

@MartinS-git

@MartinS-git MartinS-git commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds interactive states to the Badge component. Pass onClick to render the badge as a <button>, or href to render it as an <a> element — consistent with the onClick/href pattern used across other Juno components (e.g. SideNavigationItem). Without either prop, Badge renders as a non-interactive <span>.

Changes

  • Badge.component.tsx: Replace interactive prop with onClick/href for element auto-detection. Restore variant fallback handling (?? badgeVariantStyles["default"]) dropped in prior refactoring. Disabled <a> elements: remove href, add aria-disabled and tabIndex=-1. Fix disabled state: remove cursor-not-allowed which was rendered dead by pointer-events-none.
  • Badge.stories.tsx: Replace Interactive* stories with AsButton, AsButtonDisabled, AsLink, and per-variant button stories. Remove dead parameters.text (was a no-op; component props belong in args).
  • Badge.test.tsx: Rewrite describe("Interactive") block to test onClick-triggered <button> rendering and href-triggered <a> rendering. Added tests for disabled anchor behavior. Added missing variant tests for warning, danger, and error.
  • .changeset/badge-interactive-states.md: Minor version bump for @cloudoperators/juno-ui-components.

Why ring-inset instead of border for the active state

Using border caused a 2px layout shift when toggling between interactive and non-interactive (border takes layout space). ring-inset renders as an inset box-shadow — no layout impact, no size change on non-interactive badges.

Test plan

  • Storybook: Badge → AsButton → clicking triggers onClick
  • Storybook: Badge → AsButtonDisabled → button is visually dimmed, not clickable
  • Storybook: Badge → AsLink → renders as anchor with href
  • Storybook: all per-variant button stories render correctly
  • Unit tests pass: pnpm --filter @cloudoperators/juno-ui-components test

edda and others added 2 commits September 15, 2026 15:45
…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>
Copilot AI lite review requested due to automatic review settings September 15, 2026 13:51
@MartinS-git
MartinS-git requested review from a team and franzheidl as code owners September 15, 2026 13:51
@changeset-bot

changeset-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b689f7e

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 Sep 15, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

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

Built to branch gh-pages at 2026-09-17 09:03 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.

🟡 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.

Comment thread .changeset/sidenavigation-on-toggle.md Outdated
Comment thread packages/ui-components/src/components/Badge/Badge.component.tsx Outdated
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>
Comment thread packages/ui-components/src/components/Badge/Badge.component.tsx Outdated
Comment thread packages/ui-components/src/components/Badge/Badge.component.tsx
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>
Comment thread packages/ui-components/src/components/Badge/Badge.component.tsx Outdated
Comment thread packages/ui-components/src/components/Badge/Badge.component.tsx
Comment thread packages/ui-components/src/components/Badge/Badge.component.tsx
Comment thread packages/ui-components/src/components/Badge/Badge.test.tsx
Comment thread packages/ui-components/src/components/Badge/Badge.stories.tsx
…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>

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.

🔵 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>
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.

4 participants