commercetools-8.x-1.2-alpha1/modules/commercetools_decoupled/js/molecules/Pager.js

modules/commercetools_decoupled/js/molecules/Pager.js
const LABEL_FIRST = '«';
const LABEL_PREV = '‹';
const LABEL_NEXT = '›';
const LABEL_LAST = '»';

class Pager extends HTMLElement {
  constructor() {
    super();
    this.currentPage = 0;
    this.totalPages = 1;
    this.handlePageClick = this.handlePageClick.bind(this);
  }

  connectedCallback() {
    this.renderPager();
    this.addEventListener('click', this.handlePageClick);
  }

  disconnectedCallback() {
    this.removeEventListener('click', this.handlePageClick);
  }

  handlePageClick(event) {
    event.preventDefault();
    const { target } = event;
    if (target.classList.contains('page-link')) {
      const page = parseInt(target?.dataset?.page, 10);
      if (!Number.isNaN(page) && page >= 0 && page < this.totalPages) {
        this.dispatchEvent(
          new CustomEvent('page-change', { detail: { page } }),
        );
      }
    }
  }

  renderPager() {
    const maxVisible = 9;
    const total = this.totalPages;
    let start = 0;
    let end = total;

    if (total > maxVisible) {
      const half = Math.floor(maxVisible / 2);
      start = Math.max(this.currentPage - half, 0);
      if (start + maxVisible > total) {
        start = total - maxVisible;
      }
      end = start + maxVisible;
    }

    const fragment = document.createDocumentFragment();
    const nav = document.createElement('nav');
    nav.setAttribute('aria-label', 'product-pagination');

    const ul = document.createElement('ul');
    ul.className = 'pagination';

    if (this.currentPage !== 0) {
      ul.appendChild(
        Pager.createPageItem(0, LABEL_FIRST, this.currentPage === 0),
      );
      ul.appendChild(
        Pager.createPageItem(
          this.currentPage - 1,
          LABEL_PREV,
          this.currentPage === 0,
        ),
      );
    }

    if (start > 0) {
      ul.appendChild(Pager.createEllipsisItem());
    }

    for (let i = start; i < end; i++) {
      ul.appendChild(
        Pager.createPageItem(i, String(i + 1), false, i === this.currentPage),
      );
    }

    if (end < total) {
      ul.appendChild(Pager.createEllipsisItem());
    }

    if (this.currentPage !== this.totalPages - 1) {
      ul.appendChild(
        Pager.createPageItem(
          this.currentPage + 1,
          LABEL_NEXT,
          this.currentPage === total - 1,
        ),
      );
      ul.appendChild(
        Pager.createPageItem(
          total - 1,
          LABEL_LAST,
          this.currentPage === total - 1,
        ),
      );
    }

    nav.appendChild(ul);
    fragment.appendChild(nav);
    this.innerHTML = '';
    this.appendChild(fragment);
  }

  static createPageItem(page, label, isDisabled = false, isActive = false) {
    const li = document.createElement('li');
    const classMap = {
      LABEL_FIRST: 'page-item--first',
      LABEL_PREV: 'page-item--prev',
      LABEL_NEXT: 'page-item--next',
      LABEL_LAST: 'page-item--last',
    };
    const bemClasses = classMap[label] || '';
    li.className = `page-item ${bemClasses}${isDisabled ? ' disabled' : ''}${isActive ? ' active' : ''}`;

    const inner = isActive
      ? document.createElement('span')
      : document.createElement('a');
    inner.className = 'page-link';
    const url = new URL(window.location);
    url.searchParams.set('page', page);
    inner.href = isDisabled ? '#' : url.toString();
    inner.setAttribute('data-page', page);
    inner.innerHTML = label;

    li.appendChild(inner);
    return li;
  }

  static createEllipsisItem() {
    const li = document.createElement('li');
    li.className = 'page-item disabled';
    const span = document.createElement('span');
    span.className = 'page-link';
    span.textContent = '…';
    li.appendChild(span);
    return li;
  }

  setPager(currentPage, totalPages) {
    this.currentPage = currentPage;
    this.totalPages = totalPages;
    this.renderPager();
  }
}

customElements.define('ct-pager', Pager);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc