Skip to content

Commit 587d957

Browse files
tejas161Tejas Gavankarbennypowers
authored
feat(button): add href for Link Variant (#2814)
* fix: add href attribute to pf-button link * chore: add changeset for pf-button * docs: update .changeset/popular-poets-march.md * refactor(button): href * docs: changeset * fix(button): a11y * refactor(button): state * fix(button): link icon spacing and clickable * fix(button): link variant keyb a11y --------- Co-authored-by: Tejas Gavankar <[email protected]> Co-authored-by: Benny Powers - עם ישראל חי! <[email protected]> Co-authored-by: Benny Powers <[email protected]>
1 parent 4cd01f4 commit 587d957

File tree

6 files changed

+90
-35
lines changed

6 files changed

+90
-35
lines changed

.changeset/popular-poets-march.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@patternfly/elements": minor
3+
---
4+
5+
`<pf-button>`: Added `href` attribute to `<pf-button variant="link">`

elements/pf-button/demo/stateful.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
iconBtn.loading = !iconBtn.loading;
3636
});
3737
</script>
38+
3839
<style>
3940
section {
4041
padding: 1em;

elements/pf-button/demo/variants.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ <h2>Disabled</h2>
1919

2020
<section>
2121
<h2>Link variant</h2>
22-
<pf-button variant="link" icon="plus-circle">Link</pf-button>
23-
<pf-button variant="link" icon="link" icon-position="right">Link</pf-button>
24-
<pf-button variant="link" inline>Inline Link</pf-button>
25-
<pf-button variant="link" danger>Danger Link</pf-button>
22+
<pf-button variant="link" icon="plus-circle" href="#link">Link</pf-button>
23+
<pf-button variant="link" icon="link" icon-position="right" href="#icon-link">Link</pf-button>
24+
<pf-button variant="link" inline href="#inline-link">Inline Link</pf-button>
25+
<pf-button variant="link" danger href="#danger-link">Danger Link</pf-button>
2626

2727
<h3>Disabled</h3>
2828
<pf-button disabled

elements/pf-button/docs/pf-button.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ pf-button + pf-button {
4545
<pf-button variant="link" icon-set="patternfly" icon="arrow" icon-position="right">Link</pf-button>
4646
<pf-button variant="link" inline>Inline Link</pf-button>
4747
<pf-button variant="link" danger>Danger Link</pf-button>
48+
<pf-button variant="link" href="#link">Link</pf-button>
49+
<pf-button variant="link" href="https://patternflyelements.org/" target="_blank" icon="location-arrow">Go to PatternFly</pf-button>
4850
{% endhtmlexample %}
4951

5052
### Plain button

elements/pf-button/pf-button.css

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@
1010
var(--pf-global--FontWeight--normal, 400));
1111
line-height: var(--pf-c-button--LineHeight,
1212
var(--pf-global--LineHeight--md, 1.5));
13-
padding:
14-
var(--pf-c-button--PaddingTop,
15-
var(--pf-global--spacer--form-element, 0.375rem))
16-
var(--pf-c-button--PaddingRight,
17-
var(--pf-global--spacer--md, 1rem))
18-
var(--pf-c-button--PaddingBottom,
19-
var(--pf-global--spacer--form-element, 0.375rem))
20-
var(--pf-c-button--PaddingLeft,
21-
var(--pf-global--spacer--md, 1rem));
2213
display: inline-block;
2314
height: max-content;
2415
cursor: pointer;
@@ -51,9 +42,23 @@ pf-icon,
5142
vertical-align: var(--_button-icon-vertical-align);
5243
}
5344

45+
#icon {
46+
margin-inline-end: var(--pf-c-button__icon--m-start--MarginRight,
47+
var(--pf-global--spacer--xs, 0.25rem));
48+
}
49+
5450
#button {
55-
display: contents;
51+
display: inline-block;
5652
color: var(--_button-color);
53+
padding:
54+
var(--pf-c-button--PaddingTop,
55+
var(--pf-global--spacer--form-element, 0.375rem))
56+
var(--pf-c-button--PaddingRight,
57+
var(--pf-global--spacer--md, 1rem))
58+
var(--pf-c-button--PaddingBottom,
59+
var(--pf-global--spacer--form-element, 0.375rem))
60+
var(--pf-c-button--PaddingLeft,
61+
var(--pf-global--spacer--md, 1rem));
5762
&::before,
5863
&::after {
5964
position: absolute;
@@ -72,6 +77,12 @@ pf-icon,
7277
border-color: var(--pf-c-button--after--BorderColor);
7378
border-radius: var(--pf-c-button--after--BorderRadius);
7479
}
80+
&.anchor {
81+
text-decoration: none;
82+
&::after {
83+
pointer-events: all;
84+
}
85+
}
7586
}
7687

