From c3cef091c08d1df35662667af5ffe2ced14874a8 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Wed, 15 Apr 2026 15:42:55 +0300 Subject: [PATCH 1/5] feat(label): add link variant Closes #2499 Assisted-By: Claude Opus 4.6 (1M context) --- .changeset/label-link-variant.md | 6 +++++ elements/pf-label/pf-label.css | 17 +++++++++++++ elements/pf-label/pf-label.ts | 12 ++++++++- elements/pf-label/test/pf-label.spec.ts | 34 +++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .changeset/label-link-variant.md diff --git a/.changeset/label-link-variant.md b/.changeset/label-link-variant.md new file mode 100644 index 0000000000..3801c821ed --- /dev/null +++ b/.changeset/label-link-variant.md @@ -0,0 +1,6 @@ +--- +"@patternfly/elements": minor +--- + +`pf-label`: added link variant. Set the `href` attribute to render the +label as a clickable link. diff --git a/elements/pf-label/pf-label.css b/elements/pf-label/pf-label.css index f5489dc070..fe13cbac2e 100644 --- a/elements/pf-label/pf-label.css +++ b/elements/pf-label/pf-label.css @@ -240,6 +240,23 @@ pf-button { margin-left: var(--pf-c-label__c-button--MarginLeft, 0.25rem); } +#link { + color: inherit; + text-decoration: underline; +} + +#link:hover { + text-decoration: none; +} + +.link { + /** link label background color */ + --pf-c-label--BackgroundColor: transparent; + /** link label border width */ + --pf-c-label__content--before--BorderWidth: 0; + cursor: pointer; +} + svg { vertical-align:-0.125em; fill: currentColor; diff --git a/elements/pf-label/pf-label.ts b/elements/pf-label/pf-label.ts index eea234bd62..7508ebcc62 100644 --- a/elements/pf-label/pf-label.ts +++ b/elements/pf-label/pf-label.ts @@ -2,6 +2,7 @@ import { LitElement, html, isServer, type TemplateResult } from 'lit'; import { customElement } from 'lit/decorators/custom-element.js'; import { property } from 'lit/decorators/property.js'; import { classMap } from 'lit/directives/class-map.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js'; @@ -68,6 +69,9 @@ export class PfLabel extends LitElement { /** Text label for a removable label's close button */ @property({ attribute: 'close-button-label' }) closeButtonLabel?: string; + /** When set, the label becomes a link. The label text renders inside an anchor element. */ + @property({ reflect: true }) href?: string; + /** Represents the state of the anonymous and icon slots */ #slots = new SlotController(this, null, 'icon'); @@ -79,15 +83,17 @@ export class PfLabel extends LitElement { } override render(): TemplateResult<1> { - const { compact, truncated } = this; + const { compact, truncated, href } = this; const { variant, color, icon } = this; const hasIcon = !!icon || this.#slots.hasSlotted('icon'); + const isLink = !!href; return html` + ${isLink ? html` + + ` : html` + `} Default Compact `; +const exampleWithHref = html` + Link Label +`; + describe('', function() { before(function() { @@ -140,4 +144,34 @@ describe('', function() { expect(containerStyles.getPropertyValue('padding-bottom')).to.equal('0px'); expect(containerStyles.getPropertyValue('padding-left')).to.equal('8px'); // 0.5rem = 8px @ 16px browser default }); + + describe('with href attribute', function() { + let element: PfLabel; + beforeEach(async function() { + element = await createFixture(exampleWithHref); + await element.updateComplete; + }); + + it('should render an anchor element', function() { + const link = element.shadowRoot!.querySelector('#link'); + expect(link).to.be.an.instanceOf(HTMLAnchorElement); + }); + + it('should set the href on the anchor', function() { + const link = element.shadowRoot!.querySelector('#link') as HTMLAnchorElement; + expect(link.href).to.equal('https://example.com/'); + }); + + it('should have a transparent background', function() { + const container = element.shadowRoot!.querySelector('#container')!; + expect(getComputedStyle(container).getPropertyValue('background-color')).to.equal('rgba(0, 0, 0, 0)'); + }); + + it('should not render an anchor when href is not set', async function() { + const el = await createFixture(example); + await el.updateComplete; + const link = el.shadowRoot!.querySelector('#link'); + expect(link).to.be.null; + }); + }); }); From 1f43faa25537021e7070a9cb9e5dea0333906c28 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Wed, 15 Apr 2026 16:00:43 +0300 Subject: [PATCH 2/5] docs: changeset --- .changeset/label-link-variant.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.changeset/label-link-variant.md b/.changeset/label-link-variant.md index 3801c821ed..9162432e68 100644 --- a/.changeset/label-link-variant.md +++ b/.changeset/label-link-variant.md @@ -2,5 +2,4 @@ "@patternfly/elements": minor --- -`pf-label`: added link variant. Set the `href` attribute to render the -label as a clickable link. +``: added the `href` attribute to render the label as a clickable link. From 4775ce9c486646ad24dd9610e680949b0a7595b7 Mon Sep 17 00:00:00 2001 From: Steven Spriggs Date: Wed, 15 Apr 2026 11:00:41 -0400 Subject: [PATCH 3/5] docs(label): add link demo --- elements/pf-label/demo/link.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 elements/pf-label/demo/link.html diff --git a/elements/pf-label/demo/link.html b/elements/pf-label/demo/link.html new file mode 100644 index 0000000000..e144cc63b3 --- /dev/null +++ b/elements/pf-label/demo/link.html @@ -0,0 +1,14 @@ +
+ Blue + Green + Orange + Red Hat + Purple + Cyan + Gold + Grey +
+ + From c601c8a13fd161926537c63e23d6b28370bb62c9 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Wed, 15 Apr 2026 19:01:50 +0300 Subject: [PATCH 4/5] fix(label): link labels use border hover, not transparent background Match PFv4 link label behavior: on hover/focus the border thickens to 2px and changes to the primary color. Labels keep their normal background and border styling. Assisted-By: Claude Opus 4.6 (1M context) --- .changeset/label-link-variant.md | 4 +++- elements/pf-label/pf-label.css | 20 +++++++++++--------- elements/pf-label/pf-label.ts | 1 - elements/pf-label/test/pf-label.spec.ts | 5 ----- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/.changeset/label-link-variant.md b/.changeset/label-link-variant.md index 9162432e68..4cd9dabadf 100644 --- a/.changeset/label-link-variant.md +++ b/.changeset/label-link-variant.md @@ -2,4 +2,6 @@ "@patternfly/elements": minor --- -``: added the `href` attribute to render the label as a clickable link. +`pf-label`: added link variant. Set the `href` attribute to render the +label text as a clickable link. On hover, the label border thickens +and changes color to indicate interactivity. diff --git a/elements/pf-label/pf-label.css b/elements/pf-label/pf-label.css index fe13cbac2e..37b171b1da 100644 --- a/elements/pf-label/pf-label.css +++ b/elements/pf-label/pf-label.css @@ -242,21 +242,23 @@ pf-button { #link { color: inherit; - text-decoration: underline; -} - -#link:hover { text-decoration: none; + cursor: pointer; } -.link { - /** link label background color */ - --pf-c-label--BackgroundColor: transparent; - /** link label border width */ - --pf-c-label__content--before--BorderWidth: 0; +:host(:hover) #link ~ *, +:host(:focus-within) #link ~ *, +#link:hover, +#link:focus { cursor: pointer; } +:host(:hover) #container:has(#link)::before, +:host(:focus-within) #container:has(#link)::before { + border-width: var(--pf-c-label__content--link--hover--before--BorderWidth, 2px); + border-color: var(--pf-c-label__content--link--hover--before--BorderColor, var(--pf-global--primary-color--100, #06c)); +} + svg { vertical-align:-0.125em; fill: currentColor; diff --git a/elements/pf-label/pf-label.ts b/elements/pf-label/pf-label.ts index 7508ebcc62..52462efa95 100644 --- a/elements/pf-label/pf-label.ts +++ b/elements/pf-label/pf-label.ts @@ -93,7 +93,6 @@ export class PfLabel extends LitElement { hasIcon, compact, truncated, - link: isLink, [variant ?? '']: !!variant, [color ?? '']: !!color })}">