@internetarchive/collection-browser 4.2.0-alpha-webdev8164.2 → 4.2.0-alpha-webdev8164.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -65,6 +65,10 @@ export declare class MoreFacetsContent extends LitElement {
65
65
  * Updated via a ResizeObserver-based container query approach.
66
66
  */
67
67
  private isCompactView;
68
+ /** Column gap in px — matches the --facetsColumnGap default (never overridden). */
69
+ private static readonly COLUMN_GAP;
70
+ /** Column count derived from the same breakpoint as the CSS media query. */
71
+ private get columnCount();
68
72
  /**
69
73
  * Whether the horizontal scroll is at the leftmost position.
70
74
  */
@@ -1,3 +1,4 @@
1
+ var MoreFacetsContent_1;
1
2
  import { __decorate } from "tslib";
2
3
  import { css, html, LitElement, nothing, } from 'lit';
3
4
  import { customElement, property, query, state } from 'lit/decorators.js';
@@ -75,6 +76,13 @@ let MoreFacetsContent = class MoreFacetsContent extends LitElement {
75
76
  this.modalManager?.closeModal();
76
77
  };
77
78
  }
79
+ static { MoreFacetsContent_1 = this; }
80
+ /** Column gap in px — matches the --facetsColumnGap default (never overridden). */
81
+ static { this.COLUMN_GAP = 15; }
82
+ /** Column count derived from the same breakpoint as the CSS media query. */
83
+ get columnCount() {
84
+ return this.isCompactView ? 1 : 3;
85
+ }
78
86
  willUpdate(changed) {
79
87
  if (changed.has('aggregations') ||
80
88
  changed.has('facetsPerPage') ||
@@ -182,15 +190,8 @@ let MoreFacetsContent = class MoreFacetsContent extends LitElement {
182
190
  const el = this.facetsContentEl;
183
191
  if (!el)
184
192
  return 0;
185
- const facetRows = el.querySelector('.facet-rows');
186
- const styles = facetRows
187
- ? getComputedStyle(facetRows)
188
- : getComputedStyle(el);
189
- const columnCount = parseInt(styles.columnCount, 10) || 3;
190
- const columnGap = parseInt(styles.columnGap, 10) || 15;
191
- // Column width = (visible width - total gaps) / column count
192
193
  // Column step = column width + gap = (visible width + gap) / column count
193
- return (el.clientWidth + columnGap) / columnCount;
194
+ return (el.clientWidth + MoreFacetsContent_1.COLUMN_GAP) / this.columnCount;
194
195
  }
195
196
  /**
196
197
  * Snaps a scroll target to the nearest column boundary.
@@ -1041,7 +1042,7 @@ __decorate([
1041
1042
  __decorate([
1042
1043
  query('.facets-content')
1043
1044
  ], MoreFacetsContent.prototype, "facetsContentEl", void 0);
1044
- MoreFacetsContent = __decorate([
1045
+ MoreFacetsContent = MoreFacetsContent_1 = __decorate([
1045
1046
  customElement('more-facets-content')
1046
1047
  ], MoreFacetsContent);
1047
1048
  export { MoreFacetsContent };
@@ -1 +1 @@
1
- {"version":3,"file":"more-facets-content.js","sourceRoot":"","sources":["../../../src/collection-facets/more-facets-content.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n CSSResultGroup,\n html,\n LitElement,\n nothing,\n PropertyValues,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { when } from 'lit/directives/when.js';\nimport {\n Aggregation,\n Bucket,\n SearchServiceInterface,\n SearchParams,\n SearchType,\n AggregationSortType,\n FilterMap,\n PageType,\n} from '@internetarchive/search-service';\nimport type { ModalManagerInterface } from '@internetarchive/modal-manager';\nimport type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';\nimport { msg } from '@lit/localize';\nimport {\n SelectedFacets,\n FacetGroup,\n FacetBucket,\n FacetOption,\n facetTitles,\n suppressedCollections,\n valueFacetSort,\n defaultFacetSort,\n getDefaultSelectedFacets,\n FacetEventDetails,\n tvMoreFacetSort,\n} from '../models';\nimport type {\n CollectionTitles,\n PageSpecifierParams,\n TVChannelAliases,\n} from '../data-source/models';\nimport '@internetarchive/elements/ia-status-indicator/ia-status-indicator';\nimport './facets-template';\nimport {\n analyticsActions,\n analyticsCategories,\n} from '../utils/analytics-events';\nimport './toggle-switch';\nimport './more-facets-pagination';\nimport '@internetarchive/ia-clearable-text-input';\nimport arrowLeftIcon from '../assets/img/icons/arrow-left';\nimport arrowRightIcon from '../assets/img/icons/arrow-right';\nimport { srOnlyStyle } from '../styles/sr-only';\nimport {\n mergeSelectedFacets,\n sortBucketsBySelectionState,\n updateSelectedFacetBucket,\n} from '../utils/facet-utils';\nimport {\n MORE_FACETS__DEFAULT_PAGE_SIZE,\n MORE_FACETS__MAX_AGGREGATIONS,\n} from './models';\n\n/**\n * Threshold for switching from horizontal scroll to pagination.\n * If facet count >= this value, use pagination. Otherwise use horizontal scroll.\n */\nconst PAGINATION_THRESHOLD = 1000;\n\n@customElement('more-facets-content')\nexport class MoreFacetsContent extends LitElement {\n @property({ type: String }) facetKey?: FacetOption;\n\n @property({ type: String }) query?: string;\n\n @property({ type: Array }) identifiers?: string[];\n\n @property({ type: Object }) filterMap?: FilterMap;\n\n @property({ type: Number }) searchType?: SearchType;\n\n @property({ type: Object }) pageSpecifierParams?: PageSpecifierParams;\n\n @property({ type: Object })\n collectionTitles?: CollectionTitles;\n\n @property({ type: Object })\n tvChannelAliases?: TVChannelAliases;\n\n /**\n * Maximum number of facets to show per page within the modal.\n */\n @property({ type: Number }) facetsPerPage = MORE_FACETS__DEFAULT_PAGE_SIZE;\n\n /**\n * Whether we are waiting for facet data to load.\n * We begin with this set to true so that we show an initial loading indicator.\n */\n @property({ type: Boolean }) facetsLoading = true;\n\n /**\n * The set of pre-existing facet selections (including both selected & negated facets).\n */\n @property({ type: Object }) selectedFacets?: SelectedFacets;\n\n @property({ type: Number }) sortedBy: AggregationSortType =\n AggregationSortType.COUNT;\n\n @property({ type: Boolean }) isTvSearch = false;\n\n @property({ type: Object }) modalManager?: ModalManagerInterface;\n\n @property({ type: Object }) searchService?: SearchServiceInterface;\n\n @property({ type: Object, attribute: false })\n analyticsHandler?: AnalyticsManagerInterface;\n\n /**\n * The full set of aggregations received from the search service\n */\n @state() private aggregations?: Record<string, Aggregation>;\n\n /**\n * A FacetGroup storing the full set of facet buckets to be shown on the dialog.\n */\n @state() private facetGroup?: FacetGroup;\n\n /**\n * An object holding any changes the patron has made to their facet selections\n * within the modal dialog but which they have not yet applied. These are\n * eventually merged into the existing `selectedFacets` when the patron applies\n * their changes, or discarded if they cancel/close the dialog.\n */\n @state() private unappliedFacetChanges: SelectedFacets =\n getDefaultSelectedFacets();\n\n /**\n * Text entered by the user to filter facet buckets.\n * Applied to bucket.key for case-insensitive matching.\n */\n @state() private filterText = '';\n\n /**\n * Current page number for pagination (when facet count >= PAGINATION_THRESHOLD).\n */\n @state() private pageNumber = 1;\n\n /**\n * Whether the component is narrow enough to warrant compact pagination.\n * Updated via a ResizeObserver-based container query approach.\n */\n @state() private isCompactView = false;\n\n /**\n * Whether the horizontal scroll is at the leftmost position.\n */\n @state() private atScrollStart = true;\n\n /**\n * Whether the horizontal scroll is at the rightmost position.\n */\n @state() private atScrollEnd = true;\n\n @query('ia-clearable-text-input')\n private filterInput!: HTMLElement;\n\n @query('.facets-content')\n private facetsContentEl!: HTMLElement;\n\n willUpdate(changed: PropertyValues): void {\n if (\n changed.has('aggregations') ||\n changed.has('facetsPerPage') ||\n changed.has('sortedBy') ||\n changed.has('selectedFacets') ||\n changed.has('unappliedFacetChanges')\n ) {\n // Convert the merged selected facets & aggregations into a facet group, and\n // store it for reuse across pages.\n this.facetGroup = this.mergedFacets;\n }\n\n // Reset to page 1 when filter text changes (only matters for pagination mode)\n if (changed.has('filterText')) {\n this.pageNumber = 1;\n }\n }\n\n updated(changed: PropertyValues): void {\n // If any of the search properties change, it triggers a facet fetch\n if (\n changed.has('facetKey') ||\n changed.has('query') ||\n changed.has('searchType') ||\n changed.has('filterMap')\n ) {\n this.facetsLoading = true;\n this.pageNumber = 1;\n this.sortedBy =\n this.searchType === SearchType.TV\n ? tvMoreFacetSort[this.facetKey as FacetOption]\n : defaultFacetSort[this.facetKey as FacetOption];\n\n this.updateSpecificFacets();\n }\n\n // Reset horizontal scroll when filter text changes (e.g., switching from\n // horizontal-scroll mode back to pagination mode)\n if (changed.has('filterText')) {\n const facetsContent = this.shadowRoot?.querySelector('.facets-content');\n if (facetsContent) {\n facetsContent.scrollLeft = 0;\n }\n }\n\n // Manage scroll listener for horizontal scroll mode arrows.\n // Only re-evaluate when properties that affect the displayed content change.\n if (\n changed.has('filterText') ||\n changed.has('aggregations') ||\n changed.has('facetKey') ||\n changed.has('sortedBy') ||\n changed.has('selectedFacets') ||\n changed.has('unappliedFacetChanges')\n ) {\n if (!this.usePagination) {\n this.attachScrollListener();\n // Refresh scroll state whenever content may have changed (e.g., filtering)\n requestAnimationFrame(() => this.updateScrollState());\n } else {\n this.removeScrollListener();\n }\n }\n }\n\n private resizeObserver?: ResizeObserver;\n\n firstUpdated(): void {\n this.setupEscapeListeners();\n this.setupCompactViewObserver();\n this.constrainToScrollContainer();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.resizeObserver?.disconnect();\n this.removeScrollListener();\n document.removeEventListener('keydown', this.escapeHandler);\n }\n\n private scrollHandler = () => this.updateScrollState();\n\n private scrollListenerAttached = false;\n\n private scrollListenerTarget?: HTMLElement;\n\n /**\n * Attaches a scroll event listener to the facets content element\n * to track horizontal scroll position for arrow button states.\n */\n private attachScrollListener(): void {\n if (this.scrollListenerAttached || !this.facetsContentEl) return;\n this.scrollListenerTarget = this.facetsContentEl;\n this.scrollListenerTarget.addEventListener('scroll', this.scrollHandler, {\n passive: true,\n });\n this.scrollListenerAttached = true;\n // Defer initial state check until after browser layout, so scrollWidth\n // reflects the actual content dimensions.\n requestAnimationFrame(() => this.updateScrollState());\n }\n\n private removeScrollListener(): void {\n if (!this.scrollListenerAttached || !this.scrollListenerTarget) return;\n this.scrollListenerTarget.removeEventListener('scroll', this.scrollHandler);\n this.scrollListenerTarget = undefined;\n this.scrollListenerAttached = false;\n }\n\n /**\n * Updates the scroll arrow disabled states based on current scroll position.\n */\n private updateScrollState(): void {\n const el = this.facetsContentEl;\n if (!el) return;\n this.atScrollStart = el.scrollLeft <= 0;\n this.atScrollEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;\n }\n\n /**\n * Calculates the width of one column step (column width + gap) based on\n * the CSS multi-column layout of the scroll container.\n */\n private getColumnStep(): number {\n const el = this.facetsContentEl;\n if (!el) return 0;\n\n const facetRows = el.querySelector('.facet-rows') as HTMLElement;\n const styles = facetRows\n ? getComputedStyle(facetRows)\n : getComputedStyle(el);\n\n const columnCount = parseInt(styles.columnCount, 10) || 3;\n const columnGap = parseInt(styles.columnGap, 10) || 15;\n\n // Column width = (visible width - total gaps) / column count\n // Column step = column width + gap = (visible width + gap) / column count\n return (el.clientWidth + columnGap) / columnCount;\n }\n\n /**\n * Snaps a scroll target to the nearest column boundary.\n */\n private snapToColumn(target: number): number {\n const step = this.getColumnStep();\n if (step <= 0) return target;\n return Math.round(target / step) * step;\n }\n\n /**\n * Scrolls the facet content left by approximately one page, snapping to\n * the nearest column boundary.\n */\n private onScrollLeft(): void {\n const el = this.facetsContentEl;\n if (!el) return;\n const rawTarget = el.scrollLeft - el.clientWidth;\n const snapped = Math.max(0, this.snapToColumn(rawTarget));\n el.scrollTo({ left: snapped, behavior: 'smooth' });\n }\n\n /**\n * Scrolls the facet content right by approximately one page, snapping to\n * the nearest column boundary.\n */\n private onScrollRight(): void {\n const el = this.facetsContentEl;\n if (!el) return;\n const maxScroll = el.scrollWidth - el.clientWidth;\n const rawTarget = el.scrollLeft + el.clientWidth;\n const snapped = Math.min(maxScroll, this.snapToColumn(rawTarget));\n el.scrollTo({ left: snapped, behavior: 'smooth' });\n }\n\n /**\n * Sets up a ResizeObserver to toggle compact pagination based on component width.\n */\n private setupCompactViewObserver(): void {\n this.resizeObserver = new ResizeObserver(entries => {\n for (const entry of entries) {\n const compact = entry.contentRect.width <= 560;\n if (this.isCompactView !== compact) this.isCompactView = compact;\n }\n });\n this.resizeObserver.observe(this);\n }\n\n /**\n * Constrains the section's max-height to fit within the nearest\n * scroll-container ancestor (e.g., the modal's content area).\n * This is a safety net for cases where the CSS max-height calculation\n * doesn't perfectly match the container's available space.\n */\n private constrainToScrollContainer(): void {\n requestAnimationFrame(() => {\n const section = this.shadowRoot?.querySelector(\n 'section#more-facets',\n ) as HTMLElement;\n if (!section) return;\n\n // Walk up from the assigned slot to find the nearest overflow container\n let el = this.assignedSlot?.parentElement;\n while (el) {\n const cs = getComputedStyle(el);\n if (\n cs.overflowY === 'auto' ||\n cs.overflowY === 'scroll' ||\n cs.overflowY === 'hidden'\n ) {\n const containerBottom = el.getBoundingClientRect().bottom;\n const sectionTop = section.getBoundingClientRect().top;\n const available = containerBottom - sectionTop;\n // Compare against the CSS max-height rather than actual height,\n // since content may not have loaded yet at firstUpdated time\n const computedMax = parseFloat(getComputedStyle(section).maxHeight);\n if (available > 0 && available < computedMax) {\n section.style.maxHeight = `${available}px`;\n }\n return;\n }\n el = el.parentElement;\n }\n });\n }\n\n /**\n * Close more facets modal on Escape click\n */\n private escapeHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this.modalManager?.closeModal();\n };\n\n private setupEscapeListeners() {\n if (this.modalManager) {\n document.addEventListener('keydown', this.escapeHandler);\n }\n }\n\n /**\n * Whether facet requests are for the search_results page type (either defaulted or explicitly).\n */\n private get isSearchResultsPage(): boolean {\n // Default page type is search_results when none is specified, so we check\n // for undefined as well.\n const pageType: PageType | undefined = this.pageSpecifierParams?.pageType;\n return pageType === undefined || pageType === 'search_results';\n }\n\n /**\n * Get specific facets data from search-service API based of currently query params\n * - this.aggregations - hold result of search service and being used for further processing.\n */\n async updateSpecificFacets(): Promise<void> {\n if (!this.facetKey) return; // Can't fetch facets if we don't know what type of facets we need!\n\n const trimmedQuery = this.query?.trim();\n if (!trimmedQuery && this.isSearchResultsPage) return; // The search page _requires_ a query\n\n const aggregations = {\n simpleParams: [this.facetKey],\n };\n const aggregationsSize = MORE_FACETS__MAX_AGGREGATIONS; // Only request the 10K highest-count facets\n\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n identifiers: this.identifiers,\n filters: this.filterMap,\n aggregations,\n aggregationsSize,\n rows: 0, // todo - do we want server-side pagination with offset/page/limit flag?\n };\n\n try {\n const results = await this.searchService?.search(params, this.searchType);\n this.aggregations = results?.success?.response.aggregations;\n\n const collectionTitles = results?.success?.response?.collectionTitles;\n if (collectionTitles) {\n for (const [id, title] of Object.entries(collectionTitles)) {\n this.collectionTitles?.set(id, title);\n }\n }\n } finally {\n this.facetsLoading = false;\n }\n }\n\n /**\n * Combines the selected facets with the aggregations to create a single list of facets\n */\n private get mergedFacets(): FacetGroup | undefined {\n if (!this.facetKey || !this.selectedFacets) return undefined;\n\n const { selectedFacetGroup, aggregationFacetGroup } = this;\n\n // If we don't have any aggregations, then there is nothing to show yet\n if (!aggregationFacetGroup) return undefined;\n\n // Start with either the selected group if we have one, or the aggregate group otherwise\n const facetGroup = { ...(selectedFacetGroup ?? aggregationFacetGroup) };\n\n // Attach the counts to the selected buckets\n const bucketsWithCount =\n selectedFacetGroup?.buckets.map(bucket => {\n const selectedBucket = aggregationFacetGroup.buckets.find(\n b => b.key === bucket.key,\n );\n return selectedBucket\n ? {\n ...bucket,\n count: selectedBucket.count,\n }\n : bucket;\n }) ?? [];\n\n // Sort the buckets by selection state\n // We do this *prior* to considering unapplied selections, because we want the facets\n // to remain in position when they are selected/unselected, rather than re-sort themselves.\n sortBucketsBySelectionState(bucketsWithCount, this.sortedBy);\n\n // Append any additional buckets that were not selected\n aggregationFacetGroup.buckets.forEach(bucket => {\n const existingBucket = selectedFacetGroup?.buckets.find(\n b => b.key === bucket.key,\n );\n if (existingBucket) return;\n bucketsWithCount.push(bucket);\n });\n\n // Apply any unapplied selections that appear on this page\n const unappliedBuckets = this.unappliedFacetChanges[this.facetKey];\n for (const [index, bucket] of bucketsWithCount.entries()) {\n const unappliedBucket = unappliedBuckets?.[bucket.key];\n if (unappliedBucket) {\n bucketsWithCount[index] = { ...unappliedBucket };\n }\n }\n\n // For TV creator facets, uppercase the display text\n if (this.facetKey === 'creator' && this.isTvSearch) {\n bucketsWithCount.forEach(b => {\n b.displayText = (b.displayText ?? b.key)?.toLocaleUpperCase();\n\n const channelLabel = this.tvChannelAliases?.get(b.displayText);\n if (channelLabel && channelLabel !== b.displayText) {\n b.extraNote = `(${channelLabel})`;\n }\n });\n }\n\n facetGroup.buckets = bucketsWithCount;\n return facetGroup;\n }\n\n /**\n * Converts the selected facets for the current facet key to a `FacetGroup`,\n * which is easier to work with.\n */\n private get selectedFacetGroup(): FacetGroup | undefined {\n if (!this.selectedFacets || !this.facetKey) return undefined;\n\n const selectedFacetsForKey = this.selectedFacets[this.facetKey];\n if (!selectedFacetsForKey) return undefined;\n\n const facetGroupTitle = facetTitles[this.facetKey];\n\n const buckets: FacetBucket[] = Object.entries(selectedFacetsForKey).map(\n ([value, data]) => {\n const displayText =\n (this.facetKey === 'collection'\n ? this.collectionTitles?.get(value)\n : undefined) ?? value;\n return {\n displayText,\n key: value,\n count: data?.count,\n state: data?.state,\n };\n },\n );\n\n return {\n title: facetGroupTitle,\n key: this.facetKey,\n buckets,\n };\n }\n\n /**\n * Converts the raw `aggregations` for the current facet key to a `FacetGroup`,\n * which is easier to work with.\n */\n private get aggregationFacetGroup(): FacetGroup | undefined {\n if (!this.aggregations || !this.facetKey) return undefined;\n\n const currentAggregation = this.aggregations[this.facetKey];\n if (!currentAggregation) return undefined;\n\n const facetGroupTitle = facetTitles[this.facetKey];\n\n // Order the facets according to the current sort option\n let sortedBuckets = currentAggregation.getSortedBuckets(\n this.sortedBy,\n ) as Bucket[];\n\n if (this.facetKey === 'collection') {\n // we are not showing fav- collections or certain deemphasized collections in facets\n sortedBuckets = sortedBuckets?.filter(bucket => {\n const bucketKey = bucket?.key?.toString();\n return (\n !suppressedCollections[bucketKey] && !bucketKey?.startsWith('fav-')\n );\n });\n }\n\n // Construct the array of facet buckets from the aggregation buckets,\n // using collection display titles where available.\n const facetBuckets: FacetBucket[] = sortedBuckets.map(bucket => {\n const bucketKeyStr = `${bucket.key}`;\n const displayText =\n (this.facetKey === 'collection'\n ? this.collectionTitles?.get(bucketKeyStr)\n : undefined) ?? bucketKeyStr;\n return {\n displayText,\n key: `${bucketKeyStr}`,\n count: bucket.doc_count,\n state: 'none',\n };\n });\n\n // For collection facets sorted alphabetically, re-sort by display title\n // instead of the raw identifier used by getSortedBuckets.\n if (\n this.facetKey === 'collection' &&\n this.sortedBy === AggregationSortType.ALPHABETICAL\n ) {\n facetBuckets.sort((a, b) =>\n (a.displayText ?? a.key).localeCompare(b.displayText ?? b.key),\n );\n }\n\n return {\n title: facetGroupTitle,\n key: this.facetKey,\n buckets: facetBuckets,\n };\n }\n\n /**\n * Returns the facet group with buckets filtered by the current filter text.\n * Filters are applied to the full bucket list before pagination.\n */\n private get filteredFacetGroup(): FacetGroup | undefined {\n const { facetGroup, filterText } = this;\n if (!facetGroup) return undefined;\n\n // If no filter text, return the full group\n if (!filterText.trim()) {\n return facetGroup;\n }\n\n // Filter buckets by the text the user actually sees.\n // For collections, match against the displayed collection title (not the identifier).\n // For other facet types, match against the bucket key (which is also the display text).\n const lowerFilter = filterText.toLowerCase().trim();\n const filteredBuckets = facetGroup.buckets.filter(bucket => {\n const displayText = this.collectionTitles?.get(bucket.key) ?? bucket.key;\n return displayText.toLowerCase().includes(lowerFilter);\n });\n\n return {\n ...facetGroup,\n buckets: filteredBuckets,\n };\n }\n\n /**\n * Determines whether to use pagination based on the number of filtered facets.\n * Returns true if facet count >= PAGINATION_THRESHOLD, false otherwise.\n */\n private get usePagination(): boolean {\n const facetCount = this.filteredFacetGroup?.buckets.length ?? 0;\n return facetCount >= PAGINATION_THRESHOLD;\n }\n\n /**\n * Returns the facet group for the current page.\n * If using pagination (>= 1000 facets), slices to show only the current page.\n * Otherwise, returns all facets for horizontal scrolling.\n */\n private get facetGroupForCurrentPage(): FacetGroup | undefined {\n const filteredGroup = this.filteredFacetGroup;\n if (!filteredGroup) return undefined;\n\n // If facet count is below threshold, show all facets with horizontal scroll\n if (!this.usePagination) {\n return filteredGroup;\n }\n\n // Otherwise, use pagination - slice to current page\n const startIndex = (this.pageNumber - 1) * this.facetsPerPage;\n const endIndex = startIndex + this.facetsPerPage;\n const slicedBuckets = filteredGroup.buckets.slice(startIndex, endIndex);\n\n return {\n ...filteredGroup,\n buckets: slicedBuckets,\n };\n }\n\n private get moreFacetsTemplate(): TemplateResult {\n const facetGroup = this.facetGroupForCurrentPage;\n\n // Show empty state if filtering returned no results\n if (\n this.filterText.trim() &&\n (!facetGroup || facetGroup.buckets.length === 0)\n ) {\n return this.emptyFilterResultsTemplate;\n }\n\n return html`\n <facets-template\n .facetGroup=${facetGroup}\n .selectedFacets=${this.selectedFacets}\n .collectionTitles=${this.collectionTitles}\n @facetClick=${(e: CustomEvent<FacetEventDetails>) => {\n if (this.facetKey) {\n this.unappliedFacetChanges = updateSelectedFacetBucket(\n this.unappliedFacetChanges,\n this.facetKey,\n e.detail.bucket,\n );\n }\n }}\n ></facets-template>\n `;\n }\n\n private get loaderTemplate(): TemplateResult {\n return html`\n <ia-status-indicator\n class=\"facets-loader\"\n mode=\"loading\"\n ></ia-status-indicator>\n `;\n }\n\n private get emptyFilterResultsTemplate(): TemplateResult {\n return html`\n <div class=\"empty-results\">\n <p>${msg('No matching values found.')}</p>\n <p class=\"hint\">${msg('Try a different search term.')}</p>\n </div>\n `;\n }\n\n /**\n * Number of pages for pagination (only used when facet count >= PAGINATION_THRESHOLD).\n */\n private get paginationSize(): number {\n const filteredBuckets = this.filteredFacetGroup?.buckets ?? [];\n return Math.ceil(filteredBuckets.length / this.facetsPerPage);\n }\n\n /**\n * Template for pagination component.\n */\n private get facetsPaginationTemplate() {\n return html`<more-facets-pagination\n .size=${this.paginationSize}\n .currentPage=${this.pageNumber}\n .compact=${this.isCompactView}\n @pageNumberClicked=${this.pageNumberClicked}\n ></more-facets-pagination>`;\n }\n\n private get footerTemplate() {\n return html`\n ${when(this.usePagination, () => this.facetsPaginationTemplate)}\n <div class=\"footer\">\n <button class=\"btn btn-cancel\" type=\"button\" @click=${this.cancelClick}>\n Cancel\n </button>\n <button\n class=\"btn btn-submit\"\n type=\"button\"\n @click=${this.applySearchFacetsClicked}\n >\n Apply filters\n </button>\n </div>\n `;\n }\n\n private sortFacetAggregation(facetSortType: AggregationSortType) {\n this.sortedBy = facetSortType;\n this.dispatchEvent(\n new CustomEvent('sortedFacets', { detail: this.sortedBy }),\n );\n }\n\n /**\n * Handler for filter input changes. Updates the filter text and triggers re-render.\n */\n private handleFilterInput(e: Event): void {\n const input = e.target as HTMLElement & { value: string };\n this.filterText = input.value;\n }\n\n /**\n * Handler for when the filter input is cleared via the clear button.\n */\n private handleFilterClear(): void {\n this.filterText = '';\n }\n\n /**\n * Handler for pagination page number clicks.\n * Only used when facet count >= PAGINATION_THRESHOLD.\n */\n private pageNumberClicked(e: CustomEvent<{ page: number }>) {\n this.pageNumber = e.detail.page;\n\n // Track page navigation in analytics\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.moreFacetsPageChange,\n label: `${this.pageNumber}`,\n });\n\n this.dispatchEvent(\n new CustomEvent('pageChanged', {\n detail: this.pageNumber,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private get modalHeaderTemplate(): TemplateResult {\n const facetSort =\n this.sortedBy ?? defaultFacetSort[this.facetKey as FacetOption];\n const defaultSwitchSide =\n facetSort === AggregationSortType.COUNT ? 'left' : 'right';\n\n return html`<span class=\"sr-only\">${msg('More facets for:')}</span>\n <span class=\"title\"> ${this.facetGroup?.title} </span>\n <span class=\"header-controls\">\n <span class=\"sort-controls\">\n <label class=\"sort-label\">${msg('Sort by:')}</label>\n ${this.facetKey\n ? html`<toggle-switch\n class=\"sort-toggle\"\n leftValue=${AggregationSortType.COUNT}\n leftLabel=\"Count\"\n rightValue=${valueFacetSort[this.facetKey]}\n .rightLabel=${this.facetGroup?.title}\n side=${defaultSwitchSide}\n @change=${(e: CustomEvent<string>) => {\n this.sortFacetAggregation(\n Number(e.detail) as AggregationSortType,\n );\n }}\n ></toggle-switch>`\n : nothing}\n </span>\n\n <span class=\"filter-controls\">\n <label class=\"filter-label\">${msg('Filter by:')}</label>\n <ia-clearable-text-input\n class=\"filter-input\"\n .value=${this.filterText}\n .placeholder=${msg('Search...')}\n .screenReaderLabel=${msg('Filter facets')}\n .clearButtonScreenReaderLabel=${msg('Clear filter')}\n @input=${this.handleFilterInput}\n @clear=${this.handleFilterClear}\n ></ia-clearable-text-input>\n </span>\n </span>`;\n }\n\n private get horizontalScrollTemplate(): TemplateResult {\n const contentClasses = classMap({\n 'facets-content': true,\n 'horizontal-scroll-mode': true,\n });\n const showArrows = !this.atScrollStart || !this.atScrollEnd;\n\n return html`<div class=\"scroll-nav-container\">\n ${when(\n showArrows,\n () =>\n html`<button\n class=\"scroll-arrow scroll-left\"\n @click=${this.onScrollLeft}\n ?disabled=${this.atScrollStart}\n aria-label=\"Scroll facets left\"\n >\n ${arrowLeftIcon}\n </button>`,\n )}\n <div class=${contentClasses}>\n <div class=\"facets-horizontal-container\">\n ${this.moreFacetsTemplate}\n </div>\n </div>\n ${when(\n showArrows,\n () =>\n html`<button\n class=\"scroll-arrow scroll-right\"\n @click=${this.onScrollRight}\n ?disabled=${this.atScrollEnd}\n aria-label=\"Scroll facets right\"\n >\n ${arrowRightIcon}\n </button>`,\n )}\n </div>`;\n }\n\n render() {\n const sectionClasses = classMap({\n 'pagination-mode': this.usePagination,\n 'horizontal-scroll-mode': !this.usePagination,\n });\n const contentClasses = classMap({\n 'facets-content': true,\n 'pagination-mode': this.usePagination,\n });\n\n return html`\n ${this.facetsLoading\n ? this.loaderTemplate\n : html`\n <section id=\"more-facets\" class=${sectionClasses}>\n <div class=\"header-content\">${this.modalHeaderTemplate}</div>\n ${this.usePagination\n ? html`<div class=${contentClasses}>\n ${this.moreFacetsTemplate}\n </div>`\n : this.horizontalScrollTemplate}\n ${this.footerTemplate}\n </section>\n `}\n `;\n }\n\n private applySearchFacetsClicked() {\n const mergedSelections = mergeSelectedFacets(\n this.selectedFacets,\n this.unappliedFacetChanges,\n );\n\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: mergedSelections,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n\n // Reset the unapplied changes back to default, now that they have been applied\n this.unappliedFacetChanges = getDefaultSelectedFacets();\n\n // Reset filter text\n this.filterText = '';\n\n this.modalManager?.closeModal();\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: `${analyticsActions.applyMoreFacetsModal}`,\n label: `${this.facetKey}`,\n });\n }\n\n private cancelClick() {\n // Reset the unapplied changes back to default\n this.unappliedFacetChanges = getDefaultSelectedFacets();\n\n // Reset filter text\n this.filterText = '';\n\n this.modalManager?.closeModal();\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.closeMoreFacetsModal,\n label: `${this.facetKey}`,\n });\n }\n\n static get styles(): CSSResultGroup {\n const modalSubmitButton = css`var(--primaryButtonBGColor, #194880)`;\n\n return [\n srOnlyStyle,\n css`\n section#more-facets {\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 16.5rem - var(--modalBottomMargin, 2.5rem));\n padding: 10px;\n box-sizing: border-box;\n --facetsColumnCount: 3;\n }\n\n /* Both modes need a height constraint for proper column flow */\n section#more-facets.horizontal-scroll-mode,\n section#more-facets.pagination-mode {\n --facetsMaxHeight: 280px;\n }\n .header-content {\n flex-shrink: 0;\n position: relative;\n z-index: 1;\n background: #fff;\n }\n\n .header-content .title {\n display: block;\n text-align: left;\n font-size: 1.8rem;\n padding: 0 10px;\n font-weight: bold;\n }\n\n .header-controls {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 20px;\n padding: 0 10px 8px;\n }\n\n .sort-controls {\n display: inline-flex;\n align-items: center;\n white-space: nowrap;\n gap: 5px;\n }\n\n .sort-label {\n font-size: 1.3rem;\n }\n\n .sort-toggle {\n font-weight: normal;\n }\n\n .filter-controls {\n display: inline-flex;\n align-items: center;\n white-space: nowrap;\n }\n\n .filter-label {\n font-size: 1.3rem;\n }\n\n .filter-input {\n --input-height: 2.5rem;\n --input-font-size: 1.3rem;\n --input-border-radius: 4px;\n --input-padding: 4px 8px;\n --input-focused-border-color: ${modalSubmitButton};\n width: 150px;\n margin-left: 5px;\n }\n\n .empty-results {\n text-align: center;\n padding: 40px 20px;\n color: #666;\n }\n\n .empty-results .hint {\n margin-top: 10px;\n }\n\n .facets-content {\n font-size: 1.2rem;\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 10px;\n /* Force scrollbar to always be visible */\n scrollbar-width: thin; /* Firefox */\n scrollbar-color: #888 #f1f1f1; /* Firefox - thumb and track colors */\n }\n\n /* Horizontal scroll mode: horizontal scrolling only */\n .facets-content.horizontal-scroll-mode {\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n /* Webkit browsers scrollbar styling - always visible */\n .facets-content::-webkit-scrollbar {\n width: 12px; /* Vertical scrollbar width */\n height: 12px; /* Horizontal scrollbar height */\n }\n\n .facets-content::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 6px;\n }\n\n .facets-content::-webkit-scrollbar-thumb {\n background: #888;\n border-radius: 6px;\n min-height: 30px; /* Ensure thumb is always visible when scrolling is possible */\n }\n\n .facets-content::-webkit-scrollbar-thumb:hover {\n background: #555;\n }\n\n /* Force corner to match track color */\n .facets-content::-webkit-scrollbar-corner {\n background: #f1f1f1;\n }\n\n .facets-horizontal-container {\n display: inline-block;\n min-width: 100%;\n /* Allow natural width expansion based on content */\n width: fit-content;\n }\n\n .scroll-nav-container {\n display: flex;\n align-items: center;\n flex: 1 1 auto;\n min-height: 0;\n }\n\n .scroll-nav-container .facets-content {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n .scroll-arrow {\n background: none;\n border: none;\n cursor: pointer;\n padding: 5px;\n flex-shrink: 0;\n }\n\n .scroll-arrow svg {\n height: 14px;\n fill: #2c2c2c;\n }\n\n .scroll-arrow:disabled {\n opacity: 0.3;\n cursor: default;\n }\n .facets-loader {\n --icon-width: 70px;\n margin-bottom: 20px;\n display: block;\n margin-left: auto;\n margin-right: auto;\n }\n .btn {\n border: none;\n padding: 10px;\n margin-bottom: 10px;\n width: auto;\n border-radius: 4px;\n cursor: pointer;\n font-family: inherit;\n }\n .btn-cancel {\n background-color: #2c2c2c;\n color: white;\n }\n .btn-submit {\n background-color: ${modalSubmitButton};\n color: white;\n }\n more-facets-pagination {\n flex-shrink: 0;\n }\n\n .footer {\n text-align: center;\n margin-top: 10px;\n flex-shrink: 0;\n }\n\n @media (max-width: 560px) {\n section#more-facets.horizontal-scroll-mode,\n section#more-facets.pagination-mode {\n --facetsColumnCount: 1; /* Single column on mobile */\n --facetsMaxHeight: none; /* Remove fixed height for vertical scrolling */\n }\n /* On mobile, always use vertical scrolling regardless of mode */\n .facets-content,\n .facets-content.horizontal-scroll-mode {\n overflow-y: auto;\n overflow-x: hidden;\n }\n .scroll-nav-container {\n display: contents; /* Remove wrapper from layout so section flex-column works */\n }\n .scroll-arrow {\n display: none;\n }\n .filter-input {\n width: 120px;\n --input-font-size: 1.2rem;\n }\n }\n `,\n ];\n }\n}\n"]}
1
+ {"version":3,"file":"more-facets-content.js","sourceRoot":"","sources":["../../../src/collection-facets/more-facets-content.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n CSSResultGroup,\n html,\n LitElement,\n nothing,\n PropertyValues,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { when } from 'lit/directives/when.js';\nimport {\n Aggregation,\n Bucket,\n SearchServiceInterface,\n SearchParams,\n SearchType,\n AggregationSortType,\n FilterMap,\n PageType,\n} from '@internetarchive/search-service';\nimport type { ModalManagerInterface } from '@internetarchive/modal-manager';\nimport type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';\nimport { msg } from '@lit/localize';\nimport {\n SelectedFacets,\n FacetGroup,\n FacetBucket,\n FacetOption,\n facetTitles,\n suppressedCollections,\n valueFacetSort,\n defaultFacetSort,\n getDefaultSelectedFacets,\n FacetEventDetails,\n tvMoreFacetSort,\n} from '../models';\nimport type {\n CollectionTitles,\n PageSpecifierParams,\n TVChannelAliases,\n} from '../data-source/models';\nimport '@internetarchive/elements/ia-status-indicator/ia-status-indicator';\nimport './facets-template';\nimport {\n analyticsActions,\n analyticsCategories,\n} from '../utils/analytics-events';\nimport './toggle-switch';\nimport './more-facets-pagination';\nimport '@internetarchive/ia-clearable-text-input';\nimport arrowLeftIcon from '../assets/img/icons/arrow-left';\nimport arrowRightIcon from '../assets/img/icons/arrow-right';\nimport { srOnlyStyle } from '../styles/sr-only';\nimport {\n mergeSelectedFacets,\n sortBucketsBySelectionState,\n updateSelectedFacetBucket,\n} from '../utils/facet-utils';\nimport {\n MORE_FACETS__DEFAULT_PAGE_SIZE,\n MORE_FACETS__MAX_AGGREGATIONS,\n} from './models';\n\n/**\n * Threshold for switching from horizontal scroll to pagination.\n * If facet count >= this value, use pagination. Otherwise use horizontal scroll.\n */\nconst PAGINATION_THRESHOLD = 1000;\n\n@customElement('more-facets-content')\nexport class MoreFacetsContent extends LitElement {\n @property({ type: String }) facetKey?: FacetOption;\n\n @property({ type: String }) query?: string;\n\n @property({ type: Array }) identifiers?: string[];\n\n @property({ type: Object }) filterMap?: FilterMap;\n\n @property({ type: Number }) searchType?: SearchType;\n\n @property({ type: Object }) pageSpecifierParams?: PageSpecifierParams;\n\n @property({ type: Object })\n collectionTitles?: CollectionTitles;\n\n @property({ type: Object })\n tvChannelAliases?: TVChannelAliases;\n\n /**\n * Maximum number of facets to show per page within the modal.\n */\n @property({ type: Number }) facetsPerPage = MORE_FACETS__DEFAULT_PAGE_SIZE;\n\n /**\n * Whether we are waiting for facet data to load.\n * We begin with this set to true so that we show an initial loading indicator.\n */\n @property({ type: Boolean }) facetsLoading = true;\n\n /**\n * The set of pre-existing facet selections (including both selected & negated facets).\n */\n @property({ type: Object }) selectedFacets?: SelectedFacets;\n\n @property({ type: Number }) sortedBy: AggregationSortType =\n AggregationSortType.COUNT;\n\n @property({ type: Boolean }) isTvSearch = false;\n\n @property({ type: Object }) modalManager?: ModalManagerInterface;\n\n @property({ type: Object }) searchService?: SearchServiceInterface;\n\n @property({ type: Object, attribute: false })\n analyticsHandler?: AnalyticsManagerInterface;\n\n /**\n * The full set of aggregations received from the search service\n */\n @state() private aggregations?: Record<string, Aggregation>;\n\n /**\n * A FacetGroup storing the full set of facet buckets to be shown on the dialog.\n */\n @state() private facetGroup?: FacetGroup;\n\n /**\n * An object holding any changes the patron has made to their facet selections\n * within the modal dialog but which they have not yet applied. These are\n * eventually merged into the existing `selectedFacets` when the patron applies\n * their changes, or discarded if they cancel/close the dialog.\n */\n @state() private unappliedFacetChanges: SelectedFacets =\n getDefaultSelectedFacets();\n\n /**\n * Text entered by the user to filter facet buckets.\n * Applied to bucket.key for case-insensitive matching.\n */\n @state() private filterText = '';\n\n /**\n * Current page number for pagination (when facet count >= PAGINATION_THRESHOLD).\n */\n @state() private pageNumber = 1;\n\n /**\n * Whether the component is narrow enough to warrant compact pagination.\n * Updated via a ResizeObserver-based container query approach.\n */\n @state() private isCompactView = false;\n\n /** Column gap in px — matches the --facetsColumnGap default (never overridden). */\n private static readonly COLUMN_GAP = 15;\n\n /** Column count derived from the same breakpoint as the CSS media query. */\n private get columnCount(): number {\n return this.isCompactView ? 1 : 3;\n }\n\n /**\n * Whether the horizontal scroll is at the leftmost position.\n */\n @state() private atScrollStart = true;\n\n /**\n * Whether the horizontal scroll is at the rightmost position.\n */\n @state() private atScrollEnd = true;\n\n @query('ia-clearable-text-input')\n private filterInput!: HTMLElement;\n\n @query('.facets-content')\n private facetsContentEl!: HTMLElement;\n\n willUpdate(changed: PropertyValues): void {\n if (\n changed.has('aggregations') ||\n changed.has('facetsPerPage') ||\n changed.has('sortedBy') ||\n changed.has('selectedFacets') ||\n changed.has('unappliedFacetChanges')\n ) {\n // Convert the merged selected facets & aggregations into a facet group, and\n // store it for reuse across pages.\n this.facetGroup = this.mergedFacets;\n }\n\n // Reset to page 1 when filter text changes (only matters for pagination mode)\n if (changed.has('filterText')) {\n this.pageNumber = 1;\n }\n }\n\n updated(changed: PropertyValues): void {\n // If any of the search properties change, it triggers a facet fetch\n if (\n changed.has('facetKey') ||\n changed.has('query') ||\n changed.has('searchType') ||\n changed.has('filterMap')\n ) {\n this.facetsLoading = true;\n this.pageNumber = 1;\n this.sortedBy =\n this.searchType === SearchType.TV\n ? tvMoreFacetSort[this.facetKey as FacetOption]\n : defaultFacetSort[this.facetKey as FacetOption];\n\n this.updateSpecificFacets();\n }\n\n // Reset horizontal scroll when filter text changes (e.g., switching from\n // horizontal-scroll mode back to pagination mode)\n if (changed.has('filterText')) {\n const facetsContent = this.shadowRoot?.querySelector('.facets-content');\n if (facetsContent) {\n facetsContent.scrollLeft = 0;\n }\n }\n\n // Manage scroll listener for horizontal scroll mode arrows.\n // Only re-evaluate when properties that affect the displayed content change.\n if (\n changed.has('filterText') ||\n changed.has('aggregations') ||\n changed.has('facetKey') ||\n changed.has('sortedBy') ||\n changed.has('selectedFacets') ||\n changed.has('unappliedFacetChanges')\n ) {\n if (!this.usePagination) {\n this.attachScrollListener();\n // Refresh scroll state whenever content may have changed (e.g., filtering)\n requestAnimationFrame(() => this.updateScrollState());\n } else {\n this.removeScrollListener();\n }\n }\n }\n\n private resizeObserver?: ResizeObserver;\n\n firstUpdated(): void {\n this.setupEscapeListeners();\n this.setupCompactViewObserver();\n this.constrainToScrollContainer();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.resizeObserver?.disconnect();\n this.removeScrollListener();\n document.removeEventListener('keydown', this.escapeHandler);\n }\n\n private scrollHandler = () => this.updateScrollState();\n\n private scrollListenerAttached = false;\n\n private scrollListenerTarget?: HTMLElement;\n\n /**\n * Attaches a scroll event listener to the facets content element\n * to track horizontal scroll position for arrow button states.\n */\n private attachScrollListener(): void {\n if (this.scrollListenerAttached || !this.facetsContentEl) return;\n this.scrollListenerTarget = this.facetsContentEl;\n this.scrollListenerTarget.addEventListener('scroll', this.scrollHandler, {\n passive: true,\n });\n this.scrollListenerAttached = true;\n // Defer initial state check until after browser layout, so scrollWidth\n // reflects the actual content dimensions.\n requestAnimationFrame(() => this.updateScrollState());\n }\n\n private removeScrollListener(): void {\n if (!this.scrollListenerAttached || !this.scrollListenerTarget) return;\n this.scrollListenerTarget.removeEventListener('scroll', this.scrollHandler);\n this.scrollListenerTarget = undefined;\n this.scrollListenerAttached = false;\n }\n\n /**\n * Updates the scroll arrow disabled states based on current scroll position.\n */\n private updateScrollState(): void {\n const el = this.facetsContentEl;\n if (!el) return;\n this.atScrollStart = el.scrollLeft <= 0;\n this.atScrollEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;\n }\n\n /**\n * Calculates the width of one column step (column width + gap) based on\n * the CSS multi-column layout of the scroll container.\n */\n private getColumnStep(): number {\n const el = this.facetsContentEl;\n if (!el) return 0;\n // Column step = column width + gap = (visible width + gap) / column count\n return (el.clientWidth + MoreFacetsContent.COLUMN_GAP) / this.columnCount;\n }\n\n /**\n * Snaps a scroll target to the nearest column boundary.\n */\n private snapToColumn(target: number): number {\n const step = this.getColumnStep();\n if (step <= 0) return target;\n return Math.round(target / step) * step;\n }\n\n /**\n * Scrolls the facet content left by approximately one page, snapping to\n * the nearest column boundary.\n */\n private onScrollLeft(): void {\n const el = this.facetsContentEl;\n if (!el) return;\n const rawTarget = el.scrollLeft - el.clientWidth;\n const snapped = Math.max(0, this.snapToColumn(rawTarget));\n el.scrollTo({ left: snapped, behavior: 'smooth' });\n }\n\n /**\n * Scrolls the facet content right by approximately one page, snapping to\n * the nearest column boundary.\n */\n private onScrollRight(): void {\n const el = this.facetsContentEl;\n if (!el) return;\n const maxScroll = el.scrollWidth - el.clientWidth;\n const rawTarget = el.scrollLeft + el.clientWidth;\n const snapped = Math.min(maxScroll, this.snapToColumn(rawTarget));\n el.scrollTo({ left: snapped, behavior: 'smooth' });\n }\n\n /**\n * Sets up a ResizeObserver to toggle compact pagination based on component width.\n */\n private setupCompactViewObserver(): void {\n this.resizeObserver = new ResizeObserver(entries => {\n for (const entry of entries) {\n const compact = entry.contentRect.width <= 560;\n if (this.isCompactView !== compact) this.isCompactView = compact;\n }\n });\n this.resizeObserver.observe(this);\n }\n\n /**\n * Constrains the section's max-height to fit within the nearest\n * scroll-container ancestor (e.g., the modal's content area).\n * This is a safety net for cases where the CSS max-height calculation\n * doesn't perfectly match the container's available space.\n */\n private constrainToScrollContainer(): void {\n requestAnimationFrame(() => {\n const section = this.shadowRoot?.querySelector(\n 'section#more-facets',\n ) as HTMLElement;\n if (!section) return;\n\n // Walk up from the assigned slot to find the nearest overflow container\n let el = this.assignedSlot?.parentElement;\n while (el) {\n const cs = getComputedStyle(el);\n if (\n cs.overflowY === 'auto' ||\n cs.overflowY === 'scroll' ||\n cs.overflowY === 'hidden'\n ) {\n const containerBottom = el.getBoundingClientRect().bottom;\n const sectionTop = section.getBoundingClientRect().top;\n const available = containerBottom - sectionTop;\n // Compare against the CSS max-height rather than actual height,\n // since content may not have loaded yet at firstUpdated time\n const computedMax = parseFloat(getComputedStyle(section).maxHeight);\n if (available > 0 && available < computedMax) {\n section.style.maxHeight = `${available}px`;\n }\n return;\n }\n el = el.parentElement;\n }\n });\n }\n\n /**\n * Close more facets modal on Escape click\n */\n private escapeHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this.modalManager?.closeModal();\n };\n\n private setupEscapeListeners() {\n if (this.modalManager) {\n document.addEventListener('keydown', this.escapeHandler);\n }\n }\n\n /**\n * Whether facet requests are for the search_results page type (either defaulted or explicitly).\n */\n private get isSearchResultsPage(): boolean {\n // Default page type is search_results when none is specified, so we check\n // for undefined as well.\n const pageType: PageType | undefined = this.pageSpecifierParams?.pageType;\n return pageType === undefined || pageType === 'search_results';\n }\n\n /**\n * Get specific facets data from search-service API based of currently query params\n * - this.aggregations - hold result of search service and being used for further processing.\n */\n async updateSpecificFacets(): Promise<void> {\n if (!this.facetKey) return; // Can't fetch facets if we don't know what type of facets we need!\n\n const trimmedQuery = this.query?.trim();\n if (!trimmedQuery && this.isSearchResultsPage) return; // The search page _requires_ a query\n\n const aggregations = {\n simpleParams: [this.facetKey],\n };\n const aggregationsSize = MORE_FACETS__MAX_AGGREGATIONS; // Only request the 10K highest-count facets\n\n const params: SearchParams = {\n ...this.pageSpecifierParams,\n query: trimmedQuery || '',\n identifiers: this.identifiers,\n filters: this.filterMap,\n aggregations,\n aggregationsSize,\n rows: 0, // todo - do we want server-side pagination with offset/page/limit flag?\n };\n\n try {\n const results = await this.searchService?.search(params, this.searchType);\n this.aggregations = results?.success?.response.aggregations;\n\n const collectionTitles = results?.success?.response?.collectionTitles;\n if (collectionTitles) {\n for (const [id, title] of Object.entries(collectionTitles)) {\n this.collectionTitles?.set(id, title);\n }\n }\n } finally {\n this.facetsLoading = false;\n }\n }\n\n /**\n * Combines the selected facets with the aggregations to create a single list of facets\n */\n private get mergedFacets(): FacetGroup | undefined {\n if (!this.facetKey || !this.selectedFacets) return undefined;\n\n const { selectedFacetGroup, aggregationFacetGroup } = this;\n\n // If we don't have any aggregations, then there is nothing to show yet\n if (!aggregationFacetGroup) return undefined;\n\n // Start with either the selected group if we have one, or the aggregate group otherwise\n const facetGroup = { ...(selectedFacetGroup ?? aggregationFacetGroup) };\n\n // Attach the counts to the selected buckets\n const bucketsWithCount =\n selectedFacetGroup?.buckets.map(bucket => {\n const selectedBucket = aggregationFacetGroup.buckets.find(\n b => b.key === bucket.key,\n );\n return selectedBucket\n ? {\n ...bucket,\n count: selectedBucket.count,\n }\n : bucket;\n }) ?? [];\n\n // Sort the buckets by selection state\n // We do this *prior* to considering unapplied selections, because we want the facets\n // to remain in position when they are selected/unselected, rather than re-sort themselves.\n sortBucketsBySelectionState(bucketsWithCount, this.sortedBy);\n\n // Append any additional buckets that were not selected\n aggregationFacetGroup.buckets.forEach(bucket => {\n const existingBucket = selectedFacetGroup?.buckets.find(\n b => b.key === bucket.key,\n );\n if (existingBucket) return;\n bucketsWithCount.push(bucket);\n });\n\n // Apply any unapplied selections that appear on this page\n const unappliedBuckets = this.unappliedFacetChanges[this.facetKey];\n for (const [index, bucket] of bucketsWithCount.entries()) {\n const unappliedBucket = unappliedBuckets?.[bucket.key];\n if (unappliedBucket) {\n bucketsWithCount[index] = { ...unappliedBucket };\n }\n }\n\n // For TV creator facets, uppercase the display text\n if (this.facetKey === 'creator' && this.isTvSearch) {\n bucketsWithCount.forEach(b => {\n b.displayText = (b.displayText ?? b.key)?.toLocaleUpperCase();\n\n const channelLabel = this.tvChannelAliases?.get(b.displayText);\n if (channelLabel && channelLabel !== b.displayText) {\n b.extraNote = `(${channelLabel})`;\n }\n });\n }\n\n facetGroup.buckets = bucketsWithCount;\n return facetGroup;\n }\n\n /**\n * Converts the selected facets for the current facet key to a `FacetGroup`,\n * which is easier to work with.\n */\n private get selectedFacetGroup(): FacetGroup | undefined {\n if (!this.selectedFacets || !this.facetKey) return undefined;\n\n const selectedFacetsForKey = this.selectedFacets[this.facetKey];\n if (!selectedFacetsForKey) return undefined;\n\n const facetGroupTitle = facetTitles[this.facetKey];\n\n const buckets: FacetBucket[] = Object.entries(selectedFacetsForKey).map(\n ([value, data]) => {\n const displayText =\n (this.facetKey === 'collection'\n ? this.collectionTitles?.get(value)\n : undefined) ?? value;\n return {\n displayText,\n key: value,\n count: data?.count,\n state: data?.state,\n };\n },\n );\n\n return {\n title: facetGroupTitle,\n key: this.facetKey,\n buckets,\n };\n }\n\n /**\n * Converts the raw `aggregations` for the current facet key to a `FacetGroup`,\n * which is easier to work with.\n */\n private get aggregationFacetGroup(): FacetGroup | undefined {\n if (!this.aggregations || !this.facetKey) return undefined;\n\n const currentAggregation = this.aggregations[this.facetKey];\n if (!currentAggregation) return undefined;\n\n const facetGroupTitle = facetTitles[this.facetKey];\n\n // Order the facets according to the current sort option\n let sortedBuckets = currentAggregation.getSortedBuckets(\n this.sortedBy,\n ) as Bucket[];\n\n if (this.facetKey === 'collection') {\n // we are not showing fav- collections or certain deemphasized collections in facets\n sortedBuckets = sortedBuckets?.filter(bucket => {\n const bucketKey = bucket?.key?.toString();\n return (\n !suppressedCollections[bucketKey] && !bucketKey?.startsWith('fav-')\n );\n });\n }\n\n // Construct the array of facet buckets from the aggregation buckets,\n // using collection display titles where available.\n const facetBuckets: FacetBucket[] = sortedBuckets.map(bucket => {\n const bucketKeyStr = `${bucket.key}`;\n const displayText =\n (this.facetKey === 'collection'\n ? this.collectionTitles?.get(bucketKeyStr)\n : undefined) ?? bucketKeyStr;\n return {\n displayText,\n key: `${bucketKeyStr}`,\n count: bucket.doc_count,\n state: 'none',\n };\n });\n\n // For collection facets sorted alphabetically, re-sort by display title\n // instead of the raw identifier used by getSortedBuckets.\n if (\n this.facetKey === 'collection' &&\n this.sortedBy === AggregationSortType.ALPHABETICAL\n ) {\n facetBuckets.sort((a, b) =>\n (a.displayText ?? a.key).localeCompare(b.displayText ?? b.key),\n );\n }\n\n return {\n title: facetGroupTitle,\n key: this.facetKey,\n buckets: facetBuckets,\n };\n }\n\n /**\n * Returns the facet group with buckets filtered by the current filter text.\n * Filters are applied to the full bucket list before pagination.\n */\n private get filteredFacetGroup(): FacetGroup | undefined {\n const { facetGroup, filterText } = this;\n if (!facetGroup) return undefined;\n\n // If no filter text, return the full group\n if (!filterText.trim()) {\n return facetGroup;\n }\n\n // Filter buckets by the text the user actually sees.\n // For collections, match against the displayed collection title (not the identifier).\n // For other facet types, match against the bucket key (which is also the display text).\n const lowerFilter = filterText.toLowerCase().trim();\n const filteredBuckets = facetGroup.buckets.filter(bucket => {\n const displayText = this.collectionTitles?.get(bucket.key) ?? bucket.key;\n return displayText.toLowerCase().includes(lowerFilter);\n });\n\n return {\n ...facetGroup,\n buckets: filteredBuckets,\n };\n }\n\n /**\n * Determines whether to use pagination based on the number of filtered facets.\n * Returns true if facet count >= PAGINATION_THRESHOLD, false otherwise.\n */\n private get usePagination(): boolean {\n const facetCount = this.filteredFacetGroup?.buckets.length ?? 0;\n return facetCount >= PAGINATION_THRESHOLD;\n }\n\n /**\n * Returns the facet group for the current page.\n * If using pagination (>= 1000 facets), slices to show only the current page.\n * Otherwise, returns all facets for horizontal scrolling.\n */\n private get facetGroupForCurrentPage(): FacetGroup | undefined {\n const filteredGroup = this.filteredFacetGroup;\n if (!filteredGroup) return undefined;\n\n // If facet count is below threshold, show all facets with horizontal scroll\n if (!this.usePagination) {\n return filteredGroup;\n }\n\n // Otherwise, use pagination - slice to current page\n const startIndex = (this.pageNumber - 1) * this.facetsPerPage;\n const endIndex = startIndex + this.facetsPerPage;\n const slicedBuckets = filteredGroup.buckets.slice(startIndex, endIndex);\n\n return {\n ...filteredGroup,\n buckets: slicedBuckets,\n };\n }\n\n private get moreFacetsTemplate(): TemplateResult {\n const facetGroup = this.facetGroupForCurrentPage;\n\n // Show empty state if filtering returned no results\n if (\n this.filterText.trim() &&\n (!facetGroup || facetGroup.buckets.length === 0)\n ) {\n return this.emptyFilterResultsTemplate;\n }\n\n return html`\n <facets-template\n .facetGroup=${facetGroup}\n .selectedFacets=${this.selectedFacets}\n .collectionTitles=${this.collectionTitles}\n @facetClick=${(e: CustomEvent<FacetEventDetails>) => {\n if (this.facetKey) {\n this.unappliedFacetChanges = updateSelectedFacetBucket(\n this.unappliedFacetChanges,\n this.facetKey,\n e.detail.bucket,\n );\n }\n }}\n ></facets-template>\n `;\n }\n\n private get loaderTemplate(): TemplateResult {\n return html`\n <ia-status-indicator\n class=\"facets-loader\"\n mode=\"loading\"\n ></ia-status-indicator>\n `;\n }\n\n private get emptyFilterResultsTemplate(): TemplateResult {\n return html`\n <div class=\"empty-results\">\n <p>${msg('No matching values found.')}</p>\n <p class=\"hint\">${msg('Try a different search term.')}</p>\n </div>\n `;\n }\n\n /**\n * Number of pages for pagination (only used when facet count >= PAGINATION_THRESHOLD).\n */\n private get paginationSize(): number {\n const filteredBuckets = this.filteredFacetGroup?.buckets ?? [];\n return Math.ceil(filteredBuckets.length / this.facetsPerPage);\n }\n\n /**\n * Template for pagination component.\n */\n private get facetsPaginationTemplate() {\n return html`<more-facets-pagination\n .size=${this.paginationSize}\n .currentPage=${this.pageNumber}\n .compact=${this.isCompactView}\n @pageNumberClicked=${this.pageNumberClicked}\n ></more-facets-pagination>`;\n }\n\n private get footerTemplate() {\n return html`\n ${when(this.usePagination, () => this.facetsPaginationTemplate)}\n <div class=\"footer\">\n <button class=\"btn btn-cancel\" type=\"button\" @click=${this.cancelClick}>\n Cancel\n </button>\n <button\n class=\"btn btn-submit\"\n type=\"button\"\n @click=${this.applySearchFacetsClicked}\n >\n Apply filters\n </button>\n </div>\n `;\n }\n\n private sortFacetAggregation(facetSortType: AggregationSortType) {\n this.sortedBy = facetSortType;\n this.dispatchEvent(\n new CustomEvent('sortedFacets', { detail: this.sortedBy }),\n );\n }\n\n /**\n * Handler for filter input changes. Updates the filter text and triggers re-render.\n */\n private handleFilterInput(e: Event): void {\n const input = e.target as HTMLElement & { value: string };\n this.filterText = input.value;\n }\n\n /**\n * Handler for when the filter input is cleared via the clear button.\n */\n private handleFilterClear(): void {\n this.filterText = '';\n }\n\n /**\n * Handler for pagination page number clicks.\n * Only used when facet count >= PAGINATION_THRESHOLD.\n */\n private pageNumberClicked(e: CustomEvent<{ page: number }>) {\n this.pageNumber = e.detail.page;\n\n // Track page navigation in analytics\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.moreFacetsPageChange,\n label: `${this.pageNumber}`,\n });\n\n this.dispatchEvent(\n new CustomEvent('pageChanged', {\n detail: this.pageNumber,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private get modalHeaderTemplate(): TemplateResult {\n const facetSort =\n this.sortedBy ?? defaultFacetSort[this.facetKey as FacetOption];\n const defaultSwitchSide =\n facetSort === AggregationSortType.COUNT ? 'left' : 'right';\n\n return html`<span class=\"sr-only\">${msg('More facets for:')}</span>\n <span class=\"title\"> ${this.facetGroup?.title} </span>\n <span class=\"header-controls\">\n <span class=\"sort-controls\">\n <label class=\"sort-label\">${msg('Sort by:')}</label>\n ${this.facetKey\n ? html`<toggle-switch\n class=\"sort-toggle\"\n leftValue=${AggregationSortType.COUNT}\n leftLabel=\"Count\"\n rightValue=${valueFacetSort[this.facetKey]}\n .rightLabel=${this.facetGroup?.title}\n side=${defaultSwitchSide}\n @change=${(e: CustomEvent<string>) => {\n this.sortFacetAggregation(\n Number(e.detail) as AggregationSortType,\n );\n }}\n ></toggle-switch>`\n : nothing}\n </span>\n\n <span class=\"filter-controls\">\n <label class=\"filter-label\">${msg('Filter by:')}</label>\n <ia-clearable-text-input\n class=\"filter-input\"\n .value=${this.filterText}\n .placeholder=${msg('Search...')}\n .screenReaderLabel=${msg('Filter facets')}\n .clearButtonScreenReaderLabel=${msg('Clear filter')}\n @input=${this.handleFilterInput}\n @clear=${this.handleFilterClear}\n ></ia-clearable-text-input>\n </span>\n </span>`;\n }\n\n private get horizontalScrollTemplate(): TemplateResult {\n const contentClasses = classMap({\n 'facets-content': true,\n 'horizontal-scroll-mode': true,\n });\n const showArrows = !this.atScrollStart || !this.atScrollEnd;\n\n return html`<div class=\"scroll-nav-container\">\n ${when(\n showArrows,\n () =>\n html`<button\n class=\"scroll-arrow scroll-left\"\n @click=${this.onScrollLeft}\n ?disabled=${this.atScrollStart}\n aria-label=\"Scroll facets left\"\n >\n ${arrowLeftIcon}\n </button>`,\n )}\n <div class=${contentClasses}>\n <div class=\"facets-horizontal-container\">\n ${this.moreFacetsTemplate}\n </div>\n </div>\n ${when(\n showArrows,\n () =>\n html`<button\n class=\"scroll-arrow scroll-right\"\n @click=${this.onScrollRight}\n ?disabled=${this.atScrollEnd}\n aria-label=\"Scroll facets right\"\n >\n ${arrowRightIcon}\n </button>`,\n )}\n </div>`;\n }\n\n render() {\n const sectionClasses = classMap({\n 'pagination-mode': this.usePagination,\n 'horizontal-scroll-mode': !this.usePagination,\n });\n const contentClasses = classMap({\n 'facets-content': true,\n 'pagination-mode': this.usePagination,\n });\n\n return html`\n ${this.facetsLoading\n ? this.loaderTemplate\n : html`\n <section id=\"more-facets\" class=${sectionClasses}>\n <div class=\"header-content\">${this.modalHeaderTemplate}</div>\n ${this.usePagination\n ? html`<div class=${contentClasses}>\n ${this.moreFacetsTemplate}\n </div>`\n : this.horizontalScrollTemplate}\n ${this.footerTemplate}\n </section>\n `}\n `;\n }\n\n private applySearchFacetsClicked() {\n const mergedSelections = mergeSelectedFacets(\n this.selectedFacets,\n this.unappliedFacetChanges,\n );\n\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: mergedSelections,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n\n // Reset the unapplied changes back to default, now that they have been applied\n this.unappliedFacetChanges = getDefaultSelectedFacets();\n\n // Reset filter text\n this.filterText = '';\n\n this.modalManager?.closeModal();\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: `${analyticsActions.applyMoreFacetsModal}`,\n label: `${this.facetKey}`,\n });\n }\n\n private cancelClick() {\n // Reset the unapplied changes back to default\n this.unappliedFacetChanges = getDefaultSelectedFacets();\n\n // Reset filter text\n this.filterText = '';\n\n this.modalManager?.closeModal();\n this.analyticsHandler?.sendEvent({\n category: analyticsCategories.default,\n action: analyticsActions.closeMoreFacetsModal,\n label: `${this.facetKey}`,\n });\n }\n\n static get styles(): CSSResultGroup {\n const modalSubmitButton = css`var(--primaryButtonBGColor, #194880)`;\n\n return [\n srOnlyStyle,\n css`\n section#more-facets {\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 16.5rem - var(--modalBottomMargin, 2.5rem));\n padding: 10px;\n box-sizing: border-box;\n --facetsColumnCount: 3;\n }\n\n /* Both modes need a height constraint for proper column flow */\n section#more-facets.horizontal-scroll-mode,\n section#more-facets.pagination-mode {\n --facetsMaxHeight: 280px;\n }\n .header-content {\n flex-shrink: 0;\n position: relative;\n z-index: 1;\n background: #fff;\n }\n\n .header-content .title {\n display: block;\n text-align: left;\n font-size: 1.8rem;\n padding: 0 10px;\n font-weight: bold;\n }\n\n .header-controls {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 20px;\n padding: 0 10px 8px;\n }\n\n .sort-controls {\n display: inline-flex;\n align-items: center;\n white-space: nowrap;\n gap: 5px;\n }\n\n .sort-label {\n font-size: 1.3rem;\n }\n\n .sort-toggle {\n font-weight: normal;\n }\n\n .filter-controls {\n display: inline-flex;\n align-items: center;\n white-space: nowrap;\n }\n\n .filter-label {\n font-size: 1.3rem;\n }\n\n .filter-input {\n --input-height: 2.5rem;\n --input-font-size: 1.3rem;\n --input-border-radius: 4px;\n --input-padding: 4px 8px;\n --input-focused-border-color: ${modalSubmitButton};\n width: 150px;\n margin-left: 5px;\n }\n\n .empty-results {\n text-align: center;\n padding: 40px 20px;\n color: #666;\n }\n\n .empty-results .hint {\n margin-top: 10px;\n }\n\n .facets-content {\n font-size: 1.2rem;\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 10px;\n /* Force scrollbar to always be visible */\n scrollbar-width: thin; /* Firefox */\n scrollbar-color: #888 #f1f1f1; /* Firefox - thumb and track colors */\n }\n\n /* Horizontal scroll mode: horizontal scrolling only */\n .facets-content.horizontal-scroll-mode {\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n /* Webkit browsers scrollbar styling - always visible */\n .facets-content::-webkit-scrollbar {\n width: 12px; /* Vertical scrollbar width */\n height: 12px; /* Horizontal scrollbar height */\n }\n\n .facets-content::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 6px;\n }\n\n .facets-content::-webkit-scrollbar-thumb {\n background: #888;\n border-radius: 6px;\n min-height: 30px; /* Ensure thumb is always visible when scrolling is possible */\n }\n\n .facets-content::-webkit-scrollbar-thumb:hover {\n background: #555;\n }\n\n /* Force corner to match track color */\n .facets-content::-webkit-scrollbar-corner {\n background: #f1f1f1;\n }\n\n .facets-horizontal-container {\n display: inline-block;\n min-width: 100%;\n /* Allow natural width expansion based on content */\n width: fit-content;\n }\n\n .scroll-nav-container {\n display: flex;\n align-items: center;\n flex: 1 1 auto;\n min-height: 0;\n }\n\n .scroll-nav-container .facets-content {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n .scroll-arrow {\n background: none;\n border: none;\n cursor: pointer;\n padding: 5px;\n flex-shrink: 0;\n }\n\n .scroll-arrow svg {\n height: 14px;\n fill: #2c2c2c;\n }\n\n .scroll-arrow:disabled {\n opacity: 0.3;\n cursor: default;\n }\n .facets-loader {\n --icon-width: 70px;\n margin-bottom: 20px;\n display: block;\n margin-left: auto;\n margin-right: auto;\n }\n .btn {\n border: none;\n padding: 10px;\n margin-bottom: 10px;\n width: auto;\n border-radius: 4px;\n cursor: pointer;\n font-family: inherit;\n }\n .btn-cancel {\n background-color: #2c2c2c;\n color: white;\n }\n .btn-submit {\n background-color: ${modalSubmitButton};\n color: white;\n }\n more-facets-pagination {\n flex-shrink: 0;\n }\n\n .footer {\n text-align: center;\n margin-top: 10px;\n flex-shrink: 0;\n }\n\n @media (max-width: 560px) {\n section#more-facets.horizontal-scroll-mode,\n section#more-facets.pagination-mode {\n --facetsColumnCount: 1; /* Single column on mobile */\n --facetsMaxHeight: none; /* Remove fixed height for vertical scrolling */\n }\n /* On mobile, always use vertical scrolling regardless of mode */\n .facets-content,\n .facets-content.horizontal-scroll-mode {\n overflow-y: auto;\n overflow-x: hidden;\n }\n .scroll-nav-container {\n display: contents; /* Remove wrapper from layout so section flex-column works */\n }\n .scroll-arrow {\n display: none;\n }\n .filter-input {\n width: 120px;\n --input-font-size: 1.2rem;\n }\n }\n `,\n ];\n }\n}\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "The Internet Archive Collection Browser.",
4
4
  "license": "AGPL-3.0-only",
5
5
  "author": "Internet Archive",
6
- "version": "4.2.0-alpha-webdev8164.2",
6
+ "version": "4.2.0-alpha-webdev8164.3",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "scripts": {
@@ -153,6 +153,14 @@ export class MoreFacetsContent extends LitElement {
153
153
  */
154
154
  @state() private isCompactView = false;
155
155
 
156
+ /** Column gap in px — matches the --facetsColumnGap default (never overridden). */
157
+ private static readonly COLUMN_GAP = 15;
158
+
159
+ /** Column count derived from the same breakpoint as the CSS media query. */
160
+ private get columnCount(): number {
161
+ return this.isCompactView ? 1 : 3;
162
+ }
163
+
156
164
  /**
157
165
  * Whether the horizontal scroll is at the leftmost position.
158
166
  */
@@ -296,18 +304,8 @@ export class MoreFacetsContent extends LitElement {
296
304
  private getColumnStep(): number {
297
305
  const el = this.facetsContentEl;
298
306
  if (!el) return 0;
299
-
300
- const facetRows = el.querySelector('.facet-rows') as HTMLElement;
301
- const styles = facetRows
302
- ? getComputedStyle(facetRows)
303
- : getComputedStyle(el);
304
-
305
- const columnCount = parseInt(styles.columnCount, 10) || 3;
306
- const columnGap = parseInt(styles.columnGap, 10) || 15;
307
-
308
- // Column width = (visible width - total gaps) / column count
309
307
  // Column step = column width + gap = (visible width + gap) / column count
310
- return (el.clientWidth + columnGap) / columnCount;
308
+ return (el.clientWidth + MoreFacetsContent.COLUMN_GAP) / this.columnCount;
311
309
  }
312
310
 
313
311
  /**