7788
#text {
@@ -273,7 +284,7 @@ pf-icon,
273284
* *
274285
******************************/
275286

276-
:host([loading]) {
287+
:host([loading]) #button {
277288
position: relative;
278289
display: flex;
279290
align-items: center;

elements/pf-button/pf-button.ts

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,13 @@ export class PfButton extends LitElement {
204204
/** Icon set for the `icon` property */
205205
@property({ attribute: 'icon-set' }) iconSet?: string;
206206

207-
#internals = InternalsController.of(this, { role: 'button' });
207+
/** Store the URL Link */
208+
@property({ reflect: true }) href?: string;
209+
210+
/** Redirecting the URL Link to new Tab */
211+
@property({ reflect: true }) target?: string;
212+
213+
#internals = InternalsController.of(this, { role: this.variant === 'link' ? 'none' : 'button' });
208214

209215
#slots = new SlotController(this, 'icon', null);
210216

@@ -216,12 +222,19 @@ export class PfButton extends LitElement {
216222
super.connectedCallback();
217223
this.addEventListener('click', this.#onClick);
218224
this.addEventListener('keydown', this.#onKeydown);
219-
this.tabIndex = 0;
220225
}
221226

222227
protected override willUpdate(): void {
223228
this.#internals.ariaLabel = this.label || null;
224229
this.#internals.ariaDisabled = String(!!this.disabled);
230+
const isLink = this.variant === 'link' && this.href;
231+
if (isLink) {
232+
this.removeAttribute('tabindex');
233+
this.#internals.role = 'none';
234+
} else {
235+
this.tabIndex = 0;
236+
this.#internals.role = 'button';
237+
}
225238
}
226239

227240
async formDisabledCallback(): Promise<void> {
@@ -231,9 +244,46 @@ export class PfButton extends LitElement {
231244

232245
override render(): TemplateResult<1> {
233246
const hasIcon = !!this.icon || !!this.loading || this.#slots.hasSlotted('icon');
234-
const { warning, variant, danger, loading, plain, inline, block, size } = this;
247+
const { warning, variant, danger, loading, plain, inline, block, size, href, target } = this;
248+
235249
const disabled = this.#disabled;
236-
return html`
250+
251+
const content = html`
252+
<slot id="icon"
253+
part="icon"
254+
name="icon"
255+
?hidden="${!hasIcon}">
256+
<pf-icon role="presentation"
257+
icon="${ifDefined(this.icon)}"
258+
set="${ifDefined(this.iconSet)}"
259+
?hidden="${!this.icon || this.loading}"></pf-icon>
260+
<pf-spinner size="md"
261+
?hidden="${!this.loading}"
262+
aria-label="${this.getAttribute('loading-label') ?? 'loading'}"></pf-spinner>
263+
</slot>
264+
<slot id="text"></slot>
265+
`;
266+
267+
if (variant === 'link' && href) {
268+
return html`
269+
<a id="button"
270+
href="${href}"
271+
target="${ifDefined(target)}"
272+
class="${classMap({
273+
[variant]: true,
274+
[size ?? '']: !!size,
275+
anchor: true,
276+
inline,
277+
block,
278+
danger,
279+
disabled,
280+
hasIcon,
281+
loading,
282+
plain,
283+
warning,
284+
})}">${content}</a>`;
285+
} else {
286+
return html`
237287
<div id="button"
238288
class="${classMap({
239289
[variant]: true,
@@ -246,22 +296,8 @@ export class PfButton extends LitElement {
246296
loading,
247297
plain,
248298
warning,
249-
})}">
250-
<slot id="icon"
251-
part="icon"
252-
name="icon"
253-
?hidden="${!hasIcon}">
254-
<pf-icon role="presentation"
255-
icon="${ifDefined(this.icon)}"
256-
set="${ifDefined(this.iconSet)}"
257-
?hidden="${!this.icon || this.loading}"></pf-icon>
258-
<pf-spinner size="md"
259-
?hidden="${!this.loading}"
260-
aria-label="${this.getAttribute('loading-label') ?? 'loading'}"></pf-spinner>
261-
</slot>
262-
<slot id="text"></slot>
263-
</div>
264-
`;
299+
})}">${content}</div>`;
300+
}
265301
}
266302

267303
#onClick() {

0 commit comments

Comments
 (0)