{
  "version": 3,
  "sources": ["/cdn/shop/t/22/assets/paginated-list.js?tc=20260902"],
  "sourcesContent": ["import { Component } from '@theme/component';\nimport { sectionRenderer } from '@theme/section-renderer';\nimport { requestIdleCallback, viewTransition } from '@theme/utilities';\nimport { ThemeEvents } from '@theme/events';\nimport { PaginatedListAspectRatioHelper } from '@theme/paginated-list-aspect-ratio';\n\n/**\n * A custom element that renders a paginated list of items.\n *\n * @typedef {object} Refs\n * @property {HTMLUListElement} [grid] - The grid element.\n * @property {HTMLSpanElement} [viewMorePrevious] - The view more previous button.\n * @property {HTMLSpanElement} [viewMoreNext] - The view more next button.\n * @property {HTMLElement[]} [cards] - The cards elements.\n *\n * @extends Component<Refs>\n */\nexport default class PaginatedList extends Component {\n  /**\n   * @type {Map<number, string>}\n   */\n  pages = new Map();\n\n  /** @type {IntersectionObserver | undefined} */\n  infinityScrollObserver;\n\n  /** @type {((value: void) => void) | null} */\n  #resolveNextPagePromise = null;\n\n  /** @type {((value: void) => void) | null} */\n  #resolvePreviousPagePromise = null;\n\n  /** @type {PaginatedListAspectRatioHelper} */\n  #aspectRatioHelper;\n\n  /** @type {boolean} */\n  #previousPageArmed = false;\n\n  connectedCallback() {\n    super.connectedCallback();\n\n    /** @type {HTMLElement | null} */\n    const templateCard = this.querySelector('[ref=\"cardGallery\"]');\n    if (templateCard) {\n      this.#aspectRatioHelper = new PaginatedListAspectRatioHelper({\n        templateCard,\n      });\n    }\n\n    this.#fetchPage('next');\n    this.#fetchPage('previous');\n    this.#observeViewMore();\n\n    // Listen for filter updates to clear cached pages\n    document.addEventListener(ThemeEvents.FilterUpdate, this.#handleFilterUpdate);\n  }\n\n  disconnectedCallback() {\n    super.disconnectedCallback();\n    if (this.infinityScrollObserver) {\n      this.infinityScrollObserver.disconnect();\n    }\n    // Remove the filter update listener\n    document.removeEventListener(ThemeEvents.FilterUpdate, this.#handleFilterUpdate);\n  }\n\n  #observeViewMore() {\n    const { viewMorePrevious, viewMoreNext } = this.refs;\n\n    // Return if neither element exists\n    if (!viewMorePrevious && !viewMoreNext) return;\n\n    // Create observer if it doesn't exist\n    if (!this.infinityScrollObserver) {\n      this.infinityScrollObserver = new IntersectionObserver(\n        async (entries) => {\n          // Wait for any in-progress view transitions to finish\n          if (viewTransition.current) await viewTransition.current;\n\n          for (const entry of entries) {\n            // Use current refs to check which element triggered\n            const { viewMorePrevious, viewMoreNext } = this.refs;\n\n            if (entry.target === viewMorePrevious) {\n              if (!entry.isIntersecting) {\n                this.#previousPageArmed = true;\n                continue;\n              }\n\n              if (!this.#previousPageArmed) continue;\n              this.#previousPageArmed = false;\n              this.#renderPreviousPage();\n            } else if (entry.target === viewMoreNext && entry.isIntersecting) {\n              this.#renderNextPage();\n            }\n          }\n        },\n        {\n          rootMargin: '100px',\n        }\n      );\n    }\n\n    // Observe the view more elements\n    if (viewMorePrevious) {\n      this.infinityScrollObserver.observe(viewMorePrevious);\n    }\n\n    if (viewMoreNext) {\n      this.infinityScrollObserver.observe(viewMoreNext);\n    }\n  }\n\n  /**\n   * @param {{ page: number, url?: URL } | undefined} pageInfo - The page info\n   * @returns {boolean} Whether to use the page\n   */\n  #shouldUsePage(pageInfo) {\n    if (!pageInfo) return false;\n\n    const { grid } = this.refs;\n    const lastPage = grid?.dataset.lastPage;\n\n    if (!lastPage || pageInfo.page < 1 || pageInfo.page > Number(lastPage)) return false;\n\n    return true;\n  }\n\n  /**\n   * @param {\"previous\" | \"next\"} type\n   */\n  async #fetchPage(type) {\n    const page = this.#getPage(type);\n\n    // Always resolve the promise, even if we can't fetch the page\n    const resolvePromise = () => {\n      if (type === 'next') {\n        this.#resolveNextPagePromise?.();\n        this.#resolveNextPagePromise = null;\n      } else {\n        this.#resolvePreviousPagePromise?.();\n        this.#resolvePreviousPagePromise = null;\n      }\n    };\n\n    if (!page || !this.#shouldUsePage(page)) {\n      // Resolve the promise even if we can't fetch\n      resolvePromise();\n      return;\n    }\n\n    await this.#fetchSpecificPage(page.page, page.url);\n    resolvePromise();\n  }\n\n  /**\n   * @param {number} pageNumber - The page number to fetch\n   * @param {URL} [url] - Optional URL, will be constructed if not provided\n   */\n  async #fetchSpecificPage(pageNumber, url = undefined) {\n    const pageInfo = { page: pageNumber, url };\n\n    if (!url) {\n      const newUrl = new URL(window.location.href);\n      newUrl.searchParams.set('page', pageNumber.toString());\n      newUrl.hash = '';\n      pageInfo.url = newUrl;\n    }\n\n    if (!this.#shouldUsePage(pageInfo)) return;\n    const pageContent = await sectionRenderer.getSectionHTML(this.sectionId, true, pageInfo.url);\n    this.pages.set(pageNumber, pageContent);\n  }\n\n  async #renderNextPage() {\n    const { grid } = this.refs;\n\n    if (!grid) return;\n\n    const nextPage = this.#getPage('next');\n\n    if (!nextPage || !this.#shouldUsePage(nextPage)) return;\n    let nextPageItemElements = this.#getGridForPage(nextPage.page);\n\n    if (!nextPageItemElements) {\n      const promise = new Promise((res) => {\n        this.#resolveNextPagePromise = res;\n      });\n\n      // Trigger the fetch for this page\n      this.#fetchPage('next');\n\n      await promise;\n      nextPageItemElements = this.#getGridForPage(nextPage.page);\n      if (!nextPageItemElements) return;\n    }\n\n    grid.append(...nextPageItemElements);\n\n    this.#aspectRatioHelper.processNewElements();\n\n    history.pushState('', '', nextPage.url.toString());\n\n    requestIdleCallback(() => {\n      this.#fetchPage('next');\n    });\n  }\n\n  async #renderPreviousPage() {\n    const { grid } = this.refs;\n\n    if (!grid) return;\n\n    const previousPage = this.#getPage('previous');\n    if (!previousPage || !this.#shouldUsePage(previousPage)) return;\n\n    let previousPageItemElements = this.#getGridForPage(previousPage.page);\n    if (!previousPageItemElements) {\n      const promise = new Promise((res) => {\n        this.#resolvePreviousPagePromise = res;\n      });\n\n      // Trigger the fetch for this page\n      this.#fetchPage('previous');\n\n      await promise;\n      previousPageItemElements = this.#getGridForPage(previousPage.page);\n      if (!previousPageItemElements) return;\n    }\n\n    // Store the current scroll position and height of the first element\n    const scrollTop = window.scrollY;\n    const firstElement = grid.firstElementChild;\n    const oldHeight = firstElement ? firstElement.getBoundingClientRect().top + window.scrollY : 0;\n\n    // Prepend the new elements\n    grid.prepend(...previousPageItemElements);\n\n    this.#aspectRatioHelper.processNewElements();\n\n    history.pushState('', '', previousPage.url.toString());\n\n    // Calculate and adjust scroll position to maintain the same view\n    if (firstElement) {\n      const newHeight = firstElement.getBoundingClientRect().top + window.scrollY;\n      const heightDiff = newHeight - oldHeight;\n      window.scrollTo({\n        top: scrollTop + heightDiff,\n        behavior: 'instant',\n      });\n    }\n\n    requestIdleCallback(() => {\n      this.#fetchPage('previous');\n    });\n  }\n\n  /**\n   * @param {\"previous\" | \"next\"} type\n   * @returns {{ page: number, url: URL } | undefined}\n   */\n  #getPage(type) {\n    const { cards } = this.refs;\n    const isPrevious = type === 'previous';\n\n    if (!Array.isArray(cards)) return;\n\n    const targetCard = cards[isPrevious ? 0 : cards.length - 1];\n\n    if (!targetCard) return;\n\n    const currentCardPage = Number(targetCard.dataset.page);\n    const page = isPrevious ? currentCardPage - 1 : currentCardPage + 1;\n\n    const url = new URL(window.location.href);\n    url.searchParams.set('page', page.toString());\n    url.hash = '';\n\n    return {\n      page,\n      url,\n    };\n  }\n\n  /**\n   * @param {number} page\n   * @returns {NodeListOf<Element> | undefined}\n   */\n  #getGridForPage(page) {\n    const pageHTML = this.pages.get(page);\n\n    if (!pageHTML) return;\n\n    const parsedPage = new DOMParser().parseFromString(pageHTML, 'text/html');\n    const gridElement = parsedPage.querySelector('[ref=\"grid\"]');\n    if (!gridElement) return;\n    return gridElement.querySelectorAll(':scope > [ref=\"cards[]\"]');\n  }\n\n  get sectionId() {\n    const id = this.getAttribute('section-id');\n\n    if (!id) throw new Error('The section-id attribute is required');\n\n    return id;\n  }\n\n  /**\n   * Handle filter updates by clearing cached pages\n   */\n  #handleFilterUpdate = () => {\n    this.pages.clear();\n\n    // Resolve any pending promises to unblock waiting renders\n    this.#resolveNextPagePromise?.();\n    this.#resolvePreviousPagePromise?.();\n\n    this.#resolveNextPagePromise = null;\n    this.#resolvePreviousPagePromise = null;\n\n    // Store the current lastPage value to detect when it changes\n    const currentLastPage = this.refs.grid?.dataset.lastPage;\n\n    // We need to wait for the DOM to be updated with the new filtered content\n    // Using mutation observer to detect when the grid actually updates\n    const observer = new MutationObserver(() => {\n      // Check if data-last-page changed\n      const newLastPage = this.refs.grid?.dataset.lastPage;\n\n      if (newLastPage !== currentLastPage) {\n        observer.disconnect();\n\n        // Check if component is still connected\n        if (!this.isConnected) {\n          return;\n        }\n\n        // Now the DOM has been updated with the new filtered content\n        this.#observeViewMore();\n\n        // Fetch the next page\n        this.#fetchPage('next');\n      }\n    });\n\n    // Observe the grid for changes\n    const { grid } = this.refs;\n    if (grid) {\n      observer.observe(grid, {\n        attributes: true,\n        attributeFilter: ['data-last-page'],\n        childList: true, // Also watch for child changes in case the whole grid is replaced\n      });\n\n      // Set a timeout as a fallback in case the mutation never fires\n      setTimeout(() => {\n        if (observer) {\n          observer.disconnect();\n        }\n      }, 3000);\n    }\n  };\n}\n"],
  "mappings": "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",
  "names": ["viewMorePrevious", "viewMoreNext"]
}
