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,
})
);
}
}