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` ${this.pages.map((p) => p === '...' ? html`` : html` ` )} `; } 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, }) ); } }