2020-07-15 21:30:37 +00:00
# Icon
[component-header:sl-icon]
Icons are symbols that can be used to represent or provide context to various options and actions within an application.
Shoelace comes bundled with over 1,000 icons courtesy of the [Bootstrap Icons ](https://icons.getbootstrap.com/ ) project. Click or tap on an icon below to copy the name and use it like this.
```html
2020-07-28 09:58:11 +00:00
< sl-icon name = "icon-name-here" > < / sl-icon >
2020-07-15 21:30:37 +00:00
```
< div class = "icon-search" >
< div class = "icon-search-controls" >
< sl-input placeholder = "Search Icons" clearable >
< sl-icon slot = "prefix" name = "search" > < / sl-icon >
< / sl-input >
< sl-select value = "outline" >
< sl-menu-item value = "outline" > Outlined< / sl-menu-item >
< sl-menu-item value = "fill" > Filled< / sl-menu-item >
< sl-menu-item value = "all" > All icons< / sl-menu-item >
< / sl-select >
< / div >
< div class = "icon-list" > < / div >
< input type = "text" class = "icon-copy-input" >
< / div >
## Examples
### Icon Sizes
Icons are sized relative to the current font size. To change their size, set the `font-size` property on the icon itself or on a parent element as shown below.
```html preview
< div style = "font-size: 32px;" >
< sl-icon name = "exclamation-triangle" > < / sl-icon >
< sl-icon name = "archive" > < / sl-icon >
< sl-icon name = "battery-charging" > < / sl-icon >
< sl-icon name = "bell" > < / sl-icon >
< sl-icon name = "clock" > < / sl-icon >
< sl-icon name = "download" > < / sl-icon >
< sl-icon name = "file-earmark" > < / sl-icon >
< sl-icon name = "flag" > < / sl-icon >
< sl-icon name = "heart" > < / sl-icon >
< sl-icon name = "image" > < / sl-icon >
< sl-icon name = "lightning" > < / sl-icon >
< sl-icon name = "mic" > < / sl-icon >
< sl-icon name = "search" > < / sl-icon >
< sl-icon name = "star" > < / sl-icon >
< sl-icon name = "trash" > < / sl-icon >
< sl-icon name = "x-circle" > < / sl-icon >
< / div >
```
### Custom Icons
Custom icons can be loaded by setting the `src` attribute. Only SVG images are supported
```html preview
< sl-icon src = "/assets/images/shoe.svg" style = "font-size: 8rem;" > < / sl-icon >
```
< script >
fetch('/dist/shoelace/icons/icons.json')
.then(res => res.json())
.then(icons => {
const container = document.querySelector('.icon-search');
const input = container.querySelector('sl-input');
const select = container.querySelector('sl-select');
const copyInput = container.querySelector('.icon-copy-input');
const loader = container.querySelector('.icon-loader');
const list = container.querySelector('.icon-list');
const queue = [];
// Generate icons
icons.map(i => {
const item = document.createElement('div');
item.classList.add('icon-list-item');
item.setAttribute('data-name', i.name);
item.setAttribute('data-terms', [i.name, i.title, ...(i.tags || []), ...(i.categories || [])].join(' '));
item.innerHTML = `
< svg width = "1em" height = "1em" >
< use xlink:href = "/assets/icons/sprite.svg#${i.name}" > < / use >
< / svg >
`;
const tooltip = document.createElement('sl-tooltip');
tooltip.content = i.name;
tooltip.appendChild(item);
list.appendChild(tooltip);
item.addEventListener('click', () => {
copyInput.value = i.name;
copyInput.select();
document.execCommand('copy');
tooltip.content = 'Copied!';
setTimeout(() => tooltip.content = i.name, 1000);
});
});
// Filter as the user types
input.addEventListener('slInput', () => {
[...list.querySelectorAll('.icon-list-item')].map(item => {
const filter = input.value.toLowerCase();
if (filter === '') {
item.hidden = false;
} else {
const terms = item.getAttribute('data-terms').toLowerCase();
item.hidden = terms.indexOf(filter) < 0 ;
}
});
});
// Sort by type and remember preference
const iconType = localStorage.getItem('sl-icon:type') || 'outline';
select.value = iconType;
list.setAttribute('data-type', select.value);
select.addEventListener('slChange', () => {
list.setAttribute('data-type', select.value);
localStorage.setItem('sl-icon:type', select.value);
});
});
< / script >
< style >
.icon-search {
border: solid 1px var(--sl-color-gray-90);
border-radius: var(--sl-border-radius-medium);
padding: var(--sl-spacing-medium);
}
.icon-search-controls {
display: flex;
}
.icon-search-controls sl-input {
flex: 1 1 auto;
}
.icon-search-controls sl-select {
flex: 0 0 auto;
margin-left: 1rem;
}
.icon-loader {
display: flex;
align-items: center;
justify-content: center;
min-height: 30vh;
}
.icon-list {
display: grid;
grid-template-columns: repeat(12, 1fr);
position: relative;
margin-top: 1rem;
}
.icon-loader[hidden],
.icon-list[hidden] {
display: none;
}
.icon-list-item {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--sl-border-radius-circle);
font-size: 24px;
width: 2em;
height: 2em;
margin: 0 auto;
cursor: pointer;
transition: var(--sl-transition-medium) all;
}
.icon-list-item:hover {
background-color: var(--sl-color-primary-95);
color: var(--sl-color-primary-50);
}
.icon-list[data-type="outline"] .icon-list-item[data-name$="-fill"] {
display: none;
}
.icon-list[data-type="fill"] .icon-list-item:not([data-name$="-fill"]) {
display: none;
}
.icon-copy-input {
position: absolute;
opacity: 0;
pointer-events: none;
}
@media screen and (max-width: 1000px) {
.icon-search-controls {
display: block;
}
.icon-search-controls sl-select {
margin-left: 0;
margin-top: 1rem;
}
.icon-list {
grid-template-columns: repeat(8, 1fr);
}
.icon-list-item {
font-size: 20px;
}
}
@media screen and (max-width: 500px) {
.icon-list {
grid-template-columns: repeat(4, 1fr);
}
}
< / style >
[component-metadata:sl-icon]