Created
February 2, 2023 07:11
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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,[email protected],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,[email protected],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