Skip to content

feat(badge): add badge component IX-3943 - #2645

Open
alexkaduk wants to merge 13 commits into
mainfrom
feature/IX-3943-badge
Open

feat(badge): add badge component IX-3943#2645
alexkaduk wants to merge 13 commits into
mainfrom
feature/IX-3943-badge

Conversation

@alexkaduk

@alexkaduk alexkaduk commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

💡 What is the current behavior?

  • Siemens IX has no dedicated ix-badge component for count, label, dot, or status-icon indicators on anchors or as standalone badges.

Part of EIX-64

🆕 What is the new behavior?

  • Adds ix-badge (@since 5.2.0) with anatomies counter, label, dot, and status-icon.
  • Supports semantic variant values (shared with chip), outline, optional border, position (top-after | bottom-after), offset-x / offset-y, custom background / badge-color, label icon props, and optional enable-animation attention pulse.
  • Attached mode: default slot wraps an anchor; text-bearing badges expose an accessible description via aria-describedby on the anchor (dot / decorative status remain silent).
  • Standalone mode: author ARIA on the host (e.g. aria-label + naming role for nameless types).
  • Framework wrappers generated for React, Angular, and Vue; preview examples and routes in HTML / React / Vue / Angular test apps.
  • Storybook stories (counter, label, dot, status-icon) plus a11y stories; core unit + component tests; visual regression fixtures; framework aria/axe smoke coverage.

🏁 Checklist

A pull request can only be merged if all of these conditions are met (where applicable):

  • 🦮 Accessibility (a11y) features were implemented
  • 🗺️ Internationalization (i18n) - no hard coded strings
  • 📲 Responsiveness - components handle viewport changes and content overflow gracefully
  • 📕 Add or update a Storybook story
  • 📄 Documentation was reviewed/updated siemens/ix-docsuser-facing pages live in ix-docs; sync/regenerate API MDX after merge as usual
  • 🧪 Unit tests were added/updated and pass (pnpm test)
  • 📸 Visual regression tests were added/updated and pass (Guide)
  • 🧐 Static code analysis passes (pnpm lint)
  • 🏗️ Successful compilation (pnpm build, changes pushed)

👨‍💻 Help & support

  • Remaining Sonar “named arrow function” findings on React preview export default () => match repo convention — mark Won’t Fix if still reported.

Summary by CodeRabbit

  • New Features

    • Introduced the new ix-badge component (counter, label, dot, status-icon) with semantic variants, custom colors, outline/border, position + offset, and optional pulse animation.
    • Added standalone tooltip support and improved accessibility behavior for both standalone and attached (anchor) usage, including described-by handling.
    • Enabled framework integrations and typings so ix-badge is available across Angular, React, Vue, and related preview environments.
  • Documentation

    • Added badge preview pages and Storybook examples for styling, placement/offset, animation, and accessibility.
  • Tests

    • Added comprehensive component tests, accessibility/a11y snapshots, axe coverage, and visual regression tests for badge types.

@changeset-bot

changeset-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b6706dd

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

This PR includes changesets to release 5 packages
Name Type
@siemens/ix Minor
@siemens/ix-angular Minor
@siemens/ix-react Minor
@siemens/ix-vue Minor
@siemens/ix-docs Minor

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

@netlify

netlify Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploy Preview for ix-storybook ready!

Name Link
🔨 Latest commit b6706dd
🔍 Latest deploy log https://app.netlify.com/projects/ix-storybook/deploys/6a6b6ed118c90f0008bae75d
😎 Deploy Preview https://deploy-preview-2645--ix-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces the ix-badge web component with counter, label, dot, and status-icon modes, including styling, accessibility, tooltips, animation, framework bindings, previews, Storybook documentation, and automated tests.

Changes

Badge component

Layer / File(s) Summary
Core contract and implementation
packages/core/src/components/badge/*, packages/core/src/components.d.ts, packages/angular/src/*, .changeset/*
Adds badge types, formatting, rendering, attachment behavior, accessibility handling, tooltips, variants, offsets, custom colors, status icons, and animation.
Framework previews and routes
packages/angular-test-app/..., packages/angular-standalone-test-app/..., packages/html-test-app/..., packages/react-test-app/..., packages/vue-test-app/...
Adds badge preview components, routes, styles, and examples across Angular, HTML, React, and Vue applications.
Storybook documentation
packages/storybook-docs/src/stories/badge/*, packages/storybook-docs/.storybook/*
Registers the custom element and adds shared helpers, accessibility stories, and counter, dot, label, and status-icon showcases.
Regression and visual validation
packages/core/src/components/badge/test/*, testing/framework-tests/*, testing/visual-testing/tests/badge/*, AGENTS.md
Adds unit, component, accessibility snapshot, visual regression, and testing-guidance updates.

Estimated code review effort: 5 (Critical) | ~120 minutes

Suggested reviewers: nuke-ellington, danielleroux

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: introducing the new badge component.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/IX-3943-badge

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new ix-badge component integrated across Angular, React, Vue, and Core packages, along with preview examples. The review feedback highlights several critical improvements: resolving an accessibility issue where aria-describedby cannot cross the shadow boundary, ensuring proper mixin initialization by calling super.componentWillLoad(), safely handling DOM reconnection, preventing runtime crashes when a numeric label is passed, optimizing performance by syncing anchor descriptions in componentDidLoad instead of on every render, and adding required @since JSDoc tags to comply with the repository style guide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/core/src/components/badge/badge.tsx
Comment thread packages/core/src/components/badge/badge.tsx Outdated
Comment thread packages/core/src/components/badge/badge.tsx
Comment thread packages/core/src/components/badge/badge.tsx
Comment thread packages/core/src/components/badge/badge.utils.ts Outdated
Comment thread packages/core/src/components/badge/badge.tsx
Comment thread packages/core/src/components/badge/badge.tsx
@alexkaduk alexkaduk changed the title fix(badge): add badge component IX-3943 feat(badge): add badge component IX-3943 Jul 15, 2026
@alexkaduk

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces the new ix-badge component across the core library and its Angular, React, and Vue wrappers, providing overlay counts, status indicators, and standalone badges with semantic variants, outline mode, and attention animations. The review feedback highlights three important issues: an accessibility bug where the description element inside the shadow DOM cannot be referenced by light DOM anchors via aria-describedby, a lifecycle issue where re-attaching the component to the DOM leaves anchors without their descriptions, and a performance concern regarding layout thrashing from redundant DOM writes during render cycles.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/core/src/components/badge/badge.tsx
Comment thread packages/core/src/components/badge/badge.tsx Outdated
Comment thread packages/core/src/components/badge/badge.tsx
@alexkaduk
alexkaduk force-pushed the feature/IX-3943-badge branch 3 times, most recently from 088a8ee to 8251bb3 Compare July 24, 2026 06:43
@alexkaduk
alexkaduk force-pushed the feature/IX-3943-badge branch from 3e54252 to e8d4d0f Compare July 24, 2026 07:01
@alexkaduk
alexkaduk marked this pull request as ready for review July 24, 2026 07:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/components/badge/badge.scss`:
- Around line 292-303: Update the visually hidden .description styles in the
slotted badge description rule to use the modern clip-path: inset(50%) pattern
instead of the deprecated clip property, while preserving the existing
screen-reader-only behavior and other accessibility styles.

In `@packages/core/src/components/badge/badge.status-icon.ts`:
- Around line 86-90: Update isBadgeStatusIconVariant to validate only own keys
of BADGE_STATUS_ICON_BY_VARIANT rather than inherited properties, ensuring
non-state names such as value are rejected and callers fall back to info.

In `@packages/core/src/components/badge/badge.utils.ts`:
- Around line 22-25: Define a shared BadgeLabelInput type alias for string |
number | null, then replace the repeated label parameter unions in
formatBadgeLabel, coerceLabelText, formatTextLabel, and formatCounterLabel with
that alias.
- Around line 55-77: Update formatCounterLabel to reject negative numeric labels
before returning the normalized value; preserve the existing OVERFLOW_LABEL
handling and upper-threshold clamping, while ensuring counter labels produce
only non-negative counts or the existing null/overflow results.

In `@packages/core/src/components/badge/test/badge.ct.ts`:
- Around line 575-610: Move the expectVisibleTooltipText helper from inside the
describe callback to module scope, alongside the existing html constant.
Preserve its tooltip visibility assertion, shadow-root slotted-text extraction,
range measurements, and metric validations unchanged; update only its placement
so it no longer creates a nested closure.

In `@packages/react-test-app/src/preview-examples/badge-counter.tsx`:
- Around line 18-167: Give the preview component a descriptive name by replacing
the anonymous default-exported function with a named component, such as
BadgeCounter, while preserving its existing JSX and default-export behavior.

In `@packages/react-test-app/src/preview-examples/badge-dot.tsx`:
- Line 18: Replace the anonymous default-exported component in
packages/react-test-app/src/preview-examples/badge-dot.tsx:18-18 with a named
BadgeDot component while preserving its default export. Apply the same change to
packages/react-test-app/src/preview-examples/badge.tsx:15-15 using the name
Badge; no other behavior should change.

In `@packages/react-test-app/src/preview-examples/badge-label.tsx`:
- Line 19: Replace the anonymous default preview component with a named
BadgeLabel function in
packages/react-test-app/src/preview-examples/badge-label.tsx at lines 19-19, and
make the corresponding default preview component a named BadgeStatusIcon
function in packages/react-test-app/src/preview-examples/badge-status-icon.tsx
at lines 14-14; preserve each component’s existing behavior and default export.

In `@packages/storybook-docs/src/stories/badge/counter.stories.ts`:
- Around line 420-424: The badge story metadata uses duplicate CSF titles;
update the `meta` objects in
packages/storybook-docs/src/stories/badge/counter.stories.ts (lines 420-424),
packages/storybook-docs/src/stories/badge/dot.stories.ts (lines 227-231),
packages/storybook-docs/src/stories/badge/label.stories.ts (lines 279-283), and
packages/storybook-docs/src/stories/badge/status-icon.stories.ts (lines 237-241)
to use unique titles `Example/Badge/Counter`, `Example/Badge/Dot`,
`Example/Badge/Label`, and `Example/Badge/Status icon` respectively, while
preserving the shared `showcaseParameters` configuration.

In `@testing/visual-testing/tests/badge/badge.page.ts`:
- Around line 47-50: Update waitForReady() to wait until the complete ix-badge
locator is hydrated and visible before returning, rather than only awaiting the
first badge. Preserve the existing non-empty badge assertion and ensure
expectSnapshot() cannot run while later badges remain unhydrated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3e02ed4c-3b40-45b6-bd25-60a35ad59dea

📥 Commits

Reviewing files that changed from the base of the PR and between 70e1c5c and e8d4d0f.

⛔ Files ignored due to path filters (26)
  • packages/angular/standalone/src/components.ts is excluded by !packages/angular/standalone/src/components.ts
  • packages/react/src/components/components.server.ts is excluded by !packages/react/src/components/**
  • packages/react/src/components/components.ts is excluded by !packages/react/src/components/**
  • packages/vue/src/components/components.ts is excluded by !packages/vue/src/components/**
  • packages/vue/src/components/ix-badge.ts is excluded by !packages/vue/src/components/**
  • testing/framework-tests/tests/generated/axe.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-axe.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-counter-axe.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-counter.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-dot-axe.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-dot.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-label-axe.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-label.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-status-icon-axe.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge-status-icon.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/badge.spec.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/index.ts is excluded by !**/generated/**
  • testing/framework-tests/tests/generated/test-ids.autogenerated.ts is excluded by !**/generated/**
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-counter-1-chromium---classic-dark-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-counter-1-chromium---classic-light-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-dot-1-chromium---classic-dark-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-dot-1-chromium---classic-light-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-label-1-chromium---classic-dark-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-label-1-chromium---classic-light-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-status-icon-1-chromium---classic-dark-linux.png is excluded by !**/*.png
  • testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-status-icon-1-chromium---classic-light-linux.png is excluded by !**/*.png
📒 Files selected for processing (94)
  • .changeset/ix-3943-badge.md
  • packages/angular-standalone-test-app/src/app/app.routes.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-counter.css
  • packages/angular-standalone-test-app/src/preview-examples/badge-counter.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-dot.css
  • packages/angular-standalone-test-app/src/preview-examples/badge-dot.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-label.css
  • packages/angular-standalone-test-app/src/preview-examples/badge-label.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-status-icon.css
  • packages/angular-standalone-test-app/src/preview-examples/badge-status-icon.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge.css
  • packages/angular-standalone-test-app/src/preview-examples/badge.ts
  • packages/angular-test-app/src/app/app-routing.module.ts
  • packages/angular-test-app/src/app/app.module.ts
  • packages/angular-test-app/src/preview-examples/badge-counter.css
  • packages/angular-test-app/src/preview-examples/badge-counter.html
  • packages/angular-test-app/src/preview-examples/badge-counter.ts
  • packages/angular-test-app/src/preview-examples/badge-dot.css
  • packages/angular-test-app/src/preview-examples/badge-dot.html
  • packages/angular-test-app/src/preview-examples/badge-dot.ts
  • packages/angular-test-app/src/preview-examples/badge-label.css
  • packages/angular-test-app/src/preview-examples/badge-label.html
  • packages/angular-test-app/src/preview-examples/badge-label.ts
  • packages/angular-test-app/src/preview-examples/badge-status-icon.css
  • packages/angular-test-app/src/preview-examples/badge-status-icon.html
  • packages/angular-test-app/src/preview-examples/badge-status-icon.ts
  • packages/angular-test-app/src/preview-examples/badge.css
  • packages/angular-test-app/src/preview-examples/badge.html
  • packages/angular-test-app/src/preview-examples/badge.ts
  • packages/angular/src/components.ts
  • packages/angular/src/declare-components.ts
  • packages/core/src/components.d.ts
  • packages/core/src/components/badge/badge.scss
  • packages/core/src/components/badge/badge.status-icon.ts
  • packages/core/src/components/badge/badge.tsx
  • packages/core/src/components/badge/badge.types.ts
  • packages/core/src/components/badge/badge.utils.ts
  • packages/core/src/components/badge/test/badge.ct.ts
  • packages/core/src/components/badge/test/badge.page.ts
  • packages/core/src/components/badge/test/badge.spec.ts
  • packages/core/src/components/menu-category/test/menu-category.ct.ts
  • packages/html-test-app/src/preview-examples/badge-counter.css
  • packages/html-test-app/src/preview-examples/badge-counter.html
  • packages/html-test-app/src/preview-examples/badge-dot.css
  • packages/html-test-app/src/preview-examples/badge-dot.html
  • packages/html-test-app/src/preview-examples/badge-label.css
  • packages/html-test-app/src/preview-examples/badge-label.html
  • packages/html-test-app/src/preview-examples/badge-status-icon.css
  • packages/html-test-app/src/preview-examples/badge-status-icon.html
  • packages/html-test-app/src/preview-examples/badge.css
  • packages/html-test-app/src/preview-examples/badge.html
  • packages/react-test-app/src/main.tsx
  • packages/react-test-app/src/preview-examples/badge-counter.scoped.css
  • packages/react-test-app/src/preview-examples/badge-counter.tsx
  • packages/react-test-app/src/preview-examples/badge-dot.scoped.css
  • packages/react-test-app/src/preview-examples/badge-dot.tsx
  • packages/react-test-app/src/preview-examples/badge-label.scoped.css
  • packages/react-test-app/src/preview-examples/badge-label.tsx
  • packages/react-test-app/src/preview-examples/badge-status-icon.scoped.css
  • packages/react-test-app/src/preview-examples/badge-status-icon.tsx
  • packages/react-test-app/src/preview-examples/badge.scoped.css
  • packages/react-test-app/src/preview-examples/badge.tsx
  • packages/storybook-docs/.storybook/define-custom-elements.ts
  • packages/storybook-docs/src/stories/badge/accessibility/a11y-badge.stories.ts
  • packages/storybook-docs/src/stories/badge/badge-preview.css
  • packages/storybook-docs/src/stories/badge/badge-preview.shared.ts
  • packages/storybook-docs/src/stories/badge/counter.stories.ts
  • packages/storybook-docs/src/stories/badge/dot.stories.ts
  • packages/storybook-docs/src/stories/badge/label.stories.ts
  • packages/storybook-docs/src/stories/badge/status-icon.stories.ts
  • packages/vue-test-app/src/Root.vue
  • packages/vue-test-app/src/preview-examples/badge-counter.css
  • packages/vue-test-app/src/preview-examples/badge-counter.vue
  • packages/vue-test-app/src/preview-examples/badge-dot.css
  • packages/vue-test-app/src/preview-examples/badge-dot.vue
  • packages/vue-test-app/src/preview-examples/badge-label.css
  • packages/vue-test-app/src/preview-examples/badge-label.vue
  • packages/vue-test-app/src/preview-examples/badge-status-icon.css
  • packages/vue-test-app/src/preview-examples/badge-status-icon.vue
  • packages/vue-test-app/src/preview-examples/badge.css
  • packages/vue-test-app/src/preview-examples/badge.vue
  • testing/framework-tests/__snapshots__/badge-aria-snapshot.yaml
  • testing/framework-tests/__snapshots__/badge-counter-aria-snapshot.yaml
  • testing/framework-tests/__snapshots__/badge-dot-aria-snapshot.yaml
  • testing/framework-tests/__snapshots__/badge-label-aria-snapshot.yaml
  • testing/framework-tests/__snapshots__/badge-status-icon-aria-snapshot.yaml
  • testing/framework-tests/tests/working-with-axe.spec.ts
  • testing/framework-tests/tests/working.spec.ts
  • testing/visual-testing/tests/badge/badge.e2e.ts
  • testing/visual-testing/tests/badge/badge.page.ts
  • testing/visual-testing/tests/badge/counter/index.html
  • testing/visual-testing/tests/badge/dot/index.html
  • testing/visual-testing/tests/badge/label/index.html
  • testing/visual-testing/tests/badge/status-icon/index.html

Comment thread packages/core/src/components/badge/badge.scss
Comment thread packages/core/src/components/badge/badge.status-icon.ts
Comment thread packages/core/src/components/badge/badge.utils.ts
Comment thread packages/core/src/components/badge/badge.utils.ts Outdated
Comment thread packages/core/src/components/badge/test/badge.ct.ts Outdated
Comment thread packages/react-test-app/src/preview-examples/badge-counter.tsx
Comment thread packages/react-test-app/src/preview-examples/badge-dot.tsx
Comment thread packages/react-test-app/src/preview-examples/badge-label.tsx
Comment thread packages/storybook-docs/src/stories/badge/counter.stories.tsx
Comment thread testing/visual-testing/tests/badge/badge.page.ts Outdated
Comment thread packages/storybook-docs/src/stories/badge/dot.stories.tsx
Comment thread packages/core/src/components/badge/badge.tsx Outdated
Comment thread packages/storybook-docs/src/stories/badge/accessibility/a11y-badge.stories.ts Outdated
Comment thread packages/angular-standalone-test-app/src/preview-examples/badge-counter.ts Outdated
Comment thread packages/core/src/components/badge/test/badge.ct.ts
Comment thread packages/core/src/components/badge/badge.scss Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/components/badge/badge.utils.ts (1)

57-79: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Negative counter labels still not rejected.

INTEGER_LABEL_PATTERN accepts a leading -, and formatCounterLabel only clamps the upper bound (intValue > BADGE_OVERFLOW_THRESHOLD). A label="-5" on a counter badge still renders "-5", which contradicts the documented "count" semantics. This was flagged in a prior review and does not appear to have been addressed in this revision (unlike the type-alias comment on the same file, which shows an "Addressed in commits" confirmation).

🐛 Proposed fix
   const intValue = Math.trunc(Number(trimmed));

+  if (intValue < 0) {
+    return null;
+  }
+
   if (intValue > BADGE_OVERFLOW_THRESHOLD) {
     return OVERFLOW_LABEL;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/badge/badge.utils.ts` around lines 57 - 79,
Update formatCounterLabel to reject negative numeric labels after parsing,
before returning String(intValue); preserve null for invalid inputs and
OVERFLOW_LABEL for values above BADGE_OVERFLOW_THRESHOLD, while leaving the
existing OVERFLOW_LABEL handling unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/angular-standalone-test-app/src/preview-examples/badge.html`:
- Line 13: Update the counter ix-badge example’s label from the preformatted
“99+” string to the integer value 100, allowing the component’s own formatting
logic to render “99+”.

In `@packages/storybook-docs/src/stories/badge/badge-preview.shared.tsx`:
- Around line 80-98: Single root issue: badge story helpers create Stencil JSX
arrays without stable keys. Update variantGridHeaders() and
attachedVariantGridHeaders() in
packages/storybook-docs/src/stories/badge/badge-preview.shared.tsx (lines 80-98)
with unique keys for every header span; update the row-label spans and each
cell(...) entry inside flatMap callbacks in
packages/storybook-docs/src/stories/badge/counter.stories.tsx (lines 28-84),
dot.stories.tsx (lines 24-84), label.stories.tsx (lines 24-84), and
status-icon.stories.tsx (lines 24-92), using stable unique keys such as the
variant and cell identity.

In `@packages/storybook-docs/src/stories/badge/counter.stories.tsx`:
- Around line 28-84: Extract the duplicated standaloneVariantGrid and
attachedVariantGrid scaffolding into buildStandaloneVariantGrid(rows, factory)
and buildAttachedVariantGrid(rows, factory) in
packages/storybook-docs/src/stories/badge/badge-preview.shared.tsx,
parameterized by the badge factory while preserving headers and cell
composition. Update
packages/storybook-docs/src/stories/badge/counter.stories.tsx lines 28-84 to use
counterBadge, packages/storybook-docs/src/stories/badge/dot.stories.tsx lines
24-84 to use dotBadge,
packages/storybook-docs/src/stories/badge/label.stories.tsx lines 24-84 to use
labelBadge, and
packages/storybook-docs/src/stories/badge/status-icon.stories.tsx lines 24-92 to
use statusIconBadge with its existing variant rows and headers.

---

Outside diff comments:
In `@packages/core/src/components/badge/badge.utils.ts`:
- Around line 57-79: Update formatCounterLabel to reject negative numeric labels
after parsing, before returning String(intValue); preserve null for invalid
inputs and OVERFLOW_LABEL for values above BADGE_OVERFLOW_THRESHOLD, while
leaving the existing OVERFLOW_LABEL handling unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a1885d7c-0322-4a7d-a3b8-5aa596f02ceb

📥 Commits

Reviewing files that changed from the base of the PR and between e8d4d0f and 67d6787.

📒 Files selected for processing (26)
  • AGENTS.md
  • packages/angular-standalone-test-app/src/preview-examples/badge-counter.html
  • packages/angular-standalone-test-app/src/preview-examples/badge-counter.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-dot.html
  • packages/angular-standalone-test-app/src/preview-examples/badge-dot.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-label.html
  • packages/angular-standalone-test-app/src/preview-examples/badge-label.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge-status-icon.html
  • packages/angular-standalone-test-app/src/preview-examples/badge-status-icon.ts
  • packages/angular-standalone-test-app/src/preview-examples/badge.html
  • packages/angular-standalone-test-app/src/preview-examples/badge.ts
  • packages/core/src/components.d.ts
  • packages/core/src/components/badge/badge.scss
  • packages/core/src/components/badge/badge.status-icon.ts
  • packages/core/src/components/badge/badge.tsx
  • packages/core/src/components/badge/badge.utils.ts
  • packages/core/src/components/badge/badge.vars.scss
  • packages/core/src/components/badge/test/badge.ct.ts
  • packages/core/src/components/badge/test/badge.page.ts
  • packages/storybook-docs/src/stories/badge/accessibility/a11y-badge.stories.tsx
  • packages/storybook-docs/src/stories/badge/badge-preview.shared.tsx
  • packages/storybook-docs/src/stories/badge/counter.stories.tsx
  • packages/storybook-docs/src/stories/badge/dot.stories.tsx
  • packages/storybook-docs/src/stories/badge/label.stories.tsx
  • packages/storybook-docs/src/stories/badge/status-icon.stories.tsx
  • testing/visual-testing/tests/badge/badge.page.ts

Comment thread packages/angular-standalone-test-app/src/preview-examples/badge.html Outdated
Comment thread packages/storybook-docs/src/stories/badge/badge-preview.shared.tsx
Comment thread packages/storybook-docs/src/stories/badge/counter.stories.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/components/badge/badge.tsx (1)

605-607: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Honor the documented outline/border interaction.

Line 607 emits the border class whenever border is true, even when outline is also true, although the public contract says border is ignored in outline mode.

Proposed fix
-    const showBorder = this.border && type !== 'status-icon';
+    const showBorder =
+      this.border && !this.outline && type !== 'status-icon';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/badge/badge.tsx` around lines 605 - 607, Update
the showBorder calculation in the badge rendering logic so border is enabled
only when this.border is true and outline mode is inactive, while preserving the
existing status-icon exclusion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/components/badge/badge.tsx`:
- Around line 413-416: Update the ix-tooltip usage in the badge component to
pass text through the titleContent property instead of aria-label. Remove the
aria-label assignment while preserving the existing for binding to
indicatorElementRef.waitForCurrent().

In `@packages/core/src/components/badge/test/badge.ct.ts`:
- Around line 744-746: Update the nested tooltip readiness assertion in the
badge component test to locate tooltips by the accessible role="tooltip" rather
than the ix-tooltip.hydrated implementation class. Continue waiting for exactly
two hydrated tooltips before running axe.

---

Outside diff comments:
In `@packages/core/src/components/badge/badge.tsx`:
- Around line 605-607: Update the showBorder calculation in the badge rendering
logic so border is enabled only when this.border is true and outline mode is
inactive, while preserving the existing status-icon exclusion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b6d7b07e-a1a8-43b8-8665-67d8b741d58d

📥 Commits

Reviewing files that changed from the base of the PR and between 67d6787 and 22b0709.

📒 Files selected for processing (2)
  • packages/core/src/components/badge/badge.tsx
  • packages/core/src/components/badge/test/badge.ct.ts

Comment thread packages/core/src/components/badge/badge.tsx
Comment thread packages/core/src/components/badge/test/badge.ct.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/components/badge/badge.scss (1)

223-234: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use theme contrast tokens for status-icon plate colors.

Lines 227-233 hard-code #000000 and #ffffff, bypassing theme configuration and potentially producing incorrect contrast in alternate themes. Use the matching --theme-color-*-contrast token instead, with the error variant using the alarm contrast token.

As per coding guidelines, use design tokens and CSS custom properties instead of hard-coded theme values.

Proposed fix
-  color: `#000000`;
+  color: var(--theme-color-critical--contrast);

Apply the corresponding variant contrast token for warning, success, alarm, info, and error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/badge/badge.scss` around lines 223 - 234,
Replace the hard-coded colors in the status-icon plate selectors with the
corresponding --theme-color-*-contrast design tokens: use each matching token
for warning, success, alarm, and info, and use the alarm contrast token for
error. Preserve the existing type and outline selectors.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/core/src/components/badge/badge.scss`:
- Around line 223-234: Replace the hard-coded colors in the status-icon plate
selectors with the corresponding --theme-color-*-contrast design tokens: use
each matching token for warning, success, alarm, and info, and use the alarm
contrast token for error. Preserve the existing type and outline selectors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cdb92b50-0615-479b-a729-3c4a4a30a5d7

📥 Commits

Reviewing files that changed from the base of the PR and between 22b0709 and 5992064.

📒 Files selected for processing (13)
  • packages/angular-standalone-test-app/src/preview-examples/badge.html
  • packages/angular-test-app/src/preview-examples/badge.html
  • packages/core/src/components/badge/badge.scss
  • packages/core/src/components/badge/test/badge.ct.ts
  • packages/html-test-app/src/preview-examples/badge.html
  • packages/react-test-app/src/preview-examples/badge.tsx
  • packages/storybook-docs/src/stories/badge/badge-preview.shared.tsx
  • packages/storybook-docs/src/stories/badge/counter.stories.tsx
  • packages/storybook-docs/src/stories/badge/dot.stories.tsx
  • packages/storybook-docs/src/stories/badge/label.stories.tsx
  • packages/storybook-docs/src/stories/badge/status-icon.stories.tsx
  • packages/vue-test-app/src/preview-examples/badge.vue
  • testing/framework-tests/__snapshots__/badge-aria-snapshot.yaml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/components/badge/badge.scss (1)

223-234: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use theme tokens for status-icon plate colors.

The hard-coded #000000 and #ffffff values bypass theme customization. Define semantic component variables or use existing contrast tokens instead, with schema-specific defaults in badge.vars.scss.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/badge/badge.scss` around lines 223 - 234,
Replace the hard-coded colors in the status-icon plate selectors with semantic
theme variables or existing contrast tokens. Define their schema-specific
defaults in badge.vars.scss, then reference those variables for the
critical/warning/success and alarm/error/info groups while preserving the
current color mapping.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/core/src/components/badge/badge.scss`:
- Around line 223-234: Replace the hard-coded colors in the status-icon plate
selectors with semantic theme variables or existing contrast tokens. Define
their schema-specific defaults in badge.vars.scss, then reference those
variables for the critical/warning/success and alarm/error/info groups while
preserving the current color mapping.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ef13e68f-9e82-4b3c-9941-625736cca113

📥 Commits

Reviewing files that changed from the base of the PR and between 5992064 and f0c2709.

📒 Files selected for processing (1)
  • packages/core/src/components/badge/badge.scss

@danielleroux danielleroux left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Layout Issue

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The badge component itself influence the layouting of the hosted component

Screen.Recording.2026-07-30.at.08.11.51.mov

Code:

  @State() enableBadge = false;
  render() {
    return (
      <Host style={{ display: 'block', padding: '20px' }}>
        <ix-button onClick={() => (this.enableBadge = !this.enableBadge)}>
          Enable badge {this.enableBadge ? 'on' : 'off'}
        </ix-button>
        {this.enableBadge ? (
          <ix-badge label="5">
            <div
              style={{
                display: 'block',
                position: 'relative',
                background: 'red',
                width: '50%',
                height: '10rem',
              }}
            >
              Content
            </div>
          </ix-badge>
        ) : (
          <div
            style={{
              display: 'block',
              position: 'relative',
              background: 'red',
              width: '50%',
              height: '10rem',
            }}
          >
            Content
          </div>
        )}
        <div
          style={{
            display: 'block',
            position: 'relative',
            background: 'red',
            width: '50%',
            height: '10rem',
          }}
        >
          Content
        </div>
      </Host>
    );
  }



Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

fixed. thanks

*
* @since 5.2.0
*/
@Prop({ attribute: 'enable-animation', reflect: true }) enableAnimation =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Attribute naming is not required here its just needed if you have more "complex" names like i18n-test, because without attribute it will be generated to i-1-8-n-test.

But in your case it is already fine: enableAnimation be become enable-animation

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

adjusted. thanks

@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants