feat(badge): add badge component IX-3943 - #2645
Conversation
🦋 Changeset detectedLatest commit: b6706dd The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 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 |
✅ Deploy Preview for ix-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughIntroduces the ChangesBadge component
Estimated code review effort: 5 (Critical) | ~120 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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.
|
/gemini review |
There was a problem hiding this comment.
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.
088a8ee to
8251bb3
Compare
3e54252 to
e8d4d0f
Compare
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (26)
packages/angular/standalone/src/components.tsis excluded by!packages/angular/standalone/src/components.tspackages/react/src/components/components.server.tsis excluded by!packages/react/src/components/**packages/react/src/components/components.tsis excluded by!packages/react/src/components/**packages/vue/src/components/components.tsis excluded by!packages/vue/src/components/**packages/vue/src/components/ix-badge.tsis excluded by!packages/vue/src/components/**testing/framework-tests/tests/generated/axe.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-axe.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-counter-axe.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-counter.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-dot-axe.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-dot.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-label-axe.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-label.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-status-icon-axe.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge-status-icon.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/badge.spec.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/index.tsis excluded by!**/generated/**testing/framework-tests/tests/generated/test-ids.autogenerated.tsis excluded by!**/generated/**testing/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-counter-1-chromium---classic-dark-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-counter-1-chromium---classic-light-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-dot-1-chromium---classic-dark-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-dot-1-chromium---classic-light-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-label-1-chromium---classic-dark-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-label-1-chromium---classic-light-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-status-icon-1-chromium---classic-dark-linux.pngis excluded by!**/*.pngtesting/visual-testing/__screenshots__/tests/badge/badge.e2e.ts/badge-status-icon-1-chromium---classic-light-linux.pngis excluded by!**/*.png
📒 Files selected for processing (94)
.changeset/ix-3943-badge.mdpackages/angular-standalone-test-app/src/app/app.routes.tspackages/angular-standalone-test-app/src/preview-examples/badge-counter.csspackages/angular-standalone-test-app/src/preview-examples/badge-counter.tspackages/angular-standalone-test-app/src/preview-examples/badge-dot.csspackages/angular-standalone-test-app/src/preview-examples/badge-dot.tspackages/angular-standalone-test-app/src/preview-examples/badge-label.csspackages/angular-standalone-test-app/src/preview-examples/badge-label.tspackages/angular-standalone-test-app/src/preview-examples/badge-status-icon.csspackages/angular-standalone-test-app/src/preview-examples/badge-status-icon.tspackages/angular-standalone-test-app/src/preview-examples/badge.csspackages/angular-standalone-test-app/src/preview-examples/badge.tspackages/angular-test-app/src/app/app-routing.module.tspackages/angular-test-app/src/app/app.module.tspackages/angular-test-app/src/preview-examples/badge-counter.csspackages/angular-test-app/src/preview-examples/badge-counter.htmlpackages/angular-test-app/src/preview-examples/badge-counter.tspackages/angular-test-app/src/preview-examples/badge-dot.csspackages/angular-test-app/src/preview-examples/badge-dot.htmlpackages/angular-test-app/src/preview-examples/badge-dot.tspackages/angular-test-app/src/preview-examples/badge-label.csspackages/angular-test-app/src/preview-examples/badge-label.htmlpackages/angular-test-app/src/preview-examples/badge-label.tspackages/angular-test-app/src/preview-examples/badge-status-icon.csspackages/angular-test-app/src/preview-examples/badge-status-icon.htmlpackages/angular-test-app/src/preview-examples/badge-status-icon.tspackages/angular-test-app/src/preview-examples/badge.csspackages/angular-test-app/src/preview-examples/badge.htmlpackages/angular-test-app/src/preview-examples/badge.tspackages/angular/src/components.tspackages/angular/src/declare-components.tspackages/core/src/components.d.tspackages/core/src/components/badge/badge.scsspackages/core/src/components/badge/badge.status-icon.tspackages/core/src/components/badge/badge.tsxpackages/core/src/components/badge/badge.types.tspackages/core/src/components/badge/badge.utils.tspackages/core/src/components/badge/test/badge.ct.tspackages/core/src/components/badge/test/badge.page.tspackages/core/src/components/badge/test/badge.spec.tspackages/core/src/components/menu-category/test/menu-category.ct.tspackages/html-test-app/src/preview-examples/badge-counter.csspackages/html-test-app/src/preview-examples/badge-counter.htmlpackages/html-test-app/src/preview-examples/badge-dot.csspackages/html-test-app/src/preview-examples/badge-dot.htmlpackages/html-test-app/src/preview-examples/badge-label.csspackages/html-test-app/src/preview-examples/badge-label.htmlpackages/html-test-app/src/preview-examples/badge-status-icon.csspackages/html-test-app/src/preview-examples/badge-status-icon.htmlpackages/html-test-app/src/preview-examples/badge.csspackages/html-test-app/src/preview-examples/badge.htmlpackages/react-test-app/src/main.tsxpackages/react-test-app/src/preview-examples/badge-counter.scoped.csspackages/react-test-app/src/preview-examples/badge-counter.tsxpackages/react-test-app/src/preview-examples/badge-dot.scoped.csspackages/react-test-app/src/preview-examples/badge-dot.tsxpackages/react-test-app/src/preview-examples/badge-label.scoped.csspackages/react-test-app/src/preview-examples/badge-label.tsxpackages/react-test-app/src/preview-examples/badge-status-icon.scoped.csspackages/react-test-app/src/preview-examples/badge-status-icon.tsxpackages/react-test-app/src/preview-examples/badge.scoped.csspackages/react-test-app/src/preview-examples/badge.tsxpackages/storybook-docs/.storybook/define-custom-elements.tspackages/storybook-docs/src/stories/badge/accessibility/a11y-badge.stories.tspackages/storybook-docs/src/stories/badge/badge-preview.csspackages/storybook-docs/src/stories/badge/badge-preview.shared.tspackages/storybook-docs/src/stories/badge/counter.stories.tspackages/storybook-docs/src/stories/badge/dot.stories.tspackages/storybook-docs/src/stories/badge/label.stories.tspackages/storybook-docs/src/stories/badge/status-icon.stories.tspackages/vue-test-app/src/Root.vuepackages/vue-test-app/src/preview-examples/badge-counter.csspackages/vue-test-app/src/preview-examples/badge-counter.vuepackages/vue-test-app/src/preview-examples/badge-dot.csspackages/vue-test-app/src/preview-examples/badge-dot.vuepackages/vue-test-app/src/preview-examples/badge-label.csspackages/vue-test-app/src/preview-examples/badge-label.vuepackages/vue-test-app/src/preview-examples/badge-status-icon.csspackages/vue-test-app/src/preview-examples/badge-status-icon.vuepackages/vue-test-app/src/preview-examples/badge.csspackages/vue-test-app/src/preview-examples/badge.vuetesting/framework-tests/__snapshots__/badge-aria-snapshot.yamltesting/framework-tests/__snapshots__/badge-counter-aria-snapshot.yamltesting/framework-tests/__snapshots__/badge-dot-aria-snapshot.yamltesting/framework-tests/__snapshots__/badge-label-aria-snapshot.yamltesting/framework-tests/__snapshots__/badge-status-icon-aria-snapshot.yamltesting/framework-tests/tests/working-with-axe.spec.tstesting/framework-tests/tests/working.spec.tstesting/visual-testing/tests/badge/badge.e2e.tstesting/visual-testing/tests/badge/badge.page.tstesting/visual-testing/tests/badge/counter/index.htmltesting/visual-testing/tests/badge/dot/index.htmltesting/visual-testing/tests/badge/label/index.htmltesting/visual-testing/tests/badge/status-icon/index.html
There was a problem hiding this comment.
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 winNegative counter labels still not rejected.
INTEGER_LABEL_PATTERNaccepts a leading-, andformatCounterLabelonly clamps the upper bound (intValue > BADGE_OVERFLOW_THRESHOLD). Alabel="-5"on acounterbadge 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
📒 Files selected for processing (26)
AGENTS.mdpackages/angular-standalone-test-app/src/preview-examples/badge-counter.htmlpackages/angular-standalone-test-app/src/preview-examples/badge-counter.tspackages/angular-standalone-test-app/src/preview-examples/badge-dot.htmlpackages/angular-standalone-test-app/src/preview-examples/badge-dot.tspackages/angular-standalone-test-app/src/preview-examples/badge-label.htmlpackages/angular-standalone-test-app/src/preview-examples/badge-label.tspackages/angular-standalone-test-app/src/preview-examples/badge-status-icon.htmlpackages/angular-standalone-test-app/src/preview-examples/badge-status-icon.tspackages/angular-standalone-test-app/src/preview-examples/badge.htmlpackages/angular-standalone-test-app/src/preview-examples/badge.tspackages/core/src/components.d.tspackages/core/src/components/badge/badge.scsspackages/core/src/components/badge/badge.status-icon.tspackages/core/src/components/badge/badge.tsxpackages/core/src/components/badge/badge.utils.tspackages/core/src/components/badge/badge.vars.scsspackages/core/src/components/badge/test/badge.ct.tspackages/core/src/components/badge/test/badge.page.tspackages/storybook-docs/src/stories/badge/accessibility/a11y-badge.stories.tsxpackages/storybook-docs/src/stories/badge/badge-preview.shared.tsxpackages/storybook-docs/src/stories/badge/counter.stories.tsxpackages/storybook-docs/src/stories/badge/dot.stories.tsxpackages/storybook-docs/src/stories/badge/label.stories.tsxpackages/storybook-docs/src/stories/badge/status-icon.stories.tsxtesting/visual-testing/tests/badge/badge.page.ts
There was a problem hiding this comment.
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 winHonor the documented
outline/borderinteraction.Line 607 emits the
borderclass wheneverborderis true, even whenoutlineis 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
📒 Files selected for processing (2)
packages/core/src/components/badge/badge.tsxpackages/core/src/components/badge/test/badge.ct.ts
There was a problem hiding this comment.
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 winUse theme contrast tokens for status-icon plate colors.
Lines 227-233 hard-code
#000000and#ffffff, bypassing theme configuration and potentially producing incorrect contrast in alternate themes. Use the matching--theme-color-*-contrasttoken instead, with theerrorvariant 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, anderror.🤖 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
📒 Files selected for processing (13)
packages/angular-standalone-test-app/src/preview-examples/badge.htmlpackages/angular-test-app/src/preview-examples/badge.htmlpackages/core/src/components/badge/badge.scsspackages/core/src/components/badge/test/badge.ct.tspackages/html-test-app/src/preview-examples/badge.htmlpackages/react-test-app/src/preview-examples/badge.tsxpackages/storybook-docs/src/stories/badge/badge-preview.shared.tsxpackages/storybook-docs/src/stories/badge/counter.stories.tsxpackages/storybook-docs/src/stories/badge/dot.stories.tsxpackages/storybook-docs/src/stories/badge/label.stories.tsxpackages/storybook-docs/src/stories/badge/status-icon.stories.tsxpackages/vue-test-app/src/preview-examples/badge.vuetesting/framework-tests/__snapshots__/badge-aria-snapshot.yaml
There was a problem hiding this comment.
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 winUse theme tokens for status-icon plate colors.
The hard-coded
#000000and#ffffffvalues bypass theme customization. Define semantic component variables or use existing contrast tokens instead, with schema-specific defaults inbadge.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
📒 Files selected for processing (1)
packages/core/src/components/badge/badge.scss
There was a problem hiding this comment.
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>
);
}
| * | ||
| * @since 5.2.0 | ||
| */ | ||
| @Prop({ attribute: 'enable-animation', reflect: true }) enableAnimation = |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
adjusted. thanks
|



💡 What is the current behavior?
ix-badgecomponent for count, label, dot, or status-icon indicators on anchors or as standalone badges.Part of EIX-64
🆕 What is the new behavior?
ix-badge(@since 5.2.0) with anatomiescounter,label,dot, andstatus-icon.variantvalues (shared with chip),outline, optionalborder,position(top-after|bottom-after),offset-x/offset-y, custombackground/badge-color, label icon props, and optionalenable-animationattention pulse.aria-describedbyon the anchor (dot / decorative status remain silent).aria-label+ naming role for nameless types).🏁 Checklist
A pull request can only be merged if all of these conditions are met (where applicable):
pnpm test)pnpm lint)pnpm build, changes pushed)👨💻 Help & support
export default () =>match repo convention — mark Won’t Fix if still reported.Summary by CodeRabbit
New Features
ix-badgecomponent (counter, label, dot, status-icon) with semantic variants, custom colors, outline/border, position + offset, and optional pulse animation.ix-badgeis available across Angular, React, Vue, and related preview environments.Documentation
Tests