Skip to content

Instantly share code, notes, and snippets.

@elycruz
Created February 2, 2023 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elycruz/b7569baf6a723ef54fc9c5fc60d3cbea to your computer and use it in GitHub Desktop.
Save elycruz/b7569baf6a723ef54fc9c5fc60d3cbea to your computer and use it in GitHub Desktop.
Example showing how to wrap an icon font as a web component (example adapted for browser 'snippets'/console).
// Note: in real world example things would work slightly differntly:
// ----
const matSymStyleSheet = new CSSStyleSheet();
// Load css for custom 'x-icon' element - In realword scenario css can be loaded using import assertions, and/or,
// directly via app facilities (sass, webpack, etc.).
fetch('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200')
.then(res => res.text())
.then(css => matSymStyleSheet.replace(`
${css.replace('.material-symbols-outlined', ':host .material-symbols-outlined')}
:host {
--size: 24px;
/* Material icon props.
* --------------------- */
--fill: 0;
--wght: 400;
--grad: 0;
--opsz: 48;
display: inline-block;
}
:host .material-symbols-outlined {
font-variation-settings:
'FILL' var(--fill),
'wght' var(--weight),
'GRAD' var(--grad),
'opsz' var(--opsz);
font-size: var(--size);
}
`));
const materialSymbolsLink = document.createElement('link');
materialSymbolsLink.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200';
materialSymbolsLink.rel = 'stylesheet';
document.head.appendChild(materialSymbolsLink);
const xIconName = 'x-icon';
class XIcon extends HTMLElement {
static localName = xIconName;
get localName () {
return localName;
}
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.adoptedStyleSheets ?
shadowRoot.adoptedStyleSheets.push(matSymStyleSheet) :
shadowRoot.adoptedStyleSheets = [matSymStyleSheet]
;
shadowRoot.innerHTML = `
<span class="material-symbols-outlined" part="ligature">
<slot></slot>
</span>
`;
}
}
if (!customElements.get(xIconName)) {
customElements.define(xIconName, XIcon);
}
document.body.innerHTML = `
<style>
html, body {
background: #333;
color: #ddd;
}
x-icon {
--size: 100px;
}
</style>
<!-- highlights how '.material-...' class is required outside of web component -->
<span>storage</span>
<!-- Notice here how all icon details, and styles are encapsulated inside of component -->
<x-icon>storage</x-icon>
<x-icon>close</x-icon>
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment