kempo 2.1.0 → 2.2.0
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/DirectoryViewer.js +1 -1
- package/dist/components/ThemeSwitcher.js +1 -1
- package/docs/components/{directoryviewer.html → directory-viewer.html} +6 -1
- package/docs/kempo/components/DirectoryViewer.js +1 -1
- package/docs/kempo/components/ThemeSwitcher.js +1 -1
- package/icons/cards.svg +1 -0
- package/icons/chevron-left.svg +1 -0
- package/icons/chevron-right.svg +1 -0
- package/icons/label-add.svg +1 -0
- package/icons/label.svg +1 -0
- package/icons/tag.svg +1 -0
- package/package.json +1 -1
- package/src/components/DirectoryViewer.js +51 -7
- package/src/components/ThemeSwitcher.js +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import LazyComponent from"./LazyComponent.js";import Component from"./Component.js";import"./Icon.js";import{onEvent,offEvent}from"../utils/element.js";import watchDirectoryHandle from"../utils/watchDirectoryHandle.js";const handle=Symbol(),selectDirectoryClickHandler=Symbol(),openToggleClickHandler=Symbol(),fileSelectedHandler=Symbol(),watchId=Symbol(),changeCallback=Symbol();export default class DirectoryViewer extends LazyComponent{constructor(e=!1){super(),this[handle]=e,this[selectDirectoryClickHandler]=()=>this.selectDirectory(),this[openToggleClickHandler]=()=>{this.root?this.clearDirectoryHandle():this.toggleOpen()},this[changeCallback]=()=>{this.updateContents()},this.slot="content",this.registerAttributes({root:!e,hasHandle:!!e,opened:!e
|
|
1
|
+
import LazyComponent from"./LazyComponent.js";import Component from"./Component.js";import"./Icon.js";import{onEvent,offEvent}from"../utils/element.js";import watchDirectoryHandle from"../utils/watchDirectoryHandle.js";const handle=Symbol(),selectDirectoryClickHandler=Symbol(),openToggleClickHandler=Symbol(),fileSelectedHandler=Symbol(),watchId=Symbol(),changeCallback=Symbol(),filters=Symbol();export default class DirectoryViewer extends LazyComponent{constructor(e=!1){super(),this[handle]=e,this[watchId]=!1,this[filters]=[],this[selectDirectoryClickHandler]=()=>this.selectDirectory(),this[openToggleClickHandler]=()=>{this.root?this.clearDirectoryHandle():(this.toggleOpen(),this.select())},this[changeCallback]=()=>{this.updateContents()},this.slot="content",this.registerAttributes({root:!e,hasHandle:!!e,opened:!e,selected:!1})}async render(e){return!!await super.render(e)&&(onEvent(this.shadowRoot,"fileselected",this[fileSelectedHandler]),onEvent(this.shadowRoot.getElementById("selectDirectory"),"click",this[selectDirectoryClickHandler]),onEvent(this.shadowRoot.getElementById("openToggle"),"click",this[openToggleClickHandler]),this.renderDirectory(),!0)}async renderDirectory(){this[handle]&&this.rendered&&(this.innerHTML=this[handle].name,this.renderContents())}async renderContents(){if(this.querySelectorAll('[slot="content"]').forEach((e=>e.remove())),this.rendered&&this[handle]&&(this.opened||this.root)){for await(const e of this[handle].values())"directory"===e.kind&&this.filters.every((t=>t(e)))&&this.appendChild(new DirectoryViewer(e,!1));for await(const e of this[handle].values())"file"===e.kind&&this.filters.every((t=>t(e)))&&this.appendChild(new File(e));this[watchId]||(this[watchId]=watchDirectoryHandle(this[handle],this[changeCallback]))}else this[watchId]&&(clearInterval(this[watchId]),this[watchId]=!1)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot,"fileselected",this[fileSelectedHandler]),offEvent(this.shadowRoot.getElementById("selectDirectory"),"click",this[selectDirectoryClickHandler]),offEvent(this.shadowRoot.getElementById("openToggle"),"click",this[openToggleClickHandler])}attributeChangedCallback(e,t,n){"opened"===e&&t!==n&&(!n&&this.root?this.opened=!0:this.renderContents())}get rootDir(){return this.root?this:this.closest('k-directory-viewer[root="true"]')}get filters(){return this.rootDir[filters]}async selectDirectory(){window.showDirectoryPicker&&(this[handle]=await window.showDirectoryPicker(),this[handle]&&(this.hasHandle=!0,this.renderDirectory()))}open(){this.opened=!0}close(){this.root||(this.opened=!1)}toggleOpen(){this.root||(this.opened=!this.opened)}clearDirectoryHandle(){this[handle]=!1,this.hasHandle=!1,this.innerHTML=""}async updateContents(){if(this.opened||this.root){const e=new Set([...this.querySelectorAll("k-directory-viewer")]);for await(const t of this[handle].values())if("directory"===t.kind){const n=[...e].find((e=>t.isSameEntry(e[handle])&&t.name===e[handle].name));n?(this.appendChild(n),e.delete(n)):this.appendChild(new DirectoryViewer(t,!1))}e.forEach((e=>e.remove()));const t=new Set([...this.querySelectorAll("k-directory-viewer-file")]);for await(const e of this[handle].values())if("file"===e.kind){const n=[...t].find((t=>e.isSameEntry(t[handle])&&e.name===t[handle].name));n?(this.appendChild(n),t.delete(n)):this.appendChild(new File(e))}t.forEach((e=>e.remove())),this[watchId]||(this[watchId]=watchDirectoryHandle(this[handle],this[changeCallback]))}else this[watchId]&&(clearInterval(this[watchId]),this[watchId]=!1)}select(){const e=this.closest("k-directory-viewer[root]").querySelector("k-directory-viewer[selected], k-directory-viewer-file[selected]");e!==this&&(e&&(e.selected=!1),this.selected=!0,this.dispatchEvent(new CustomEvent("dirselected",{detail:{dirHandle:this[handle],dirComponent:this},bubbles:!0,composed:!0})))}addFilter(e){this[filters].push(e),this.renderContents()}get shadowTemplate(){return`\n <button\n id="selectDirectory"\n >\n <slot name="selectButton">\n <k-icon name="folder-create"></k-icon> Select Directory\n </slot>\n </button>\n <button\n id="openToggle"\n class="no-btn"\n >\n <k-icon name="folder" id="folder-closed"></k-icon>\n <k-icon name="folder-open" id="folder-opened"></k-icon>\n <k-icon name="folder-clear" id="folder-clear"></k-icon>\n ${super.shadowTemplate}\n </button>\n <div id="tree">\n <slot name="content"></slot>\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host([has-handle]) #selectDirectory,\n :host([opened]) #folder-closed,\n :host(:not([opened])) #folder-opened,\n :host(:not([has-handle])) #folder-closed,\n :host(:not([has-handle])) #folder-opened,\n :host(:not([has-handle])) #folder-clear,\n :host(:not([root])) #folder-clear,\n :host([root]) #folder-opened {\n display: none;\n }\n #openToggle {\n display: block;\n width: 100%;\n flex: 1 1 auto;\n }\n #tree {\n padding-left: var(--spacer);\n }\n #wrapper {\n display: flex;\n }\n #clearSelectedDirectory {\n flex: none;\n }\n :host([selected]) #openToggle {\n background-color: var(--c_primary);\n color: var(--tc_on_primary);\n border-radius: var(--raidus);\n }\n `}static observedAttributes=[...LazyComponent.observedAttributes,"opened"];static watchInterval=1e3}window.customElements.define("k-directory-viewer",DirectoryViewer);const selectFileClickHandler=Symbol();export class File extends Component{constructor(e=!1){super(),this[handle]=e,this[selectFileClickHandler]=()=>this.select(),this.slot="content",this.registerAttribute("selected",!1)}async render(e){if(await super.render(e)){if(this[handle]){this.innerHTML=this[handle].name;const e=this[handle].name.split(".").pop(),t=this.shadowRoot.getElementById("extIcon");["png","gif","jpeg","jpg","tif","webp"].includes(e)?t.name="image":["txt","rtf","js","css","html"].includes(e)?t.name="file-text":t.name="file",onEvent(this.shadowRoot.getElementById("selectFile"),"click",this[selectFileClickHandler])}return!0}return!1}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("selectFile"),"click",this[selectFileClickHandler])}select(){const e=this.closest("k-directory-viewer[root]").querySelector("k-directory-viewer[selected], k-directory-viewer-file[selected]");e!==this&&(e&&(e.selected=!1),this.selected=!0,this.dispatchEvent(new CustomEvent("fileselected",{detail:{fileHandle:this[handle],fileComponent:this},bubbles:!0,composed:!0})))}get shadowTemplate(){return`\n <button\n id="selectFile"\n class="no-btn"\n >\n <k-icon\n id="extIcon"\n name=""\n ></k-icon>\n ${super.shadowTemplate}\n </button>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n width: 100%;\n }\n :host([selected]) {\n background-color: var(--c_primary);\n color: var(--tc_on_primary);\n border-radius: var(--raidus);\n }\n #selectFile {\n width: 100%;\n }\n `}}window.customElements.define("k-directory-viewer-file",File);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";import{onEvent,dispatchEvent}from"../utils/element.js";const storageWatcher=Symbol("storageWatcher"),clickHandler=Symbol("clickHandler");export default class ThemeSwitcher extends Component{constructor(){super(),this[storageWatcher]=()=>{this.currentTheme=ThemeSwitcher.getCurrentTheme()},this[clickHandler]=()=>{ThemeSwitcher.setTheme("light"===ThemeSwitcher.getCurrentTheme()?"dark":"light")},this.registerAttribute("currentTheme",ThemeSwitcher.getCurrentTheme())}async render(e){return!!await super.render(e)&&(onEvent(window,"storage",this[storageWatcher]),onEvent(this.shadowRoot.getElementById("toggle"),"click",this[clickHandler]),!0)}get shadowTemplate(){return'\n <button\n id="toggle"\n class="no-btn"\n >\n <k-icon\n id="lightMode"\n name="light-mode"\n ></k-icon>\n <k-icon\n id="darkMode"\n name="dark-mode"\n ></k-icon>\n </button>\n '}get shadowStyles(){return'\n :host {\n --padding: var(--spacer);\n\n display: flex;\n }\n #toggle {\n padding: var(--padding);\n }\n :host([current-theme="dark"]) #darkMode,\n :host([current-theme="light"]) #lightMode {\n display: none;\n }\n '}static setTheme(e){localStorage.setItem("theme",e),document.documentElement.setAttribute("theme",e),dispatchEvent(window,"storage",{theme:e})}static getCurrentTheme(){let e=document.documentElement.getAttribute("theme");return e||(e=localStorage.getItem("theme")),e}}const colorSchemeQuery=window.matchMedia("(prefers-color-scheme: dark)"),colorSchemeChangeHandler=e=>document.documentElement.setAttribute("auto-theme",e.matches?"dark":"light");colorSchemeQuery.addEventListener("change",colorSchemeChangeHandler),colorSchemeChangeHandler(colorSchemeQuery),ThemeSwitcher.setTheme(ThemeSwitcher.getCurrentTheme()),window.customElements.define("k-theme-switcher",ThemeSwitcher);
|
|
1
|
+
import Component from"./Component.js";import{onEvent,dispatchEvent}from"../utils/element.js";import"./Icon.js";const storageWatcher=Symbol("storageWatcher"),clickHandler=Symbol("clickHandler");export default class ThemeSwitcher extends Component{constructor(){super(),this[storageWatcher]=()=>{this.currentTheme=ThemeSwitcher.getCurrentTheme()},this[clickHandler]=()=>{ThemeSwitcher.setTheme("light"===ThemeSwitcher.getCurrentTheme()?"dark":"light")},this.registerAttribute("currentTheme",ThemeSwitcher.getCurrentTheme())}async render(e){return!!await super.render(e)&&(onEvent(window,"storage",this[storageWatcher]),onEvent(this.shadowRoot.getElementById("toggle"),"click",this[clickHandler]),!0)}get shadowTemplate(){return'\n <button\n id="toggle"\n class="no-btn"\n >\n <k-icon\n id="lightMode"\n name="light-mode"\n ></k-icon>\n <k-icon\n id="darkMode"\n name="dark-mode"\n ></k-icon>\n </button>\n '}get shadowStyles(){return'\n :host {\n --padding: var(--spacer);\n\n display: flex;\n }\n #toggle {\n padding: var(--padding);\n }\n :host([current-theme="dark"]) #darkMode,\n :host([current-theme="light"]) #lightMode {\n display: none;\n }\n '}static setTheme(e){localStorage.setItem("theme",e),document.documentElement.setAttribute("theme",e),dispatchEvent(window,"storage",{theme:e})}static getCurrentTheme(){let e=document.documentElement.getAttribute("theme");return e||(e=localStorage.getItem("theme")),e}}const colorSchemeQuery=window.matchMedia("(prefers-color-scheme: dark)"),colorSchemeChangeHandler=e=>document.documentElement.setAttribute("auto-theme",e.matches?"dark":"light");colorSchemeQuery.addEventListener("change",colorSchemeChangeHandler),colorSchemeChangeHandler(colorSchemeQuery),ThemeSwitcher.setTheme(ThemeSwitcher.getCurrentTheme()),window.customElements.define("k-theme-switcher",ThemeSwitcher);
|
|
@@ -34,7 +34,12 @@
|
|
|
34
34
|
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-directory-viewer</span>></span><span class="hljs-tag"></<span class="hljs-name">k-directory-viewer</span>></span></code></pre>
|
|
35
35
|
</div>
|
|
36
36
|
<div class="col d-span-6 t-span-6 m-span-12 px">
|
|
37
|
-
<k-directory-viewer></k-directory-viewer>
|
|
37
|
+
<k-directory-viewer id="dv"></k-directory-viewer>
|
|
38
|
+
<script type="module">
|
|
39
|
+
await window.customElements.whenDefined('k-directory-viewer');
|
|
40
|
+
document.getElementById('dv').addFilter(({kind})=>kind!='file');
|
|
41
|
+
document.getElementById('dv').addFilter(({name})=>!name.startsWith('.')&&!name.startsWith('_'));
|
|
42
|
+
</script>
|
|
38
43
|
</div>
|
|
39
44
|
</div>
|
|
40
45
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import LazyComponent from"./LazyComponent.js";import Component from"./Component.js";import"./Icon.js";import{onEvent,offEvent}from"../utils/element.js";import watchDirectoryHandle from"../utils/watchDirectoryHandle.js";const handle=Symbol(),selectDirectoryClickHandler=Symbol(),openToggleClickHandler=Symbol(),fileSelectedHandler=Symbol(),watchId=Symbol(),changeCallback=Symbol();export default class DirectoryViewer extends LazyComponent{constructor(e=!1){super(),this[handle]=e,this[selectDirectoryClickHandler]=()=>this.selectDirectory(),this[openToggleClickHandler]=()=>{this.root?this.clearDirectoryHandle():this.toggleOpen()},this[changeCallback]=()=>{this.updateContents()},this.slot="content",this.registerAttributes({root:!e,hasHandle:!!e,opened:!e
|
|
1
|
+
import LazyComponent from"./LazyComponent.js";import Component from"./Component.js";import"./Icon.js";import{onEvent,offEvent}from"../utils/element.js";import watchDirectoryHandle from"../utils/watchDirectoryHandle.js";const handle=Symbol(),selectDirectoryClickHandler=Symbol(),openToggleClickHandler=Symbol(),fileSelectedHandler=Symbol(),watchId=Symbol(),changeCallback=Symbol(),filters=Symbol();export default class DirectoryViewer extends LazyComponent{constructor(e=!1){super(),this[handle]=e,this[watchId]=!1,this[filters]=[],this[selectDirectoryClickHandler]=()=>this.selectDirectory(),this[openToggleClickHandler]=()=>{this.root?this.clearDirectoryHandle():(this.toggleOpen(),this.select())},this[changeCallback]=()=>{this.updateContents()},this.slot="content",this.registerAttributes({root:!e,hasHandle:!!e,opened:!e,selected:!1})}async render(e){return!!await super.render(e)&&(onEvent(this.shadowRoot,"fileselected",this[fileSelectedHandler]),onEvent(this.shadowRoot.getElementById("selectDirectory"),"click",this[selectDirectoryClickHandler]),onEvent(this.shadowRoot.getElementById("openToggle"),"click",this[openToggleClickHandler]),this.renderDirectory(),!0)}async renderDirectory(){this[handle]&&this.rendered&&(this.innerHTML=this[handle].name,this.renderContents())}async renderContents(){if(this.querySelectorAll('[slot="content"]').forEach((e=>e.remove())),this.rendered&&this[handle]&&(this.opened||this.root)){for await(const e of this[handle].values())"directory"===e.kind&&this.filters.every((t=>t(e)))&&this.appendChild(new DirectoryViewer(e,!1));for await(const e of this[handle].values())"file"===e.kind&&this.filters.every((t=>t(e)))&&this.appendChild(new File(e));this[watchId]||(this[watchId]=watchDirectoryHandle(this[handle],this[changeCallback]))}else this[watchId]&&(clearInterval(this[watchId]),this[watchId]=!1)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot,"fileselected",this[fileSelectedHandler]),offEvent(this.shadowRoot.getElementById("selectDirectory"),"click",this[selectDirectoryClickHandler]),offEvent(this.shadowRoot.getElementById("openToggle"),"click",this[openToggleClickHandler])}attributeChangedCallback(e,t,n){"opened"===e&&t!==n&&(!n&&this.root?this.opened=!0:this.renderContents())}get rootDir(){return this.root?this:this.closest('k-directory-viewer[root="true"]')}get filters(){return this.rootDir[filters]}async selectDirectory(){window.showDirectoryPicker&&(this[handle]=await window.showDirectoryPicker(),this[handle]&&(this.hasHandle=!0,this.renderDirectory()))}open(){this.opened=!0}close(){this.root||(this.opened=!1)}toggleOpen(){this.root||(this.opened=!this.opened)}clearDirectoryHandle(){this[handle]=!1,this.hasHandle=!1,this.innerHTML=""}async updateContents(){if(this.opened||this.root){const e=new Set([...this.querySelectorAll("k-directory-viewer")]);for await(const t of this[handle].values())if("directory"===t.kind){const n=[...e].find((e=>t.isSameEntry(e[handle])&&t.name===e[handle].name));n?(this.appendChild(n),e.delete(n)):this.appendChild(new DirectoryViewer(t,!1))}e.forEach((e=>e.remove()));const t=new Set([...this.querySelectorAll("k-directory-viewer-file")]);for await(const e of this[handle].values())if("file"===e.kind){const n=[...t].find((t=>e.isSameEntry(t[handle])&&e.name===t[handle].name));n?(this.appendChild(n),t.delete(n)):this.appendChild(new File(e))}t.forEach((e=>e.remove())),this[watchId]||(this[watchId]=watchDirectoryHandle(this[handle],this[changeCallback]))}else this[watchId]&&(clearInterval(this[watchId]),this[watchId]=!1)}select(){const e=this.closest("k-directory-viewer[root]").querySelector("k-directory-viewer[selected], k-directory-viewer-file[selected]");e!==this&&(e&&(e.selected=!1),this.selected=!0,this.dispatchEvent(new CustomEvent("dirselected",{detail:{dirHandle:this[handle],dirComponent:this},bubbles:!0,composed:!0})))}addFilter(e){this[filters].push(e),this.renderContents()}get shadowTemplate(){return`\n <button\n id="selectDirectory"\n >\n <slot name="selectButton">\n <k-icon name="folder-create"></k-icon> Select Directory\n </slot>\n </button>\n <button\n id="openToggle"\n class="no-btn"\n >\n <k-icon name="folder" id="folder-closed"></k-icon>\n <k-icon name="folder-open" id="folder-opened"></k-icon>\n <k-icon name="folder-clear" id="folder-clear"></k-icon>\n ${super.shadowTemplate}\n </button>\n <div id="tree">\n <slot name="content"></slot>\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host([has-handle]) #selectDirectory,\n :host([opened]) #folder-closed,\n :host(:not([opened])) #folder-opened,\n :host(:not([has-handle])) #folder-closed,\n :host(:not([has-handle])) #folder-opened,\n :host(:not([has-handle])) #folder-clear,\n :host(:not([root])) #folder-clear,\n :host([root]) #folder-opened {\n display: none;\n }\n #openToggle {\n display: block;\n width: 100%;\n flex: 1 1 auto;\n }\n #tree {\n padding-left: var(--spacer);\n }\n #wrapper {\n display: flex;\n }\n #clearSelectedDirectory {\n flex: none;\n }\n :host([selected]) #openToggle {\n background-color: var(--c_primary);\n color: var(--tc_on_primary);\n border-radius: var(--raidus);\n }\n `}static observedAttributes=[...LazyComponent.observedAttributes,"opened"];static watchInterval=1e3}window.customElements.define("k-directory-viewer",DirectoryViewer);const selectFileClickHandler=Symbol();export class File extends Component{constructor(e=!1){super(),this[handle]=e,this[selectFileClickHandler]=()=>this.select(),this.slot="content",this.registerAttribute("selected",!1)}async render(e){if(await super.render(e)){if(this[handle]){this.innerHTML=this[handle].name;const e=this[handle].name.split(".").pop(),t=this.shadowRoot.getElementById("extIcon");["png","gif","jpeg","jpg","tif","webp"].includes(e)?t.name="image":["txt","rtf","js","css","html"].includes(e)?t.name="file-text":t.name="file",onEvent(this.shadowRoot.getElementById("selectFile"),"click",this[selectFileClickHandler])}return!0}return!1}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("selectFile"),"click",this[selectFileClickHandler])}select(){const e=this.closest("k-directory-viewer[root]").querySelector("k-directory-viewer[selected], k-directory-viewer-file[selected]");e!==this&&(e&&(e.selected=!1),this.selected=!0,this.dispatchEvent(new CustomEvent("fileselected",{detail:{fileHandle:this[handle],fileComponent:this},bubbles:!0,composed:!0})))}get shadowTemplate(){return`\n <button\n id="selectFile"\n class="no-btn"\n >\n <k-icon\n id="extIcon"\n name=""\n ></k-icon>\n ${super.shadowTemplate}\n </button>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n width: 100%;\n }\n :host([selected]) {\n background-color: var(--c_primary);\n color: var(--tc_on_primary);\n border-radius: var(--raidus);\n }\n #selectFile {\n width: 100%;\n }\n `}}window.customElements.define("k-directory-viewer-file",File);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";import{onEvent,dispatchEvent}from"../utils/element.js";const storageWatcher=Symbol("storageWatcher"),clickHandler=Symbol("clickHandler");export default class ThemeSwitcher extends Component{constructor(){super(),this[storageWatcher]=()=>{this.currentTheme=ThemeSwitcher.getCurrentTheme()},this[clickHandler]=()=>{ThemeSwitcher.setTheme("light"===ThemeSwitcher.getCurrentTheme()?"dark":"light")},this.registerAttribute("currentTheme",ThemeSwitcher.getCurrentTheme())}async render(e){return!!await super.render(e)&&(onEvent(window,"storage",this[storageWatcher]),onEvent(this.shadowRoot.getElementById("toggle"),"click",this[clickHandler]),!0)}get shadowTemplate(){return'\n <button\n id="toggle"\n class="no-btn"\n >\n <k-icon\n id="lightMode"\n name="light-mode"\n ></k-icon>\n <k-icon\n id="darkMode"\n name="dark-mode"\n ></k-icon>\n </button>\n '}get shadowStyles(){return'\n :host {\n --padding: var(--spacer);\n\n display: flex;\n }\n #toggle {\n padding: var(--padding);\n }\n :host([current-theme="dark"]) #darkMode,\n :host([current-theme="light"]) #lightMode {\n display: none;\n }\n '}static setTheme(e){localStorage.setItem("theme",e),document.documentElement.setAttribute("theme",e),dispatchEvent(window,"storage",{theme:e})}static getCurrentTheme(){let e=document.documentElement.getAttribute("theme");return e||(e=localStorage.getItem("theme")),e}}const colorSchemeQuery=window.matchMedia("(prefers-color-scheme: dark)"),colorSchemeChangeHandler=e=>document.documentElement.setAttribute("auto-theme",e.matches?"dark":"light");colorSchemeQuery.addEventListener("change",colorSchemeChangeHandler),colorSchemeChangeHandler(colorSchemeQuery),ThemeSwitcher.setTheme(ThemeSwitcher.getCurrentTheme()),window.customElements.define("k-theme-switcher",ThemeSwitcher);
|
|
1
|
+
import Component from"./Component.js";import{onEvent,dispatchEvent}from"../utils/element.js";import"./Icon.js";const storageWatcher=Symbol("storageWatcher"),clickHandler=Symbol("clickHandler");export default class ThemeSwitcher extends Component{constructor(){super(),this[storageWatcher]=()=>{this.currentTheme=ThemeSwitcher.getCurrentTheme()},this[clickHandler]=()=>{ThemeSwitcher.setTheme("light"===ThemeSwitcher.getCurrentTheme()?"dark":"light")},this.registerAttribute("currentTheme",ThemeSwitcher.getCurrentTheme())}async render(e){return!!await super.render(e)&&(onEvent(window,"storage",this[storageWatcher]),onEvent(this.shadowRoot.getElementById("toggle"),"click",this[clickHandler]),!0)}get shadowTemplate(){return'\n <button\n id="toggle"\n class="no-btn"\n >\n <k-icon\n id="lightMode"\n name="light-mode"\n ></k-icon>\n <k-icon\n id="darkMode"\n name="dark-mode"\n ></k-icon>\n </button>\n '}get shadowStyles(){return'\n :host {\n --padding: var(--spacer);\n\n display: flex;\n }\n #toggle {\n padding: var(--padding);\n }\n :host([current-theme="dark"]) #darkMode,\n :host([current-theme="light"]) #lightMode {\n display: none;\n }\n '}static setTheme(e){localStorage.setItem("theme",e),document.documentElement.setAttribute("theme",e),dispatchEvent(window,"storage",{theme:e})}static getCurrentTheme(){let e=document.documentElement.getAttribute("theme");return e||(e=localStorage.getItem("theme")),e}}const colorSchemeQuery=window.matchMedia("(prefers-color-scheme: dark)"),colorSchemeChangeHandler=e=>document.documentElement.setAttribute("auto-theme",e.matches?"dark":"light");colorSchemeQuery.addEventListener("change",colorSchemeChangeHandler),colorSchemeChangeHandler(colorSchemeQuery),ThemeSwitcher.setTheme(ThemeSwitcher.getCurrentTheme()),window.customElements.define("k-theme-switcher",ThemeSwitcher);
|
package/icons/cards.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M240-500v-220h220v220H240Zm0 260v-220h220v220H240Zm260-260v-220h220v220H500Zm0 260v-220h220v220H500ZM320-580h60v-60h-60v60Zm260 0h60v-60h-60v60ZM320-320h60v-60h-60v60Zm260 0h60v-60h-60v60ZM380-580Zm200 0Zm0 200Zm-200 0ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-160v-80h120l180-240-180-240H160v200H80v-200q0-33 23.5-56.5T160-800h440q19 0 36 8.5t28 23.5l216 288-216 288q-11 15-28 23.5t-36 8.5H480Zm-10-320ZM200-120v-120H80v-80h120v-120h80v120h120v80H280v120h-80Z"/></svg>
|
package/icons/label.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h440q19 0 36 8.5t28 23.5l216 288-216 288q-11 15-28 23.5t-36 8.5H160Zm0-80h440l180-240-180-240H160v480Zm220-240Z"/></svg>
|
package/icons/tag.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="m240-160 40-160H120l20-80h160l40-160H180l20-80h160l40-160h80l-40 160h160l40-160h80l-40 160h160l-20 80H660l-40 160h160l-20 80H600l-40 160h-80l40-160H360l-40 160h-80Zm140-240h160l40-160H420l-40 160Z"/></svg>
|
package/package.json
CHANGED
|
@@ -12,19 +12,23 @@ const handle = Symbol(),
|
|
|
12
12
|
openToggleClickHandler = Symbol(),
|
|
13
13
|
fileSelectedHandler = Symbol(),
|
|
14
14
|
watchId = Symbol(),
|
|
15
|
-
changeCallback = Symbol()
|
|
15
|
+
changeCallback = Symbol(),
|
|
16
|
+
filters = Symbol();
|
|
16
17
|
export default class DirectoryViewer extends LazyComponent {
|
|
17
18
|
constructor(_handle = false){
|
|
18
19
|
super();
|
|
19
20
|
|
|
20
21
|
/* Private Members */
|
|
21
22
|
this[handle] = _handle;
|
|
23
|
+
this[watchId] = false;
|
|
24
|
+
this[filters] = [];
|
|
22
25
|
|
|
23
26
|
/* Private Methods */
|
|
24
27
|
this[selectDirectoryClickHandler] = () => this.selectDirectory();
|
|
25
28
|
this[openToggleClickHandler] = () => {
|
|
26
29
|
if(!this.root){
|
|
27
30
|
this.toggleOpen();
|
|
31
|
+
this.select();
|
|
28
32
|
} else {
|
|
29
33
|
this.clearDirectoryHandle();
|
|
30
34
|
}
|
|
@@ -38,9 +42,9 @@ export default class DirectoryViewer extends LazyComponent {
|
|
|
38
42
|
this.registerAttributes({
|
|
39
43
|
root: !_handle,
|
|
40
44
|
hasHandle: !!_handle,
|
|
41
|
-
opened: !_handle
|
|
45
|
+
opened: !_handle,
|
|
46
|
+
selected: false
|
|
42
47
|
});
|
|
43
|
-
this[watchId] = false;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/* Lifecycle Callbacks */
|
|
@@ -61,15 +65,23 @@ export default class DirectoryViewer extends LazyComponent {
|
|
|
61
65
|
}
|
|
62
66
|
async renderContents(){
|
|
63
67
|
this.querySelectorAll('[slot="content"]').forEach(e=>e.remove());
|
|
64
|
-
if(
|
|
68
|
+
if(
|
|
69
|
+
this.rendered &&
|
|
70
|
+
this[handle] &&
|
|
71
|
+
(this.opened || this.root)
|
|
72
|
+
){
|
|
65
73
|
for await(const entry of this[handle].values()){
|
|
66
74
|
if(entry.kind === 'directory'){
|
|
67
|
-
this.
|
|
75
|
+
if(this.filters.every(filter=>filter(entry))){
|
|
76
|
+
this.appendChild(new DirectoryViewer(entry, false));
|
|
77
|
+
}
|
|
68
78
|
}
|
|
69
79
|
}
|
|
70
80
|
for await(const entry of this[handle].values()){
|
|
71
81
|
if(entry.kind === 'file'){
|
|
72
|
-
this.
|
|
82
|
+
if(this.filters.every(filter=>filter(entry))){
|
|
83
|
+
this.appendChild(new File(entry));
|
|
84
|
+
}
|
|
73
85
|
}
|
|
74
86
|
}
|
|
75
87
|
if(!this[watchId]) this[watchId] = watchDirectoryHandle(this[handle], this[changeCallback]);
|
|
@@ -96,6 +108,15 @@ export default class DirectoryViewer extends LazyComponent {
|
|
|
96
108
|
}
|
|
97
109
|
}
|
|
98
110
|
|
|
111
|
+
/* Protected Members */
|
|
112
|
+
get rootDir(){
|
|
113
|
+
if(this.root) return this;
|
|
114
|
+
else return this.closest('k-directory-viewer[root="true"]')
|
|
115
|
+
}
|
|
116
|
+
get filters(){
|
|
117
|
+
return this.rootDir[filters];
|
|
118
|
+
}
|
|
119
|
+
|
|
99
120
|
|
|
100
121
|
/* Public Methods */
|
|
101
122
|
async selectDirectory(){
|
|
@@ -156,6 +177,24 @@ export default class DirectoryViewer extends LazyComponent {
|
|
|
156
177
|
}
|
|
157
178
|
}
|
|
158
179
|
}
|
|
180
|
+
select(){
|
|
181
|
+
const $currentSelection = this.closest('k-directory-viewer[root]').querySelector('k-directory-viewer[selected], k-directory-viewer-file[selected]');
|
|
182
|
+
if($currentSelection === this) return;
|
|
183
|
+
if($currentSelection) $currentSelection.selected = false;
|
|
184
|
+
this.selected = true;
|
|
185
|
+
this.dispatchEvent(new CustomEvent('dirselected', {
|
|
186
|
+
detail: {
|
|
187
|
+
dirHandle: this[handle],
|
|
188
|
+
dirComponent: this
|
|
189
|
+
},
|
|
190
|
+
bubbles: true,
|
|
191
|
+
composed: true
|
|
192
|
+
}));
|
|
193
|
+
}
|
|
194
|
+
addFilter(filter){
|
|
195
|
+
this[filters].push(filter);
|
|
196
|
+
this.renderContents();
|
|
197
|
+
}
|
|
159
198
|
|
|
160
199
|
/* Shadow DOM */
|
|
161
200
|
get shadowTemplate(){
|
|
@@ -208,6 +247,11 @@ export default class DirectoryViewer extends LazyComponent {
|
|
|
208
247
|
#clearSelectedDirectory {
|
|
209
248
|
flex: none;
|
|
210
249
|
}
|
|
250
|
+
:host([selected]) #openToggle {
|
|
251
|
+
background-color: var(--c_primary);
|
|
252
|
+
color: var(--tc_on_primary);
|
|
253
|
+
border-radius: var(--raidus);
|
|
254
|
+
}
|
|
211
255
|
`;
|
|
212
256
|
}
|
|
213
257
|
|
|
@@ -263,7 +307,7 @@ export class File extends Component {
|
|
|
263
307
|
|
|
264
308
|
/* Public Methods */
|
|
265
309
|
select(){
|
|
266
|
-
const $currentSelection = this.closest('k-directory-viewer[root]').querySelector('k-directory-viewer-file[selected]');
|
|
310
|
+
const $currentSelection = this.closest('k-directory-viewer[root]').querySelector('k-directory-viewer[selected], k-directory-viewer-file[selected]');
|
|
267
311
|
if($currentSelection === this) return;
|
|
268
312
|
if($currentSelection) $currentSelection.selected = false;
|
|
269
313
|
this.selected = true;
|