add pagination component
Signed-off-by: Tobias Erbshäußer <tobias@tesoft.dev>
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
<template id="tesoft-pagination-template">
|
||||||
|
<style>
|
||||||
|
@import "/src/styles/default.css";
|
||||||
|
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host > div {
|
||||||
|
align-items: center;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto auto;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cur-page {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<tesoft-button class="prev" disabled>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="2.4rem" viewBox="0 -960 960 960" width="2.4rem" fill="#000000">
|
||||||
|
<path d="M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z"/>
|
||||||
|
</svg>
|
||||||
|
</tesoft-button>
|
||||||
|
<div class="cur-page">
|
||||||
|
1
|
||||||
|
</div>
|
||||||
|
<tesoft-button class="next" disabled>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="2.4rem" viewBox="0 -960 960 960" width="2.4rem" fill="#000000">
|
||||||
|
<path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/>
|
||||||
|
</svg>
|
||||||
|
</tesoft-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="/src/components/pagination.ts" type="module"></script>
|
||||||
|
{% includeOnce 'components/button.njk' %}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import {TesoftComponent} from "../scripts/main.ts";
|
||||||
|
import {TesoftButton} from "./button.ts";
|
||||||
|
|
||||||
|
export class TesoftPagination extends TesoftComponent {
|
||||||
|
static observedAttributes = ["cur-page", "last-page"];
|
||||||
|
|
||||||
|
private readonly curPageDiv: HTMLDivElement;
|
||||||
|
private readonly prevButton: TesoftButton;
|
||||||
|
private readonly nextButton: TesoftButton;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
const template = document.getElementById("tesoft-pagination-template") as HTMLTemplateElement;
|
||||||
|
const templateContent = template.content;
|
||||||
|
|
||||||
|
const shadowRoot = this.attachShadow({mode: "open"});
|
||||||
|
shadowRoot.appendChild(templateContent.cloneNode(true));
|
||||||
|
|
||||||
|
this.curPageDiv = shadowRoot.querySelector<HTMLDivElement>(".cur-page")!;
|
||||||
|
this.prevButton = shadowRoot.querySelector<TesoftButton>(".prev")!;
|
||||||
|
this.nextButton = shadowRoot.querySelector<TesoftButton>(".next")!;
|
||||||
|
}
|
||||||
|
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {
|
||||||
|
if (name === "cur-page") {
|
||||||
|
this.update(this.parsePage(newValue), this.parsePage(this.getAttribute("last-page")));
|
||||||
|
} else if (name === "last-page") {
|
||||||
|
this.update(this.parsePage(this.getAttribute("cur-page")), this.parsePage(newValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set curPage(value: number) {
|
||||||
|
this.setAttribute("cur-page", value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
set lastPage(value: number) {
|
||||||
|
this.setAttribute("last-page", value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private update(curPage: number, lastPage: number) {
|
||||||
|
this.curPageDiv.innerText = curPage.toString();
|
||||||
|
|
||||||
|
if (curPage <= 1) {
|
||||||
|
this.prevButton.setAttribute("disabled", "");
|
||||||
|
} else {
|
||||||
|
this.prevButton.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
this.prevButton.onclick = () => {
|
||||||
|
this.dispatchEvent(new CustomEvent("update-page", {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
composed: true,
|
||||||
|
detail: {
|
||||||
|
page: curPage - 1,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (curPage >= lastPage) {
|
||||||
|
this.nextButton.setAttribute("disabled", "");
|
||||||
|
} else {
|
||||||
|
this.nextButton.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
this.nextButton.onclick = () => {
|
||||||
|
this.dispatchEvent(new CustomEvent("updatePage", {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
composed: true,
|
||||||
|
detail: {
|
||||||
|
page: curPage + 1,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private parsePage(str: string | null): number {
|
||||||
|
return str ? parseInt(str) : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("tesoft-pagination", TesoftPagination);
|
||||||
Reference in New Issue
Block a user