feat(dees-pagination): Add new pagination component to the library along with its demo and integration in the main export.
This commit is contained in:
parent
12861b2230
commit
af3dc5c466
@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-04-25 - 1.8.0 - feat(dees-pagination)
|
||||||
|
Add new pagination component to the library along with its demo and integration in the main export.
|
||||||
|
|
||||||
|
- Introduced dees-pagination component with support for various page range scenarios.
|
||||||
|
- Created demo file to showcase pagination with both small and large sets of pages.
|
||||||
|
- Updated the module's index to export the new pagination component.
|
||||||
|
|
||||||
## 2025-04-22 - 1.7.0 - feat(dees-searchbar)
|
## 2025-04-22 - 1.7.0 - feat(dees-searchbar)
|
||||||
Add dees-searchbar component with live search and filter demo
|
Add dees-searchbar component with live search and filter demo
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@design.estate/dees-catalog',
|
name: '@design.estate/dees-catalog',
|
||||||
version: '1.7.0',
|
version: '1.8.0',
|
||||||
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
||||||
}
|
}
|
||||||
|
28
ts_web/elements/dees-pagination.demo.ts
Normal file
28
ts_web/elements/dees-pagination.demo.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { html } from '@design.estate/dees-element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demo for dees-pagination component
|
||||||
|
*/
|
||||||
|
export const demoFunc = () => html`
|
||||||
|
<div style="display: flex; align-items: center; gap: 16px;">
|
||||||
|
<!-- Small set of pages -->
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 4px;">
|
||||||
|
<span>5 pages, starting at 1:</span>
|
||||||
|
<dees-pagination
|
||||||
|
.total=${5}
|
||||||
|
.page=${1}
|
||||||
|
@page-change=${(e: CustomEvent) => console.log('Page changed to', e.detail.page)}
|
||||||
|
></dees-pagination>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Larger set of pages -->
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 4px;">
|
||||||
|
<span>15 pages, starting at 8:</span>
|
||||||
|
<dees-pagination
|
||||||
|
.total=${15}
|
||||||
|
.page=${8}
|
||||||
|
@page-change=${(e: CustomEvent) => console.log('Page changed to', e.detail.page)}
|
||||||
|
></dees-pagination>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
133
ts_web/elements/dees-pagination.ts
Normal file
133
ts_web/elements/dees-pagination.ts
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import { customElement, html, DeesElement, property, css, cssManager, type TemplateResult } from '@design.estate/dees-element';
|
||||||
|
import { demoFunc } from './dees-pagination.demo.js';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-pagination': DeesPagination;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple pagination component.
|
||||||
|
* @fires page-change - Emitted when the page is changed. detail: { page: number }
|
||||||
|
*/
|
||||||
|
@customElement('dees-pagination')
|
||||||
|
export class DeesPagination extends DeesElement {
|
||||||
|
public static demo = demoFunc;
|
||||||
|
/** Current page (1-based) */
|
||||||
|
@property({ type: Number, reflect: true })
|
||||||
|
public page = 1;
|
||||||
|
|
||||||
|
/** Total number of pages */
|
||||||
|
@property({ type: Number, reflect: true })
|
||||||
|
public total = 1;
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
cssManager.defaultStyles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
button:hover:not(:disabled) {
|
||||||
|
background: ${cssManager.bdTheme('#eee', '#444')};
|
||||||
|
}
|
||||||
|
button:disabled {
|
||||||
|
cursor: default;
|
||||||
|
color: ${cssManager.bdTheme('#aaa', '#666')};
|
||||||
|
}
|
||||||
|
button.current {
|
||||||
|
background: #0050b9;
|
||||||
|
color: #fff;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
span.ellipsis {
|
||||||
|
margin: 0 4px;
|
||||||
|
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
private get pages(): (number | string)[] {
|
||||||
|
const pages: (number | string)[] = [];
|
||||||
|
const total = this.total;
|
||||||
|
const current = this.page;
|
||||||
|
if (total <= 7) {
|
||||||
|
for (let i = 1; i <= total; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pages.push(1);
|
||||||
|
if (current > 4) {
|
||||||
|
pages.push('...');
|
||||||
|
}
|
||||||
|
const start = Math.max(2, current - 2);
|
||||||
|
const end = Math.min(total - 1, current + 2);
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
if (current < total - 3) {
|
||||||
|
pages.push('...');
|
||||||
|
}
|
||||||
|
pages.push(total);
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<button
|
||||||
|
@click=${() => this.changePage(this.page - 1)}
|
||||||
|
?disabled=${this.page <= 1}
|
||||||
|
aria-label="Previous page"
|
||||||
|
>
|
||||||
|
‹
|
||||||
|
</button>
|
||||||
|
${this.pages.map((p) =>
|
||||||
|
p === '...'
|
||||||
|
? html`<span class="ellipsis">…</span>`
|
||||||
|
: html`
|
||||||
|
<button
|
||||||
|
class="${p === this.page ? 'current' : ''}"
|
||||||
|
@click=${() => this.changePage(p as number)}
|
||||||
|
?disabled=${p === this.page}
|
||||||
|
aria-label="Page ${p}"
|
||||||
|
>
|
||||||
|
${p}
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
@click=${() => this.changePage(this.page + 1)}
|
||||||
|
?disabled=${this.page >= this.total}
|
||||||
|
aria-label="Next page"
|
||||||
|
>
|
||||||
|
›
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private changePage(newPage: number) {
|
||||||
|
if (newPage < 1 || newPage > this.total || newPage === this.page) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.page = newPage;
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('page-change', {
|
||||||
|
detail: { page: this.page },
|
||||||
|
bubbles: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -48,3 +48,4 @@ export * from './dees-toast.js';
|
|||||||
export * from './dees-updater.js';
|
export * from './dees-updater.js';
|
||||||
export * from './dees-windowcontrols.js';
|
export * from './dees-windowcontrols.js';
|
||||||
export * from './dees-windowlayer.js';
|
export * from './dees-windowlayer.js';
|
||||||
|
export * from './dees-pagination.js';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user