{"version":3,"file":"BqPagination-cAbk5J0u.cjs","names":[],"sources":["../src/components/pagination/BqPagination.ts"],"sourcesContent":["/**\r\n * Pagination navigation component.\r\n * @element bq-pagination\r\n * @prop {number}  page             - Current page (1-based)\r\n * @prop {number}  total            - Total number of pages\r\n * @prop {number}  sibling-count    - Number of sibling pages each side\r\n * @prop {boolean} show-first-last  - Render first/last page buttons\r\n * @prop {boolean} disabled\r\n * @fires bq-page-change - { page: number }\r\n */\r\nimport type { ComponentDefinition } from '@bquery/bquery/component';\r\nimport { bool, component, html } from '@bquery/bquery/component';\r\nimport { t } from '../../i18n/index.js';\r\nimport { getBaseStyles } from '../../utils/styles.js';\r\n\r\ntype BqPaginationProps = {\r\n  page: number;\r\n  total: number;\r\n  'sibling-count': number;\r\n  'show-first-last': boolean;\r\n  disabled: boolean;\r\n};\r\n\r\nfunction buildPages(\r\n  page: number,\r\n  total: number,\r\n  siblings: number\r\n): Array<number | '...'> {\r\n  if (total <= 0) return [1];\r\n  const validPage = Math.max(1, Math.min(page, total));\r\n  if (total <= 7 + siblings * 2)\r\n    return Array.from({ length: total }, (_, i) => i + 1);\r\n  const left = Math.max(2, validPage - siblings);\r\n  const right = Math.min(total - 1, validPage + siblings);\r\n  const showLeft = left > 2;\r\n  const showRight = right < total - 1;\r\n  const pages: Array<number | '...'> = [1];\r\n  if (showLeft) pages.push('...');\r\n  for (let i = left; i <= right; i++) pages.push(i);\r\n  if (showRight) pages.push('...');\r\n  pages.push(total);\r\n  return pages;\r\n}\r\n\r\nconst definition: ComponentDefinition<BqPaginationProps> = {\r\n  props: {\r\n    page: { type: Number, default: 1 },\r\n    total: { type: Number, default: 1 },\r\n    'sibling-count': { type: Number, default: 1 },\r\n    'show-first-last': { type: Boolean, default: false },\r\n    disabled: { type: Boolean, default: false },\r\n  },\r\n  styles: `\r\n    ${getBaseStyles()}\r\n    *, *::before, *::after { box-sizing: border-box; }\r\n    :host { display: block; }\r\n    .pagination { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; font-family: var(--bq-font-family-sans); }\r\n    :host([disabled]) .pagination { opacity: 0.5; pointer-events: none; }\r\n    .page-btn {\r\n      display: inline-flex; align-items: center; justify-content: center;\r\n      min-width: 2.25rem; height: 2.25rem; padding: 0 0.5rem;\r\n      border: 1.5px solid var(--bq-border-emphasis,#cbd5e1);\r\n      border-radius: var(--bq-radius-md,0.375rem);\r\n      background: var(--bq-bg-base,#fff); color: var(--bq-text-base,#0f172a);\r\n      font-size: var(--bq-font-size-sm,0.875rem); font-weight: var(--bq-font-weight-medium,500);\r\n      cursor: pointer; font-family: inherit;\r\n      transition: all var(--bq-duration-fast) var(--bq-easing-standard);\r\n    }\r\n    .page-btn:hover:not(:disabled):not([data-current=\"true\"]) { background: var(--bq-bg-muted,#f1f5f9); border-color: var(--bq-color-primary-300,#93c5fd); }\r\n    .page-btn[data-current=\"true\"] { background: var(--bq-color-primary-600,#2563eb); border-color: var(--bq-color-primary-600,#2563eb); color: #fff; }\r\n    .page-btn:disabled { opacity: 0.45; cursor: not-allowed; }\r\n    .page-btn:focus-visible { outline: 2px solid transparent; box-shadow: var(--bq-focus-ring); }\r\n    .ellipsis { display: inline-flex; align-items: center; justify-content: center; min-width: 2.25rem; height: 2.25rem; color: var(--bq-text-subtle,#94a3b8); font-size: var(--bq-font-size-sm,0.875rem); }\r\n    @media (prefers-reduced-motion: reduce) {\r\n      .page-btn { transition: none; }\r\n    }\r\n  `,\r\n  connected() {\r\n    const self = this;\r\n    const handler = (e: Event) => {\r\n      const btn = (e.target as Element).closest(\r\n        '.page-btn'\r\n      ) as HTMLElement | null;\r\n      if (!btn || btn.hasAttribute('disabled') || self.hasAttribute('disabled'))\r\n        return;\r\n      const p = parseInt(btn.getAttribute('data-page') ?? '0', 10);\r\n      if (!p || isNaN(p)) return;\r\n      self.setAttribute('page', String(p));\r\n      self.dispatchEvent(\r\n        new CustomEvent('bq-page-change', {\r\n          detail: { page: p },\r\n          bubbles: true,\r\n          composed: true,\r\n        })\r\n      );\r\n    };\r\n    (self as unknown as Record<string, unknown>)['_handler'] = handler;\r\n    self.shadowRoot?.addEventListener('click', handler);\r\n  },\r\n  disconnected() {\r\n    const h = (this as unknown as Record<string, unknown>)['_handler'] as\r\n      | EventListener\r\n      | undefined;\r\n    if (h) this.shadowRoot?.removeEventListener('click', h);\r\n  },\r\n  render({ props }) {\r\n    const page = Math.max(1, Math.min(props.page, props.total || 1));\r\n    const total = props.total;\r\n    const siblings = props['sibling-count'];\r\n    const pages = buildPages(page, total, siblings);\r\n    const prevDisabled = page <= 1 || props.disabled;\r\n    const nextDisabled = page >= total || props.disabled;\r\n    const showFirstLast = props['show-first-last'];\r\n    const pageItems = pages\r\n      .map((p) => {\r\n        if (p === '...')\r\n          return '<span class=\"ellipsis\" role=\"separator\" aria-hidden=\"true\">&#8230;</span>';\r\n        return `<button class=\"page-btn\" data-page=\"${p}\" data-current=\"${p === page ? 'true' : 'false'}\" ${p === page ? 'aria-current=\"page\"' : ''} type=\"button\" aria-label=\"${t('pagination.page')} ${p}\">${p}</button>`;\r\n      })\r\n      .join('');\r\n    return html`\r\n      <nav aria-label=\"${t('pagination.nav')}\" part=\"nav\">\r\n        <div class=\"pagination\" part=\"pagination\">\r\n          ${showFirstLast\r\n            ? `<button\r\n                class=\"page-btn\"\r\n                data-page=\"1\"\r\n                ${prevDisabled ? 'disabled' : ''}\r\n                aria-label=\"${t('pagination.firstPage')}\"\r\n                type=\"button\"\r\n              >&#171;</button>`\r\n            : ''}\r\n          <button\r\n            class=\"page-btn\"\r\n            data-page=\"${String(page - 1)}\"\r\n            ${bool('disabled', prevDisabled)}\r\n            aria-label=\"${t('pagination.prev')}\"\r\n            type=\"button\"\r\n          >\r\n            &#8249;\r\n          </button>\r\n          ${pageItems}\r\n          <button\r\n            class=\"page-btn\"\r\n            data-page=\"${String(page + 1)}\"\r\n            ${bool('disabled', nextDisabled)}\r\n            aria-label=\"${t('pagination.next')}\"\r\n            type=\"button\"\r\n          >\r\n            &#8250;\r\n          </button>\r\n          ${showFirstLast\r\n            ? `<button\r\n                class=\"page-btn\"\r\n                data-page=\"${String(Math.max(1, total))}\"\r\n                ${nextDisabled ? 'disabled' : ''}\r\n                aria-label=\"${t('pagination.lastPage')}\"\r\n                type=\"button\"\r\n              >&#187;</button>`\r\n            : ''}\r\n        </div>\r\n      </nav>\r\n    `;\r\n  },\r\n};\r\n\r\ncomponent<BqPaginationProps>('bq-pagination', definition);\r\n"],"mappings":"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"}