Skip to content

Commit

Permalink
Add href etc to sl-icon-button (#496)
Browse files Browse the repository at this point in the history
* perf: only calculate the used button template

* feat: add href and friends to icon-button

closes #495
  • Loading branch information
bennypowers committed Aug 10, 2021
1 parent fe766dc commit 34db968
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 31 deletions.
10 changes: 9 additions & 1 deletion docs/components/icon-button.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Icon buttons are designed to have a uniform appearance, so their color is not in
.icon-button-color sl-icon-button::part(base) {
color: #b00091;
}
.icon-button-color sl-icon-button::part(base):hover,
.icon-button-color sl-icon-button::part(base):focus {
color: #c913aa;
Expand All @@ -49,6 +49,14 @@ Icon buttons are designed to have a uniform appearance, so their color is not in
</style>
```

### Link Buttons

Use the `href` attribute to convert the button to a link.

```html preview
<sl-icon-button name="gear" label="Settings" href="https://example.com" target="_blank"></sl-icon-button>
```

### Icon Button with Tooltip

Wrap a tooltip around an icon button to provide contextual information to the user.
Expand Down
40 changes: 18 additions & 22 deletions src/components/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ export default class SlButton extends LitElement {
${this.loading ? html`<sl-spinner></sl-spinner>` : ''}
`;

const button = html`
<button
return isLink ? html`
<a
ref=${(el: HTMLLinkElement) => (this.button = el)}
part="base"
class=${classMap({
button: true,
Expand All @@ -178,21 +179,21 @@ export default class SlButton extends LitElement {
'button--has-prefix': this.hasPrefix,
'button--has-suffix': this.hasSuffix
})}
?disabled=${this.disabled}
type=${this.submit ? 'submit' : 'button'}
name=${ifDefined(this.name)}
value=${ifDefined(this.value)}
href=${ifDefined(this.href)}
target=${ifDefined(this.target)}
download=${ifDefined(this.download)}
rel=${ifDefined(this.target ? 'noreferrer noopener' : undefined)}
role="button"
aria-disabled=${this.disabled ? 'true' : 'false'}
tabindex=${this.disabled ? '-1' : '0'}
@blur=${this.handleBlur}
@focus=${this.handleFocus}
@click=${this.handleClick}
>
${interior}
</button>
`;

const link = html`
<a
ref=${(el: HTMLLinkElement) => (this.button = el)}
</a>
` : html`
<button
part="base"
class=${classMap({
button: true,
Expand All @@ -216,22 +217,17 @@ export default class SlButton extends LitElement {
'button--has-prefix': this.hasPrefix,
'button--has-suffix': this.hasSuffix
})}
href=${ifDefined(this.href)}
target=${ifDefined(this.target)}
download=${ifDefined(this.download)}
rel=${ifDefined(this.target ? 'noreferrer noopener' : undefined)}
role="button"
aria-disabled=${this.disabled ? 'true' : 'false'}
tabindex=${this.disabled ? '-1' : '0'}
?disabled=${this.disabled}
type=${this.submit ? 'submit' : 'button'}
name=${ifDefined(this.name)}
value=${ifDefined(this.value)}
@blur=${this.handleBlur}
@focus=${this.handleFocus}
@click=${this.handleClick}
>
${interior}
</a>
</button>
`;

return isLink ? link : button;
}
}

Expand Down
47 changes: 39 additions & 8 deletions src/components/icon-button/icon-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import '../icon/icon';
export default class SlIconButton extends LitElement {
static styles = styles;

@query('button') button: HTMLButtonElement;
@query('button') button: HTMLButtonElement|HTMLLinkElement;

/** The name of the icon to draw. */
@property() name: string;
Expand All @@ -30,6 +30,15 @@ export default class SlIconButton extends LitElement {
/** An external URL of an SVG file. */
@property() src: string;

/** When set, the underlying button will be rendered as an `<a>` with this `href` instead of a `<button>`. */
@property() href: string;

/** Tells the browser where to open the link. Only used when `href` is set. */
@property() target: '_blank' | '_parent' | '_self' | '_top';

/** Tells the browser to download the linked file as this filename. Only used when `href` is set. */
@property() download: string;

/**
* A description that gets read by screen readers and other assistive devices. For optimal accessibility, you should
* always include a label that describes what the icon button does.
Expand All @@ -50,7 +59,34 @@ export default class SlIconButton extends LitElement {
}

render() {
return html`
const isLink = this.href ? true : false;

const interior = html`
<sl-icon
name=${ifDefined(this.name)}
library=${ifDefined(this.library)}
src=${ifDefined(this.src)}
aria-hidden="true"
></sl-icon>
`;

return isLink ? html`
<a
ref=${(el: HTMLLinkElement) => (this.button = el)}
part="base"
class="icon-button"
href=${ifDefined(this.href)}
target=${ifDefined(this.target)}
download=${ifDefined(this.download)}
rel=${ifDefined(this.target ? 'noreferrer noopener' : undefined)}
role="button"
aria-disabled=${this.disabled ? 'true' : 'false'}
aria-label="${this.label}"
tabindex=${this.disabled ? '-1' : '0'}
>
${interior}
</a>
` : html`
<button
part="base"
class=${classMap({
Expand All @@ -61,12 +97,7 @@ export default class SlIconButton extends LitElement {
type="button"
aria-label=${this.label}
>
<sl-icon
name=${ifDefined(this.name)}
library=${ifDefined(this.library)}
src=${ifDefined(this.src)}
aria-hidden="true"
></sl-icon>
${interior}
</button>
`;
}
Expand Down

0 comments on commit 34db968

Please sign in to comment.