dile-button-icon
Web Component to create a customizable button with an icon.
Installation
npm i @dile/ui
This component extends dile-button, so you can use the component in a similar way. The main difference is that this component allows you to pass icons as Lit templates, SVG templates, or image elements.
The
dile-buttoncomponent can already display an icon by itself by passing the icon name to theiconproperty as a string (e.g.,"lucide.rocket"). Usedile-button-iconwhen you want to pass the icon as a Lit template, an SVG template, or an<img>element instead.
Usage
Import the component.
import '@dile/ui/components/button/button-icon.js';
The icon is assigned via the icon property.
html`<dile-button-icon .icon="${someIconHtmlTemplate}">Button Label</dile-button-icon>`
Usually, the provided icon will be a Lit template, so when you use it on a Lit component, it is necessary to bind the property value using a dot notation in the component attribute.
Using a custom icon
You can customize the icon of the button using a template with your own svg. To do that its is posible to declare a lit-html template:
const appsIcon = html`<svg class="dile-icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></svg>`;
Then, you can use the template created:
html`<dile-button-icon .icon="${appsIcon}">Button Label</dile-button-icon>`
Using a icons library
There are some icons in the @dile/icons package. So, you can use them easily in your components.
import { closeIcon } from '@dile/icons';
// Late, in render() method of the component
html`<dile-button-icon .icon="${closeIcon}">Button Label</dile-button-icon>`
Using an image
It is also possible to use any custom image or SVG by creating a template with an <img> tag.
let imageIcon = html`<img src="./images/loto.png">`;
html`<dile-button-icon .icon=${imageIcon}>Yoga practice</dile-button-icon>`
Properties
Same as dile-button, but also:
- icon: Lit-html template with the content to display the icon
Inherited from dile-button and also useful here:
- iconPosition:
"left"(default) or"right"(attributeicon-position). - no-wrap: Apply the necessary CSS style so that the button's text does not break into multiple lines.
- label: String used as the accessible name (
aria-label). Required when the button shows only the icon.
Icon-only buttons
When the button has no slotted text, the icon is centered with no dead space
beside it (previously a leftover margin made icon-only buttons look misaligned).
Remember to set a label so the button has an accessible name.
html`<dile-button-icon .icon=${closeIcon} label="Close"></dile-button-icon>`
CSS Custom Properties
You can customize it using the same dile-button CSS Custom Properties but also:
| Custom property | Description | Default |
|---|---|---|
| --dile-button-icon-separation | Space between the icon and the button text | 0.3rem |
| --dile-button-icon-size | Icon size | 1.125 * --dile-button-font-size |
| --dile-icon-button-color | Icon color | --dile-on-primary-color or #ffffff |
| --dile-button-icon-hover-color | Icon hover color | --dile-on-primary-light-color or #888 |
dile-button-icon demos
Button icon demo
<script type="module">
import { LitElement, html, css } from 'lit';
import { appsIcon } from "@dile/icons";
import '@dile/ui/components/button/button-icon';
class MyComponent extends LitElement {
static get styles() {
return css`
:host {
--dile-icon-color: #fff;
}
`
}
render() {
return html`
<dile-button-icon .icon=${this.appsIcon}>Control Panel</dile-button-icon>
`
}
firstUpdated() {
// This should not be necessary but the component to show the demo does not work well with interpoplation of strings
this.shadowRoot.querySelector('dile-button-icon').icon = appsIcon;
}
}
customElements.define('my-component', MyComponent);
</script>
<my-component></my-component>
Styled button icon
<script type="module">
import { LitElement, html, css } from 'lit';
import '@dile/ui/components/button/button-icon';
class OtherComponent extends LitElement {
static get styles() {
return css`
.styled {
--dile-button-border-color: #0f010f;
--dile-button-background-color: #ffffdd;
--dile-button-hover-background-color: #f3d6e3;
--dile-button-text-color: #396;
--dile-button-hover-text-color: #000;
--dile-button-font-weight: bold;
--dile-button-font-size: 1.4rem;
--dile-button-ring-color: #cc5099;
--dile-button-ring-offset-width: 2px;
--dile-button-border-radius: 3px;
--dile-button-text-transform: uppercase;
--dile-icon-color: #fff;
--dile-button-icon-size: 32px;
}
`
}
render() {
return html`
<dile-button-icon class="styled" .icon=${this.icon}>Dile Components</dile-button-icon>
`
}
firstUpdated() {
// This should not be necessary but the component to show the demo does not work well with interpoplation of strings
this.shadowRoot.querySelector('dile-button-icon').icon = this.icon;
}
get icon() {
return html`
<img src="/images/logo-polydile.png" style="width: 40px;">
`
}
}
customElements.define('other-component', OtherComponent);
</script>
<other-component></other-component>
dile-components