kempo 2.11.3 → 2.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Card.js +1 -1
- package/dist/components/Collapsible.js +1 -0
- package/dist/components/Icon.js +1 -1
- package/dist/components/Import.js +1 -1
- package/dist/components/PersistantCollapsible.js +1 -0
- package/dist/components/SideMenu.js +1 -1
- package/dist/utils/element.js +1 -1
- package/docs/components/icon.html +3 -1
- package/docs/kempo/components/Card.js +1 -1
- package/docs/kempo/components/Collapsible.js +1 -0
- package/docs/kempo/components/Icon.js +1 -1
- package/docs/kempo/components/Import.js +1 -1
- package/docs/kempo/components/PersistantCollapsible.js +1 -0
- package/docs/kempo/components/SideMenu.js +1 -1
- package/docs/kempo/utils/element.js +1 -1
- package/docs/nav.inc.html +36 -36
- package/package.json +1 -1
- package/src/components/Card.js +1 -4
- package/src/components/Collapsible.js +104 -0
- package/src/components/Icon.js +21 -11
- package/src/components/Import.js +20 -7
- package/src/components/PersistantCollapsible.js +44 -0
- package/src/components/SideMenu.js +1 -7
- package/src/utils/element.js +2 -2
package/dist/components/Card.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";import{setProp}from"../utils/element.js";export default class Card extends Component{constructor(
|
|
1
|
+
import Component from"./Component.js";import{setProp}from"../utils/element.js";export default class Card extends Component{constructor(e=""){super(),this.registerAttribute("label",e)}attributeChangedCallback(e,r,n){"label"===e&&setProp(this.shadowRoot.getElementById("label"),"innerHTML",n)}get shadowTemplate(){return`\n <div id="card">\n <div id="label">${this.label}</div>\n ${super.shadowTemplate}\n </div>\n `}get shadowStyles(){return"\n :host {\n display: block;\n }\n #card {\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n margin-bottom: var(--spacer);\n padding: var(--spacer);\n position: relative;\n background-color: var(--c_bg);\n }\n #label {\n position: absolute;\n top: -1.25em;\n left: 1.25em;\n background-color: var(--c_bg);\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n padding: var(--spacer_h);\n }\n :host([label]) {\n padding-top: calc(1.5 * var(--spacer));\n margin-top: var(--spacer);\n }\n :host([label]) #card {\n padding-top: calc(1.5 * var(--spacer));\n }\n :host(:not([label])) #label {\n display: none;\n }\n\n "}static observedAttributes=[...super.observedAttributes,"label"]}window.customElements.define("k-card",Card);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import Component from".//Component.js";import"./Icon.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";const clickHandler=Symbol("clickHandler");export default class Collapsible extends Component{constructor(e=!1){super(),this[clickHandler]=()=>{this.toggle()},this.registerAttributes({opened:e})}async render(e){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("label"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("label"),"click",this[clickHandler])}attributeChangedCallback(e,n,t){super.attributeChangedCallback(e,n,t),"opened"===e&&n!==t&&dispatchEvent(this,"openedchanged "+("true"===t?"open":"close"))}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened=!this.opened,dispatchEvent(this,"openedtoggled")}get shadowTemplate(){return`\n <div id="labelContainer">\n <div id="label">\n <slot name="label"></slot>\n </div>\n <div id="labelIcon">\n <slot name="labelIcon">\n <k-icon name="chevron-right"></k-icon>\n </slot>\n </div>\n </div>\n <div id="content">\n ${super.shadowTemplate}\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n }\n #labelContainer {\n display: flex;\n cursor: pointer;\n }\n #label {\n flex: 1 1 auto;\n }\n #labelIcon {\n flex: 0 0 none;\n opacity: 0.5;\n transform: rotate(90deg);\n transition: transform var(--animation_ms, 256ms);\n }\n #labelContainer:hover #labelIcon {\n opacity: 1;\n }\n :host([opened="true"]) #labelIcon {\n transform: rotate(-90deg);\n }\n :host(:not([opened="true"])) #content {\n display: none;\n }\n `}static observedAttributes=[...super.observedAttributes,"opened"]}window.customElements.define("k-collapsible",Collapsible);
|
package/dist/components/Icon.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";const cache={},getIconByPath=async t=>(cache[t]||(cache[t]=new Promise((async(e,n)=>{try{const n=await fetch(t);200===n.status
|
|
1
|
+
import Component from"./Component.js";const cache={},getIconByPath=async t=>(cache[t]||(cache[t]=new Promise((async(e,n)=>{const s=(new AbortController).signal;try{const n=await fetch(t,{signal:s});200===n.status?e(await n.text()):404===n.status&&e(null)}catch(t){"AbortError"!==t.name&&n(t)}})).catch((()=>null))),await cache[t]),getIconByName=t=>{const e=async e=>getIconByPath(`${e}/${t}.svg`);return new Promise((async(t,n)=>{let s;for(let t=0;t<Icon.pathToIcons.length&&!s;t++)try{s=await e(Icon.pathToIcons[t])}catch(t){}t(s||null)}))};export default class Icon extends Component{constructor(t=""){super(),this.registerAttributes({src:"",name:t})}connectedCallback(){}async render(t){if(await super.render(t)){if(this.src){const t=await getIconByPath(this.src);t?(this.innerHTML=t,this.fixSVG()):this.innerHTML.length||(this.innerHTML=Icon.fallback)}else if(this.name){const t=await getIconByName(this.name);t?(this.innerHTML=t,this.fixSVG()):this.innerHTML.length||(this.innerHTML=Icon.fallback)}else this.rendered=!1,this.innerHTML.length||(this.innerHTML=Icon.fallback);return!0}return!1}attributeChangedCallback(t,e,n){super.attributeChangedCallback(t,e,n),["src","name"].includes(t)&&n&&this.render(!0)}fixSVG(){const t=this.querySelector("svg");t.removeAttribute("width"),t.removeAttribute("height"),t.querySelectorAll("path, rect, circle").forEach((t=>{t.setAttribute("fill","currentColor")}))}get shadowStyles(){return"\n :host {\n display: inline-block;\n vertical-align: bottom;\n }\n ::slotted(svg){\n height: 1.35em;\n vertical-align: middle;\n }\n "}static observedAttributes=["name","src"];static pathToIcons=["/icons"];static fallback='\n <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>\n '}window.customElements.define("k-icon",Icon);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";export default class Import extends Component{constructor(){super(),this.registerAttribute("src")}attributeChangedCallback(t,e,r){"src"===t&&e!==r&&this.render(!0)}async render(t){const e=this.src;e&&await super.render(t)
|
|
1
|
+
import Component from"./Component.js";export default class Import extends Component{constructor(t=""){super(),this.registerAttribute("src",t)}attributeChangedCallback(t,e,r){"src"===t&&e!==r&&this.render(!0)}async render(t){const e=this.src;if(e&&await super.render(t)){let t=await(await fetch(e)).text();for(const[e,r]of Object.entries(Import.replacements))t=t.replace(new RegExp(`%%${e}%%`,"g"),r);return this.innerHTML=t,this.querySelectorAll("script").forEach((t=>{const e=document.createElement("script");t.getAttribute("type")&&(e.type=t.getAttribute("type")),t.getAttribute("src")&&(e.src=t.getAttribute("src")),t.textContent&&(e.textContent=t.textContent),t.parentElement.replaceChild(e,t)})),!0}return!1}get shadowStyles(){return"\n :host {\n display: contents;\n }\n "}static replacements={root:"./"};static addReplacement(t,e){this.replacements={...this.replacements,[t]:e}}static observedAttributes=[...super.observedAttributes,"src"]}window.customElements.define("k-import",Import);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import Collapsible from"./Collapsible.js";import{onEvent,offEvent}from"../utils/element.js";const updateFromStorage=Symbol("updateFromStorage"),storageChangeHandler=Symbol("storageChangeHandler"),changeHandler=Symbol("changeHandler");export default class PersistantCollapsible extends Collapsible{constructor(){super(),this[updateFromStorage]=()=>{this.opened="true"===localStorage.getItem(`PersistantCollapsible-${this.id}`)},this[storageChangeHandler]=e=>{e.key===`PersistantCollapsible-${this.id}`&&this[updateFromStorage]()},this[changeHandler]=()=>{this.id&&localStorage.setItem(`PersistantCollapsible-${this.id}`,this.opened)}}async render(e){return!!await super.render(e)&&(this[updateFromStorage](),onEvent(window,"storage",this[storageChangeHandler]),onEvent(this,"openedchanged",this[changeHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(window,"storage",this[storageChangeHandler]),offEvent(this,"openedchanged",this[changeHandler]),window.removeEventListener("storage",this[storageChangeHandler])}}window.customElements.define("k-p-collapsible",PersistantCollapsible);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import LazyComponent from"./LazyComponent.js";import"./Icon.js";import"./FocusCapture.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";export default class SideMenu extends LazyComponent{constructor(){super(),this.registerAttribute("opened",!1),this.registerAttribute("overlayClose",!0),this.registerProps({_overlayClick:()=>{this.overlayClose&&this.close()}})}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}attributeChangedCallback(n,e,t){super.attributeChangedCallback(n,e,t),"opened"===n&&dispatchEvent(this,"true"===t?"change open":"change close")}render(n){super.render(n),onEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened?this.close():this.open(),dispatchEvent(this,"toggle")}get shadowTemplate(){return`\n <k-focus-capture>\n <div id="container">\n <button id="overlay" class="no-btn">\n <k-icon id="overlay-x" name="close"></k-icon>\n </button>\n <div id="menu">\n ${super.shadowTemplate}\n </div>\n </div>\n </k-focus-capture>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n --bg: var(--c_bg);\n --width: 20rem;\n\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n max-width: 100%;\n height: 100vh;\n z-index: 100;\n pointer-events: none;\n }\n :host([opened]) {\n pointer-events: auto;\n }\n k-focus-capture {\n width: 100%;\n height: 100%;\n }\n #container {\n position: relative;\n width: 100%;\n height: 100%;\n opacity: 0;\n transition: opacity var(--animation_ms, 256ms);\n }\n :host([opened]) #container {\n opacity: 1;\n }\n #overlay {\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n background: var(--overlay, rgba(0, 0, 0, 0.5));\n }\n #overlay-x {\n position: absolute;\n top: var(--spacer_h);\n right: var(--spacer_h);\n font-size: 1.75rem;\n cursor: pointer;\n color: var(--tc_light);\n }\n :host([overlay-close="false"]) #overlay-x {\n display: none;\n }\n :host([overlay-close="false"]) #overlay {\n cursor: default;\n }\n #menu {\n position: absolute;\n width: var(--width);\n max-width: calc(100vw - 6rem);\n height: 100vh;\n overflow-y: auto;\n left: calc(var(--width) * -1);\n top: 0;\n background: var(--bg);\n transition: left var(--animation_ms, 256ms);\n padding: var(--menu_padding, var(--spacer))\n }\n :host([opened]) #menu {\n left: 0;\n }\n :host([side="right"]) #menu {\n left: auto;\n transition: right var(--animation_ms, 256ms);\n right: calc(var(--width) * -1);\n }\n :host([opened][side="right"]) #menu {\n right: 0;\n }\n :host([side="right"]) #overlay-x {\n right: auto;\n left: var(--spacer_h);\n }\n `}static
|
|
1
|
+
import LazyComponent from"./LazyComponent.js";import"./Icon.js";import"./FocusCapture.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";export default class SideMenu extends LazyComponent{constructor(){super(),this.registerAttribute("opened",!1),this.registerAttribute("overlayClose",!0),this.registerProps({_overlayClick:()=>{this.overlayClose&&this.close()}})}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}attributeChangedCallback(n,e,t){super.attributeChangedCallback(n,e,t),"opened"===n&&dispatchEvent(this,"true"===t?"change open":"change close")}render(n){super.render(n),onEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened?this.close():this.open(),dispatchEvent(this,"toggle")}get shadowTemplate(){return`\n <k-focus-capture>\n <div id="container">\n <button id="overlay" class="no-btn">\n <k-icon id="overlay-x" name="close"></k-icon>\n </button>\n <div id="menu">\n ${super.shadowTemplate}\n </div>\n </div>\n </k-focus-capture>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n --bg: var(--c_bg);\n --width: 20rem;\n\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n max-width: 100%;\n height: 100vh;\n z-index: 100;\n pointer-events: none;\n }\n :host([opened]) {\n pointer-events: auto;\n }\n k-focus-capture {\n width: 100%;\n height: 100%;\n }\n #container {\n position: relative;\n width: 100%;\n height: 100%;\n opacity: 0;\n transition: opacity var(--animation_ms, 256ms);\n }\n :host([opened]) #container {\n opacity: 1;\n }\n #overlay {\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n background: var(--overlay, rgba(0, 0, 0, 0.5));\n }\n #overlay-x {\n position: absolute;\n top: var(--spacer_h);\n right: var(--spacer_h);\n font-size: 1.75rem;\n cursor: pointer;\n color: var(--tc_light);\n }\n :host([overlay-close="false"]) #overlay-x {\n display: none;\n }\n :host([overlay-close="false"]) #overlay {\n cursor: default;\n }\n #menu {\n position: absolute;\n width: var(--width);\n max-width: calc(100vw - 6rem);\n height: 100vh;\n overflow-y: auto;\n left: calc(var(--width) * -1);\n top: 0;\n background: var(--bg);\n transition: left var(--animation_ms, 256ms);\n padding: var(--menu_padding, var(--spacer))\n }\n :host([opened]) #menu {\n left: 0;\n }\n :host([side="right"]) #menu {\n left: auto;\n transition: right var(--animation_ms, 256ms);\n right: calc(var(--width) * -1);\n }\n :host([opened][side="right"]) #menu {\n right: 0;\n }\n :host([side="right"]) #overlay-x {\n right: auto;\n left: var(--spacer_h);\n }\n `}static observedAttributes=[...super.observedAttributes,"opened"]}window.customElements.define("k-side-menu",SideMenu);
|
package/dist/utils/element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import waitFrames from"./waitFrames.js";export const onEvent=(t,
|
|
1
|
+
import waitFrames from"./waitFrames.js";export const onEvent=(e,t,n,o=document)=>{e instanceof EventTarget?t.toLowerCase().split(" ").forEach((t=>{e.addEventListener(t,n)})):e instanceof NodeList||e instanceof Array?e.forEach((e=>onEvent(e,t,n))):"string"==typeof e&&o.querySelectorAll(e).forEach((e=>onEvent(e,t,n)))};export const offEvent=(e,t,n,o=document)=>{e instanceof EventTarget?t.toLowerCase().split(" ").forEach((t=>{e.removeEventListener(t,n)})):e instanceof NodeList||e instanceof Array?e.forEach((e=>offEvent(e,t,n))):"string"==typeof e&&o.querySelectorAll(e).forEach((e=>offEvent(e,t,n)))};export const dispatchEvent=(e,t,n,{scope:o=document,bubbles:i=!1}={})=>{e instanceof EventTarget?t.toLowerCase().split(" ").forEach((t=>{e.dispatchEvent(new CustomEvent(t,{bubbles:i,detail:n}))})):e instanceof NodeList||e instanceof Array?e.forEach((e=>dispatchEvent(e,t,n,{scope:o,bubbles:i}))):"string"==typeof e&&o.querySelectorAll(e).forEach((e=>dispatchEvent(e,t,n,{scope:o,bubbles:i})))};export const isInView=async e=>{await waitFrames(2);const t=e.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth;if(t.bottom<0||t.top>n||t.right<0||t.left>o)return!1;for(;e;){const t=getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility)return!1;e=e.parentElement}return!0};export const firstFocusable=e=>e.querySelector('a[href]:not([disabled]), button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])');export const setProp=(e,t,n,o=document)=>{e instanceof HTMLElement?e[t]=n:e instanceof NodeList||e instanceof Array?[...e].forEach((e=>dispatchEvent(e,t,n))):"string"==typeof e&&dispatchEvent(o.querySelectorAll(e),t,n)};export default{onEvent:onEvent,offEvent:offEvent,dispatchEvent:dispatchEvent,isInView:isInView,firstFocusable:firstFocusable,setProp:setProp};
|
|
@@ -7,14 +7,16 @@
|
|
|
7
7
|
<link rel="stylesheet" href="../kempo/kempo-vars.css" /><link rel="stylesheet" href="../kempo/kempo-styles.css" />
|
|
8
8
|
<link rel="stylesheet" href="../kempo/kempo-hljs.css" />
|
|
9
9
|
<script type="module">
|
|
10
|
+
import Import from '../kempo/components/Import.js';
|
|
10
11
|
import Icon from '../kempo/components/Icon.js';
|
|
11
12
|
import Search from '../kempo/components/Search.js';
|
|
13
|
+
Import.addReplacement('root', '../');
|
|
12
14
|
Icon.pathToIcons = ['../icons'];
|
|
13
15
|
Search.searchDataUrl = '../search.json';
|
|
14
16
|
</script>
|
|
15
17
|
</head>
|
|
16
18
|
<body>
|
|
17
|
-
<k-import src="../nav
|
|
19
|
+
<k-import src="../nav.inc.html"></k-import>
|
|
18
20
|
<h1 class="ta-center">Icon</h1>
|
|
19
21
|
<main>
|
|
20
22
|
<details class="b r mb">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";import{setProp}from"../utils/element.js";export default class Card extends Component{constructor(
|
|
1
|
+
import Component from"./Component.js";import{setProp}from"../utils/element.js";export default class Card extends Component{constructor(e=""){super(),this.registerAttribute("label",e)}attributeChangedCallback(e,r,n){"label"===e&&setProp(this.shadowRoot.getElementById("label"),"innerHTML",n)}get shadowTemplate(){return`\n <div id="card">\n <div id="label">${this.label}</div>\n ${super.shadowTemplate}\n </div>\n `}get shadowStyles(){return"\n :host {\n display: block;\n }\n #card {\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n margin-bottom: var(--spacer);\n padding: var(--spacer);\n position: relative;\n background-color: var(--c_bg);\n }\n #label {\n position: absolute;\n top: -1.25em;\n left: 1.25em;\n background-color: var(--c_bg);\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n padding: var(--spacer_h);\n }\n :host([label]) {\n padding-top: calc(1.5 * var(--spacer));\n margin-top: var(--spacer);\n }\n :host([label]) #card {\n padding-top: calc(1.5 * var(--spacer));\n }\n :host(:not([label])) #label {\n display: none;\n }\n\n "}static observedAttributes=[...super.observedAttributes,"label"]}window.customElements.define("k-card",Card);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import Component from".//Component.js";import"./Icon.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";const clickHandler=Symbol("clickHandler");export default class Collapsible extends Component{constructor(e=!1){super(),this[clickHandler]=()=>{this.toggle()},this.registerAttributes({opened:e})}async render(e){return!!await super.render(e)&&(onEvent(this.shadowRoot.getElementById("label"),"click",this[clickHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("label"),"click",this[clickHandler])}attributeChangedCallback(e,n,t){super.attributeChangedCallback(e,n,t),"opened"===e&&n!==t&&dispatchEvent(this,"openedchanged "+("true"===t?"open":"close"))}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened=!this.opened,dispatchEvent(this,"openedtoggled")}get shadowTemplate(){return`\n <div id="labelContainer">\n <div id="label">\n <slot name="label"></slot>\n </div>\n <div id="labelIcon">\n <slot name="labelIcon">\n <k-icon name="chevron-right"></k-icon>\n </slot>\n </div>\n </div>\n <div id="content">\n ${super.shadowTemplate}\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n }\n #labelContainer {\n display: flex;\n cursor: pointer;\n }\n #label {\n flex: 1 1 auto;\n }\n #labelIcon {\n flex: 0 0 none;\n opacity: 0.5;\n transform: rotate(90deg);\n transition: transform var(--animation_ms, 256ms);\n }\n #labelContainer:hover #labelIcon {\n opacity: 1;\n }\n :host([opened="true"]) #labelIcon {\n transform: rotate(-90deg);\n }\n :host(:not([opened="true"])) #content {\n display: none;\n }\n `}static observedAttributes=[...super.observedAttributes,"opened"]}window.customElements.define("k-collapsible",Collapsible);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";const cache={},getIconByPath=async t=>(cache[t]||(cache[t]=new Promise((async(e,n)=>{try{const n=await fetch(t);200===n.status
|
|
1
|
+
import Component from"./Component.js";const cache={},getIconByPath=async t=>(cache[t]||(cache[t]=new Promise((async(e,n)=>{const s=(new AbortController).signal;try{const n=await fetch(t,{signal:s});200===n.status?e(await n.text()):404===n.status&&e(null)}catch(t){"AbortError"!==t.name&&n(t)}})).catch((()=>null))),await cache[t]),getIconByName=t=>{const e=async e=>getIconByPath(`${e}/${t}.svg`);return new Promise((async(t,n)=>{let s;for(let t=0;t<Icon.pathToIcons.length&&!s;t++)try{s=await e(Icon.pathToIcons[t])}catch(t){}t(s||null)}))};export default class Icon extends Component{constructor(t=""){super(),this.registerAttributes({src:"",name:t})}connectedCallback(){}async render(t){if(await super.render(t)){if(this.src){const t=await getIconByPath(this.src);t?(this.innerHTML=t,this.fixSVG()):this.innerHTML.length||(this.innerHTML=Icon.fallback)}else if(this.name){const t=await getIconByName(this.name);t?(this.innerHTML=t,this.fixSVG()):this.innerHTML.length||(this.innerHTML=Icon.fallback)}else this.rendered=!1,this.innerHTML.length||(this.innerHTML=Icon.fallback);return!0}return!1}attributeChangedCallback(t,e,n){super.attributeChangedCallback(t,e,n),["src","name"].includes(t)&&n&&this.render(!0)}fixSVG(){const t=this.querySelector("svg");t.removeAttribute("width"),t.removeAttribute("height"),t.querySelectorAll("path, rect, circle").forEach((t=>{t.setAttribute("fill","currentColor")}))}get shadowStyles(){return"\n :host {\n display: inline-block;\n vertical-align: bottom;\n }\n ::slotted(svg){\n height: 1.35em;\n vertical-align: middle;\n }\n "}static observedAttributes=["name","src"];static pathToIcons=["/icons"];static fallback='\n <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>\n '}window.customElements.define("k-icon",Icon);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";export default class Import extends Component{constructor(){super(),this.registerAttribute("src")}attributeChangedCallback(t,e,r){"src"===t&&e!==r&&this.render(!0)}async render(t){const e=this.src;e&&await super.render(t)
|
|
1
|
+
import Component from"./Component.js";export default class Import extends Component{constructor(t=""){super(),this.registerAttribute("src",t)}attributeChangedCallback(t,e,r){"src"===t&&e!==r&&this.render(!0)}async render(t){const e=this.src;if(e&&await super.render(t)){let t=await(await fetch(e)).text();for(const[e,r]of Object.entries(Import.replacements))t=t.replace(new RegExp(`%%${e}%%`,"g"),r);return this.innerHTML=t,this.querySelectorAll("script").forEach((t=>{const e=document.createElement("script");t.getAttribute("type")&&(e.type=t.getAttribute("type")),t.getAttribute("src")&&(e.src=t.getAttribute("src")),t.textContent&&(e.textContent=t.textContent),t.parentElement.replaceChild(e,t)})),!0}return!1}get shadowStyles(){return"\n :host {\n display: contents;\n }\n "}static replacements={root:"./"};static addReplacement(t,e){this.replacements={...this.replacements,[t]:e}}static observedAttributes=[...super.observedAttributes,"src"]}window.customElements.define("k-import",Import);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import Collapsible from"./Collapsible.js";import{onEvent,offEvent}from"../utils/element.js";const updateFromStorage=Symbol("updateFromStorage"),storageChangeHandler=Symbol("storageChangeHandler"),changeHandler=Symbol("changeHandler");export default class PersistantCollapsible extends Collapsible{constructor(){super(),this[updateFromStorage]=()=>{this.opened="true"===localStorage.getItem(`PersistantCollapsible-${this.id}`)},this[storageChangeHandler]=e=>{e.key===`PersistantCollapsible-${this.id}`&&this[updateFromStorage]()},this[changeHandler]=()=>{this.id&&localStorage.setItem(`PersistantCollapsible-${this.id}`,this.opened)}}async render(e){return!!await super.render(e)&&(this[updateFromStorage](),onEvent(window,"storage",this[storageChangeHandler]),onEvent(this,"openedchanged",this[changeHandler]),!0)}disconnectedCallback(){super.disconnectedCallback(),offEvent(window,"storage",this[storageChangeHandler]),offEvent(this,"openedchanged",this[changeHandler]),window.removeEventListener("storage",this[storageChangeHandler])}}window.customElements.define("k-p-collapsible",PersistantCollapsible);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import LazyComponent from"./LazyComponent.js";import"./Icon.js";import"./FocusCapture.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";export default class SideMenu extends LazyComponent{constructor(){super(),this.registerAttribute("opened",!1),this.registerAttribute("overlayClose",!0),this.registerProps({_overlayClick:()=>{this.overlayClose&&this.close()}})}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}attributeChangedCallback(n,e,t){super.attributeChangedCallback(n,e,t),"opened"===n&&dispatchEvent(this,"true"===t?"change open":"change close")}render(n){super.render(n),onEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened?this.close():this.open(),dispatchEvent(this,"toggle")}get shadowTemplate(){return`\n <k-focus-capture>\n <div id="container">\n <button id="overlay" class="no-btn">\n <k-icon id="overlay-x" name="close"></k-icon>\n </button>\n <div id="menu">\n ${super.shadowTemplate}\n </div>\n </div>\n </k-focus-capture>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n --bg: var(--c_bg);\n --width: 20rem;\n\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n max-width: 100%;\n height: 100vh;\n z-index: 100;\n pointer-events: none;\n }\n :host([opened]) {\n pointer-events: auto;\n }\n k-focus-capture {\n width: 100%;\n height: 100%;\n }\n #container {\n position: relative;\n width: 100%;\n height: 100%;\n opacity: 0;\n transition: opacity var(--animation_ms, 256ms);\n }\n :host([opened]) #container {\n opacity: 1;\n }\n #overlay {\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n background: var(--overlay, rgba(0, 0, 0, 0.5));\n }\n #overlay-x {\n position: absolute;\n top: var(--spacer_h);\n right: var(--spacer_h);\n font-size: 1.75rem;\n cursor: pointer;\n color: var(--tc_light);\n }\n :host([overlay-close="false"]) #overlay-x {\n display: none;\n }\n :host([overlay-close="false"]) #overlay {\n cursor: default;\n }\n #menu {\n position: absolute;\n width: var(--width);\n max-width: calc(100vw - 6rem);\n height: 100vh;\n overflow-y: auto;\n left: calc(var(--width) * -1);\n top: 0;\n background: var(--bg);\n transition: left var(--animation_ms, 256ms);\n padding: var(--menu_padding, var(--spacer))\n }\n :host([opened]) #menu {\n left: 0;\n }\n :host([side="right"]) #menu {\n left: auto;\n transition: right var(--animation_ms, 256ms);\n right: calc(var(--width) * -1);\n }\n :host([opened][side="right"]) #menu {\n right: 0;\n }\n :host([side="right"]) #overlay-x {\n right: auto;\n left: var(--spacer_h);\n }\n `}static
|
|
1
|
+
import LazyComponent from"./LazyComponent.js";import"./Icon.js";import"./FocusCapture.js";import{onEvent,offEvent,dispatchEvent}from"../utils/element.js";export default class SideMenu extends LazyComponent{constructor(){super(),this.registerAttribute("opened",!1),this.registerAttribute("overlayClose",!0),this.registerProps({_overlayClick:()=>{this.overlayClose&&this.close()}})}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}attributeChangedCallback(n,e,t){super.attributeChangedCallback(n,e,t),"opened"===n&&dispatchEvent(this,"true"===t?"change open":"change close")}render(n){super.render(n),onEvent(this.shadowRoot.getElementById("overlay"),"click",this._overlayClick)}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened?this.close():this.open(),dispatchEvent(this,"toggle")}get shadowTemplate(){return`\n <k-focus-capture>\n <div id="container">\n <button id="overlay" class="no-btn">\n <k-icon id="overlay-x" name="close"></k-icon>\n </button>\n <div id="menu">\n ${super.shadowTemplate}\n </div>\n </div>\n </k-focus-capture>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n --bg: var(--c_bg);\n --width: 20rem;\n\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n max-width: 100%;\n height: 100vh;\n z-index: 100;\n pointer-events: none;\n }\n :host([opened]) {\n pointer-events: auto;\n }\n k-focus-capture {\n width: 100%;\n height: 100%;\n }\n #container {\n position: relative;\n width: 100%;\n height: 100%;\n opacity: 0;\n transition: opacity var(--animation_ms, 256ms);\n }\n :host([opened]) #container {\n opacity: 1;\n }\n #overlay {\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n background: var(--overlay, rgba(0, 0, 0, 0.5));\n }\n #overlay-x {\n position: absolute;\n top: var(--spacer_h);\n right: var(--spacer_h);\n font-size: 1.75rem;\n cursor: pointer;\n color: var(--tc_light);\n }\n :host([overlay-close="false"]) #overlay-x {\n display: none;\n }\n :host([overlay-close="false"]) #overlay {\n cursor: default;\n }\n #menu {\n position: absolute;\n width: var(--width);\n max-width: calc(100vw - 6rem);\n height: 100vh;\n overflow-y: auto;\n left: calc(var(--width) * -1);\n top: 0;\n background: var(--bg);\n transition: left var(--animation_ms, 256ms);\n padding: var(--menu_padding, var(--spacer))\n }\n :host([opened]) #menu {\n left: 0;\n }\n :host([side="right"]) #menu {\n left: auto;\n transition: right var(--animation_ms, 256ms);\n right: calc(var(--width) * -1);\n }\n :host([opened][side="right"]) #menu {\n right: 0;\n }\n :host([side="right"]) #overlay-x {\n right: auto;\n left: var(--spacer_h);\n }\n `}static observedAttributes=[...super.observedAttributes,"opened"]}window.customElements.define("k-side-menu",SideMenu);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import waitFrames from"./waitFrames.js";export const onEvent=(t,
|
|
1
|
+
import waitFrames from"./waitFrames.js";export const onEvent=(e,t,n,o=document)=>{e instanceof EventTarget?t.toLowerCase().split(" ").forEach((t=>{e.addEventListener(t,n)})):e instanceof NodeList||e instanceof Array?e.forEach((e=>onEvent(e,t,n))):"string"==typeof e&&o.querySelectorAll(e).forEach((e=>onEvent(e,t,n)))};export const offEvent=(e,t,n,o=document)=>{e instanceof EventTarget?t.toLowerCase().split(" ").forEach((t=>{e.removeEventListener(t,n)})):e instanceof NodeList||e instanceof Array?e.forEach((e=>offEvent(e,t,n))):"string"==typeof e&&o.querySelectorAll(e).forEach((e=>offEvent(e,t,n)))};export const dispatchEvent=(e,t,n,{scope:o=document,bubbles:i=!1}={})=>{e instanceof EventTarget?t.toLowerCase().split(" ").forEach((t=>{e.dispatchEvent(new CustomEvent(t,{bubbles:i,detail:n}))})):e instanceof NodeList||e instanceof Array?e.forEach((e=>dispatchEvent(e,t,n,{scope:o,bubbles:i}))):"string"==typeof e&&o.querySelectorAll(e).forEach((e=>dispatchEvent(e,t,n,{scope:o,bubbles:i})))};export const isInView=async e=>{await waitFrames(2);const t=e.getBoundingClientRect(),n=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth;if(t.bottom<0||t.top>n||t.right<0||t.left>o)return!1;for(;e;){const t=getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility)return!1;e=e.parentElement}return!0};export const firstFocusable=e=>e.querySelector('a[href]:not([disabled]), button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])');export const setProp=(e,t,n,o=document)=>{e instanceof HTMLElement?e[t]=n:e instanceof NodeList||e instanceof Array?[...e].forEach((e=>dispatchEvent(e,t,n))):"string"==typeof e&&dispatchEvent(o.querySelectorAll(e),t,n)};export default{onEvent:onEvent,offEvent:offEvent,dispatchEvent:dispatchEvent,isInView:isInView,firstFocusable:firstFocusable,setProp:setProp};
|
package/docs/nav.inc.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
>
|
|
8
8
|
<k-icon name="menu"></k-icon>
|
|
9
9
|
</button>
|
|
10
|
-
<a href="
|
|
10
|
+
<a href="%%root%%">Home</a>
|
|
11
11
|
<k-search
|
|
12
12
|
class="flex mr"
|
|
13
13
|
style="min-width:10rem;max-width:24rem"
|
|
@@ -21,43 +21,43 @@
|
|
|
21
21
|
>
|
|
22
22
|
<h1>Kempo Docs</h1>
|
|
23
23
|
<menu>
|
|
24
|
-
<a href="
|
|
24
|
+
<a href="%%root%%" class="h5 pl0 mb">Home</a>
|
|
25
25
|
<h5 class="mb0">Styles</h5>
|
|
26
26
|
<div class="pl mb">
|
|
27
|
-
<a href="
|
|
28
|
-
<a href="
|
|
29
|
-
<a href="
|
|
30
|
-
<a href="
|
|
31
|
-
<a href="
|
|
32
|
-
<a href="
|
|
33
|
-
<a href="
|
|
27
|
+
<a href="%%root%%styles/typography.html">Typography</a>
|
|
28
|
+
<a href="%%root%%styles/displays-layouts.html">Displays and Layouts</a>
|
|
29
|
+
<a href="%%root%%styles/borders-spacing.html">Borders and Spacing</a>
|
|
30
|
+
<a href="%%root%%styles/inputs.html">Inputs</a>
|
|
31
|
+
<a href="%%root%%styles/buttons.html">Buttons</a>
|
|
32
|
+
<a href="%%root%%styles/tables.html">Tables</a>
|
|
33
|
+
<a href="%%root%%styles/colors.html">Colors</a>
|
|
34
34
|
</div>
|
|
35
35
|
<h5 class="mb0">Components</h5>
|
|
36
36
|
<div class="pl mb">
|
|
37
|
-
<a href="
|
|
38
|
-
<a href="
|
|
39
|
-
<a href="
|
|
40
|
-
<a href="
|
|
41
|
-
<a href="
|
|
37
|
+
<a href="%%root%%components/component.html">Component</a>
|
|
38
|
+
<a href="%%root%%components/lazy-component.html">LazyComponent</a>
|
|
39
|
+
<a href="%%root%%components/reactivecomponent.html">ReactiveComponent</a>
|
|
40
|
+
<a href="%%root%%components/reactivelazy-component.html">ReactiveLazyComponent</a>
|
|
41
|
+
<a href="%%root%%components/focuscapture.html">FocusCapture</a>
|
|
42
42
|
<hr />
|
|
43
|
-
<a href="
|
|
44
|
-
<a href="
|
|
45
|
-
<a href="
|
|
46
|
-
<a href="
|
|
47
|
-
<a href="
|
|
48
|
-
<a href="
|
|
49
|
-
<a href="
|
|
50
|
-
<a href="
|
|
51
|
-
<a href="
|
|
52
|
-
<a href="
|
|
53
|
-
<a href="
|
|
54
|
-
<a href="
|
|
55
|
-
<a href="
|
|
56
|
-
<a href="
|
|
57
|
-
<a href="
|
|
58
|
-
<a href="
|
|
59
|
-
<a href="
|
|
60
|
-
<a href="
|
|
43
|
+
<a href="%%root%%components/accordion.html">Accordion</a>
|
|
44
|
+
<a href="%%root%%components/card.html">Card</a>
|
|
45
|
+
<a href="%%root%%components/content-slider.html">Content Slider</a>
|
|
46
|
+
<a href="%%root%%components/dialog.html">Dialog</a>
|
|
47
|
+
<a href="%%root%%components/directory-viewer.html">Directory Viewer</a>
|
|
48
|
+
<a href="%%root%%components/icon.html">Icon</a>
|
|
49
|
+
<a href="%%root%%components/import.html">Import</a>
|
|
50
|
+
<a href="%%root%%components/resize.html">Resize</a>
|
|
51
|
+
<a href="%%root%%components/search.html">Search</a>
|
|
52
|
+
<a href="%%root%%components/show-more.html">Show More</a>
|
|
53
|
+
<a href="%%root%%components/side-menu.html">Side Menu</a>
|
|
54
|
+
<a href="%%root%%components/split.html">Split</a>
|
|
55
|
+
<a href="%%root%%components/table.html">Table</a>
|
|
56
|
+
<a href="%%root%%components/tabs.html">Tabs</a>
|
|
57
|
+
<a href="%%root%%components/tags.html">Tags</a>
|
|
58
|
+
<a href="%%root%%components/theme-switcher.html">Theme Switcher</a>
|
|
59
|
+
<a href="%%root%%components/timestamp.html">Timestamp</a>
|
|
60
|
+
<a href="%%root%%components/toggle.html">Toggle</a>
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
63
|
<h5 class="mb0">Utils</h5>
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
document.getElementById('side-menu').open();
|
|
73
73
|
});
|
|
74
74
|
</script>
|
|
75
|
-
<script src="
|
|
76
|
-
<script src="
|
|
77
|
-
<script src="
|
|
78
|
-
<script src="
|
|
75
|
+
<script src="%%root%%kempo/components/SideMenu.js" type="module"></script>
|
|
76
|
+
<script src="%%root%%kempo/components/Icon.js" type="module"></script>
|
|
77
|
+
<script src="%%root%%kempo/components/ThemeSwitcher.js" type="module"></script>
|
|
78
|
+
<script src="%%root%%kempo/components/Search.js" type="module"></script>
|
package/package.json
CHANGED
package/src/components/Card.js
CHANGED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import Component from './/Component.js';
|
|
2
|
+
import './Icon.js';
|
|
3
|
+
import { onEvent, offEvent, dispatchEvent } from '../utils/element.js';
|
|
4
|
+
|
|
5
|
+
const clickHandler = Symbol('clickHandler');
|
|
6
|
+
export default class Collapsible extends Component {
|
|
7
|
+
constructor(opened = false){
|
|
8
|
+
super();
|
|
9
|
+
|
|
10
|
+
/* Private Methods */
|
|
11
|
+
this[clickHandler] = () => {
|
|
12
|
+
this.toggle();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* Init */
|
|
16
|
+
this.registerAttributes({
|
|
17
|
+
opened
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Lifecycle Callbacks */
|
|
22
|
+
async render(force){
|
|
23
|
+
if(await super.render(force)){
|
|
24
|
+
onEvent(this.shadowRoot.getElementById('label'), 'click', this[clickHandler]);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
disconnectedCallback(){
|
|
30
|
+
super.disconnectedCallback();
|
|
31
|
+
offEvent(this.shadowRoot.getElementById('label'), 'click', this[clickHandler]);
|
|
32
|
+
}
|
|
33
|
+
attributeChangedCallback(n, oV, nV){
|
|
34
|
+
super.attributeChangedCallback(n, oV, nV);
|
|
35
|
+
if(n === 'opened' && oV !== nV){
|
|
36
|
+
dispatchEvent(this, `openedchanged ${nV==='true'?'open':'close'}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Public Methods */
|
|
41
|
+
open(){
|
|
42
|
+
this.opened = true;
|
|
43
|
+
}
|
|
44
|
+
close(){
|
|
45
|
+
this.opened = false;
|
|
46
|
+
}
|
|
47
|
+
toggle(){
|
|
48
|
+
this.opened = !this.opened;
|
|
49
|
+
dispatchEvent(this, 'openedtoggled');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Shadow DOM */
|
|
53
|
+
get shadowTemplate(){
|
|
54
|
+
return /*html*/`
|
|
55
|
+
<div id="labelContainer">
|
|
56
|
+
<div id="label">
|
|
57
|
+
<slot name="label"></slot>
|
|
58
|
+
</div>
|
|
59
|
+
<div id="labelIcon">
|
|
60
|
+
<slot name="labelIcon">
|
|
61
|
+
<k-icon name="chevron-right"></k-icon>
|
|
62
|
+
</slot>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
<div id="content">
|
|
66
|
+
${super.shadowTemplate}
|
|
67
|
+
</div>
|
|
68
|
+
`;
|
|
69
|
+
}
|
|
70
|
+
get shadowStyles(){
|
|
71
|
+
return /*css*/`
|
|
72
|
+
${super.shadowStyles}
|
|
73
|
+
:host {
|
|
74
|
+
display: block;
|
|
75
|
+
}
|
|
76
|
+
#labelContainer {
|
|
77
|
+
display: flex;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
}
|
|
80
|
+
#label {
|
|
81
|
+
flex: 1 1 auto;
|
|
82
|
+
}
|
|
83
|
+
#labelIcon {
|
|
84
|
+
flex: 0 0 none;
|
|
85
|
+
opacity: 0.5;
|
|
86
|
+
transform: rotate(90deg);
|
|
87
|
+
transition: transform var(--animation_ms, 256ms);
|
|
88
|
+
}
|
|
89
|
+
#labelContainer:hover #labelIcon {
|
|
90
|
+
opacity: 1;
|
|
91
|
+
}
|
|
92
|
+
:host([opened="true"]) #labelIcon {
|
|
93
|
+
transform: rotate(-90deg);
|
|
94
|
+
}
|
|
95
|
+
:host(:not([opened="true"])) #content {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Static Attributes */
|
|
102
|
+
static observedAttributes = [...super.observedAttributes, 'opened'];
|
|
103
|
+
}
|
|
104
|
+
window.customElements.define('k-collapsible', Collapsible);
|
package/src/components/Icon.js
CHANGED
|
@@ -3,17 +3,27 @@ import Component from './Component.js';
|
|
|
3
3
|
const cache = {};
|
|
4
4
|
|
|
5
5
|
const getIconByPath = async (path) => {
|
|
6
|
-
if(!cache[path]){
|
|
7
|
-
cache[path] = new Promise(async (resolve, reject)=>{
|
|
6
|
+
if (!cache[path]) {
|
|
7
|
+
cache[path] = new Promise(async (resolve, reject) => {
|
|
8
|
+
const controller = new AbortController();
|
|
9
|
+
const signal = controller.signal;
|
|
8
10
|
try {
|
|
9
|
-
const response = await fetch(path);
|
|
10
|
-
if(response.status === 200)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const response = await fetch(path, { signal });
|
|
12
|
+
if (response.status === 200) {
|
|
13
|
+
resolve(await response.text());
|
|
14
|
+
} else if (response.status === 404) {
|
|
15
|
+
resolve(null);
|
|
16
|
+
}
|
|
17
|
+
} catch (e) {
|
|
18
|
+
if (e.name !== 'AbortError') {
|
|
19
|
+
reject(e);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}).catch(() => null);
|
|
23
|
+
}
|
|
15
24
|
return await cache[path];
|
|
16
|
-
}
|
|
25
|
+
};
|
|
26
|
+
|
|
17
27
|
const getIconByName = (name) => {
|
|
18
28
|
const tryDir = async (dir) => getIconByPath(`${dir}/${name}.svg`);
|
|
19
29
|
|
|
@@ -27,7 +37,7 @@ const getIconByName = (name) => {
|
|
|
27
37
|
if(svg){
|
|
28
38
|
resolve(svg);
|
|
29
39
|
} else {
|
|
30
|
-
|
|
40
|
+
resolve(null);
|
|
31
41
|
}
|
|
32
42
|
});
|
|
33
43
|
}
|
|
@@ -103,7 +113,7 @@ export default class Icon extends Component {
|
|
|
103
113
|
'/icons'
|
|
104
114
|
];
|
|
105
115
|
static fallback = /*html*/`
|
|
106
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="
|
|
116
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>
|
|
107
117
|
`;
|
|
108
118
|
}
|
|
109
119
|
window.customElements.define('k-icon', Icon);
|
package/src/components/Import.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import Component from './Component.js';
|
|
2
2
|
|
|
3
3
|
export default class Import extends Component {
|
|
4
|
-
constructor(){
|
|
4
|
+
constructor(src = ''){
|
|
5
5
|
super();
|
|
6
|
-
this.registerAttribute('src');
|
|
6
|
+
this.registerAttribute('src', src);
|
|
7
7
|
}
|
|
8
8
|
attributeChangedCallback(n, oV, nV){
|
|
9
9
|
if(n === 'src' && oV !== nV){
|
|
@@ -13,7 +13,11 @@ export default class Import extends Component {
|
|
|
13
13
|
async render(force){
|
|
14
14
|
const src = this.src;
|
|
15
15
|
if(src && await super.render(force)){
|
|
16
|
-
|
|
16
|
+
let contents = await (await fetch(src)).text();
|
|
17
|
+
for (const [name, value] of Object.entries(Import.replacements)) {
|
|
18
|
+
contents = contents.replace(new RegExp(`%%${name}%%`, 'g'), value);
|
|
19
|
+
}
|
|
20
|
+
this.innerHTML = contents;
|
|
17
21
|
this.querySelectorAll('script').forEach( $badScript => {
|
|
18
22
|
const $goodScript = document.createElement('script');
|
|
19
23
|
if($badScript.getAttribute('type')) $goodScript.type = $badScript.getAttribute('type');
|
|
@@ -21,20 +25,29 @@ export default class Import extends Component {
|
|
|
21
25
|
if($badScript.textContent) $goodScript.textContent = $badScript.textContent;
|
|
22
26
|
$badScript.parentElement.replaceChild($goodScript, $badScript);
|
|
23
27
|
});
|
|
24
|
-
|
|
28
|
+
return true;
|
|
25
29
|
}
|
|
30
|
+
return false;
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
get shadowStyles(){
|
|
29
34
|
return /*css*/`
|
|
30
35
|
:host {
|
|
31
|
-
display:
|
|
36
|
+
display: contents;
|
|
32
37
|
}
|
|
33
38
|
`;
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
/* Static Members */
|
|
42
|
+
static replacements = {
|
|
43
|
+
root: './'
|
|
44
|
+
};
|
|
45
|
+
static addReplacement(name, value){
|
|
46
|
+
this.replacements = {
|
|
47
|
+
...this.replacements,
|
|
48
|
+
[name]: value,
|
|
49
|
+
};
|
|
38
50
|
}
|
|
51
|
+
static observedAttributes = [...super.observedAttributes, 'src'];
|
|
39
52
|
}
|
|
40
53
|
window.customElements.define('k-import', Import);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import Collapsible from './Collapsible.js';
|
|
2
|
+
import { onEvent, offEvent } from '../utils/element.js';
|
|
3
|
+
|
|
4
|
+
const updateFromStorage = Symbol('updateFromStorage'),
|
|
5
|
+
storageChangeHandler = Symbol('storageChangeHandler'),
|
|
6
|
+
changeHandler = Symbol('changeHandler');
|
|
7
|
+
export default class PersistantCollapsible extends Collapsible {
|
|
8
|
+
constructor(){
|
|
9
|
+
super();
|
|
10
|
+
|
|
11
|
+
/* Private Methods */
|
|
12
|
+
this[updateFromStorage] = () => {
|
|
13
|
+
this.opened = localStorage.getItem(`PersistantCollapsible-${this.id}`) === 'true';
|
|
14
|
+
}
|
|
15
|
+
this[storageChangeHandler] = (event) => {
|
|
16
|
+
if (event.key === `PersistantCollapsible-${this.id}`) {
|
|
17
|
+
this[updateFromStorage]();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
this[changeHandler] = () => {
|
|
21
|
+
if(this.id){
|
|
22
|
+
localStorage.setItem(`PersistantCollapsible-${this.id}`, this.opened);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Lifecycle Callbacks */
|
|
28
|
+
async render(force){
|
|
29
|
+
if(await super.render(force)){
|
|
30
|
+
this[updateFromStorage]();
|
|
31
|
+
onEvent(window, 'storage', this[storageChangeHandler]);
|
|
32
|
+
onEvent(this, 'openedchanged', this[changeHandler]);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
disconnectedCallback(){
|
|
38
|
+
super.disconnectedCallback();
|
|
39
|
+
offEvent(window, 'storage', this[storageChangeHandler]);
|
|
40
|
+
offEvent(this, 'openedchanged', this[changeHandler]);
|
|
41
|
+
window.removeEventListener('storage', this[storageChangeHandler]);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
window.customElements.define('k-p-collapsible', PersistantCollapsible);
|
|
@@ -145,12 +145,6 @@ export default class SideMenu extends LazyComponent {
|
|
|
145
145
|
}
|
|
146
146
|
`;
|
|
147
147
|
}
|
|
148
|
-
|
|
149
|
-
static get observedAttributes(){
|
|
150
|
-
return [
|
|
151
|
-
'opened',
|
|
152
|
-
...super.observedAttributes
|
|
153
|
-
]
|
|
154
|
-
}
|
|
148
|
+
static observedAttributes = [...super.observedAttributes, 'opened'];
|
|
155
149
|
}
|
|
156
150
|
window.customElements.define('k-side-menu', SideMenu);
|
package/src/utils/element.js
CHANGED
|
@@ -31,9 +31,9 @@ export const dispatchEvent = (element, events, detail, {
|
|
|
31
31
|
element.dispatchEvent(new CustomEvent(event, { bubbles, detail } ));
|
|
32
32
|
});
|
|
33
33
|
} else if(element instanceof NodeList || element instanceof Array){
|
|
34
|
-
element.forEach( el => dispatchEvent(el, events,
|
|
34
|
+
element.forEach( el => dispatchEvent(el, events, detail, { scope, bubbles }));
|
|
35
35
|
} else if(typeof(element) == 'string'){
|
|
36
|
-
scope.querySelectorAll(element).forEach( el => dispatchEvent(el, events,
|
|
36
|
+
scope.querySelectorAll(element).forEach( el => dispatchEvent(el, events, detail, { scope, bubbles }));
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
export const isInView = async (element) => {
|