UNPKG

@riovir/wc-fontawesome

Version:

Web components for Font Awesome

100 lines (83 loc) 3.57 kB
import { applyStyleWith } from './apply-style-with.js'; import { parseTransform, textToHtml } from './svg-core.js'; import { definePropsOn, BooleanProp, StringProp } from './core.js'; import { updateElementClass } from './utils.js'; import { Props as IconProps } from './font-awesome-icon.js'; const applyStyle = applyStyleWith({ css: /* css */` :host { box-sizing: border-box; display: inline-block; line-height: 1; } .fa-layers-counter { background: var(--fa-layers-counter-background, #ff253a); } ` }); export const template = document.createElement('template'); template.innerHTML = /* html */` <span class="fa-layers-text"></span> `; function toHtmlFallback(text = '') { const span = document.createElement('span'); span.className = 'fa-layers-text'; span.textContent = text; return [span.outerHTML]; } const Internal = { CONTAINER: Symbol('container'), NEEDS_REDRAW: Symbol('needs-complete-redraw-of-structure'), }; const updateContainerClass = updateElementClass(Internal.CONTAINER); const prefixContainerClass = prefix => updateContainerClass(value => prefix.concat(value)); export const Props = { value: StringProp({ attribute: 'value', observe: updateContainer }), transform: { ...IconProps.transform, observe: updateContainer }, parsedTransform: IconProps.parsedTransform, size: StringProp({ attribute: 'size', observe: prefixContainerClass('fa-') }), position: StringProp({ attribute: 'position', observe: prefixContainerClass('fa-layers-') }), fixedWidth: BooleanProp({ attribute: 'fixed-width', observe: updateContainerClass('fa-fw') }), inverse: BooleanProp({ attribute: 'inverse', observe: updateContainerClass('fa-inverse') }), counter: BooleanProp({ attribute: 'counter', observe: updateContainer }), }; export class FontAwesomeLayersText extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.content.cloneNode(true)); applyStyle(this); this[Internal.CONTAINER] = shadowRoot.querySelector('.fa-layers-text'); this[Internal.NEEDS_REDRAW] = host => host.transform; this._toHtml = textToHtml; this._parseTransform = parseTransform; } } definePropsOn(FontAwesomeLayersText, Props); function updateContainer(host) { if (host[Internal.NEEDS_REDRAW](host)) { redrawElements(host); } updateLayerClass(host); updateTextValue(host); } function redrawElements(host) { const classes = host[Internal.CONTAINER].classList; host[Internal.CONTAINER].remove(); const options = { transform: host.parsedTransform, }; const [container] = host._toHtml(String(host.value), options) || toHtmlFallback(host.value, options); host.shadowRoot.innerHTML = host.shadowRoot.innerHTML.concat(container); host[Internal.CONTAINER] = host.shadowRoot.querySelector('.fa-layers-text'); host[Internal.CONTAINER].classList.add(...classes); const { transform } = host; host[Internal.NEEDS_REDRAW] = host => transform !== host.transform; } function updateLayerClass(host) { const classList = host[Internal.CONTAINER].classList; const layerClass = host.counter ? 'fa-layers-counter' : 'fa-layers-text'; if (classList.contains(layerClass)) { return; } host[Internal.CONTAINER].classList.remove('fa-layers-counter', 'fa-layers-text'); host[Internal.CONTAINER].classList.add(layerClass); } function updateTextValue(host, value = host.value) { const text = host.counter && !value ? 0 : value; host[Internal.CONTAINER].textContent = text; }