UNPKG

sober

Version:

Sober is a library of UI components designed with reference to Material You.

107 lines (106 loc) 5.98 kB
import { useElement, useProps } from './core/element.js'; const svgData = { none: '', home: 'M240-200h120v-240h240v240h120v-360L480-740 240-560v360Zm-80 80v-480l320-240 320 240v480H520v-240h-80v240H160Zm320-350Z', add: 'M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z', search: 'M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z', menu: 'M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z', arrow_back: 'm313-440 224 224-57 56-320-320 320-320 57 56-224 224h487v80H313Z', arrow_forward: { name: 'arrow_back', angle: 180 }, arrow_upward: { name: 'arrow_back', angle: 90 }, arrow_downward: { name: 'arrow_back', angle: -90 }, arrow_drop_up: 'm280-400 200-200 200 200H280Z', arrow_drop_down: { name: 'arrow_drop_up', angle: 180 }, arrow_drop_left: { name: 'arrow_drop_up', angle: -90 }, arrow_drop_right: { name: 'arrow_drop_up', angle: 90 }, more_vert: 'M480-160q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm0-240q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm0-240q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Z', more_horiz: { name: 'more_vert', angle: 90 }, close: 'm256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z', done: 'M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z', chevron_up: 'M480-528 296-344l-56-56 240-240 240 240-56 56-184-184Z', chevron_down: { name: 'chevron_up', angle: 180 }, chevron_left: { name: 'chevron_up', angle: -90 }, chevron_right: { name: 'chevron_up', angle: 90 }, light_mode: 'M480-360q50 0 85-35t35-85q0-50-35-85t-85-35q-50 0-85 35t-35 85q0 50 35 85t85 35Zm0 80q-83 0-141.5-58.5T280-480q0-83 58.5-141.5T480-680q83 0 141.5 58.5T680-480q0 83-58.5 141.5T480-280ZM200-440H40v-80h160v80Zm720 0H760v-80h160v80ZM440-760v-160h80v160h-80Zm0 720v-160h80v160h-80ZM256-650l-101-97 57-59 96 100-52 56Zm492 496-97-101 53-55 101 97-57 59Zm-98-550 97-101 59 57-100 96-56-52ZM154-212l101-97 55 53-97 101-59-57Zm326-268Z', dark_mode: 'M480-120q-150 0-255-105T120-480q0-150 105-255t255-105q14 0 27.5 1t26.5 3q-41 29-65.5 75.5T444-660q0 90 63 153t153 63q55 0 101-24.5t75-65.5q2 13 3 26.5t1 27.5q0 150-105 255T480-120Zm0-80q88 0 158-48.5T740-375q-20 5-40 8t-40 3q-123 0-209.5-86.5T364-660q0-20 3-40t8-40q-78 32-126.5 102T200-480q0 116 82 198t198 82Zm-10-270Z', star: 'm354-287 126-76 126 77-33-144 111-96-146-13-58-136-58 135-146 13 111 97-33 143ZM233-120l65-281L80-590l288-25 112-265 112 265 288 25-218 189 65 281-247-149-247 149Zm247-350Z', favorite: 'm480-120-58-52q-101-91-167-157T150-447.5Q111-500 95.5-544T80-634q0-94 63-157t157-63q52 0 99 22t81 62q34-40 81-62t99-22q94 0 157 63t63 157q0 46-15.5 90T810-447.5Q771-395 705-329T538-172l-58 52Zm0-108q96-86 158-147.5t98-107q36-45.5 50-81t14-70.5q0-60-40-100t-100-40q-47 0-87 26.5T518-680h-76q-15-41-55-67.5T300-774q-60 0-100 40t-40 100q0 35 14 70.5t50 81q36 45.5 98 107T480-228Zm0-273Z', }; const name = 's-icon'; const props = useProps({ name: Object.keys(svgData), $src: '' }); const style = /*css*/ ` :host{ display: inline-flex; vertical-align: middle; justify-content: center; align-items: center; width: 24px; aspect-ratio: 1; -webkit-aspect-ratio: 1; fill: currentColor; box-sizing: border-box; color: var(--s-color-on-surface-variant, ${"#40484C" /* Theme.colorOnSurfaceVariant */}); } svg, img{ width: 100%; height: 100%; } ::slotted(*){ width: 100%; height: 100%; } `; const template = /*html*/ `<slot></slot>`; export class Icon extends useElement({ style, template, props, setup(shadowRoot) { const slot = shadowRoot.querySelector('slot'); const img = document.createElement('img'); const getSVG = (d = svgData.none, transform = '') => `<svg viewBox="0 -960 960 960"><path d="${d}" transform="${transform}"></path></svg>`; return { name: (value) => { const data = svgData[value]; if (typeof data === 'string') return slot.innerHTML = getSVG(data); const n = data.name; if (typeof svgData[n] === 'string') slot.innerHTML = getSVG(svgData[n], `rotate(${data.angle} 480 -480)`); }, src: async () => { try { const url = new URL(this.src, location.href); if (url.pathname.endsWith('.svg')) { const res = await fetch(url.href); const svg = await res.text(); const temp = document.createElement('template'); temp.innerHTML = svg; const el = temp.content.childNodes[0]; if (!(el instanceof SVGElement)) throw new Error('Invalid SVG'); slot.innerHTML = ''; slot.appendChild(el); this.dispatchEvent(new Event('load')); } else { img.src = url.href; img.onload = () => { slot.innerHTML = ''; slot.appendChild(img); this.dispatchEvent(new Event('load')); }; img.onerror = () => this.dispatchEvent(new ErrorEvent('error')); } } catch (error) { this.dispatchEvent(new ErrorEvent('error')); } } }; } }) { } Icon.define(name);