From a398aea827d4f5cb4827eedc21d867738f9c935b Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Fri, 8 May 2026 14:06:13 -0400 Subject: [PATCH 01/12] feat(badge): add pf-v6-badge element Port pf-v5-badge to pf-v6-badge with v6 design tokens, CSS, and API parity with PatternFly v6 React Badge component. Changes from v5: - Updated CSS custom properties to --pf-v6-c-badge--* namespace - Added border overlay via ::after pseudo-element (new in v6) - Added disabled state with pointer-events: none - Switched to CSS logical properties (padding-inline-start/end) - Simplified render: no wrapper span, slot for default content - Added `@cssprop` JSDoc for all public CSS custom properties - Added `@summary` and `@slot` JSDoc annotations - Exported BadgeState type union Demos match patternfly.org: read, unread, disabled, plus WC-specific threshold demo. Tests cover: instantiation, number/threshold display, state colors, disabled styling, accessibility tree, slot content. Closes #2982 Assisted-By: Claude Opus 4.6 --- elements/package.json | 1 + elements/pf-v6-badge/demo/disabled.html | 12 ++ elements/pf-v6-badge/demo/index.html | 12 ++ elements/pf-v6-badge/demo/read.html | 12 ++ elements/pf-v6-badge/demo/threshold.html | 10 ++ elements/pf-v6-badge/demo/unread.html | 12 ++ elements/pf-v6-badge/pf-v6-badge.css | 58 ++++++++ elements/pf-v6-badge/pf-v6-badge.ts | 72 +++++++++ elements/test/pf-v6-badge.spec.ts | 181 +++++++++++++++++++++++ 9 files changed, 370 insertions(+) create mode 100644 elements/pf-v6-badge/demo/disabled.html create mode 100644 elements/pf-v6-badge/demo/index.html create mode 100644 elements/pf-v6-badge/demo/read.html create mode 100644 elements/pf-v6-badge/demo/threshold.html create mode 100644 elements/pf-v6-badge/demo/unread.html create mode 100644 elements/pf-v6-badge/pf-v6-badge.css create mode 100644 elements/pf-v6-badge/pf-v6-badge.ts create mode 100644 elements/test/pf-v6-badge.spec.ts diff --git a/elements/package.json b/elements/package.json index fe8dda2080..11d9359e77 100644 --- a/elements/package.json +++ b/elements/package.json @@ -18,6 +18,7 @@ "./pf-v5-back-to-top/pf-v5-back-to-top.js": "./pf-v5-back-to-top/pf-v5-back-to-top.js", "./pf-v5-background-image/pf-v5-background-image.js": "./pf-v5-background-image/pf-v5-background-image.js", "./pf-v5-badge/pf-v5-badge.js": "./pf-v5-badge/pf-v5-badge.js", + "./pf-v6-badge/pf-v6-badge.js": "./pf-v6-badge/pf-v6-badge.js", "./pf-v5-banner/pf-v5-banner.js": "./pf-v5-banner/pf-v5-banner.js", "./pf-v5-button/pf-v5-button.js": "./pf-v5-button/pf-v5-button.js", "./pf-v5-card/pf-v5-card.js": "./pf-v5-card/pf-v5-card.js", diff --git a/elements/pf-v6-badge/demo/disabled.html b/elements/pf-v6-badge/demo/disabled.html new file mode 100644 index 0000000000..3e57ccf9e2 --- /dev/null +++ b/elements/pf-v6-badge/demo/disabled.html @@ -0,0 +1,12 @@ +--- +name: Disabled +description: Disabled badges indicate that the associated content or action is currently unavailable. +--- +7 +24 +240 +999+ + + diff --git a/elements/pf-v6-badge/demo/index.html b/elements/pf-v6-badge/demo/index.html new file mode 100644 index 0000000000..b0239ac479 --- /dev/null +++ b/elements/pf-v6-badge/demo/index.html @@ -0,0 +1,12 @@ +--- +name: Read +description: Read badges display a numeric value with read state styling, indicating the content has been viewed. +--- +7 +24 +240 +999+ + + diff --git a/elements/pf-v6-badge/demo/read.html b/elements/pf-v6-badge/demo/read.html new file mode 100644 index 0000000000..b0239ac479 --- /dev/null +++ b/elements/pf-v6-badge/demo/read.html @@ -0,0 +1,12 @@ +--- +name: Read +description: Read badges display a numeric value with read state styling, indicating the content has been viewed. +--- +7 +24 +240 +999+ + + diff --git a/elements/pf-v6-badge/demo/threshold.html b/elements/pf-v6-badge/demo/threshold.html new file mode 100644 index 0000000000..b27ea00fca --- /dev/null +++ b/elements/pf-v6-badge/demo/threshold.html @@ -0,0 +1,10 @@ +--- +name: Threshold +description: A threshold appends a "+" when the numeric value exceeds a set maximum. +--- +400 +900 + + diff --git a/elements/pf-v6-badge/demo/unread.html b/elements/pf-v6-badge/demo/unread.html new file mode 100644 index 0000000000..7e16b908e2 --- /dev/null +++ b/elements/pf-v6-badge/demo/unread.html @@ -0,0 +1,12 @@ +--- +name: Unread +description: Unread badges use a bold, branded style to indicate content that has not yet been viewed. +--- +7 +24 +240 +999+ + + diff --git a/elements/pf-v6-badge/pf-v6-badge.css b/elements/pf-v6-badge/pf-v6-badge.css new file mode 100644 index 0000000000..e158aedfcd --- /dev/null +++ b/elements/pf-v6-badge/pf-v6-badge.css @@ -0,0 +1,58 @@ +:host { + position: relative; + display: inline-block; + min-width: var(--pf-v6-c-badge--MinWidth, + var(--pf-t--global--spacer--xl, 2rem)); + padding-inline-start: var(--pf-v6-c-badge--PaddingInlineStart, + var(--pf-t--global--spacer--sm, 0.5rem)); + padding-inline-end: var(--pf-v6-c-badge--PaddingInlineEnd, + var(--pf-t--global--spacer--sm, 0.5rem)); + font-size: var(--pf-v6-c-badge--FontSize, + var(--pf-t--global--font--size--body--sm, 0.75rem)); + font-weight: var(--pf-v6-c-badge--FontWeight, + var(--pf-t--global--font--weight--body--bold, 700)); + color: var(--pf-v6-c-badge--Color, + var(--pf-t--global--text--color--nonstatus--on-gray--default, #151515)); + text-align: center; + white-space: nowrap; + background-color: var(--pf-v6-c-badge--BackgroundColor, + var(--pf-t--global--color--nonstatus--gray--default, #f0f0f0)); + border-radius: var(--pf-v6-c-badge--BorderRadius, + var(--pf-t--global--border--radius--pill, 180em)); +} + +:host::after { + position: absolute; + inset: 0; + pointer-events: none; + content: ""; + border: var(--pf-v6-c-badge--BorderWidth, + var(--pf-t--global--border--width--regular, 1px)) solid var(--pf-v6-c-badge--BorderColor, transparent); + border-radius: inherit; +} + +:host([state="read"]) { + --pf-v6-c-badge--Color: var(--pf-v6-c-badge--m-read--Color, + var(--pf-t--global--text--color--nonstatus--on-gray--default, #151515)); + --pf-v6-c-badge--BackgroundColor: var(--pf-v6-c-badge--m-read--BackgroundColor, + var(--pf-t--global--color--nonstatus--gray--default, #f0f0f0)); + --pf-v6-c-badge--BorderColor: var(--pf-v6-c-badge--m-read--BorderColor, + var(--pf-t--global--border--color--high-contrast, #151515)); +} + +:host([state="unread"]) { + --pf-v6-c-badge--Color: var(--pf-v6-c-badge--m-unread--Color, + var(--pf-t--global--text--color--on-brand--default, #fff)); + --pf-v6-c-badge--BackgroundColor: var(--pf-v6-c-badge--m-unread--BackgroundColor, + var(--pf-t--global--color--brand--default, #06c)); +} + +:host([disabled]) { + --pf-v6-c-badge--Color: var(--pf-v6-c-badge--m-disabled--Color, + var(--pf-t--global--text--color--on-disabled, #6a6e73)); + --pf-v6-c-badge--BackgroundColor: var(--pf-v6-c-badge--m-disabled--BackgroundColor, + var(--pf-t--global--background--color--disabled--default, #d2d2d2)); + --pf-v6-c-badge--BorderColor: var(--pf-v6-c-badge--m-disabled--BorderColor, + var(--pf-t--global--border--color--disabled, #d2d2d2)); + pointer-events: none; +} diff --git a/elements/pf-v6-badge/pf-v6-badge.ts b/elements/pf-v6-badge/pf-v6-badge.ts new file mode 100644 index 0000000000..2492456c14 --- /dev/null +++ b/elements/pf-v6-badge/pf-v6-badge.ts @@ -0,0 +1,72 @@ +import { LitElement, html, type TemplateResult } from 'lit'; +import { customElement } from 'lit/decorators/custom-element.js'; +import { property } from 'lit/decorators/property.js'; + +import styles from './pf-v6-badge.css'; + +export type BadgeState = 'unread' | 'read'; + +/** + * A **badge** is used to annotate other information like a label or an object name. + * @summary Displays a numeric value as an annotation + * @slot - Badge content, typically a number or short text + * @cssprop {} --pf-v6-c-badge--Color - Text color of the badge + * @cssprop {} --pf-v6-c-badge--BackgroundColor - Background color of the badge + * @cssprop {} --pf-v6-c-badge--BorderColor - Border color of the badge + * @cssprop {} --pf-v6-c-badge--BorderWidth - Border width of the badge + * @cssprop {} --pf-v6-c-badge--BorderRadius - Border radius of the badge + * @cssprop {} --pf-v6-c-badge--MinWidth - Minimum width of the badge + * @cssprop {} --pf-v6-c-badge--PaddingInlineStart - Inline start padding + * @cssprop {} --pf-v6-c-badge--PaddingInlineEnd - Inline end padding + * @cssprop {} --pf-v6-c-badge--FontSize - Font size of the badge text + * @cssprop {} --pf-v6-c-badge--FontWeight - Font weight of the badge text + * @cssprop {} --pf-v6-c-badge--m-read--Color - Text color in read state + * @cssprop {} --pf-v6-c-badge--m-read--BackgroundColor - Background color in read state + * @cssprop {} --pf-v6-c-badge--m-read--BorderColor - Border color in read state + * @cssprop {} --pf-v6-c-badge--m-unread--Color - Text color in unread state + * @cssprop {} --pf-v6-c-badge--m-unread--BackgroundColor - Background color in unread state + * @cssprop {} --pf-v6-c-badge--m-disabled--Color - Text color when disabled + * @cssprop {} --pf-v6-c-badge--m-disabled--BackgroundColor - Background color when disabled + * @cssprop {} --pf-v6-c-badge--m-disabled--BorderColor - Border color when disabled + */ +@customElement('pf-v6-badge') +export class PfV6Badge extends LitElement { + static readonly styles = [styles]; + + /** + * Denotes the state-of-affairs this badge represents. + */ + @property({ reflect: true }) state?: BadgeState; + + /** + * Sets a numeric value for a badge. + * + * You can pair it with `threshold` attribute to add a `+` sign + * if the number exceeds the threshold value. + */ + @property({ reflect: true, type: Number }) number?: number; + + /** + * Sets a threshold for the numeric value and adds `+` sign if + * the numeric value exceeds the threshold value. + */ + @property({ reflect: true, type: Number }) threshold?: number; + + /** Disables the badge */ + @property({ type: Boolean, reflect: true }) disabled = false; + + override render(): TemplateResult<1> { + const { threshold, number } = this; + const displayText = + (threshold && number && (threshold < number)) ? `${threshold.toString()}+` + : (number != null) ? number.toString() + : ''; + return html`${!displayText ? html`` : displayText}`; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'pf-v6-badge': PfV6Badge; + } +} diff --git a/elements/test/pf-v6-badge.spec.ts b/elements/test/pf-v6-badge.spec.ts new file mode 100644 index 0000000000..ad2dee0e5b --- /dev/null +++ b/elements/test/pf-v6-badge.spec.ts @@ -0,0 +1,181 @@ +import { expect, html } from '@open-wc/testing'; +import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js'; +import { a11ySnapshot } from '@patternfly/pfe-tools/test/a11y-snapshot.js'; +import { getColor, hexToRgb } from '@patternfly/pfe-tools/test/hex-to-rgb.js'; +import { PfV6Badge } from '@patternfly/elements/pf-v6-badge/pf-v6-badge.js'; + +describe('', function() { + it('imperatively instantiates', function() { + expect(document.createElement('pf-v6-badge')).to.be.an.instanceof(PfV6Badge); + }); + + it('should upgrade', async function() { + const el = await createFixture(html`10`); + expect(el) + .to.be.an.instanceOf(customElements.get('pf-v6-badge')) + .and + .to.be.an.instanceOf(PfV6Badge); + }); + + describe('with number attribute', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 100 + `); + await element.updateComplete; + }); + + it('should have the number property set', function() { + expect(element.number).to.equal(100); + }); + + it('should be visible in the accessibility tree', async function() { + const snapshot = await a11ySnapshot(); + expect(snapshot.children?.length).to.be.greaterThan(0); + const badgeNode = snapshot.children?.find( + (child: { name?: string }) => child.name?.includes('100') + ); + expect(badgeNode).to.exist; + }); + }); + + describe('with number exceeding threshold', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 900 + `); + await element.updateComplete; + }); + + it('should display threshold with "+" in the accessibility tree', async function() { + const snapshot = await a11ySnapshot(); + const badgeNode = snapshot.children?.find( + (child: { name?: string }) => child.name?.includes('100+') + ); + expect(badgeNode).to.exist; + }); + }); + + describe('with number below threshold', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 50 + `); + await element.updateComplete; + }); + + it('should display the number without "+" in the accessibility tree', async function() { + const snapshot = await a11ySnapshot(); + const badgeNode = snapshot.children?.find( + (child: { name?: string }) => + child.name?.includes('50') && !child.name?.includes('+') + ); + expect(badgeNode).to.exist; + }); + }); + + describe('without state attribute', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 10 + `); + await element.updateComplete; + }); + + it('should display default background color', function() { + const [r, g, b] = getColor(element, 'background-color'); + expect([r, g, b]).to.deep.equal(hexToRgb('#f0f0f0')); + }); + }); + + describe('with state="read"', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 10 + `); + await element.updateComplete; + }); + + it('should display read background color', function() { + const [r, g, b] = getColor(element, 'background-color'); + expect([r, g, b]).to.deep.equal(hexToRgb('#f0f0f0')); + }); + }); + + describe('with state="unread"', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 10 + `); + await element.updateComplete; + }); + + it('should display unread background color', function() { + const [r, g, b] = getColor(element, 'background-color'); + expect([r, g, b]).to.deep.equal(hexToRgb('#0066cc')); + }); + + it('should display unread text color', function() { + const [r, g, b] = getColor(element, 'color'); + expect([r, g, b]).to.deep.equal(hexToRgb('#ffffff')); + }); + }); + + describe('with disabled attribute', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + 10 + `); + await element.updateComplete; + }); + + it('should display disabled background color', function() { + const [r, g, b] = getColor(element, 'background-color'); + expect([r, g, b]).to.deep.equal(hexToRgb('#d2d2d2')); + }); + + it('should have pointer-events: none', function() { + const styles = getComputedStyle(element); + expect(styles.pointerEvents).to.equal('none'); + }); + }); + + describe('accessibility', function() { + it('should contain text in the accessibility tree', async function() { + await createFixture(html` + 10 + `); + const snapshot = await a11ySnapshot(); + expect(snapshot.children?.length).to.be.greaterThan(0); + }); + }); + + describe('slot content', function() { + let element: PfV6Badge; + + beforeEach(async function() { + element = await createFixture(html` + Custom Text + `); + await element.updateComplete; + }); + + it('should display slotted text content when no number is set', function() { + expect(element.textContent?.trim()).to.equal('Custom Text'); + }); + }); +}); From 4b6f72826973cc640289af87ce60ee1d4f63db54 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Fri, 8 May 2026 15:28:56 -0400 Subject: [PATCH 02/12] fix(badge): apply review fixes - Remove reflect from number and threshold properties (no CSS selectors) - Fix threshold comparison: use <= instead of < so number=threshold shows + - Simplify render return type to TemplateResult - Add cem generate output path to config Assisted-By: Claude Opus 4.6 --- .config/cem.yaml | 1 + elements/pf-v6-badge/pf-v6-badge.ts | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.config/cem.yaml b/.config/cem.yaml index febc90fcec..86f5f070a6 100644 --- a/.config/cem.yaml +++ b/.config/cem.yaml @@ -1,5 +1,6 @@ sourceControlRootUrl: https://github.com/patternfly/patternfly-elements/tree/main/ generate: + output: ./elements/custom-elements.json files: - ./elements/*/*.ts - ./core/*/*.ts diff --git a/elements/pf-v6-badge/pf-v6-badge.ts b/elements/pf-v6-badge/pf-v6-badge.ts index 2492456c14..50bcd55173 100644 --- a/elements/pf-v6-badge/pf-v6-badge.ts +++ b/elements/pf-v6-badge/pf-v6-badge.ts @@ -44,21 +44,21 @@ export class PfV6Badge extends LitElement { * You can pair it with `threshold` attribute to add a `+` sign * if the number exceeds the threshold value. */ - @property({ reflect: true, type: Number }) number?: number; + @property({ type: Number }) number?: number; /** * Sets a threshold for the numeric value and adds `+` sign if * the numeric value exceeds the threshold value. */ - @property({ reflect: true, type: Number }) threshold?: number; + @property({ type: Number }) threshold?: number; /** Disables the badge */ @property({ type: Boolean, reflect: true }) disabled = false; - override render(): TemplateResult<1> { + override render(): TemplateResult { const { threshold, number } = this; const displayText = - (threshold && number && (threshold < number)) ? `${threshold.toString()}+` + (threshold && number && (threshold <= number)) ? `${threshold.toString()}+` : (number != null) ? number.toString() : ''; return html`${!displayText ? html`` : displayText}`; From 4253b926e62542166f42e1c2ef718e5fe3687574 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Fri, 8 May 2026 15:49:23 -0400 Subject: [PATCH 03/12] test(badge): move test to element directory --- elements/pf-v6-badge/pf-v6-badge.ts | 2 +- elements/{ => pf-v6-badge}/test/pf-v6-badge.spec.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename elements/{ => pf-v6-badge}/test/pf-v6-badge.spec.ts (100%) diff --git a/elements/pf-v6-badge/pf-v6-badge.ts b/elements/pf-v6-badge/pf-v6-badge.ts index 50bcd55173..e22a11ee9c 100644 --- a/elements/pf-v6-badge/pf-v6-badge.ts +++ b/elements/pf-v6-badge/pf-v6-badge.ts @@ -31,7 +31,7 @@ export type BadgeState = 'unread' | 'read'; */ @customElement('pf-v6-badge') export class PfV6Badge extends LitElement { - static readonly styles = [styles]; + static readonly styles: CSSStyleSheet[] = [styles]; /** * Denotes the state-of-affairs this badge represents. diff --git a/elements/test/pf-v6-badge.spec.ts b/elements/pf-v6-badge/test/pf-v6-badge.spec.ts similarity index 100% rename from elements/test/pf-v6-badge.spec.ts rename to elements/pf-v6-badge/test/pf-v6-badge.spec.ts From 3a4af73fbece2c80b62ceb051aa70c9d5aa8a99b Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Fri, 8 May 2026 16:01:27 -0400 Subject: [PATCH 04/12] docs(badge): correct index demo to simplest --- elements/pf-v6-badge/demo/index.html | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/elements/pf-v6-badge/demo/index.html b/elements/pf-v6-badge/demo/index.html index b0239ac479..418d93581a 100644 --- a/elements/pf-v6-badge/demo/index.html +++ b/elements/pf-v6-badge/demo/index.html @@ -1,11 +1,8 @@ --- -name: Read -description: Read badges display a numeric value with read state styling, indicating the content has been viewed. +name: Basic +description: A basic badge displays a numeric value. --- -7 -24 -240 -999+ +7 -``` - -Or, if you are using [NPM](https://npm.im), install it - -```bash -npm install @patternfly/elements -``` - -Then once installed, import it to your application: - -```js -import '@patternfly/elements/pf-v5-badge/pf-v5-badge.js'; -``` - -## Usage - -```html -
- 2 -
-``` - -Please refer to the [specification](https://www.w3.org/TR/wai-aria/#aria-label) for additional details. - -With the `threshold` attribute: - -```html -
- 1 - 17 - 900 -
-``` - -With two state options for the `state` attribute: - -```html -
- 10 - 20 -
-``` - diff --git a/elements/pf-v5-badge/demo/index.html b/elements/pf-v5-badge/demo/index.html deleted file mode 100644 index 0976ef0f30..0000000000 --- a/elements/pf-v5-badge/demo/index.html +++ /dev/null @@ -1,12 +0,0 @@ -
- 613 -
- - - diff --git a/elements/pf-v5-badge/demo/read.html b/elements/pf-v5-badge/demo/read.html deleted file mode 100644 index d8f5029bcc..0000000000 --- a/elements/pf-v5-badge/demo/read.html +++ /dev/null @@ -1,15 +0,0 @@ -
- 7 - 24 - 240 - 999 -
- - - diff --git a/elements/pf-v5-badge/demo/threshold.html b/elements/pf-v5-badge/demo/threshold.html deleted file mode 100644 index 2132e3679a..0000000000 --- a/elements/pf-v5-badge/demo/threshold.html +++ /dev/null @@ -1,16 +0,0 @@ -
- 400 - 900 -

In this demo, the threshold is set to 500. - It should add '+' sign if the value exceeds the threshold. - It shouldn't add a '+' sign if the value doesn't exceed the threshold

-
- - - diff --git a/elements/pf-v5-badge/demo/unread.html b/elements/pf-v5-badge/demo/unread.html deleted file mode 100644 index 826b244593..0000000000 --- a/elements/pf-v5-badge/demo/unread.html +++ /dev/null @@ -1,15 +0,0 @@ -
- 7 - 24 - 240 - 999 -
- - - diff --git a/elements/pf-v5-badge/docs/CHANGELOG.old.md b/elements/pf-v5-badge/docs/CHANGELOG.old.md deleted file mode 100644 index e3d18c1936..0000000000 --- a/elements/pf-v5-badge/docs/CHANGELOG.old.md +++ /dev/null @@ -1,62 +0,0 @@ -# @patternfly/pfe-badge - -## 2.0.0-next.4 - -### Patch Changes - -- 5bc0a5ad: Made `state` property on `BaseBadge` abstract. - -## 2.0.0-next.3 - -### Major Changes - -- 686c01e2: Rewrote `` to more closely implement the PatternFly v4 spec. This includes component API changes, but HTML implementation remains the same. - - ```html - 7 - ``` - - ```html - 7 - ``` - - #### Updates - - - Options for the `state` attribute have changed to `read` and `unread`. - - `pfe` Sass variables were replaced by `--pf-*` css variables. - -## 2.0.0-next.2 - -### Patch Changes - -- bfad8b4b: Updates dependencies -- Updated dependencies [bfad8b4b] - - @patternfly/pfe-core@2.0.0-next.8 - -## 2.0.0-next.1 - -### Patch Changes - -- 447b2d75: Remove `esbuild` export condition, as this anyways was a runtime error -- Updated dependencies [447b2d75] - - @patternfly/pfe-core@2.0.0-next.3 - -## 2.0.0-next.0 - -### Major Changes - -- e4a76fb2: ## 🔥 Migrate to Lit - - This release migrates `` to LitElement. - - ### Breaking Changes - - - Initial render is now [asynchronous](https://lit.dev/docs/components/lifecycle/#reactive-update-cycle). - If your code assumes that shadow DOM is ready once the element is constructed, update it to `await element.updateComplete`; - - See [docs](https://patternflyelements.org/components/badge/) for more info - -### Patch Changes - -- Updated dependencies [e8788c72] - - @patternfly/pfe-core@2.0.0-next.0 diff --git a/elements/pf-v5-badge/docs/pf-v5-badge.md b/elements/pf-v5-badge/docs/pf-v5-badge.md deleted file mode 100644 index 02d5080fdc..0000000000 --- a/elements/pf-v5-badge/docs/pf-v5-badge.md +++ /dev/null @@ -1,43 +0,0 @@ -{% renderInstallation %} {% endrenderInstallation %} - -{% renderOverview %} - 17 - 900 - 10 -{% endrenderOverview %} - -{% band header="Usage" %} - To provide context to your badge, it is highly encouraged that you also include an `aria-label` attribute in your markup. - - ### Default - {% htmlexample %} - 2 - {% endhtmlexample %} - - ### With a threshold - This adds a "+" next to the number once the threshold value has been passed. - - {% htmlexample %} - 20 - {% endhtmlexample %} - - ### With a state - This adds a background color to the badge based on the state. - - {% htmlexample %} - 10 - 20 - {% endhtmlexample %} -{% endband %} - -{% renderSlots %}{% endrenderSlots %} - -{% renderAttributes %}{% endrenderAttributes %} - -{% renderMethods %}{% endrenderMethods %} - -{% renderEvents %}{% endrenderEvents %} - -{% renderCssCustomProperties %}{% endrenderCssCustomProperties %} - -{% renderCssParts %}{% endrenderCssParts %} diff --git a/elements/pf-v5-badge/docs/screenshot.png b/elements/pf-v5-badge/docs/screenshot.png deleted file mode 100644 index 0d28220ba3c95a379141e134d7438e9f2c31a405..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8955 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 WHjY~ujl$p|Nam%&i(+vDzyAVX1UD1_ diff --git a/elements/pf-v5-badge/pf-v5-badge.css b/elements/pf-v5-badge/pf-v5-badge.css deleted file mode 100644 index 732ed346ca..0000000000 --- a/elements/pf-v5-badge/pf-v5-badge.css +++ /dev/null @@ -1,51 +0,0 @@ -:host { - position: relative; - white-space: nowrap; - text-align: center; - display: inline-block; - /** Border radius for badge */ - border-radius: var(--pf-v5-c-badge--BorderRadius, - var(--pf-global--BorderRadius--lg, 180em)); - /** Minimum width for badge */ - min-width: var(--pf-v5-c-badge--MinWidth, - var(--pf-global--spacer--xl, 2rem)); - /** Left padding for badge */ - padding-left: var(--pf-v5-c-badge--PaddingLeft, - var(--pf-global--spacer--sm, 0.5rem)); - /** Right padding for badge */ - padding-right: var(--pf-v5-c-badge--PaddingRight, - var(--pf-global--spacer--sm, 0.5rem)); - /** Font size for badge */ - font-size: var(--pf-v5-c-badge--FontSize, - var(--pf-v5-theme--font-size, 0.75em)); - /** Font weight for badge */ - font-weight: var(--pf-v5-c-badge--FontWeight, - var(--pf-v5-theme--font-weight--bold, 700)); - /** Line height for badge */ - line-height: var(--pf-v5-c-badge--LineHeight, - var(--pf-global--LineHeight--md, 1.5)); - /** Color for badge */ - color: var(--pf-v5-c-badge--Color, - var(--pf-global--palette--black-900, #151515)); - /** Background color for badge */ - background-color: var(--pf-v5-c-badge--BackgroundColor, - var(--pf-global--palette--black-200, #f0f0f0)); -} - -:host([state="read"]) { - /** Color for read badge */ - --pf-v5-c-badge--Color: var(--pf-v5-c-badge--m-read--Color, - var(--pf-global--palette--black-900, #151515)); - /** Background color for read badge */ - --pf-v5-c-badge--BackgroundColor: var(--pf-v5-c-badge--m-read--BackgroundColor, - var(--pf-global--palette--black-200, #f0f0f0)); -} - -:host([state="unread"]) { - /** Color for unread badge */ - --pf-v5-c-badge--Color: var(--pf-v5-c-badge--m-unread--Color, - var(--pf-global--palette--white, #fff)); - /** Background color for unread badge */ - --pf-v5-c-badge--BackgroundColor: var(--pf-v5-c-badge--m-unread--BackgroundColor, - var(--pf-global--palette--blue-400, #06c)); -} diff --git a/elements/pf-v5-badge/pf-v5-badge.ts b/elements/pf-v5-badge/pf-v5-badge.ts deleted file mode 100644 index b2fd42a183..0000000000 --- a/elements/pf-v5-badge/pf-v5-badge.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { LitElement, html, type TemplateResult } from 'lit'; -import { customElement } from 'lit/decorators/custom-element.js'; -import { property } from 'lit/decorators/property.js'; - -import styles from './pf-v5-badge.css'; - -/** - * A **badge** is used to annotate other information like a label or an object name. - * @alias Badge - */ - - -@customElement('pf-v5-badge') -export class PfV5Badge extends LitElement { - static readonly styles: CSSStyleSheet[] = [styles]; - - /** - * Denotes the state-of-affairs this badge represents - * Options include read and unread - */ - @property({ reflect: true }) state?: 'unread' | 'read'; - - /** - * Sets a numeric value for a badge. - * - * You can pair it with `threshold` attribute to add a `+` sign - * if the number exceeds the threshold value. - */ - @property({ reflect: true, type: Number }) number?: number; - - /** - * Sets a threshold for the numeric value and adds `+` sign if - * the numeric value exceeds the threshold value. - */ - @property({ reflect: true, type: Number }) threshold?: number; - - override render(): TemplateResult<1> { - const { threshold, number, textContent } = this; - const displayText = - (threshold && number && (threshold < number)) ? `${threshold.toString()}+` - : (number != null) ? number.toString() - : textContent ?? ''; - return html` - ${displayText} - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'pf-v5-badge': PfV5Badge; - } -} diff --git a/elements/pf-v5-badge/test/pf-badge.e2e.ts b/elements/pf-v5-badge/test/pf-badge.e2e.ts deleted file mode 100644 index cbf4e4d311..0000000000 --- a/elements/pf-v5-badge/test/pf-badge.e2e.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { test } from '@playwright/test'; -import { PfeDemoPage } from '@patternfly/pfe-tools/test/playwright/PfeDemoPage.js'; -import { SSRPage } from '@patternfly/pfe-tools/test/playwright/SSRPage.js'; - -const tagName = 'pf-v5-badge'; - -test.describe(tagName, () => { - test('snapshot', async ({ page }) => { - const componentPage = new PfeDemoPage(page, tagName); - await componentPage.navigate(); - await componentPage.snapshot(); - }); - - test('ssr', async ({ browser }) => { - const fixture = new SSRPage({ - tagName, - browser, - demoDir: new URL('../demo/', import.meta.url), - importSpecifiers: [ - `@patternfly/elements/${tagName}/${tagName}.js`, - ], - }); - await fixture.snapshots(); - }); -}); diff --git a/elements/pf-v5-badge/test/pf-badge.spec.ts b/elements/pf-v5-badge/test/pf-badge.spec.ts deleted file mode 100644 index 5eb0726cb2..0000000000 --- a/elements/pf-v5-badge/test/pf-badge.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { expect, html, nextFrame } from '@open-wc/testing'; -import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js'; -import { hexToRgb, getColor } from '@patternfly/pfe-tools/test/hex-to-rgb.js'; -import { PfV5Badge } from '@patternfly/elements/pf-v5-badge/pf-v5-badge.js'; - -// Background colors for the various states -const states = { - default: '#f0f0f0', - read: '#f0f0f0', - unread: '#0066cc', -}; - -const element = html`10`; - -describe('', function() { - it('imperatively instantiates', function() { - expect(document.createElement('pf-v5-badge')).to.be.an.instanceof(PfV5Badge); - }); - - it('should upgrade', async function() { - const el = await createFixture(element); - expect(el, 'pf-v5-badge should be an instance of PfV5Badge') - .to.be.an - .instanceOf(customElements.get('pf-v5-badge')) - .and - .to.be.an.instanceof(PfV5Badge); - }); - - it('should display text equivalent to the number attribute', async function() { - const el = await createFixture(html`10`); - await nextFrame(); - expect(el.shadowRoot!.querySelector('span')!.textContent).to.equal('100'); - }); - - it('should add \'+\' sign if the value exceeds the threshold', async function() { - const el = await createFixture(html`900`); - await nextFrame(); - expect(el.shadowRoot!.querySelector('span')!.textContent).to.equal('100+'); - }); - - it('shouldn\'t add a \'+\' sign if the value doesn\'t exceed the threshold', async function() { - const el = await createFixture(html`900`); - await el.updateComplete; - expect(el.textContent).to.equal('900'); - expect(el.shadowRoot!.querySelector('span')!.textContent).to.equal('900'); - }); - - // This is the one that created an error: - Object.entries(states).forEach(([state, color]) => { - it(`should have a background color of '${color}' when state is ${state}`, async function() { - const el = await createFixture(element); - - if (state !== 'default') { - el.setAttribute('state', state); - } - - const [r, g, b] = getColor(el, 'background-color'); - expect([r, g, b]).to.deep.equal(hexToRgb(color)); - }); - }); -}); From c9a849a68c5adde36040fbfcbb3674361c1a3782 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Wed, 13 May 2026 13:13:50 -0400 Subject: [PATCH 06/12] chore: replace pf-v5-badge refs with pf-v6-badge refs --- elements/pf-v5-select/pf-v5-select.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elements/pf-v5-select/pf-v5-select.ts b/elements/pf-v5-select/pf-v5-select.ts index eda637b4c6..b7fafc5559 100644 --- a/elements/pf-v5-select/pf-v5-select.ts +++ b/elements/pf-v5-select/pf-v5-select.ts @@ -216,7 +216,7 @@ export class PfV5Select extends LitElement { ${this.#buttonLabel}${!hasBadge ? '' : html` - ${selectedOptions.length} + ${selectedOptions.length} `} Date: Wed, 13 May 2026 13:14:40 -0400 Subject: [PATCH 07/12] fix(badge): correct jsdoc to cem format documentation --- elements/pf-v6-badge/pf-v6-badge.css | 105 ++++++++++++++++++--------- elements/pf-v6-badge/pf-v6-badge.ts | 21 +----- 2 files changed, 72 insertions(+), 54 deletions(-) diff --git a/elements/pf-v6-badge/pf-v6-badge.css b/elements/pf-v6-badge/pf-v6-badge.css index e158aedfcd..5acc5dad8b 100644 --- a/elements/pf-v6-badge/pf-v6-badge.css +++ b/elements/pf-v6-badge/pf-v6-badge.css @@ -1,24 +1,40 @@ :host { position: relative; display: inline-block; - min-width: var(--pf-v6-c-badge--MinWidth, - var(--pf-t--global--spacer--xl, 2rem)); - padding-inline-start: var(--pf-v6-c-badge--PaddingInlineStart, - var(--pf-t--global--spacer--sm, 0.5rem)); - padding-inline-end: var(--pf-v6-c-badge--PaddingInlineEnd, - var(--pf-t--global--spacer--sm, 0.5rem)); - font-size: var(--pf-v6-c-badge--FontSize, - var(--pf-t--global--font--size--body--sm, 0.75rem)); - font-weight: var(--pf-v6-c-badge--FontWeight, - var(--pf-t--global--font--weight--body--bold, 700)); - color: var(--pf-v6-c-badge--Color, - var(--pf-t--global--text--color--nonstatus--on-gray--default, #151515)); + min-width: + /** Minimum width of the badge */ + var(--pf-v6-c-badge--MinWidth, + var(--pf-t--global--spacer--xl, 2rem)); + padding-inline-start: + /** Inline start padding */ + var(--pf-v6-c-badge--PaddingInlineStart, + var(--pf-t--global--spacer--sm, 0.5rem)); + padding-inline-end: + /** Inline end padding */ + var(--pf-v6-c-badge--PaddingInlineEnd, + var(--pf-t--global--spacer--sm, 0.5rem)); + font-size: + /** Font size of the badge text */ + var(--pf-v6-c-badge--FontSize, + var(--pf-t--global--font--size--body--sm, 0.75rem)); + font-weight: + /** Font weight of the badge text */ + var(--pf-v6-c-badge--FontWeight, + var(--pf-t--global--font--weight--body--bold, 700)); + color: + /** Text color of the badge */ + var(--pf-v6-c-badge--Color, + var(--pf-t--global--text--color--nonstatus--on-gray--default, #151515)); text-align: center; white-space: nowrap; - background-color: var(--pf-v6-c-badge--BackgroundColor, - var(--pf-t--global--color--nonstatus--gray--default, #f0f0f0)); - border-radius: var(--pf-v6-c-badge--BorderRadius, - var(--pf-t--global--border--radius--pill, 180em)); + background-color: + /** Background color of the badge */ + var(--pf-v6-c-badge--BackgroundColor, + var(--pf-t--global--color--nonstatus--gray--default, #f0f0f0)); + border-radius: + /** Border radius of the badge */ + var(--pf-v6-c-badge--BorderRadius, + var(--pf-t--global--border--radius--pill, 180em)); } :host::after { @@ -26,33 +42,54 @@ inset: 0; pointer-events: none; content: ""; - border: var(--pf-v6-c-badge--BorderWidth, - var(--pf-t--global--border--width--regular, 1px)) solid var(--pf-v6-c-badge--BorderColor, transparent); + border: + /** Border width of the badge */ + var(--pf-v6-c-badge--BorderWidth, + var(--pf-t--global--border--width--regular, 1px)) + solid + /** Border color of the badge */ + var(--pf-v6-c-badge--BorderColor, transparent); border-radius: inherit; } :host([state="read"]) { - --pf-v6-c-badge--Color: var(--pf-v6-c-badge--m-read--Color, - var(--pf-t--global--text--color--nonstatus--on-gray--default, #151515)); - --pf-v6-c-badge--BackgroundColor: var(--pf-v6-c-badge--m-read--BackgroundColor, - var(--pf-t--global--color--nonstatus--gray--default, #f0f0f0)); - --pf-v6-c-badge--BorderColor: var(--pf-v6-c-badge--m-read--BorderColor, - var(--pf-t--global--border--color--high-contrast, #151515)); + --pf-v6-c-badge--Color: + /** Text color in read state */ + var(--pf-v6-c-badge--m-read--Color, + var(--pf-t--global--text--color--nonstatus--on-gray--default, #151515)); + --pf-v6-c-badge--BackgroundColor: + /** Background color in read state */ + var(--pf-v6-c-badge--m-read--BackgroundColor, + var(--pf-t--global--color--nonstatus--gray--default, #f0f0f0)); + --pf-v6-c-badge--BorderColor: + /** Border color in read state */ + var(--pf-v6-c-badge--m-read--BorderColor, + var(--pf-t--global--border--color--high-contrast, #151515)); } :host([state="unread"]) { - --pf-v6-c-badge--Color: var(--pf-v6-c-badge--m-unread--Color, - var(--pf-t--global--text--color--on-brand--default, #fff)); - --pf-v6-c-badge--BackgroundColor: var(--pf-v6-c-badge--m-unread--BackgroundColor, - var(--pf-t--global--color--brand--default, #06c)); + --pf-v6-c-badge--Color: + /** Text color in unread state */ + var(--pf-v6-c-badge--m-unread--Color, + var(--pf-t--global--text--color--on-brand--default, #fff)); + --pf-v6-c-badge--BackgroundColor: + /** Background color in unread state */ + var(--pf-v6-c-badge--m-unread--BackgroundColor, + var(--pf-t--global--color--brand--default, #06c)); } :host([disabled]) { - --pf-v6-c-badge--Color: var(--pf-v6-c-badge--m-disabled--Color, - var(--pf-t--global--text--color--on-disabled, #6a6e73)); - --pf-v6-c-badge--BackgroundColor: var(--pf-v6-c-badge--m-disabled--BackgroundColor, - var(--pf-t--global--background--color--disabled--default, #d2d2d2)); - --pf-v6-c-badge--BorderColor: var(--pf-v6-c-badge--m-disabled--BorderColor, - var(--pf-t--global--border--color--disabled, #d2d2d2)); + --pf-v6-c-badge--Color: + /** Text color when disabled */ + var(--pf-v6-c-badge--m-disabled--Color, + var(--pf-t--global--text--color--on-disabled, #6a6e73)); + --pf-v6-c-badge--BackgroundColor: + /** Background color when disabled */ + var(--pf-v6-c-badge--m-disabled--BackgroundColor, + var(--pf-t--global--background--color--disabled--default, #d2d2d2)); + --pf-v6-c-badge--BorderColor: + /** Border color when disabled */ + var(--pf-v6-c-badge--m-disabled--BorderColor, + var(--pf-t--global--border--color--disabled, #d2d2d2)); pointer-events: none; } diff --git a/elements/pf-v6-badge/pf-v6-badge.ts b/elements/pf-v6-badge/pf-v6-badge.ts index e22a11ee9c..34742a9d2c 100644 --- a/elements/pf-v6-badge/pf-v6-badge.ts +++ b/elements/pf-v6-badge/pf-v6-badge.ts @@ -9,25 +9,6 @@ export type BadgeState = 'unread' | 'read'; /** * A **badge** is used to annotate other information like a label or an object name. * @summary Displays a numeric value as an annotation - * @slot - Badge content, typically a number or short text - * @cssprop {} --pf-v6-c-badge--Color - Text color of the badge - * @cssprop {} --pf-v6-c-badge--BackgroundColor - Background color of the badge - * @cssprop {} --pf-v6-c-badge--BorderColor - Border color of the badge - * @cssprop {} --pf-v6-c-badge--BorderWidth - Border width of the badge - * @cssprop {} --pf-v6-c-badge--BorderRadius - Border radius of the badge - * @cssprop {} --pf-v6-c-badge--MinWidth - Minimum width of the badge - * @cssprop {} --pf-v6-c-badge--PaddingInlineStart - Inline start padding - * @cssprop {} --pf-v6-c-badge--PaddingInlineEnd - Inline end padding - * @cssprop {} --pf-v6-c-badge--FontSize - Font size of the badge text - * @cssprop {} --pf-v6-c-badge--FontWeight - Font weight of the badge text - * @cssprop {} --pf-v6-c-badge--m-read--Color - Text color in read state - * @cssprop {} --pf-v6-c-badge--m-read--BackgroundColor - Background color in read state - * @cssprop {} --pf-v6-c-badge--m-read--BorderColor - Border color in read state - * @cssprop {} --pf-v6-c-badge--m-unread--Color - Text color in unread state - * @cssprop {} --pf-v6-c-badge--m-unread--BackgroundColor - Background color in unread state - * @cssprop {} --pf-v6-c-badge--m-disabled--Color - Text color when disabled - * @cssprop {} --pf-v6-c-badge--m-disabled--BackgroundColor - Background color when disabled - * @cssprop {} --pf-v6-c-badge--m-disabled--BorderColor - Border color when disabled */ @customElement('pf-v6-badge') export class PfV6Badge extends LitElement { @@ -61,7 +42,7 @@ export class PfV6Badge extends LitElement { (threshold && number && (threshold <= number)) ? `${threshold.toString()}+` : (number != null) ? number.toString() : ''; - return html`${!displayText ? html`` : displayText}`; + return html`${!displayText ? html`` : displayText}`; } } From 54dd0e88b787ad4b20255b24334a8fd513aae2d8 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Wed, 13 May 2026 14:00:51 -0400 Subject: [PATCH 08/12] chore: add changeset --- .changeset/forty-ties-crash.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .changeset/forty-ties-crash.md diff --git a/.changeset/forty-ties-crash.md b/.changeset/forty-ties-crash.md new file mode 100644 index 0000000000..1e46cebaa8 --- /dev/null +++ b/.changeset/forty-ties-crash.md @@ -0,0 +1,20 @@ +--- +"@patternfly/elements": major +--- + +✨ Added `` replacing ``. Badge now follows +PatternFly v6 design specs. + +```html +7 +``` + +** Breaking Changes from v5 ** + +- Renamed tag from `` to `` +- ✨ Added `disabled` attribute +- ✨ Added v6 design tokens and `color-scheme` support via `light-dark()` +- CSS custom properties renamed from `--pf-v5-c-badge--*` to `--pf-v6-c-badge--*` +- `threshold` comparison changed from < to <= (now shows + when number equals +threshold) +- `number` and `threshold` no longer reflect to attributes From deb4a0fe584dd163720edb524eb9c279a3168836 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Thu, 14 May 2026 12:16:54 -0400 Subject: [PATCH 09/12] docs(badge): add README.md --- elements/pf-v6-badge/README.md | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 elements/pf-v6-badge/README.md diff --git a/elements/pf-v6-badge/README.md b/elements/pf-v6-badge/README.md new file mode 100644 index 0000000000..99cf9cf053 --- /dev/null +++ b/elements/pf-v6-badge/README.md @@ -0,0 +1,54 @@ +# Badge + +A badge is used to annotate other information like a label or an object name. + +## Usage + +### Basic badge with a number + +```html + +``` + +### Read badge with threshold + +```html + +``` + +### Badge with slotted content + +```html +New +``` + +## Divergences from React `Badge` + +### Not implemented + +| React prop | Notes | +| --- | --- | +| `screenReaderText` | No built-in screen reader text span. Authors should provide their own visually-hidden text adjacent to the badge. | + +### Changed API + +| React prop | Web component | Difference | +| --- | --- | --- | +| `isRead` | `state` attribute | Boolean replaced with `'read' \| 'unread'` enum. Omitting `state` gives neutral styling (no read/unread indication). | + +### Added + +| Web component API | Notes | +| --- | --- | +| `number` property | Numeric value displayed in the badge. | +| `threshold` property | When `number` exceeds this value, displays `{threshold}+` instead. | +| `--pf-v6-c-badge--MinWidth` | Minimum width of the badge. | +| `--pf-v6-c-badge--PaddingInlineStart` | Inline start padding. | +| `--pf-v6-c-badge--PaddingInlineEnd` | Inline end padding. | +| `--pf-v6-c-badge--FontSize` | Font size of the badge text. | +| `--pf-v6-c-badge--FontWeight` | Font weight of the badge text. | +| `--pf-v6-c-badge--Color` | Text color of the badge. | +| `--pf-v6-c-badge--BackgroundColor` | Background color of the badge. | +| `--pf-v6-c-badge--BorderRadius` | Border radius of the badge. | +| `--pf-v6-c-badge--BorderWidth` | Border width of the badge. | +| `--pf-v6-c-badge--BorderColor` | Border color of the badge. | From 28fb72ca013f12061cb2a44998486d4a4fec1df8 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Tue, 19 May 2026 10:34:37 -0400 Subject: [PATCH 10/12] fix(badge): improve language around screen reader text usage --- elements/pf-v6-badge/README.md | 2 +- elements/pf-v6-badge/pf-v6-badge.ts | 4 +++- elements/pf-v6-badge/test/pf-v6-badge.spec.ts | 13 +++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/elements/pf-v6-badge/README.md b/elements/pf-v6-badge/README.md index 99cf9cf053..6cc3dc115e 100644 --- a/elements/pf-v6-badge/README.md +++ b/elements/pf-v6-badge/README.md @@ -28,7 +28,7 @@ A badge is used to annotate other information like a label or an object name. | React prop | Notes | | --- | --- | -| `screenReaderText` | No built-in screen reader text span. Authors should provide their own visually-hidden text adjacent to the badge. | +| `screenReaderText` | Authors slot visually-hidden text alongside the badge content for screen reader context, e.g. `3 unread messages
`. | ### Changed API diff --git a/elements/pf-v6-badge/pf-v6-badge.ts b/elements/pf-v6-badge/pf-v6-badge.ts index 34742a9d2c..9d3b0e85a4 100644 --- a/elements/pf-v6-badge/pf-v6-badge.ts +++ b/elements/pf-v6-badge/pf-v6-badge.ts @@ -9,6 +9,8 @@ export type BadgeState = 'unread' | 'read'; /** * A **badge** is used to annotate other information like a label or an object name. * @summary Displays a numeric value as an annotation + * @slot - Badge content, typically a number or short text. Include a visually-hidden + * `` for screen reader context when the number alone is not descriptive. */ @customElement('pf-v6-badge') export class PfV6Badge extends LitElement { @@ -42,7 +44,7 @@ export class PfV6Badge extends LitElement { (threshold && number && (threshold <= number)) ? `${threshold.toString()}+` : (number != null) ? number.toString() : ''; - return html`${!displayText ? html`` : displayText}`; + return html`${!displayText ? html`` : displayText}`; } } diff --git a/elements/pf-v6-badge/test/pf-v6-badge.spec.ts b/elements/pf-v6-badge/test/pf-v6-badge.spec.ts index ad2dee0e5b..ea5d07ca37 100644 --- a/elements/pf-v6-badge/test/pf-v6-badge.spec.ts +++ b/elements/pf-v6-badge/test/pf-v6-badge.spec.ts @@ -33,7 +33,6 @@ describe('', function() { it('should be visible in the accessibility tree', async function() { const snapshot = await a11ySnapshot(); - expect(snapshot.children?.length).to.be.greaterThan(0); const badgeNode = snapshot.children?.find( (child: { name?: string }) => child.name?.includes('100') ); @@ -155,12 +154,22 @@ describe('', function() { }); describe('accessibility', function() { + it('should be accessible', async function() { + const element = await createFixture(html` + 10 + `); + await expect(element).to.be.accessible(); + }); + it('should contain text in the accessibility tree', async function() { await createFixture(html` 10 `); const snapshot = await a11ySnapshot(); - expect(snapshot.children?.length).to.be.greaterThan(0); + const badgeNode = snapshot.children?.find( + (child: { name?: string }) => child.name?.includes('10') + ); + expect(badgeNode).to.exist; }); }); From ebbecc3b321216d19f341d14a42697ea6af1480f Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Tue, 19 May 2026 14:42:54 -0400 Subject: [PATCH 11/12] docs(badge): add missing docs markdown and screenshot --- elements/pf-v6-badge/docs/pf-v6-badge.md | 39 +++++++++++++++++++++++ elements/pf-v6-badge/docs/screenshot.png | Bin 0 -> 25286 bytes 2 files changed, 39 insertions(+) create mode 100644 elements/pf-v6-badge/docs/pf-v6-badge.md create mode 100644 elements/pf-v6-badge/docs/screenshot.png diff --git a/elements/pf-v6-badge/docs/pf-v6-badge.md b/elements/pf-v6-badge/docs/pf-v6-badge.md new file mode 100644 index 0000000000..331a06e004 --- /dev/null +++ b/elements/pf-v6-badge/docs/pf-v6-badge.md @@ -0,0 +1,39 @@ +{% renderOverview %} + A badge is used to annotate other information like a label or an object name. + + 7 + 24 +{% endrenderOverview %} + +{% band header="Usage" %} + ### Read and unread + {% htmlexample %} + 7 + 24 + {% endhtmlexample %} + + ### With threshold + Use the `threshold` attribute to cap the displayed value with a `+` suffix. + + {% htmlexample %} + 900 + 50 + {% endhtmlexample %} + + ### Disabled + {% htmlexample %} + 10 + {% endhtmlexample %} +{% endband %} + +{% renderSlots %}{% endrenderSlots %} + +{% renderAttributes %}{% endrenderAttributes %} + +{% renderMethods %}{% endrenderMethods %} + +{% renderEvents %}{% endrenderEvents %} + +{% renderCssCustomProperties %}{% endrenderCssCustomProperties %} + +{% renderCssParts %}{% endrenderCssParts %} diff --git a/elements/pf-v6-badge/docs/screenshot.png b/elements/pf-v6-badge/docs/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b04ef300fb730d51924136493c3b9e4e594d8bef GIT binary patch literal 25286 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 literal 0 HcmV?d00001 From df74de84d776b726a33e98fe0d72413e6f3e5dda Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Tue, 19 May 2026 14:43:08 -0400 Subject: [PATCH 12/12] test(badge): add missing e2e test --- elements/pf-v6-badge/test/pf-v6-badge.e2e.ts | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 elements/pf-v6-badge/test/pf-v6-badge.e2e.ts diff --git a/elements/pf-v6-badge/test/pf-v6-badge.e2e.ts b/elements/pf-v6-badge/test/pf-v6-badge.e2e.ts new file mode 100644 index 0000000000..76be61a685 --- /dev/null +++ b/elements/pf-v6-badge/test/pf-v6-badge.e2e.ts @@ -0,0 +1,25 @@ +import { test } from '@playwright/test'; +import { PfeDemoPage } from '@patternfly/pfe-tools/test/playwright/PfeDemoPage.js'; +import { SSRPage } from '@patternfly/pfe-tools/test/playwright/SSRPage.js'; + +const tagName = 'pf-v6-badge'; + +test.describe(tagName, () => { + test('snapshot', async ({ page }) => { + const componentPage = new PfeDemoPage(page, tagName); + await componentPage.navigate(); + await componentPage.snapshot(); + }); + + test('ssr', async ({ browser }) => { + const fixture = new SSRPage({ + tagName, + browser, + demoDir: new URL('../demo/', import.meta.url), + importSpecifiers: [ + `@patternfly/elements/${tagName}/${tagName}.js`, + ], + }); + await fixture.snapshots(); + }); +});