Skip to content

Commit 9cda1f8

Browse files
authored
feat: add href attribute to uui-button & uui-tab
* href property on uui-button * uui-button final corrections * uui-tab href support * test rendering href as anchor tag * feat: support href for uui-button and uui-tab * clean up story * same rel and target behaviour on all href comps * testing Href for uui-button & uui-tab
1 parent 506a45f commit 9cda1f8

File tree

10 files changed

+411
-91
lines changed

10 files changed

+411
-91
lines changed

packages/uui-button/lib/uui-button.element.ts

Lines changed: 77 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from '@umbraco-ui/uui-icon-registry-essential/lib/svgs';
1212
import { css, html, LitElement } from 'lit';
1313
import { property, query } from 'lit/decorators.js';
14+
import { ifDefined } from 'lit/directives/if-defined.js';
1415

1516
export type UUIButtonState = undefined | 'waiting' | 'success' | 'failed';
1617

@@ -76,6 +77,7 @@ export class UUIButtonElement extends FormControlMixin(
7677
}
7778
7879
.label {
80+
line-height: normal; /** needed to reset 'a > span' */
7981
display: block;
8082
transition: opacity 120ms;
8183
}
@@ -95,7 +97,7 @@ export class UUIButtonElement extends FormControlMixin(
9597
animation-fill-mode: forwards;
9698
}
9799
98-
button {
100+
#button {
99101
height: 100%;
100102
width: 100%;
101103
background-color: transparent;
@@ -107,6 +109,12 @@ export class UUIButtonElement extends FormControlMixin(
107109
text-align: inherit;
108110
border: none;
109111
cursor: inherit;
112+
display: block;
113+
114+
/* for anchor tag: */
115+
text-decoration: none;
116+
color: currentColor;
117+
line-height: normal;
110118
111119
border-width: var(--uui-button-border-width, 1px);
112120
border-style: solid;
@@ -123,7 +131,8 @@ export class UUIButtonElement extends FormControlMixin(
123131
vertical-align: middle;
124132
box-shadow: none;
125133
}
126-
button[disabled]:active {
134+
button[disabled]:active,
135+
a:not([href]):active {
127136
animation: ${UUIHorizontalShakeAnimationValue};
128137
}
129138
#icon-check,
@@ -161,43 +170,43 @@ export class UUIButtonElement extends FormControlMixin(
161170
}
162171
163172
/* edge case for default color */
164-
:host(:not([color]):not([look='primary'])) button,
165-
:host([color='']:not([look='primary'])) button,
166-
:host([color='default']:not([look='primary'])) button {
173+
:host(:not([color]):not([look='primary'])) #button,
174+
:host([color='']:not([look='primary'])) #button,
175+
:host([color='default']:not([look='primary'])) #button {
167176
--uui-button-contrast-hover: var(--uui-color-default-emphasis);
168177
}
169178
170-
:host([color='warning'][look='outline']) button,
171-
:host([color='warning'][look='placeholder']) button {
179+
:host([color='warning'][look='outline']) #button,
180+
:host([color='warning'][look='placeholder']) #button {
172181
--uui-button-contrast-hover: var(--color-standalone);
173182
}
174183
175184
/** Button color attribute: */
176-
button {
185+
#button {
177186
--color: var(--uui-color-default);
178187
--color-standalone: var(--uui-color-default-standalone);
179188
--color-emphasis: var(--uui-color-default-emphasis);
180189
--color-contrast: var(--uui-color-default-contrast);
181190
}
182-
:host([color='positive']) button {
191+
:host([color='positive']) #button {
183192
--color: var(--uui-color-positive);
184193
--color-standalone: var(--uui-color-positive-standalone);
185194
--color-emphasis: var(--uui-color-positive-emphasis);
186195
--color-contrast: var(--uui-color-positive-contrast);
187196
}
188-
:host([color='warning']) button {
197+
:host([color='warning']) #button {
189198
--color: var(--uui-color-warning);
190199
--color-standalone: var(--uui-color-warning-standalone);
191200
--color-emphasis: var(--uui-color-warning-emphasis);
192201
--color-contrast: var(--uui-color-warning-contrast);
193202
}
194-
:host([color='danger']) button {
203+
:host([color='danger']) #button {
195204
--color: var(--uui-color-danger);
196205
--color-standalone: var(--uui-color-danger-standalone);
197206
--color-emphasis: var(--uui-color-danger-emphasis);
198207
--color-contrast: var(--uui-color-danger-contrast);
199208
}
200-
:host([disabled]) button {
209+
:host([disabled]) #button {
201210
--color: var(--uui-color-disabled);
202211
--color-standalone: var(--uui-color-disabled-contrast);
203212
--color-emphasis: var(--uui-color-disabled);
@@ -208,20 +217,20 @@ export class UUIButtonElement extends FormControlMixin(
208217
209218
/** Button look attribute: */
210219
/* DEFAULT */
211-
button {
220+
#button {
212221
background-color: var(--uui-button-background-color, transparent);
213222
color: var(--uui-button-contrast, var(--color-standalone));
214223
border-color: var(--uui-button-border-color, transparent);
215224
}
216-
:host(:not([disabled]):hover) button {
225+
:host(:not([disabled]):hover) #button {
217226
background-color: var(
218227
--uui-button-background-color-hover,
219228
var(--uui-color-surface-emphasis)
220229
);
221230
color: var(--uui-button-contrast-hover, var(--color-standalone));
222231
border-color: var(--uui-button-border-color-hover, transparent);
223232
}
224-
:host([disabled]) button {
233+
:host([disabled]) #button {
225234
background-color: var(
226235
--uui-button-background-color-disabled,
227236
transparent
@@ -231,23 +240,23 @@ export class UUIButtonElement extends FormControlMixin(
231240
}
232241
233242
/* PRIMARY */
234-
:host([look='primary']) button {
243+
:host([look='primary']) #button {
235244
background-color: var(--uui-button-background-color, var(--color));
236245
color: var(--uui-button-contrast, var(--color-contrast));
237246
border-color: var(--uui-button-border-color, transparent);
238247
239248
/* special for primary: */
240249
font-weight: var(--uui-button-font-weight, 700);
241250
}
242-
:host([look='primary']:hover) button {
251+
:host([look='primary']:hover) #button {
243252
background-color: var(
244253
--uui-button-background-color-hover,
245254
var(--color-emphasis)
246255
);
247256
color: var(--uui-button-contrast-hover, var(--color-contrast));
248257
border-color: var(--uui-button-border-color-hover, transparent);
249258
}
250-
:host([look='primary'][disabled]) button {
259+
:host([look='primary'][disabled]) #button {
251260
background-color: var(
252261
--uui-button-background-color-disabled,
253262
var(--color)
@@ -256,7 +265,7 @@ export class UUIButtonElement extends FormControlMixin(
256265
border-color: var(--uui-button-border-color-disabled, var(--color));
257266
}
258267
/* SECONDARY */
259-
:host([look='secondary']) button {
268+
:host([look='secondary']) #button {
260269
background-color: var(
261270
--uui-button-background-color,
262271
var(--uui-color-surface-alt)
@@ -267,15 +276,15 @@ export class UUIButtonElement extends FormControlMixin(
267276
/* special for secondary: */
268277
font-weight: var(--uui-button-font-weight, 700);
269278
}
270-
:host([look='secondary']:hover) button {
279+
:host([look='secondary']:hover) #button {
271280
background-color: var(
272281
--uui-button-background-color-hover,
273282
var(--uui-color-surface-emphasis)
274283
);
275284
color: var(--uui-button-contrast-hover, var(--color-standalone));
276285
border-color: var(--uui-button-border-color-hover, transparent);
277286
}
278-
:host([look='secondary'][disabled]) button {
287+
:host([look='secondary'][disabled]) #button {
279288
background-color: var(
280289
--uui-button-background-color-disabled,
281290
var(--color)
@@ -285,23 +294,23 @@ export class UUIButtonElement extends FormControlMixin(
285294
}
286295
287296
/* OUTLINE */
288-
:host([look='outline']) button {
297+
:host([look='outline']) #button {
289298
background-color: var(--uui-button-background-color, transparent);
290299
color: var(--uui-button-contrast, var(--color-standalone));
291300
border-color: var(--uui-button-border-color, --color-standalone);
292301
293302
/* special for outline: */
294303
font-weight: var(--uui-button-font-weight, 700);
295304
}
296-
:host([look='outline']:not([disabled]):hover) button {
305+
:host([look='outline']:not([disabled]):hover) #button {
297306
background-color: var(--uui-button-background-color-hover, transparent);
298307
color: var(--uui-button-contrast-hover, var(--color-emphasis));
299308
border-color: var(
300309
--uui-button-border-color-hover,
301310
var(--color-emphasis)
302311
);
303312
}
304-
:host([look='outline'][disabled]) button {
313+
:host([look='outline'][disabled]) #button {
305314
background-color: var(
306315
--uui-button-background-color-disabled,
307316
transparent
@@ -314,7 +323,7 @@ export class UUIButtonElement extends FormControlMixin(
314323
}
315324
316325
/* PLACEHOLDER */
317-
:host([look='placeholder']) button {
326+
:host([look='placeholder']) #button {
318327
border-style: dashed;
319328
background-color: var(--uui-button-background-color, transparent);
320329
color: var(--uui-button-contrast, var(--color-standalone));
@@ -323,12 +332,12 @@ export class UUIButtonElement extends FormControlMixin(
323332
var(--uui-color-border-standalone)
324333
);
325334
}
326-
:host([look='placeholder']:not([disabled]):hover) button {
335+
:host([look='placeholder']:not([disabled]):hover) #button {
327336
background-color: var(--uui-button-background-color-hover, transparent);
328337
color: var(--uui-button-contrast-hover, var(--color-standalone));
329338
border-color: var(--uui-button-border-color-hover, --color-standalone);
330339
}
331-
:host([look='placeholder'][disabled]) button {
340+
:host([look='placeholder'][disabled]) #button {
332341
background-color: var(
333342
--uui-button-background-color-disabled,
334343
var(--color)
@@ -395,6 +404,24 @@ export class UUIButtonElement extends FormControlMixin(
395404
@property({ type: String, reflect: true })
396405
state: UUIButtonState = undefined;
397406

407+
/**
408+
* Set an href, this will turns the button into a anchor tag.
409+
* @type {string}
410+
* @attr
411+
* @default undefined
412+
*/
413+
@property({ type: String })
414+
public href?: string;
415+
416+
/**
417+
* Set an anchor tag target, only used when using href.
418+
* @type {string}
419+
* @attr
420+
* @default undefined
421+
*/
422+
@property({ type: String })
423+
public target?: '_blank' | '_parent' | '_self' | '_top';
424+
398425
@query('#button')
399426
protected _button!: HTMLInputElement;
400427

@@ -475,12 +502,29 @@ export class UUIButtonElement extends FormControlMixin(
475502
}
476503

477504
render() {
478-
return html`
479-
<button id="button" ?disabled=${this.disabled} aria-label="${this.label}">
480-
${this.renderState()} ${this.renderLabel()}
481-
<slot name="extra"></slot>
482-
</button>
483-
`;
505+
return this.href
506+
? html`
507+
<a
508+
id="button"
509+
aria-label=${this.label}
510+
href=${ifDefined(!this.disabled ? this.href : undefined)}
511+
target=${ifDefined(this.target || undefined)}
512+
rel=${ifDefined(
513+
this.target === '_blank' ? 'noopener noreferrer' : undefined
514+
)}>
515+
${this.renderState()} ${this.renderLabel()}
516+
<slot name="extra"></slot>
517+
</a>
518+
`
519+
: html`
520+
<button
521+
id="button"
522+
?disabled=${this.disabled}
523+
aria-label=${this.label}>
524+
${this.renderState()} ${this.renderLabel()}
525+
<slot name="extra"></slot>
526+
</button>
527+
`;
484528
}
485529
}
486530

packages/uui-button/lib/uui-button.story.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export default {
1111
id: 'uui-button',
1212

1313
args: {
14+
href: undefined,
15+
target: undefined,
1416
look: 'default',
1517
color: 'default',
1618
type: '',
@@ -89,6 +91,8 @@ const Template: Story = props => {
8991
color=${props.color}
9092
label=${props.label}
9193
state=${props.state}
94+
href=${props.href}
95+
target=${props.target}
9296
>${props.content}</uui-button
9397
>
9498
`;
@@ -247,8 +251,8 @@ export const LooksAndColors: Story = props => html`
247251
${looks.map(
248252
look => html` <uui-button
249253
type=${props.type}
250-
.look=${look}
251-
.color=${color}
254+
.look=${look as any}
255+
.color=${color as any}
252256
label="Button displaying the ${uppercaseFirstLetter(look)} look"
253257
state=${props.state}
254258
?disabled=${props.disabled}
@@ -315,3 +319,22 @@ WaitingState.parameters = {
315319
},
316320
},
317321
};
322+
323+
export const AnchorTag = Template.bind({});
324+
AnchorTag.args = {
325+
href: 'https://www.umbraco.com',
326+
target: '_blank',
327+
};
328+
AnchorTag.parameters = {
329+
docs: {
330+
source: {
331+
code: html`
332+
<uui-button
333+
label="Open umbraco.com"
334+
href="http://www.umbraco.com"
335+
target="_blank">
336+
</uui-button>
337+
`.strings,
338+
},
339+
},
340+
};

0 commit comments

Comments
 (0)