kempo 2.7.3 → 2.8.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/Table.js +1 -1
- package/dist/components/ThemeSwitcher.js +1 -1
- package/docs/components/table.html +259 -151
- package/docs/icons/add.svg +1 -0
- package/docs/icons/arrow-back.svg +1 -0
- package/docs/icons/arrow-forward.svg +1 -0
- package/docs/icons/cards.svg +1 -0
- package/docs/icons/chevron-left.svg +1 -0
- package/docs/icons/chevron-right.svg +1 -0
- package/docs/icons/drawing2.svg +124 -0
- package/docs/icons/file-text.svg +1 -0
- package/docs/icons/file.svg +1 -0
- package/docs/icons/folder-clear.svg +1 -0
- package/docs/icons/folder-create.svg +1 -0
- package/docs/icons/folder-open.svg +1 -0
- package/docs/icons/folder.svg +1 -0
- package/docs/icons/image.svg +1 -0
- package/docs/icons/label-add.svg +1 -0
- package/docs/icons/label.svg +1 -0
- package/docs/icons/mode-auto.svg +1 -0
- package/docs/icons/refresh.svg +1 -0
- package/docs/icons/tag.svg +1 -0
- package/docs/icons/tools.svg +1 -0
- package/docs/kempo/components/Table.js +1 -1
- package/docs/kempo/components/ThemeSwitcher.js +1 -1
- package/icons/add.svg +1 -0
- package/icons/refresh.svg +1 -0
- package/package.json +1 -1
- package/scripts/build.js +14 -0
- package/src/components/Table.js +383 -34
- package/src/components/ThemeSwitcher.js +1 -1
- package/README.md +0 -2
- /package/docs/icons/{dark-mode.svg → mode-dark.svg} +0 -0
- /package/docs/icons/{light-mode.svg → mode-light.svg} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M200-200h560v-367L567-760H200v560Zm0 80q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h400l240 240v400q0 33-23.5 56.5T760-120H200Zm80-160h400v-80H280v80Zm0-160h400v-80H280v80Zm0-160h280v-80H280v80Zm-80 400v-560 560Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-280q66 0 113-47t47-113q0-66-47-113t-113-47q-66 0-113 47t-47 113q0 66 47 113t113 47Zm-46-248q11-5 22-8.5t24-3.5q42 0 71 29t29 71q0 13-3.5 24t-8.5 22L434-528Zm46 188q-42 0-71-29t-29-71q0-13 3.5-24t8.5-22l134 134q-11 5-22 8.5t-24 3.5ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80h640v-400H447l-80-80H160v480Zm0 0v-480 480Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M560-320h80v-80h80v-80h-80v-80h-80v80h-80v80h80v80ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80h640v-400H447l-80-80H160v480Zm0 0v-480 480Z"/></svg>
|
|
@@ -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-800h240l80 80h320q33 0 56.5 23.5T880-640H447l-80-80H160v480l96-320h684L837-217q-8 26-29.5 41.5T760-160H160Zm84-80h516l72-240H316l-72 240Zm0 0 72-240-72 240Zm-84-400v-80 80Z"/></svg>
|
|
@@ -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-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80h640v-400H447l-80-80H160v480Zm0 0v-480 480Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M200-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-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"/></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>
|
|
@@ -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>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M 440 -920 L 440 -760 L 520 -760 L 520 -920 L 440 -920 z M 818.67969 -885.5332 L 583.66602 -651.38281 C 553.04363 -670.31258 518.55019 -680 480 -680 C 424.66678 -680 377.49992 -660.49992 338.5 -621.5 C 299.50008 -582.50008 280 -535.33322 280 -480 C 280 -441.71314 289.5643 -407.43184 308.23633 -376.96484 L 97.058594 -166.5625 L 168.59375 -92.332031 L 263.80078 -187.18945 C 267.09506 -183.63709 270.46257 -180.11555 273.9375 -176.64062 C 343.93736 -106.64077 428.9377 -71.640625 528.9375 -71.640625 C 628.9373 -71.640625 713.93764 -106.64077 783.9375 -176.64062 C 853.93736 -246.64049 888.9375 -331.64082 888.9375 -431.64062 C 888.9375 -440.97395 888.60417 -450.14064 887.9375 -459.14062 C 887.27083 -468.14062 886.27083 -476.97398 884.9375 -485.64062 C 865.60421 -458.30735 840.60411 -436.47393 809.9375 -420.14062 C 779.27089 -403.80733 745.60409 -395.64062 708.9375 -395.64062 C 648.93762 -395.64062 597.93742 -416.64072 555.9375 -458.64062 C 552.62172 -461.95641 549.47084 -465.3433 546.42188 -468.77344 L 890.21484 -811.30273 L 818.67969 -885.5332 z M 212 -806 L 155 -747 L 256 -650 L 308 -706 L 212 -806 z M 480 -600 C 495.83397 -600 510.50253 -597.28065 524.08008 -592.01562 L 367.83594 -436.34375 C 362.67843 -449.80488 360 -464.32853 360 -480 C 360 -513.33327 371.66671 -541.66671 395 -565 C 418.33329 -588.33329 446.66673 -600 480 -600 z M 40 -520 L 40 -440 L 200 -440 L 200 -520 L 40 -520 z M 489.73047 -412.28906 C 492.87534 -408.86757 496.09809 -405.48004 499.4375 -402.14062 C 557.10405 -344.47408 626.93766 -315.64062 708.9375 -315.64062 C 722.27081 -315.64062 735.60419 -316.64064 748.9375 -318.64062 C 762.27081 -320.64062 775.60419 -323.3073 788.9375 -326.64062 C 767.60421 -274.64074 733.60407 -232.4739 686.9375 -200.14062 C 640.27093 -167.80736 587.60405 -151.64062 528.9375 -151.64062 C 451.60432 -151.64062 385.60406 -178.97407 330.9375 -233.64062 C 327.48999 -237.08813 324.17746 -240.59082 320.95312 -244.13086 L 489.73047 -412.28906 z " /></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"/></svg>
|
|
@@ -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>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M756-120 537-339l84-84 219 219-84 84Zm-552 0-84-84 276-276-68-68-28 28-51-51v82l-28 28-121-121 28-28h82l-50-50 142-142q20-20 43-29t47-9q24 0 47 9t43 29l-92 92 50 50-28 28 68 68 90-90q-4-11-6.5-23t-2.5-24q0-59 40.5-99.5T701-841q15 0 28.5 3t27.5 9l-99 99 72 72 99-99q7 14 9.5 27.5T841-701q0 59-40.5 99.5T701-561q-12 0-24-2t-23-7L204-120Z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import Component from"./Component.js";import Icon from"./Icon.js";import{toTitleCase}from"../utils/string.js";export default class Table extends Component{
|
|
1
|
+
import Component from"./Component.js";import Icon from"./Icon.js";import{toTitleCase}from"../utils/string.js";import{onEvent,dispatchEvent}from"../utils/element.js";export default class Table extends Component{static controls={prevPage:{render:e=>{const t=document.createElement("button");return t.classList.add("pq"),t.appendChild(new Icon("chevron-left")),onEvent(t,"click",(()=>e.prevPage())),onEvent(e,"pageChange",(()=>{t.disabled=1===e.getCurrentPage()})),t}},nextPage:{render:e=>{const t=document.createElement("button");return t.classList.add("pq"),t.appendChild(new Icon("chevron-right")),onEvent(t,"click",(()=>e.nextPage())),onEvent(e,"pageChange",(()=>{t.disabled=e.getCurrentPage()===e.getTotalPages()})),t}},pageSelect:{render:e=>new PageSelect(e)},pageSize:{render:e=>new PageSize(e)},spacer:{html:'<div class="flex"></div>'}};constructor({records:e=[],fields:t=[],controls:n={before:[],after:[],top:[],bottom:[]},pageSize:s=100,pageSizeOptions:r=[10,25,50,100,500],currentPage:a=1}={}){super(),this.registerProps({fields:t,records:e,controls:n,pageSize:s,pageSizeOptions:r,currentPage:a})}async render(e){return!!await super.render(e)&&(this.setData({records:this.records,fields:this.fields,controls:this.controls,pageSize:this.pageSize,pageSizeOptions:this.pageSizeOptions,currentPage:this.currentPage}),!0)}renderFields(){if(!this.rendered)return;const e=this.controls?.before?.length?"<th></th>":"",t=this.controls?.after?.length?"<th></th>":"";this.shadowRoot.getElementById("fields").innerHTML=`${e}${this.fields.map((({label:e})=>`<th>${e}</th>`)).join("")}${t}`}renderRecords(){if(!this.rendered)return;const e=this.shadowRoot.getElementById("records");e.innerHTML="";const t=(this.currentPage-1)*this.pageSize,n=t+this.pageSize;this.records.slice(t,n).forEach(((s,r)=>{const a=document.createElement("tr");this.controls?.before?.length&&a.appendChild(this.renderRowControls(this.controls.before,s,t+r)),this.fields.forEach((({name:e,formatter:r,calculator:o})=>{const i=document.createElement("td");if(null===s)i.innerHTML="Loading...",dispatchEvent(this,"fetchRecords",{start:t,end:n});else{let t;o?t=o(s,this):(t=s[e]||"",Array.isArray(t)?t=r?t.map(r).join(", "):t.join(", "):r&&(t=r(t))),i.innerHTML=t}a.appendChild(i)})),this.controls?.after?.length&&a.appendChild(this.renderRowControls(this.controls.after,s,t+r)),e.appendChild(a)}))}renderRowControls(e=[],t,n){if(!this.rendered)return;const s=document.createElement("td");return e.forEach((({html:e,icon:r,action:a,render:o})=>{if(e)s.appendChild(document.createRange().createContextualFragment(e));else if(o&&"function"==typeof o){const e=o(this,t,n);e instanceof HTMLElement?s.appendChild(e):"string"==typeof e&&s.appendChild(document.createRange().createContextualFragment(e))}else if(r){const e=document.createElement("button");e.classList.add("pq"),e.appendChild(new Icon(r)),a&&onEvent(e,"click",(()=>a(this,t,n))),s.appendChild(e)}})),s}renderControls(e=[],t){if(!this.rendered)return;const n=this.shadowRoot.getElementById(t);n.innerHTML="",e.forEach((({html:e,icon:t,action:s,render:r})=>{if(e)n.appendChild(document.createRange().createContextualFragment(e));else if(r&&"function"==typeof r){const e=r(this);e instanceof HTMLElement?n.appendChild(e):"string"==typeof e&&n.appendChild(document.createRange().createContextualFragment(e))}else if(t){const e=document.createElement("button");e.classList.add("pq"),e.appendChild(new Icon(t)),s&&onEvent(e,"click",(()=>s(this))),n.appendChild(e)}}))}getCurrentPage(){return this.currentPage}getTotalPages(){return Math.ceil(this.records.length/this.pageSize)}setPage(e){e<1||e>this.getTotalPages()||(this.currentPage=e,this.renderRecords(),dispatchEvent(this,"pageChange"))}nextPage(){this.currentPage<this.getTotalPages()&&this.setPage(this.currentPage+1)}prevPage(){this.currentPage>1&&this.setPage(this.currentPage-1)}setPageSize(e){this.pageSize=e,this.currentPage=1,this.renderRecords(),dispatchEvent(this,"pageSizeChange")}setData({records:e=!1,fields:t=!1,controls:n=!1,pageSize:s=!1,pageSizeOptions:r=!1,currentPage:a=!1}={}){let o=!1,i=!1;e&&(this.records=e,this.fields=t||Table.extractFieldsFromRecords(this.records),o=!0),s&&(this.pageSize=s,o=!0),r&&(this.pageSizeOptions=r),n&&(this.controls=n,i=!0),a&&(this.currentPage=a,o=!0),o&&(this.renderFields(),this.renderRecords()),i&&(this.renderControls(this.controls.top,"top"),this.renderControls(this.controls.bottom,"bottom"))}setRecords(e){this.records=e,this.currentPage=1,this.renderRecords(),dispatchEvent(this,"recordsSet",{records:e})}setupFetchRecords(e,t){const n=this.records.length;n<e&&(this.records.length=e,this.records.fill(null,n)),onEvent(this,"fetchRecords",(async e=>{const{start:n,end:s}=e.detail,r=await t(n,s-n);this.records.splice(n,r.length,...r),this.renderRecords()}))}addRecord(e){this.records.push(e),this.renderRecords(),dispatchEvent(this,"recordAdded",{record:e})}updateRecord(e,t){this.records[e]=t;const n=(this.currentPage-1)*this.pageSize,s=n+this.pageSize;e>=n&&e<s&&this.renderRecords()}deleteRecord(e){e>=0&&e<this.records.length&&(this.records.splice(e,1),this.renderRecords(),dispatchEvent(this,"recordDeleted",{index:e}))}get shadowTemplate(){return`\n ${super.shadowTemplate}\n <div class="responsive-table">\n <div id="top"></div>\n <table class="b0">\n <thead id="fields"></thead>\n <tbody id="records"></tbody>\n </table>\n <div id="bottom"></div>\n </div>\n `}get shadowStyles(){return`\n ${super.shadowStyles}\n :host {\n display: block;\n margin-bottom: var(--spacer);\n border: 1px solid var(--c_border);\n border-radius: var(--radius);\n }\n #top, #bottom {\n display: flex;\n }\n th {\n border-top: none;\n }\n tr:last-child td:first-child {\n border-bottom-left-radius: 0;\n }\n tr:last-child td:last-child {\n border-bottom-right-radius: 0;\n }\n tr:last-child td {\n border-bottom: none;\n }\n th:first-child, td:first-child {\n border-left: none;\n }\n th:last-child, td:last-child {\n border-right: none;\n }\n #top:not(:empty) {\n border-bottom: 1px solid var(--c_border);\n }\n #bottom:not(:empty) {\n border-top: 1px solid var(--c_border);\n }\n `}static extractFieldsFromRecords(e,t=100){const n=new Set;return e.slice(0,t).forEach((e=>{Object.keys(e).forEach((e=>n.add(e)))})),[...n].map((e=>({name:e,label:toTitleCase(e)})))}}window.customElements.define("k-table",Table);class PageSelect extends Component{constructor(e){super(),this.table=e,this.classList.add("mxq")}connectedCallback(){this.render()}async render(){return!!await super.render()&&(this.updateOptions(),!0)}updateOptions(){const e=this.shadowRoot.getElementById("pageSelect");e.innerHTML="";for(let t=1;t<=this.table.getTotalPages();t++){const n=document.createElement("option");n.value=t,n.textContent=t,e.appendChild(n)}e.value=this.table.getCurrentPage();this.shadowRoot.getElementById("totalPages").textContent=this.table.getTotalPages(),onEvent(e,"change",(()=>{this.table.setPage(parseInt(e.value))})),onEvent(this.table,"pageSizeChange",(()=>{this.updateOptions()})),onEvent(this.table,"pageChange",(()=>{e.value=this.table.getCurrentPage()}))}get shadowTemplate(){return'\n <select id="pageSelect" class="mxq"></select>\n <label> out of <span id="totalPages"></span></label>\n '}get shadowStyles(){return"\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n }\n #pageSelect, label {\n display: inline;\n }\n label {\n white-space: nowrap;\n }\n "}}window.customElements.define("k-table-page-select",PageSelect);class PageSize extends Component{constructor(e){super(),this.table=e,this.classList.add("mxq")}connectedCallback(){this.render()}async render(){if(await super.render()){const e=this.shadowRoot.getElementById("pageSizeSelect");return this.table.pageSizeOptions.forEach((t=>{const n=document.createElement("option");n.value=t,n.textContent=t,e.appendChild(n)})),e.value=this.table.pageSize,onEvent(e,"change",(()=>{this.table.setPageSize(parseInt(e.value))})),onEvent(this.table,"pageSizeChange",(()=>{e.value=this.table.pageSize})),!0}return!1}get shadowTemplate(){return'\n <label for="pageSizeSelect">Page Size: </label>\n <select id="pageSizeSelect" class="mxq"></select>\n '}get shadowStyles(){return"\n :host {\n display: inline-flex;\n width: max-content;\n align-items: baseline;\n }\n label {\n white-space: nowrap;\n }\n "}}window.customElements.define("k-table-page-size",PageSize);
|
|
@@ -1 +1 @@
|
|
|
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]=()=>{const e=ThemeSwitcher.getCurrentTheme();"auto"===e&&ThemeSwitcher.setTheme("light"),"light"===e&&ThemeSwitcher.setTheme("dark"),"dark"===e&&ThemeSwitcher.setTheme("auto")},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)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("toggle"),"click",this[clickHandler])}get shadowTemplate(){return'\n <button\n id="toggle"\n class="no-btn"\n >\n <k-icon\n id="autoMode"\n name="mode-auto"\n class="mode"\n ></k-icon>\n <k-icon\n id="lightMode"\n name="mode-light"\n class="mode"\n ></k-icon>\n <k-icon\n id="darkMode"\n name="mode-dark"\n class="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 .mode {\n display: none;\n }\n :host([current-theme="auto"]) #autoMode,\n :host([current-theme="light"]) #lightMode,\n :host([current-theme="dark"]) #darkMode {\n display: block;\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]=()=>{const e=ThemeSwitcher.getCurrentTheme();"auto"===e&&ThemeSwitcher.setTheme("light"),"light"===e&&ThemeSwitcher.setTheme("dark"),"dark"===e&&ThemeSwitcher.setTheme("auto")},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)}disconnectedCallback(){super.disconnectedCallback(),offEvent(this.shadowRoot.getElementById("toggle"),"click",this[clickHandler])}get shadowTemplate(){return'\n <button\n id="toggle"\n class="no-btn"\n >\n <k-icon\n id="autoMode"\n name="mode-auto"\n class="mode"\n ></k-icon>\n <k-icon\n id="lightMode"\n name="mode-light"\n class="mode"\n ></k-icon>\n <k-icon\n id="darkMode"\n name="mode-dark"\n class="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 .mode {\n display: none;\n }\n :host([current-theme="auto"]) #autoMode,\n :host([current-theme="light"]) #lightMode,\n :host([current-theme="dark"]) #darkMode {\n display: block;\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||"auto"}}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/add.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"/></svg>
|
package/package.json
CHANGED
package/scripts/build.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import fse from 'fs-extra';
|
|
3
3
|
import { minify } from 'terser';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
4
9
|
|
|
5
10
|
console.log('Loading utils');
|
|
6
11
|
const components = (await fs.readdir('./src/components/')).map(f=>f.substring(0,f.length-3));
|
|
@@ -118,4 +123,13 @@ console.log('Copying dist/ to docs/');
|
|
|
118
123
|
await fse.ensureDir('./docs/'); // will also ensure docs/kempo
|
|
119
124
|
await fse.copy('./dist', './docs/kempo')
|
|
120
125
|
|
|
126
|
+
const iconsSrcDir = path.join(__dirname, '../icons');
|
|
127
|
+
const iconsDestDir = path.join(__dirname, '../docs/icons');
|
|
128
|
+
|
|
129
|
+
console.log('Deleting svg icons currently in docs/icons');
|
|
130
|
+
await fse.ensureDir(iconsDestDir);
|
|
131
|
+
await fse.emptyDir(iconsDestDir);
|
|
132
|
+
console.log('Copying all files from icons to docs/icons');
|
|
133
|
+
await fse.copy(iconsSrcDir, iconsDestDir);
|
|
134
|
+
|
|
121
135
|
console.log('Build Complete');
|
package/src/components/Table.js
CHANGED
|
@@ -1,68 +1,147 @@
|
|
|
1
1
|
import Component from './Component.js';
|
|
2
|
-
import Icon from './Icon.js';
|
|
2
|
+
import Icon from './Icon.js';
|
|
3
3
|
import { toTitleCase } from '../utils/string.js';
|
|
4
|
+
import { onEvent, dispatchEvent } from '../utils/element.js';
|
|
4
5
|
|
|
5
6
|
export default class Table extends Component {
|
|
6
|
-
|
|
7
|
+
static controls = {
|
|
8
|
+
prevPage: {
|
|
9
|
+
render: (table) => {
|
|
10
|
+
const $button = document.createElement('button');
|
|
11
|
+
$button.classList.add('pq');
|
|
12
|
+
$button.appendChild(new Icon('chevron-left'));
|
|
13
|
+
onEvent($button, 'click', () => table.prevPage());
|
|
14
|
+
|
|
15
|
+
// Disable button if on the first page
|
|
16
|
+
onEvent(table, 'pageChange', () => {
|
|
17
|
+
$button.disabled = table.getCurrentPage() === 1;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return $button;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
nextPage: {
|
|
24
|
+
render: (table) => {
|
|
25
|
+
const $button = document.createElement('button');
|
|
26
|
+
$button.classList.add('pq');
|
|
27
|
+
$button.appendChild(new Icon('chevron-right'));
|
|
28
|
+
onEvent($button, 'click', () => table.nextPage());
|
|
29
|
+
|
|
30
|
+
// Disable button if on the last page
|
|
31
|
+
onEvent(table, 'pageChange', () => {
|
|
32
|
+
$button.disabled = table.getCurrentPage() === table.getTotalPages();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return $button;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
pageSelect: {
|
|
39
|
+
render: (table) => new PageSelect(table)
|
|
40
|
+
},
|
|
41
|
+
pageSize: {
|
|
42
|
+
render: (table) => new PageSize(table)
|
|
43
|
+
},
|
|
44
|
+
spacer: {
|
|
45
|
+
html: '<div class="flex"></div>'
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
constructor({
|
|
50
|
+
records = [],
|
|
51
|
+
fields = [],
|
|
52
|
+
controls = { before: [], after: [], top: [], bottom: [] },
|
|
53
|
+
pageSize = 100,
|
|
54
|
+
pageSizeOptions = [10, 25, 50, 100, 500],
|
|
55
|
+
currentPage = 1,
|
|
56
|
+
} = {}) {
|
|
7
57
|
super();
|
|
8
58
|
|
|
9
59
|
this.registerProps({
|
|
10
|
-
fields:
|
|
11
|
-
records:
|
|
12
|
-
controls:
|
|
60
|
+
fields: fields,
|
|
61
|
+
records: records,
|
|
62
|
+
controls: controls,
|
|
63
|
+
pageSize,
|
|
64
|
+
pageSizeOptions,
|
|
65
|
+
currentPage,
|
|
13
66
|
});
|
|
14
67
|
|
|
15
68
|
/* Init */
|
|
16
|
-
|
|
17
|
-
this.setData(data, fields, controls);
|
|
18
|
-
}
|
|
69
|
+
//
|
|
19
70
|
}
|
|
20
71
|
async render(force){
|
|
21
72
|
if(await super.render(force)){
|
|
22
|
-
this.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
73
|
+
this.setData({
|
|
74
|
+
records: this.records,
|
|
75
|
+
fields: this.fields,
|
|
76
|
+
controls: this.controls,
|
|
77
|
+
pageSize: this.pageSize,
|
|
78
|
+
pageSizeOptions: this.pageSizeOptions,
|
|
79
|
+
currentPage: this.currentPage
|
|
80
|
+
});
|
|
26
81
|
return true;
|
|
27
82
|
}
|
|
28
83
|
return false;
|
|
29
84
|
}
|
|
30
85
|
renderFields(){
|
|
86
|
+
if(!this.rendered) return;
|
|
31
87
|
const beforeControls = this.controls?.before?.length ? '<th></th>' : '';
|
|
32
88
|
const afterControls = this.controls?.after?.length ? '<th></th>' : '';
|
|
33
89
|
this.shadowRoot.getElementById('fields').innerHTML = `${beforeControls}${this.fields.map(({label})=>`<th>${label}</th>`).join('')}${afterControls}`;
|
|
34
90
|
}
|
|
35
91
|
renderRecords(){
|
|
92
|
+
if(!this.rendered) return;
|
|
36
93
|
const $records = this.shadowRoot.getElementById('records');
|
|
37
94
|
$records.innerHTML = '';
|
|
38
|
-
this.
|
|
95
|
+
const start = (this.currentPage - 1) * this.pageSize;
|
|
96
|
+
const end = start + this.pageSize;
|
|
97
|
+
const paginatedRecords = this.records.slice(start, end);
|
|
98
|
+
paginatedRecords.forEach((record, index) => {
|
|
39
99
|
const $tr = document.createElement('tr');
|
|
40
100
|
if(this.controls?.before?.length){
|
|
41
|
-
$tr.appendChild(this.renderRowControls(this.controls.before, record));
|
|
101
|
+
$tr.appendChild(this.renderRowControls(this.controls.before, record, start + index));
|
|
42
102
|
}
|
|
43
|
-
this.fields.forEach(({name}) => {
|
|
103
|
+
this.fields.forEach(({name, formatter, calculator}) => {
|
|
44
104
|
const $td = document.createElement('td');
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
105
|
+
if (record === null) {
|
|
106
|
+
$td.innerHTML = 'Loading...';
|
|
107
|
+
dispatchEvent(this, 'fetchRecords', { start, end });
|
|
108
|
+
} else {
|
|
109
|
+
let value;
|
|
110
|
+
if(calculator){
|
|
111
|
+
value = calculator(record, this);
|
|
112
|
+
} else {
|
|
113
|
+
value = record[name] || '';
|
|
114
|
+
if (Array.isArray(value)) {
|
|
115
|
+
if(formatter){
|
|
116
|
+
value = value.map(formatter).join(', ');
|
|
117
|
+
} else {
|
|
118
|
+
value = value.join(', ');
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
if(formatter){
|
|
122
|
+
value = formatter(value);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
$td.innerHTML = value;
|
|
48
127
|
}
|
|
49
|
-
$td.innerHTML = value;
|
|
50
128
|
$tr.appendChild($td);
|
|
51
129
|
});
|
|
52
130
|
if(this.controls?.after?.length){
|
|
53
|
-
$tr.appendChild(this.renderRowControls(this.controls.after, record));
|
|
131
|
+
$tr.appendChild(this.renderRowControls(this.controls.after, record, start + index));
|
|
54
132
|
}
|
|
55
133
|
$records.appendChild($tr);
|
|
56
134
|
});
|
|
57
135
|
}
|
|
58
136
|
|
|
59
|
-
renderRowControls(controls = [], record) {
|
|
137
|
+
renderRowControls(controls = [], record, index) {
|
|
138
|
+
if(!this.rendered) return;
|
|
60
139
|
const $td = document.createElement('td');
|
|
61
140
|
controls.forEach(({ html, icon, action, render }) => {
|
|
62
141
|
if(html){
|
|
63
142
|
$td.appendChild(document.createRange().createContextualFragment(html));
|
|
64
143
|
} else if(render && typeof(render) === 'function'){
|
|
65
|
-
const rendered = render(this, record);
|
|
144
|
+
const rendered = render(this, record, index);
|
|
66
145
|
if(rendered instanceof HTMLElement){
|
|
67
146
|
$td.appendChild(rendered);
|
|
68
147
|
} else if(typeof(rendered) === 'string'){
|
|
@@ -70,9 +149,10 @@ export default class Table extends Component {
|
|
|
70
149
|
}
|
|
71
150
|
} else if(icon){
|
|
72
151
|
const $button = document.createElement('button');
|
|
152
|
+
$button.classList.add('pq');
|
|
73
153
|
$button.appendChild(new Icon(icon));
|
|
74
154
|
if (action) {
|
|
75
|
-
$button
|
|
155
|
+
onEvent($button, 'click', () => action(this, record, index));
|
|
76
156
|
}
|
|
77
157
|
$td.appendChild($button);
|
|
78
158
|
}
|
|
@@ -81,7 +161,9 @@ export default class Table extends Component {
|
|
|
81
161
|
}
|
|
82
162
|
|
|
83
163
|
renderControls(controls = [], position) {
|
|
84
|
-
|
|
164
|
+
if(!this.rendered) return;
|
|
165
|
+
const $container = this.shadowRoot.getElementById(position);
|
|
166
|
+
$container.innerHTML = '';
|
|
85
167
|
controls.forEach(({ html, icon, action, render }) => {
|
|
86
168
|
if(html){
|
|
87
169
|
$container.appendChild(document.createRange().createContextualFragment(html));
|
|
@@ -94,25 +176,135 @@ export default class Table extends Component {
|
|
|
94
176
|
}
|
|
95
177
|
} else if(icon){
|
|
96
178
|
const $button = document.createElement('button');
|
|
179
|
+
$button.classList.add('pq');
|
|
97
180
|
$button.appendChild(new Icon(icon));
|
|
98
181
|
if (action) {
|
|
99
|
-
$button
|
|
182
|
+
onEvent($button, 'click', () => action(this));
|
|
100
183
|
}
|
|
101
184
|
$container.appendChild($button);
|
|
102
185
|
}
|
|
103
186
|
});
|
|
104
|
-
this.shadowRoot.getElementById(position).innerHTML = '';
|
|
105
|
-
this.shadowRoot.getElementById(position).appendChild($container);
|
|
106
187
|
}
|
|
107
188
|
|
|
108
|
-
|
|
189
|
+
getCurrentPage() {
|
|
190
|
+
return this.currentPage;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
getTotalPages() {
|
|
194
|
+
return Math.ceil(this.records.length / this.pageSize);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
setPage(page) {
|
|
198
|
+
if (page < 1 || page > this.getTotalPages()) return;
|
|
199
|
+
this.currentPage = page;
|
|
200
|
+
this.renderRecords();
|
|
201
|
+
// Trigger page change event
|
|
202
|
+
dispatchEvent(this, 'pageChange');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
nextPage() {
|
|
206
|
+
if (this.currentPage < this.getTotalPages()) {
|
|
207
|
+
this.setPage(this.currentPage + 1);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
prevPage() {
|
|
212
|
+
if (this.currentPage > 1) {
|
|
213
|
+
this.setPage(this.currentPage - 1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
setPageSize(pageSize) {
|
|
218
|
+
this.pageSize = pageSize;
|
|
219
|
+
this.currentPage = 1;
|
|
220
|
+
this.renderRecords();
|
|
221
|
+
// Trigger page size change event
|
|
222
|
+
dispatchEvent(this, 'pageSizeChange');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
setData({
|
|
226
|
+
records = false,
|
|
227
|
+
fields = false,
|
|
228
|
+
controls = false,
|
|
229
|
+
pageSize = false,
|
|
230
|
+
pageSizeOptions = false,
|
|
231
|
+
currentPage = false
|
|
232
|
+
} = {}) {
|
|
233
|
+
let rerender = false;
|
|
234
|
+
let rerenderControls = false;
|
|
235
|
+
if(records){
|
|
236
|
+
this.records = records;
|
|
237
|
+
this.fields = fields || Table.extractFieldsFromRecords(this.records);
|
|
238
|
+
rerender = true;
|
|
239
|
+
}
|
|
240
|
+
if (pageSize) {
|
|
241
|
+
this.pageSize = pageSize;
|
|
242
|
+
rerender = true;
|
|
243
|
+
}
|
|
244
|
+
if (pageSizeOptions) {
|
|
245
|
+
this.pageSizeOptions = pageSizeOptions;
|
|
246
|
+
}
|
|
247
|
+
if (controls) {
|
|
248
|
+
this.controls = controls;
|
|
249
|
+
rerenderControls = true;
|
|
250
|
+
}
|
|
251
|
+
if(currentPage){
|
|
252
|
+
this.currentPage = currentPage;
|
|
253
|
+
rerender = true;
|
|
254
|
+
}
|
|
255
|
+
if(rerender){
|
|
256
|
+
this.renderFields();
|
|
257
|
+
this.renderRecords();
|
|
258
|
+
}
|
|
259
|
+
if(rerenderControls){
|
|
260
|
+
this.renderControls(this.controls.top, 'top');
|
|
261
|
+
this.renderControls(this.controls.bottom, 'bottom');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
setRecords(records) {
|
|
109
266
|
this.records = records;
|
|
110
|
-
this.
|
|
111
|
-
this.controls = controls;
|
|
112
|
-
this.renderControls(this.controls.top, 'top');
|
|
113
|
-
this.renderFields();
|
|
267
|
+
this.currentPage = 1;
|
|
114
268
|
this.renderRecords();
|
|
115
|
-
|
|
269
|
+
dispatchEvent(this, 'recordsSet', { records });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
setupFetchRecords(totalRecords, callback) {
|
|
273
|
+
const previousLength = this.records.length;
|
|
274
|
+
if (previousLength < totalRecords) {
|
|
275
|
+
this.records.length = totalRecords;
|
|
276
|
+
this.records.fill(null, previousLength);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
onEvent(this, 'fetchRecords', async (event) => {
|
|
280
|
+
const { start, end } = event.detail;
|
|
281
|
+
const records = await callback(start, end - start);
|
|
282
|
+
this.records.splice(start, records.length, ...records);
|
|
283
|
+
this.renderRecords();
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
addRecord(record) {
|
|
288
|
+
this.records.push(record);
|
|
289
|
+
this.renderRecords();
|
|
290
|
+
dispatchEvent(this, 'recordAdded', { record });
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
updateRecord(index, newRecord) {
|
|
294
|
+
this.records[index] = newRecord;
|
|
295
|
+
const start = (this.currentPage - 1) * this.pageSize;
|
|
296
|
+
const end = start + this.pageSize;
|
|
297
|
+
if (index >= start && index < end) {
|
|
298
|
+
this.renderRecords();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
deleteRecord(index) {
|
|
303
|
+
if (index >= 0 && index < this.records.length) {
|
|
304
|
+
this.records.splice(index, 1);
|
|
305
|
+
this.renderRecords();
|
|
306
|
+
dispatchEvent(this, 'recordDeleted', { index });
|
|
307
|
+
}
|
|
116
308
|
}
|
|
117
309
|
|
|
118
310
|
get shadowTemplate(){
|
|
@@ -120,7 +312,7 @@ export default class Table extends Component {
|
|
|
120
312
|
${super.shadowTemplate}
|
|
121
313
|
<div class="responsive-table">
|
|
122
314
|
<div id="top"></div>
|
|
123
|
-
<table>
|
|
315
|
+
<table class="b0">
|
|
124
316
|
<thead id="fields"></thead>
|
|
125
317
|
<tbody id="records"></tbody>
|
|
126
318
|
</table>
|
|
@@ -134,6 +326,35 @@ export default class Table extends Component {
|
|
|
134
326
|
:host {
|
|
135
327
|
display: block;
|
|
136
328
|
margin-bottom: var(--spacer);
|
|
329
|
+
border: 1px solid var(--c_border);
|
|
330
|
+
border-radius: var(--radius);
|
|
331
|
+
}
|
|
332
|
+
#top, #bottom {
|
|
333
|
+
display: flex;
|
|
334
|
+
}
|
|
335
|
+
th {
|
|
336
|
+
border-top: none;
|
|
337
|
+
}
|
|
338
|
+
tr:last-child td:first-child {
|
|
339
|
+
border-bottom-left-radius: 0;
|
|
340
|
+
}
|
|
341
|
+
tr:last-child td:last-child {
|
|
342
|
+
border-bottom-right-radius: 0;
|
|
343
|
+
}
|
|
344
|
+
tr:last-child td {
|
|
345
|
+
border-bottom: none;
|
|
346
|
+
}
|
|
347
|
+
th:first-child, td:first-child {
|
|
348
|
+
border-left: none;
|
|
349
|
+
}
|
|
350
|
+
th:last-child, td:last-child {
|
|
351
|
+
border-right: none;
|
|
352
|
+
}
|
|
353
|
+
#top:not(:empty) {
|
|
354
|
+
border-bottom: 1px solid var(--c_border);
|
|
355
|
+
}
|
|
356
|
+
#bottom:not(:empty) {
|
|
357
|
+
border-top: 1px solid var(--c_border);
|
|
137
358
|
}
|
|
138
359
|
`;
|
|
139
360
|
}
|
|
@@ -147,3 +368,131 @@ export default class Table extends Component {
|
|
|
147
368
|
}
|
|
148
369
|
}
|
|
149
370
|
window.customElements.define('k-table', Table);
|
|
371
|
+
|
|
372
|
+
class PageSelect extends Component {
|
|
373
|
+
constructor(table) {
|
|
374
|
+
super();
|
|
375
|
+
this.table = table;
|
|
376
|
+
this.classList.add('mxq');
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
connectedCallback() {
|
|
380
|
+
this.render();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async render() {
|
|
384
|
+
if(await super.render()){
|
|
385
|
+
this.updateOptions();
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
updateOptions() {
|
|
392
|
+
const $select = this.shadowRoot.getElementById('pageSelect');
|
|
393
|
+
$select.innerHTML = '';
|
|
394
|
+
for (let i = 1; i <= this.table.getTotalPages(); i++) {
|
|
395
|
+
const $option = document.createElement('option');
|
|
396
|
+
$option.value = i;
|
|
397
|
+
$option.textContent = i;
|
|
398
|
+
$select.appendChild($option);
|
|
399
|
+
}
|
|
400
|
+
$select.value = this.table.getCurrentPage();
|
|
401
|
+
const $totalPages = this.shadowRoot.getElementById('totalPages');
|
|
402
|
+
$totalPages.textContent = this.table.getTotalPages();
|
|
403
|
+
|
|
404
|
+
onEvent($select, 'change', () => {
|
|
405
|
+
this.table.setPage(parseInt($select.value));
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
onEvent(this.table, 'pageSizeChange', () => {
|
|
409
|
+
this.updateOptions();
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
onEvent(this.table, 'pageChange', () => {
|
|
413
|
+
$select.value = this.table.getCurrentPage();
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
get shadowTemplate() {
|
|
418
|
+
return /*html*/`
|
|
419
|
+
<select id="pageSelect" class="mxq"></select>
|
|
420
|
+
<label> out of <span id="totalPages"></span></label>
|
|
421
|
+
`;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
get shadowStyles() {
|
|
425
|
+
return /*css*/`
|
|
426
|
+
:host {
|
|
427
|
+
display: inline-flex;
|
|
428
|
+
width: max-content;
|
|
429
|
+
align-items: baseline;
|
|
430
|
+
}
|
|
431
|
+
#pageSelect, label {
|
|
432
|
+
display: inline;
|
|
433
|
+
}
|
|
434
|
+
label {
|
|
435
|
+
white-space: nowrap;
|
|
436
|
+
}
|
|
437
|
+
`;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
window.customElements.define('k-table-page-select', PageSelect);
|
|
441
|
+
|
|
442
|
+
class PageSize extends Component {
|
|
443
|
+
constructor(table) {
|
|
444
|
+
super();
|
|
445
|
+
this.table = table;
|
|
446
|
+
this.classList.add('mxq');
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
connectedCallback() {
|
|
450
|
+
this.render();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async render() {
|
|
454
|
+
if(await super.render()){
|
|
455
|
+
const $select = this.shadowRoot.getElementById('pageSizeSelect');
|
|
456
|
+
const options = this.table.pageSizeOptions;
|
|
457
|
+
options.forEach(size => {
|
|
458
|
+
const $option = document.createElement('option');
|
|
459
|
+
$option.value = size;
|
|
460
|
+
$option.textContent = size;
|
|
461
|
+
$select.appendChild($option);
|
|
462
|
+
});
|
|
463
|
+
$select.value = this.table.pageSize;
|
|
464
|
+
|
|
465
|
+
onEvent($select, 'change', () => {
|
|
466
|
+
this.table.setPageSize(parseInt($select.value));
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
onEvent(this.table, 'pageSizeChange', () => {
|
|
470
|
+
$select.value = this.table.pageSize;
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
get shadowTemplate() {
|
|
479
|
+
return /*html*/`
|
|
480
|
+
<label for="pageSizeSelect">Page Size: </label>
|
|
481
|
+
<select id="pageSizeSelect" class="mxq"></select>
|
|
482
|
+
`;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
get shadowStyles() {
|
|
486
|
+
return /*css*/`
|
|
487
|
+
:host {
|
|
488
|
+
display: inline-flex;
|
|
489
|
+
width: max-content;
|
|
490
|
+
align-items: baseline;
|
|
491
|
+
}
|
|
492
|
+
label {
|
|
493
|
+
white-space: nowrap;
|
|
494
|
+
}
|
|
495
|
+
`;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
window.customElements.define('k-table-page-size', PageSize);
|