@internetarchive/collection-browser 4.3.2-rc-webdev-8334.3 → 4.4.0

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.
@@ -1,3 +1,4 @@
1
+ var CollectionBrowser_1;
1
2
  import { __decorate } from "tslib";
2
3
  import { html, css, LitElement, nothing, } from 'lit';
3
4
  import { customElement, property, query, state } from 'lit/decorators.js';
@@ -24,6 +25,7 @@ import './collection-facets';
24
25
  import './circular-activity-indicator';
25
26
  import './collection-facets/smart-facets/smart-facet-bar';
26
27
  let CollectionBrowser = class CollectionBrowser extends LitElement {
28
+ static { CollectionBrowser_1 = this; }
27
29
  constructor() {
28
30
  super();
29
31
  this.baseImageUrl = 'https://archive.org';
@@ -188,6 +190,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
188
190
  */
189
191
  this.dataSourceInstallInProgress = false;
190
192
  this.placeholderCellTemplate = html `<collection-browser-loading-tile></collection-browser-loading-tile>`;
193
+ this.deferredFetchTimer = 0;
191
194
  /**
192
195
  * Updates the height of the left column according to its position on the page.
193
196
  * Arrow function ensures proper `this` binding.
@@ -225,7 +228,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
225
228
  const model = this.dataSource.getTileModelAt(index);
226
229
  /**
227
230
  * If we encounter a model we don't have yet and we're not in the middle of an
228
- * automated scroll, fetch the page and just return undefined.
231
+ * automated scroll, schedule a fetch for the missing page and return undefined.
229
232
  * The datasource will be updated once the page is loaded and the cell will be rendered.
230
233
  *
231
234
  * We disable it during the automated scroll since we don't want to fetch pages for intervening cells the
@@ -233,10 +236,52 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
233
236
  */
234
237
  if (!model && !this.isScrollingToCell && this.dataSource.queryInitialized) {
235
238
  const pageNumber = Math.floor(index / this.pageSize) + 1;
236
- this.dataSource.fetchPage(pageNumber);
239
+ this.scheduleDeferredPageFetch(pageNumber);
237
240
  }
238
241
  return model;
239
242
  }
243
+ /**
244
+ * Debounce delay for page fetches initiated by new cells becoming visible.
245
+ * Tuned so quick scrolling through unloaded regions doesn't send rapid-fire
246
+ * search requests for every page we pass through, but to still feel responsive
247
+ * when the scroll ends.
248
+ */
249
+ static { this.DEFERRED_FETCH_DELAY_MS = 150; }
250
+ /**
251
+ * Schedules a fetch for the given page, debounced to ensure we don't
252
+ * rapid-fire fetches while scrolling through pages quickly.
253
+ *
254
+ * If there's no pending fetch timer yet, it will fire a fetch immediately.
255
+ * Otherwise, it will reset any existing timer. In either case, a deferred
256
+ * fetch for the visible pages is scheduled after a brief delay to account
257
+ * for whatever pages we land on after scrolling.
258
+ */
259
+ scheduleDeferredPageFetch(pageNumber) {
260
+ if (!this.deferredFetchTimer) {
261
+ this.dataSource.fetchPage(pageNumber);
262
+ }
263
+ else {
264
+ window.clearTimeout(this.deferredFetchTimer);
265
+ }
266
+ this.deferredFetchTimer = window.setTimeout(() => {
267
+ this.deferredFetchTimer = 0;
268
+ this.fetchVisiblePages();
269
+ }, CollectionBrowser_1.DEFERRED_FETCH_DELAY_MS);
270
+ }
271
+ /**
272
+ * Fetch each currently-visible page whose first cell still has no
273
+ * loaded model.
274
+ */
275
+ fetchVisiblePages() {
276
+ const visibleIndices = this.infiniteScroller?.getVisibleCellIndices() ?? [];
277
+ const visiblePages = new Set(visibleIndices.map(i => Math.floor(i / this.pageSize) + 1));
278
+ for (const page of visiblePages) {
279
+ const firstCellOfPage = (page - 1) * this.pageSize;
280
+ if (!this.dataSource.getTileModelAt(firstCellOfPage)) {
281
+ this.dataSource.fetchPage(page);
282
+ }
283
+ }
284
+ }
240
285
  // this is the total number of tiles we expect if
241
286
  // the data returned is a full page worth
242
287
  // this is useful for putting in placeholders for the expected number of tiles
@@ -406,32 +451,32 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
406
451
  }
407
452
  }
408
453
  render() {
409
- return html `
454
+ return html `
410
455
  ${this.showSmartFacetBar && this.placeholderType === null
411
- ? html `<smart-facet-bar
412
- .query=${this.baseQuery}
413
- .aggregations=${this.dataSource.aggregations}
414
- .selectedFacets=${this.selectedFacets}
415
- .collectionTitles=${this.dataSource.collectionTitles}
416
- .filterToggleShown=${!this.mobileView}
417
- .filterToggleActive=${this.facetPaneVisible}
418
- .label=${this.smartFacetBarLabel}
419
- @facetsChanged=${this.facetsChanged}
456
+ ? html `<smart-facet-bar
457
+ .query=${this.baseQuery}
458
+ .aggregations=${this.dataSource.aggregations}
459
+ .selectedFacets=${this.selectedFacets}
460
+ .collectionTitles=${this.dataSource.collectionTitles}
461
+ .filterToggleShown=${!this.mobileView}
462
+ .filterToggleActive=${this.facetPaneVisible}
463
+ .label=${this.smartFacetBarLabel}
464
+ @facetsChanged=${this.facetsChanged}
420
465
  @filtersToggled=${() => {
421
466
  this.facetPaneVisible = !this.facetPaneVisible;
422
467
  this.emitFacetPaneVisibilityChanged();
423
- }}
468
+ }}
424
469
  ></smart-facet-bar>`
425
- : nothing}
426
-
427
- <div
428
- id="content-container"
429
- class=${this.mobileView ? 'mobile' : 'desktop'}
430
- >
470
+ : nothing}
471
+
472
+ <div
473
+ id="content-container"
474
+ class=${this.mobileView ? 'mobile' : 'desktop'}
475
+ >
431
476
  ${this.placeholderType
432
477
  ? this.emptyPlaceholderTemplate
433
- : this.collectionBrowserTemplate}
434
- </div>
478
+ : this.collectionBrowserTemplate}
479
+ </div>
435
480
  `;
436
481
  }
437
482
  /**
@@ -475,23 +520,23 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
475
520
  * Template for the placeholder content to show when no results are available.
476
521
  */
477
522
  get emptyPlaceholderTemplate() {
478
- return html `
479
- <empty-placeholder
480
- .placeholderType=${this.placeholderType}
481
- ?isMobileView=${this.mobileView}
482
- ?isCollection=${!!this.withinCollection}
483
- .detailMessage=${this.dataSource.queryErrorMessage ?? ''}
484
- .baseNavigationUrl=${this.baseNavigationUrl}
485
- ></empty-placeholder>
523
+ return html `
524
+ <empty-placeholder
525
+ .placeholderType=${this.placeholderType}
526
+ ?isMobileView=${this.mobileView}
527
+ ?isCollection=${!!this.withinCollection}
528
+ .detailMessage=${this.dataSource.queryErrorMessage ?? ''}
529
+ .baseNavigationUrl=${this.baseNavigationUrl}
530
+ ></empty-placeholder>
486
531
  `;
487
532
  }
488
533
  /**
489
534
  * Top-level template for rendering the left (facets) and right (results) columns.
490
535
  */
491
536
  get collectionBrowserTemplate() {
492
- return html `
493
- <div id="left-column-scroll-sentinel"></div>
494
- ${this.leftColumnTemplate} ${this.rightColumnTemplate}
537
+ return html `
538
+ <div id="left-column-scroll-sentinel"></div>
539
+ ${this.leftColumnTemplate} ${this.rightColumnTemplate}
495
540
  `;
496
541
  }
497
542
  /**
@@ -510,33 +555,33 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
510
555
  * accordion-style facets.
511
556
  */
512
557
  get mobileLeftColumnTemplate() {
513
- return html `
514
- <div
515
- id="left-column"
516
- class="column${this.isResizeToMobile ? ' preload' : ''}"
517
- >
518
- ${this.facetTopViewSlot} ${this.resultsCountTemplate}
519
- <div id="facets-header-container">${this.mobileFacetsTemplate}</div>
520
- </div>
558
+ return html `
559
+ <div
560
+ id="left-column"
561
+ class="column${this.isResizeToMobile ? ' preload' : ''}"
562
+ >
563
+ ${this.facetTopViewSlot} ${this.resultsCountTemplate}
564
+ <div id="facets-header-container">${this.mobileFacetsTemplate}</div>
565
+ </div>
521
566
  `;
522
567
  }
523
568
  /**
524
569
  * Template for the desktop version of the left column, displaying the facets sidebar.
525
570
  */
526
571
  get desktopLeftColumnTemplate() {
527
- return html `
528
- <div id="left-column" class="column" ?hidden=${!this.facetPaneVisible}>
529
- ${this.facetTopViewSlot}
530
- <div id="facets-header-container">
531
- <h2 id="facets-header" class="sr-only">${msg('Filters')}</h2>
532
- ${this.resultsCountTemplate} ${this.clearFiltersBtnTemplate(false)}
533
- </div>
534
- <div id="facets-container" aria-labelledby="facets-header">
535
- ${this.facetsTemplate}
536
- <div id="facets-scroll-sentinel"></div>
537
- </div>
538
- <div id="facets-bottom-fade"></div>
539
- </div>
572
+ return html `
573
+ <div id="left-column" class="column" ?hidden=${!this.facetPaneVisible}>
574
+ ${this.facetTopViewSlot}
575
+ <div id="facets-header-container">
576
+ <h2 id="facets-header" class="sr-only">${msg('Filters')}</h2>
577
+ ${this.resultsCountTemplate} ${this.clearFiltersBtnTemplate(false)}
578
+ </div>
579
+ <div id="facets-container" aria-labelledby="facets-header">
580
+ ${this.facetsTemplate}
581
+ <div id="facets-scroll-sentinel"></div>
582
+ </div>
583
+ <div id="facets-bottom-fade"></div>
584
+ </div>
540
585
  `;
541
586
  }
542
587
  /**
@@ -544,8 +589,8 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
544
589
  * - mainly used to render userlists
545
590
  */
546
591
  get facetTopViewSlot() {
547
- return html `<div id="facet-top-view">
548
- <slot name="facet-top-slot"></slot>
592
+ return html `<div id="facet-top-view">
593
+ <slot name="facet-top-slot"></slot>
549
594
  </div>`;
550
595
  }
551
596
  /**
@@ -560,15 +605,15 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
560
605
  const resultsCount = this.totalResults?.toLocaleString();
561
606
  const resultsLabel = this.totalResults === 1 ? 'Result' : 'Results';
562
607
  // Added data-testid for Playwright testing
563
- return html `
564
- <div id="results-total" class=${classes} data-testid="results-total">
565
- <span id="big-results-count">
566
- ${shouldShowSearching ? html `Searching&hellip;` : resultsCount}
567
- </span>
568
- <span id="big-results-label">
569
- ${shouldShowSearching ? nothing : resultsLabel}
570
- </span>
571
- </div>
608
+ return html `
609
+ <div id="results-total" class=${classes} data-testid="results-total">
610
+ <span id="big-results-count">
611
+ ${shouldShowSearching ? html `Searching&hellip;` : resultsCount}
612
+ </span>
613
+ <span id="big-results-label">
614
+ ${shouldShowSearching ? nothing : resultsLabel}
615
+ </span>
616
+ </div>
572
617
  `;
573
618
  }
574
619
  /**
@@ -581,45 +626,47 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
581
626
  'full-width': !this.facetPaneVisible,
582
627
  'smart-results-spacing': !!this.showSmartResults,
583
628
  });
584
- return html `
585
- <div id="right-column" class=${rightColumnClasses}>
629
+ return html `
630
+ <div id="right-column" class=${rightColumnClasses}>
586
631
  ${this.showSmartResults
587
632
  ? html `<slot name="smart-results"></slot>`
588
- : nothing}
589
- <section id="results">
590
- <h2 class="results-section-heading">
591
- <slot name="results-heading"></slot>
592
- </h2>
593
- <div id="cb-top-view">
594
- <slot name="cb-top-slot"></slot>
595
- </div>
633
+ : nothing}
634
+ <section id="results">
635
+ <h2 class="results-section-heading">
636
+ <slot name="results-heading"></slot>
637
+ </h2>
638
+ <div id="cb-top-view">
639
+ <slot name="cb-top-slot"></slot>
640
+ </div>
596
641
  ${this.isManageView
597
642
  ? this.manageBarTemplate
598
- : this.sortFilterBarTemplate}
599
- <slot name="cb-results"></slot>
643
+ : this.sortFilterBarTemplate}
644
+ <slot name="cb-results"></slot>
600
645
  ${this.displayMode === `list-compact` && this.totalResults
601
646
  ? this.listHeaderTemplate
602
- : nothing}
603
- ${this.suppressResultTiles ? nothing : this.infiniteScrollerTemplate}
604
- </section>
605
- </div>
647
+ : nothing}
648
+ ${this.suppressResultTiles ? nothing : this.infiniteScrollerTemplate}
649
+ </section>
650
+ </div>
606
651
  `;
607
652
  }
608
653
  /**
609
654
  * Template for the infinite scroller widget that contains the result tiles.
610
655
  */
611
656
  get infiniteScrollerTemplate() {
612
- return html `<infinite-scroller
613
- class=${this.infiniteScrollerClasses}
614
- itemCount=${this.placeholderType ? 0 : nothing}
615
- ariaLandmarkLabel="Search results"
616
- .cellProvider=${this}
617
- .placeholderCellTemplate=${this.placeholderCellTemplate}
618
- @scrollThresholdReached=${this.scrollThresholdReached}
619
- @visibleCellsChanged=${this.visibleCellsChanged}
657
+ return html `<infinite-scroller
658
+ class=${this.infiniteScrollerClasses}
659
+ itemCount=${this.placeholderType ? 0 : nothing}
660
+ ariaLandmarkLabel="Search results"
661
+ .estimatedCellHeight=${this.estimatedTileHeight}
662
+ .minBufferMarginCells=${this.pageSize}
663
+ .cellProvider=${this}
664
+ .placeholderCellTemplate=${this.placeholderCellTemplate}
665
+ @scrollThresholdReached=${this.scrollThresholdReached}
666
+ @visibleCellsChanged=${this.visibleCellsChanged}
620
667
  >${this.displayMode === 'grid'
621
668
  ? html `<slot name="result-last-tile" slot="result-last-tile"></slot>`
622
- : nothing}
669
+ : nothing}
623
670
  </infinite-scroller>`;
624
671
  }
625
672
  /**
@@ -632,6 +679,24 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
632
679
  hidden: !!this.placeholderType,
633
680
  });
634
681
  }
682
+ /**
683
+ * Best-effort hint of how tall a single rendered tile is, by display mode.
684
+ * The scroller uses this to better estimate the size its initial scroll
685
+ * spacer and buffer position before real cell heights are measured.
686
+ * Should roughly match the placeholder heights since the initial render
687
+ * of a new page generally shows placeholders only anyway.
688
+ */
689
+ get estimatedTileHeight() {
690
+ switch (this.displayMode) {
691
+ case 'list-detail':
692
+ return 80;
693
+ case 'list-compact':
694
+ return 45;
695
+ case 'grid':
696
+ default:
697
+ return 225;
698
+ }
699
+ }
635
700
  /**
636
701
  * Template for the sort & filtering bar that appears atop the search results.
637
702
  */
@@ -653,29 +718,29 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
653
718
  }
654
719
  // We only show relevance sort if a search query is currently defined
655
720
  sortFieldAvailability.relevance = this.isRelevanceSortAvailable;
656
- return html `
657
- <sort-filter-bar
658
- .defaultSortField=${this.defaultSortField}
659
- .defaultSortDirection=${this.defaultSortDirection}
660
- .selectedSort=${this.selectedSort}
661
- .sortDirection=${this.sortDirection}
662
- .sortFieldAvailability=${sortFieldAvailability}
663
- .displayMode=${this.displayMode}
664
- .selectedTitleFilter=${this.selectedTitleFilter}
665
- .selectedCreatorFilter=${this.selectedCreatorFilter}
666
- .prefixFilterCountMap=${this.dataSource.prefixFilterCountMap}
667
- .enableSortOptionsSlot=${this.enableSortOptionsSlot}
668
- .suppressDisplayModes=${this.suppressDisplayModes}
669
- @sortChanged=${this.userChangedSort}
670
- @displayModeChanged=${this.displayModeChanged}
671
- @titleLetterChanged=${this.titleLetterSelected}
672
- @creatorLetterChanged=${this.creatorLetterSelected}
673
- >
674
- ${this.tileBlurCheckboxTemplate}
675
- <slot name="sort-options-left" slot="sort-options-left"></slot>
676
- <slot name="sort-options" slot="sort-options"></slot>
677
- <slot name="sort-options-right" slot="sort-options-right"></slot>
678
- </sort-filter-bar>
721
+ return html `
722
+ <sort-filter-bar
723
+ .defaultSortField=${this.defaultSortField}
724
+ .defaultSortDirection=${this.defaultSortDirection}
725
+ .selectedSort=${this.selectedSort}
726
+ .sortDirection=${this.sortDirection}
727
+ .sortFieldAvailability=${sortFieldAvailability}
728
+ .displayMode=${this.displayMode}
729
+ .selectedTitleFilter=${this.selectedTitleFilter}
730
+ .selectedCreatorFilter=${this.selectedCreatorFilter}
731
+ .prefixFilterCountMap=${this.dataSource.prefixFilterCountMap}
732
+ .enableSortOptionsSlot=${this.enableSortOptionsSlot}
733
+ .suppressDisplayModes=${this.suppressDisplayModes}
734
+ @sortChanged=${this.userChangedSort}
735
+ @displayModeChanged=${this.displayModeChanged}
736
+ @titleLetterChanged=${this.titleLetterSelected}
737
+ @creatorLetterChanged=${this.creatorLetterSelected}
738
+ >
739
+ ${this.tileBlurCheckboxTemplate}
740
+ <slot name="sort-options-left" slot="sort-options-left"></slot>
741
+ <slot name="sort-options" slot="sort-options"></slot>
742
+ <slot name="sort-options-right" slot="sort-options-right"></slot>
743
+ </sort-filter-bar>
679
744
  `;
680
745
  }
681
746
  /**
@@ -686,20 +751,20 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
686
751
  // Only show the checkbox for @archive.org users
687
752
  if (!this.dataSource.sessionContext?.is_archive_user)
688
753
  return nothing;
689
- return html `
690
- <label
691
- id="tile-blur-label"
692
- for="tile-blur-check"
693
- slot="sort-options-right"
694
- >
695
- ${msg('Blurring')}
696
- <input
697
- id="tile-blur-check"
698
- type="checkbox"
699
- ?checked=${!this.shouldSuppressTileBlurring}
700
- @change=${this.tileBlurCheckboxChanged}
701
- />
702
- </label>
754
+ return html `
755
+ <label
756
+ id="tile-blur-label"
757
+ for="tile-blur-check"
758
+ slot="sort-options-right"
759
+ >
760
+ ${msg('Blurring')}
761
+ <input
762
+ id="tile-blur-check"
763
+ type="checkbox"
764
+ ?checked=${!this.shouldSuppressTileBlurring}
765
+ @change=${this.tileBlurCheckboxChanged}
766
+ />
767
+ </label>
703
768
  `;
704
769
  }
705
770
  /**
@@ -707,27 +772,27 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
707
772
  * showing the management view. This generally replaces the sort bar when present.
708
773
  */
709
774
  get manageBarTemplate() {
710
- return html `
711
- <manage-bar
712
- .label=${this.manageViewLabel}
713
- .modalManager=${this.modalManager}
714
- .selectedItems=${this.dataSource.checkedTileModels}
715
- .profileElement=${this.profileElement}
716
- showSelectAll
717
- showUnselectAll
718
- ?showItemManageButton=${this.pageContext === 'search'}
719
- ?removeAllowed=${this.dataSource.checkedTileModels.length !== 0}
720
- @removeItems=${this.handleRemoveItems}
721
- @manageItems=${this.handleManageItems}
722
- @selectAll=${() => this.dataSource.checkAllTiles()}
723
- @unselectAll=${() => this.dataSource.uncheckAllTiles()}
775
+ return html `
776
+ <manage-bar
777
+ .label=${this.manageViewLabel}
778
+ .modalManager=${this.modalManager}
779
+ .selectedItems=${this.dataSource.checkedTileModels}
780
+ .profileElement=${this.profileElement}
781
+ showSelectAll
782
+ showUnselectAll
783
+ ?showItemManageButton=${this.pageContext === 'search'}
784
+ ?removeAllowed=${this.dataSource.checkedTileModels.length !== 0}
785
+ @removeItems=${this.handleRemoveItems}
786
+ @manageItems=${this.handleManageItems}
787
+ @selectAll=${() => this.dataSource.checkAllTiles()}
788
+ @unselectAll=${() => this.dataSource.uncheckAllTiles()}
724
789
  @cancel=${() => {
725
790
  this.isManageView = false;
726
791
  this.dataSource.uncheckAllTiles();
727
792
  if (this.searchResultsLoading)
728
793
  this.dataSource.resetPages();
729
- }}
730
- ></manage-bar>
794
+ }}
795
+ ></manage-bar>
731
796
  `;
732
797
  }
733
798
  /**
@@ -815,7 +880,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
815
880
  if ((this.currentPage ?? 1) > 1) {
816
881
  this.goToPage(1);
817
882
  }
818
- this.currentPage = 1;
883
+ this.setCurrentPage(1);
819
884
  }
820
885
  /**
821
886
  * Fires an analytics event for sorting changes.
@@ -962,15 +1027,15 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
962
1027
  label: target.open ? 'open' : 'closed',
963
1028
  });
964
1029
  };
965
- return html `
966
- <details id="mobile-filter-collapse" @toggle=${toggleFacetsVisible}>
967
- <summary>
968
- <span class="collapser-icon">${chevronIcon}</span>
969
- <h2>${msg('Filters')}</h2>
970
- ${this.clearFiltersBtnTemplate(true)}
971
- </summary>
972
- ${this.facetsTemplate}
973
- </details>
1030
+ return html `
1031
+ <details id="mobile-filter-collapse" @toggle=${toggleFacetsVisible}>
1032
+ <summary>
1033
+ <span class="collapser-icon">${chevronIcon}</span>
1034
+ <h2>${msg('Filters')}</h2>
1035
+ ${this.clearFiltersBtnTemplate(true)}
1036
+ </summary>
1037
+ ${this.facetsTemplate}
1038
+ </details>
974
1039
  `;
975
1040
  }
976
1041
  /**
@@ -1054,50 +1119,50 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1054
1119
  const filterByNetworkLabel = msg('Filter by Network');
1055
1120
  const filterByShowLabel = msg('Filter by Show');
1056
1121
  const shows = showEntries.map(([show]) => show);
1057
- const loadingIndicator = html `
1058
- <span slot="empty-options">
1059
- <img src="https://archive.org/images/loading.gif" />
1060
- </span>
1122
+ const loadingIndicator = html `
1123
+ <span slot="empty-options">
1124
+ <img src="https://archive.org/images/loading.gif" />
1125
+ </span>
1061
1126
  `;
1062
- const errorMessage = html `
1063
- <span slot="empty-options">
1064
- ${msg('Unable to fetch options, try again later')}
1065
- </span>
1127
+ const errorMessage = html `
1128
+ <span slot="empty-options">
1129
+ ${msg('Unable to fetch options, try again later')}
1130
+ </span>
1066
1131
  `;
1067
- return html `
1068
- <div id="tv-filters" slot="facets-top">
1069
- <ia-combo-box
1070
- id="tv-networks"
1071
- class="tv-filter-dropdown"
1072
- placeholder=${filterByNetworkLabel}
1073
- clearable
1074
- wrap-arrow-keys
1075
- sort
1076
- .options=${networks.map((n, i) => ({ id: `network-${i}`, text: n }))}
1077
- @toggle=${this.tvDropdownToggled}
1078
- @change=${this.networksDropdownChanged}
1079
- >
1080
- <span slot="label" class="sr-only">${filterByNetworkLabel}</span>
1081
- ${this.tvMapsLoading ? loadingIndicator : nothing}
1082
- ${this.tvMapsErrored ? errorMessage : nothing}
1083
- </ia-combo-box>
1084
- <ia-combo-box
1085
- id="tv-shows"
1086
- class="tv-filter-dropdown"
1087
- placeholder=${filterByShowLabel}
1088
- max-autocomplete-entries="500"
1089
- clearable
1090
- wrap-arrow-keys
1091
- sort
1092
- .options=${shows.map((s, i) => ({ id: `show-${i}`, text: s }))}
1093
- @toggle=${this.tvDropdownToggled}
1094
- @change=${this.showsDropdownChanged}
1095
- >
1096
- <span slot="label" class="sr-only">${filterByShowLabel}</span>
1097
- ${this.tvMapsLoading ? loadingIndicator : nothing}
1098
- ${this.tvMapsErrored ? errorMessage : nothing}
1099
- </ia-combo-box>
1100
- </div>
1132
+ return html `
1133
+ <div id="tv-filters" slot="facets-top">
1134
+ <ia-combo-box
1135
+ id="tv-networks"
1136
+ class="tv-filter-dropdown"
1137
+ placeholder=${filterByNetworkLabel}
1138
+ clearable
1139
+ wrap-arrow-keys
1140
+ sort
1141
+ .options=${networks.map((n, i) => ({ id: `network-${i}`, text: n }))}
1142
+ @toggle=${this.tvDropdownToggled}
1143
+ @change=${this.networksDropdownChanged}
1144
+ >
1145
+ <span slot="label" class="sr-only">${filterByNetworkLabel}</span>
1146
+ ${this.tvMapsLoading ? loadingIndicator : nothing}
1147
+ ${this.tvMapsErrored ? errorMessage : nothing}
1148
+ </ia-combo-box>
1149
+ <ia-combo-box
1150
+ id="tv-shows"
1151
+ class="tv-filter-dropdown"
1152
+ placeholder=${filterByShowLabel}
1153
+ max-autocomplete-entries="500"
1154
+ clearable
1155
+ wrap-arrow-keys
1156
+ sort
1157
+ .options=${shows.map((s, i) => ({ id: `show-${i}`, text: s }))}
1158
+ @toggle=${this.tvDropdownToggled}
1159
+ @change=${this.showsDropdownChanged}
1160
+ >
1161
+ <span slot="label" class="sr-only">${filterByShowLabel}</span>
1162
+ ${this.tvMapsLoading ? loadingIndicator : nothing}
1163
+ ${this.tvMapsErrored ? errorMessage : nothing}
1164
+ </ia-combo-box>
1165
+ </div>
1101
1166
  `;
1102
1167
  }
1103
1168
  /**
@@ -1107,10 +1172,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1107
1172
  if (FACETLESS_PAGE_ELEMENTS.includes(this.profileElement))
1108
1173
  return nothing;
1109
1174
  if (this.facetLoadStrategy === 'off') {
1110
- return html `
1111
- <p class="facets-message">
1112
- ${msg('Facets are temporarily unavailable.')}
1113
- </p>
1175
+ return html `
1176
+ <p class="facets-message">
1177
+ ${msg('Facets are temporarily unavailable.')}
1178
+ </p>
1114
1179
  `;
1115
1180
  }
1116
1181
  // We switch to TV facet ordering & date picker if we are in a TV collection or showing TV search results
@@ -1119,46 +1184,46 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1119
1184
  const facetDisplayOrder = shouldUseTvInterface
1120
1185
  ? tvFacetDisplayOrder
1121
1186
  : defaultFacetDisplayOrder;
1122
- const facets = html `
1123
- <collection-facets
1124
- .collectionPagePath=${this.collectionPagePath}
1125
- .parentCollections=${this.dataSource.parentCollections}
1126
- .pageSpecifierParams=${this.dataSource.pageSpecifierParams}
1127
- .searchService=${this.searchService}
1128
- .featureFeedbackService=${this.featureFeedbackService}
1129
- .recaptchaManager=${this.recaptchaManager}
1130
- .resizeObserver=${this.resizeObserver}
1131
- .searchType=${this.searchType}
1132
- .aggregations=${this.dataSource.aggregations}
1133
- .histogramAggregation=${this.dataSource.histogramAggregation}
1134
- .minSelectedDate=${this.minSelectedDate}
1135
- .maxSelectedDate=${this.maxSelectedDate}
1136
- .selectedFacets=${this.selectedFacets}
1137
- .baseNavigationUrl=${this.baseNavigationUrl}
1138
- .collectionTitles=${this.dataSource.collectionTitles}
1139
- .tvChannelAliases=${this.dataSource.tvChannelAliases}
1140
- .showHistogramDatePicker=${this.showHistogramDatePicker}
1141
- .allowExpandingDatePicker=${!this.mobileView}
1142
- .allowDatePickerMonths=${shouldUseTvInterface}
1143
- .contentWidth=${this.contentWidth}
1144
- .query=${this.baseQuery}
1145
- .identifiers=${this.identifiers}
1146
- .filterMap=${this.dataSource.filterMap}
1147
- .isManageView=${this.isManageView}
1148
- .modalManager=${this.modalManager}
1149
- .analyticsHandler=${this.analyticsHandler}
1150
- .facetDisplayOrder=${facetDisplayOrder}
1151
- .isTvSearch=${shouldUseTvInterface}
1152
- ?collapsableFacets=${this.mobileView}
1153
- ?facetsLoading=${this.facetsLoading}
1154
- ?histogramAggregationLoading=${this.facetsLoading}
1155
- ?suppressMediatypeFacets=${this.suppressMediatypeFacets}
1156
- @facetClick=${this.facetClickHandler}
1157
- @facetsChanged=${this.facetsChanged}
1158
- @histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
1159
- >
1160
- ${this.tvDropdownFiltersTemplate}
1161
- </collection-facets>
1187
+ const facets = html `
1188
+ <collection-facets
1189
+ .collectionPagePath=${this.collectionPagePath}
1190
+ .parentCollections=${this.dataSource.parentCollections}
1191
+ .pageSpecifierParams=${this.dataSource.pageSpecifierParams}
1192
+ .searchService=${this.searchService}
1193
+ .featureFeedbackService=${this.featureFeedbackService}
1194
+ .recaptchaManager=${this.recaptchaManager}
1195
+ .resizeObserver=${this.resizeObserver}
1196
+ .searchType=${this.searchType}
1197
+ .aggregations=${this.dataSource.aggregations}
1198
+ .histogramAggregation=${this.dataSource.histogramAggregation}
1199
+ .minSelectedDate=${this.minSelectedDate}
1200
+ .maxSelectedDate=${this.maxSelectedDate}
1201
+ .selectedFacets=${this.selectedFacets}
1202
+ .baseNavigationUrl=${this.baseNavigationUrl}
1203
+ .collectionTitles=${this.dataSource.collectionTitles}
1204
+ .tvChannelAliases=${this.dataSource.tvChannelAliases}
1205
+ .showHistogramDatePicker=${this.showHistogramDatePicker}
1206
+ .allowExpandingDatePicker=${!this.mobileView}
1207
+ .allowDatePickerMonths=${shouldUseTvInterface}
1208
+ .contentWidth=${this.contentWidth}
1209
+ .query=${this.baseQuery}
1210
+ .identifiers=${this.identifiers}
1211
+ .filterMap=${this.dataSource.filterMap}
1212
+ .isManageView=${this.isManageView}
1213
+ .modalManager=${this.modalManager}
1214
+ .analyticsHandler=${this.analyticsHandler}
1215
+ .facetDisplayOrder=${facetDisplayOrder}
1216
+ .isTvSearch=${shouldUseTvInterface}
1217
+ ?collapsableFacets=${this.mobileView}
1218
+ ?facetsLoading=${this.facetsLoading}
1219
+ ?histogramAggregationLoading=${this.facetsLoading}
1220
+ ?suppressMediatypeFacets=${this.suppressMediatypeFacets}
1221
+ @facetClick=${this.facetClickHandler}
1222
+ @facetsChanged=${this.facetsChanged}
1223
+ @histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
1224
+ >
1225
+ ${this.tvDropdownFiltersTemplate}
1226
+ </collection-facets>
1162
1227
  `;
1163
1228
  // If we are using one of the opt-in facet load strategies, we may need to wrap the
1164
1229
  // desktop view facets in a <details> widget so that patrons can opt into loading them.
@@ -1166,20 +1231,20 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1166
1231
  const showDesktopOptInWidget = this.facetLoadStrategy === 'opt-in' ||
1167
1232
  (this.facetLoadStrategy === 'opt-in-or-login' && !this.loggedIn);
1168
1233
  if (showDesktopOptInWidget && !this.mobileView) {
1169
- return html `
1170
- <details
1171
- class="desktop-facets-dropdown"
1234
+ return html `
1235
+ <details
1236
+ class="desktop-facets-dropdown"
1172
1237
  @toggle=${(e) => {
1173
1238
  const target = e.target;
1174
1239
  this.collapsibleFacetsVisible = target.open;
1175
- }}
1176
- >
1177
- <summary>
1178
- <span class="collapser-icon">${chevronIcon}</span>
1179
- <h2>${msg('Filters')}</h2>
1180
- </summary>
1181
- ${facets}
1182
- </details>
1240
+ }}
1241
+ >
1242
+ <summary>
1243
+ <span class="collapser-icon">${chevronIcon}</span>
1244
+ <h2>${msg('Filters')}</h2>
1245
+ </summary>
1246
+ ${facets}
1247
+ </details>
1183
1248
  `;
1184
1249
  }
1185
1250
  // Otherwise, just render the facets component bare
@@ -1199,34 +1264,34 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1199
1264
  mobile,
1200
1265
  });
1201
1266
  const buttonText = mobile ? 'Clear all' : 'Clear all filters';
1202
- return html `
1203
- <div class="clear-filters-btn-row">
1267
+ return html `
1268
+ <div class="clear-filters-btn-row">
1204
1269
  ${mobile
1205
1270
  ? html `<span class="clear-filters-btn-separator">&nbsp;</span>`
1206
- : nothing}
1207
- <button class=${buttonClasses} @click=${this.clearFilters}>
1208
- ${buttonText}
1209
- </button>
1210
- </div>
1271
+ : nothing}
1272
+ <button class=${buttonClasses} @click=${this.clearFilters}>
1273
+ ${buttonText}
1274
+ </button>
1275
+ </div>
1211
1276
  `;
1212
1277
  }
1213
1278
  /**
1214
1279
  * Template for the table header content that appears atop the compact list view.
1215
1280
  */
1216
1281
  get listHeaderTemplate() {
1217
- return html `
1218
- <div id="list-header">
1219
- <tile-dispatcher
1220
- .tileDisplayMode=${'list-header'}
1221
- .resizeObserver=${this.resizeObserver}
1222
- .sortParam=${this.sortParam}
1223
- .defaultSortParam=${this.defaultSortParam}
1224
- .mobileBreakpoint=${this.mobileBreakpoint}
1225
- .loggedIn=${this.loggedIn}
1226
- .suppressBlurring=${this.shouldSuppressTileBlurring}
1227
- >
1228
- </tile-dispatcher>
1229
- </div>
1282
+ return html `
1283
+ <div id="list-header">
1284
+ <tile-dispatcher
1285
+ .tileDisplayMode=${'list-header'}
1286
+ .resizeObserver=${this.resizeObserver}
1287
+ .sortParam=${this.sortParam}
1288
+ .defaultSortParam=${this.defaultSortParam}
1289
+ .mobileBreakpoint=${this.mobileBreakpoint}
1290
+ .loggedIn=${this.loggedIn}
1291
+ .suppressBlurring=${this.shouldSuppressTileBlurring}
1292
+ >
1293
+ </tile-dispatcher>
1294
+ </div>
1230
1295
  `;
1231
1296
  }
1232
1297
  /**
@@ -1457,6 +1522,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1457
1522
  if (this.boundNavigationHandler) {
1458
1523
  window.removeEventListener('popstate', this.boundNavigationHandler);
1459
1524
  }
1525
+ if (this.deferredFetchTimer) {
1526
+ window.clearTimeout(this.deferredFetchTimer);
1527
+ this.deferredFetchTimer = 0;
1528
+ }
1460
1529
  this.leftColIntersectionObserver?.disconnect();
1461
1530
  this.facetsIntersectionObserver?.disconnect();
1462
1531
  window.removeEventListener('resize', this.updateLeftColumnHeight);
@@ -1628,26 +1697,39 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1628
1697
  * @returns
1629
1698
  */
1630
1699
  visibleCellsChanged(e) {
1700
+ this.updateVisiblePage(e.detail.visibleCellIndices);
1701
+ }
1702
+ /**
1703
+ * Recomputes the current page from the given set of visible cell indices
1704
+ * and emits `visiblePageChanged` if the page actually changed.
1705
+ */
1706
+ updateVisiblePage(visibleCellIndices) {
1631
1707
  if (this.isScrollingToCell)
1632
1708
  return;
1633
- const { visibleCellIndices } = e.detail;
1634
1709
  if (visibleCellIndices.length === 0)
1635
1710
  return;
1711
+ // The indices aren't necessarily sorted, so sort them here to ensure our
1712
+ // calculations below find the right cell/page.
1713
+ const sorted = [...visibleCellIndices].sort((a, b) => a - b);
1636
1714
  // For page determination, do not count more than a single page of visible cells,
1637
1715
  // since otherwise patrons using very tall screens will be treated as one page
1638
1716
  // further than they actually are.
1639
- const lastIndexWithinCurrentPage = Math.min(this.pageSize, visibleCellIndices.length) - 1;
1640
- const lastVisibleCellIndex = visibleCellIndices[lastIndexWithinCurrentPage];
1717
+ const lastIndexWithinCurrentPage = Math.min(this.pageSize, sorted.length) - 1;
1718
+ const lastVisibleCellIndex = sorted[lastIndexWithinCurrentPage];
1641
1719
  const lastVisibleCellPage = Math.floor(lastVisibleCellIndex / this.pageSize) + 1;
1642
- if (this.currentPage !== lastVisibleCellPage) {
1643
- this.currentPage = lastVisibleCellPage;
1644
- }
1645
- const event = new CustomEvent('visiblePageChanged', {
1646
- detail: {
1647
- pageNumber: lastVisibleCellPage,
1648
- },
1649
- });
1650
- this.dispatchEvent(event);
1720
+ this.setCurrentPage(lastVisibleCellPage);
1721
+ }
1722
+ /**
1723
+ * Sets the current page number and emits a `visiblePageChanged`
1724
+ * event if the new page differs from the previous one.
1725
+ */
1726
+ setCurrentPage(pageNumber) {
1727
+ if (this.currentPage === pageNumber)
1728
+ return;
1729
+ this.currentPage = pageNumber;
1730
+ this.dispatchEvent(new CustomEvent('visiblePageChanged', {
1731
+ detail: { pageNumber },
1732
+ }));
1651
1733
  }
1652
1734
  /**
1653
1735
  * A Promise which, after each query change, resolves once the fetches for the initial
@@ -1723,10 +1805,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1723
1805
  this.selectedFacets = restorationState.selectedFacets;
1724
1806
  if (!this.suppressURLQuery)
1725
1807
  this.baseQuery = restorationState.baseQuery;
1726
- this.currentPage = restorationState.currentPage ?? 1;
1808
+ this.setCurrentPage(restorationState.currentPage ?? 1);
1727
1809
  this.minSelectedDate = restorationState.minSelectedDate;
1728
1810
  this.maxSelectedDate = restorationState.maxSelectedDate;
1729
- if (this.currentPage > 1) {
1811
+ if (this.currentPage && this.currentPage > 1) {
1730
1812
  this.goToPage(this.currentPage);
1731
1813
  }
1732
1814
  }
@@ -1794,25 +1876,36 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1794
1876
  label: facetType,
1795
1877
  });
1796
1878
  }
1797
- scrollToPage(pageNumber) {
1798
- return new Promise(resolve => {
1799
- const cellIndexToScrollTo = this.pageSize * (pageNumber - 1);
1800
- // without this setTimeout, Safari just pauses until the `fetchPage` is complete
1801
- // then scrolls to the cell
1802
- setTimeout(() => {
1803
- this.isScrollingToCell = true;
1804
- this.infiniteScroller?.scrollToCell(cellIndexToScrollTo, true);
1805
- // This timeout is to give the scroll animation time to finish
1806
- // then updating the infinite scroller once we're done scrolling
1807
- // There's no scroll animation completion callback so we're
1808
- // giving it 0.5s to finish.
1809
- setTimeout(() => {
1810
- this.isScrollingToCell = false;
1811
- this.infiniteScroller?.refreshAllVisibleCells();
1812
- resolve();
1813
- }, 500);
1814
- }, 0);
1879
+ async scrollToPage(pageNumber) {
1880
+ const cellIndexToScrollTo = this.pageSize * (pageNumber - 1);
1881
+ // Wait for the infinite scroller be rendered before proceeding
1882
+ let waitAttempts = 0;
1883
+ while (!this.infiniteScroller && waitAttempts < 20) {
1884
+ await this.updateComplete;
1885
+ waitAttempts++;
1886
+ }
1887
+ if (!this.infiniteScroller)
1888
+ return;
1889
+ // The scroller have its default `itemCount=0`, so propagate our estimated
1890
+ // tile count before jumping to the desired page.
1891
+ if (this.infiniteScroller.itemCount < this.estimatedTileCount) {
1892
+ this.infiniteScroller.itemCount = this.estimatedTileCount;
1893
+ await this.updateComplete;
1894
+ }
1895
+ // Without this setTimeout(0), Safari just pauses until the `fetchPage`
1896
+ // is complete then scrolls to the cell.
1897
+ await new Promise(resolve => {
1898
+ setTimeout(resolve, 0);
1815
1899
  });
1900
+ this.isScrollingToCell = true;
1901
+ const scrolled = await this.infiniteScroller.scrollToCell(cellIndexToScrollTo, true);
1902
+ this.isScrollingToCell = false;
1903
+ this.infiniteScroller.refreshAllVisibleCells();
1904
+ // After we finish scrolling, recompute the visible page from the new state
1905
+ // so that it doesn't fall out of sync.
1906
+ if (scrolled) {
1907
+ this.updateVisiblePage(this.infiniteScroller.getVisibleCellIndices());
1908
+ }
1816
1909
  }
1817
1910
  /**
1818
1911
  * Whether sorting by relevance makes sense for the current state.
@@ -1956,28 +2049,28 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
1956
2049
  const isRadioSearch = this.searchType === SearchType.RADIO;
1957
2050
  const { isTVCollection, isRadioCollection } = this;
1958
2051
  const shouldUseLocalTime = isTVSearch || isRadioSearch || isTVCollection || isRadioCollection;
1959
- return html `
1960
- <tile-dispatcher
1961
- .collectionPagePath=${this.collectionPagePath}
1962
- .baseNavigationUrl=${this.baseNavigationUrl}
1963
- .baseImageUrl=${this.baseImageUrl}
1964
- .model=${model}
1965
- .tileDisplayMode=${this.displayMode}
1966
- .resizeObserver=${this.resizeObserver}
1967
- .collectionTitles=${this.dataSource.collectionTitles}
1968
- .sortParam=${this.sortParam}
1969
- .defaultSortParam=${this.defaultSortParam}
1970
- .creatorFilter=${this.selectedCreatorFilter}
1971
- .mobileBreakpoint=${this.mobileBreakpoint}
1972
- .loggedIn=${this.loggedIn}
1973
- .suppressBlurring=${this.shouldSuppressTileBlurring}
1974
- .isManageView=${this.isManageView}
1975
- ?showTvClips=${isTVSearch || isTVCollection}
1976
- ?enableHoverPane=${true}
1977
- ?useLocalTime=${shouldUseLocalTime}
1978
- @resultSelected=${(e) => this.resultSelected(e)}
1979
- >
1980
- </tile-dispatcher>
2052
+ return html `
2053
+ <tile-dispatcher
2054
+ .collectionPagePath=${this.collectionPagePath}
2055
+ .baseNavigationUrl=${this.baseNavigationUrl}
2056
+ .baseImageUrl=${this.baseImageUrl}
2057
+ .model=${model}
2058
+ .tileDisplayMode=${this.displayMode}
2059
+ .resizeObserver=${this.resizeObserver}
2060
+ .collectionTitles=${this.dataSource.collectionTitles}
2061
+ .sortParam=${this.sortParam}
2062
+ .defaultSortParam=${this.defaultSortParam}
2063
+ .creatorFilter=${this.selectedCreatorFilter}
2064
+ .mobileBreakpoint=${this.mobileBreakpoint}
2065
+ .loggedIn=${this.loggedIn}
2066
+ .suppressBlurring=${this.shouldSuppressTileBlurring}
2067
+ .isManageView=${this.isManageView}
2068
+ ?showTvClips=${isTVSearch || isTVCollection}
2069
+ ?enableHoverPane=${true}
2070
+ ?useLocalTime=${shouldUseLocalTime}
2071
+ @resultSelected=${(e) => this.resultSelected(e)}
2072
+ >
2073
+ </tile-dispatcher>
1981
2074
  `;
1982
2075
  }
1983
2076
  /**
@@ -2012,479 +2105,479 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
2012
2105
  static get styles() {
2013
2106
  return [
2014
2107
  srOnlyStyle,
2015
- css `
2016
- :host {
2017
- display: block;
2018
- --leftColumnWidth: 18rem;
2019
- --leftColumnPaddingTop: 2rem;
2020
- --leftColumnPaddingRight: 2.5rem;
2021
- }
2022
-
2023
- #facet-top-view {
2024
- display: flex;
2025
- }
2026
-
2027
- /**
2028
- * When page width resizes from desktop to mobile, use this class to
2029
- * disable expand/collapse transition when loading.
2030
- */
2031
- .preload * {
2032
- transition: none !important;
2033
- -webkit-transition: none !important;
2034
- -moz-transition: none !important;
2035
- -ms-transition: none !important;
2036
- -o-transition: none !important;
2037
- }
2038
-
2039
- #content-container {
2040
- display: flex;
2041
- }
2042
-
2043
- empty-placeholder {
2044
- margin-top: var(--placeholderMarginTop, 0);
2045
- }
2046
-
2047
- .collapser-icon {
2048
- display: inline-block;
2049
- }
2050
-
2051
- .collapser-icon svg {
2052
- display: inline-block;
2053
- width: 12px;
2054
- height: 12px;
2055
- transition: transform 0.2s ease-out;
2056
- }
2057
-
2058
- #mobile-filter-collapse {
2059
- width: 100%;
2060
- }
2061
-
2062
- #mobile-filter-collapse > summary {
2063
- cursor: pointer;
2064
- list-style: none;
2065
- }
2066
-
2067
- #mobile-filter-collapse[open] > summary {
2068
- margin-bottom: 10px;
2069
- }
2070
-
2071
- #mobile-filter-collapse h2 {
2072
- display: inline-block;
2073
- margin: 0;
2074
- font-size: 2rem;
2075
- }
2076
-
2077
- #mobile-filter-collapse[open] svg {
2078
- transform: rotate(90deg);
2079
- }
2080
-
2081
- #content-container.mobile {
2082
- display: block;
2083
- }
2084
-
2085
- #right-column {
2086
- flex: 1;
2087
- position: relative;
2088
- min-height: 90vh;
2089
- border-right: 1px solid rgb(232, 232, 232);
2090
- margin-top: var(--rightColumnMarginTop, 0);
2091
- padding-top: var(--rightColumnPaddingTop, 2rem);
2092
- background: #fff;
2093
- }
2094
-
2095
- #left-column:not([hidden]) + #right-column {
2096
- border-left: 1px solid rgb(232, 232, 232);
2097
- }
2098
-
2099
- #right-column.smart-results-spacing {
2100
- padding-top: 0.5rem;
2101
- border-right: none;
2102
- background: transparent;
2103
- min-width: 0;
2104
- }
2105
-
2106
- #results {
2107
- background: #fff;
2108
- padding-left: 1rem;
2109
- padding-right: 1rem;
2110
- }
2111
-
2112
- #right-column.smart-results-spacing #results {
2113
- border-radius: 10px 10px 0px 0px;
2114
- padding-top: 0.5rem;
2115
- margin-top: 1rem;
2116
- }
2117
-
2118
- .mobile #right-column {
2119
- border-left: none;
2120
- }
2121
-
2122
- .mobile #results {
2123
- padding: 5px 5px 0;
2124
- }
2125
-
2126
- #left-column {
2127
- width: var(--leftColumnWidth, 18rem);
2128
- /* Prevents Safari from shrinking col at first draw */
2129
- min-width: var(--leftColumnWidth, 18rem);
2130
- padding-top: var(--leftColumnPaddingTop, 2rem);
2131
- /* Reduced padding by 0.2rem to add the invisible border in the rule below */
2132
- padding-right: calc(var(--leftColumnPaddingRight, 2.5rem) - 0.2rem);
2133
- border-right: 0.2rem solid transparent; /* Pads to the right of the scrollbar a bit */
2134
- z-index: 1;
2135
- }
2136
-
2137
- .desktop #left-column {
2138
- top: 0;
2139
- position: sticky;
2140
- height: calc(100vh - 2rem);
2141
- max-height: calc(100vh - 2rem);
2142
- overflow-x: hidden;
2143
- overflow-y: scroll;
2144
-
2145
- /*
2146
- * Firefox doesn't support any of the -webkit-scrollbar stuff below, but
2147
- * does at least give us a tiny bit of control over width & color.
2148
- */
2149
- scrollbar-width: thin;
2150
- scrollbar-color: transparent transparent;
2151
- }
2152
- .desktop #left-column:hover {
2153
- scrollbar-color: auto;
2154
- }
2155
- .desktop #left-column::-webkit-scrollbar {
2156
- appearance: none;
2157
- width: 6px;
2158
- }
2159
- .desktop #left-column::-webkit-scrollbar-button {
2160
- height: 3px;
2161
- background: transparent;
2162
- }
2163
- .desktop #left-column::-webkit-scrollbar-corner {
2164
- background: transparent;
2165
- }
2166
- .desktop #left-column::-webkit-scrollbar-thumb {
2167
- border-radius: 4px;
2168
- }
2169
- .desktop #left-column:hover::-webkit-scrollbar-thumb {
2170
- background: rgba(0, 0, 0, 0.15);
2171
- }
2172
- .desktop #left-column:hover::-webkit-scrollbar-thumb:hover {
2173
- background: rgba(0, 0, 0, 0.2);
2174
- }
2175
- .desktop #left-column:hover::-webkit-scrollbar-thumb:active {
2176
- background: rgba(0, 0, 0, 0.3);
2177
- }
2178
-
2179
- #facets-bottom-fade {
2180
- background: linear-gradient(
2181
- to bottom,
2182
- #fbfbfd00 0%,
2183
- #fbfbfdc0 50%,
2184
- #fbfbfd 80%,
2185
- #fbfbfd 100%
2186
- );
2187
- position: fixed;
2188
- bottom: 0;
2189
- height: 50px;
2190
- /* Wide enough to cover the content, but leave the scrollbar uncovered */
2191
- width: calc(
2192
- var(--leftColumnWidth) + var(--leftColumnPaddingRight) - 10px
2193
- );
2194
- z-index: 2;
2195
- pointer-events: none;
2196
- transition: height 0.1s ease;
2197
- }
2198
- #facets-bottom-fade.hidden {
2199
- height: 0;
2200
- }
2201
-
2202
- .facets-message {
2203
- font-size: 1.4rem;
2204
- }
2205
-
2206
- .desktop-facets-dropdown > summary {
2207
- cursor: pointer;
2208
- list-style: none;
2209
- }
2210
-
2211
- .desktop-facets-dropdown h2 {
2212
- display: inline-block;
2213
- margin: 0;
2214
- font-size: 1.6rem;
2215
- }
2216
-
2217
- .desktop-facets-dropdown[open] > summary {
2218
- margin-bottom: 10px;
2219
- }
2220
-
2221
- .desktop-facets-dropdown[open] svg {
2222
- transform: rotate(90deg);
2223
- }
2224
-
2225
- .desktop #left-column-scroll-sentinel {
2226
- width: 1px;
2227
- height: 100vh;
2228
- background: transparent;
2229
- }
2230
-
2231
- .desktop #facets-scroll-sentinel {
2232
- width: 1px;
2233
- height: 1px;
2234
- background: transparent;
2235
- }
2236
-
2237
- #facets-header-container {
2238
- display: flex;
2239
- justify-content: space-between;
2240
- align-items: flex-start;
2241
- clear: both;
2242
- }
2243
-
2244
- .desktop #facets-header-container {
2245
- flex-wrap: wrap;
2246
- }
2247
-
2248
- .mobile #left-column {
2249
- width: 100%;
2250
- min-width: 0;
2251
- padding: 5px 0;
2252
- border: 0;
2253
- }
2254
-
2255
- .clear-filters-btn-row {
2256
- display: inline-block;
2257
- }
2258
-
2259
- .desktop .clear-filters-btn-row {
2260
- width: 100%;
2261
- }
2262
-
2263
- .clear-filters-btn {
2264
- display: inline-block;
2265
- appearance: none;
2266
- margin: 0;
2267
- padding: 0;
2268
- border: 0;
2269
- background: none;
2270
- color: var(--ia-theme-link-color);
2271
- font-size: 1.4rem;
2272
- font-family: inherit;
2273
- cursor: pointer;
2274
- }
2275
-
2276
- .clear-filters-btn:hover {
2277
- text-decoration: underline;
2278
- }
2279
-
2280
- .clear-filters-btn-separator {
2281
- display: inline-block;
2282
- margin-left: 5px;
2283
- border-left: 1px solid #2c2c2c;
2284
- font-size: 1.4rem;
2285
- line-height: 1.3rem;
2286
- }
2287
-
2288
- #tv-filters {
2289
- margin-bottom: 15px;
2290
- }
2291
-
2292
- #tv-shows {
2293
- --comboBoxListWidth: 300px;
2294
- }
2295
-
2296
- .tv-filter-dropdown {
2297
- display: block;
2298
- font-size: 14px;
2299
- margin-left: 1px;
2300
- margin-bottom: 5px;
2301
- }
2302
-
2303
- .tv-filter-dropdown::part(combo-box) {
2304
- outline-offset: 1px;
2305
- }
2306
-
2307
- .tv-filter-dropdown::part(option) {
2308
- line-height: 1.1;
2309
- padding: 7px;
2310
- }
2311
-
2312
- .tv-filter-dropdown::part(clear-button) {
2313
- flex: 0 0 26px;
2314
- --combo-box-clear-icon-size: 14px;
2315
- }
2316
-
2317
- .tv-filter-dropdown::part(icon) {
2318
- width: 1.4rem;
2319
- height: 1.4rem;
2320
- }
2321
-
2322
- #facets-container {
2323
- position: relative;
2324
- max-height: 0;
2325
- transition: max-height 0.2s ease-in-out;
2326
- z-index: 1;
2327
- margin-top: var(--facetsContainerMarginTop, 3rem);
2328
- padding-bottom: 2rem;
2329
- }
2330
-
2331
- .desktop #facets-container {
2332
- width: 18rem;
2333
- }
2334
-
2335
- .mobile #facets-container {
2336
- overflow: hidden;
2337
- padding-bottom: 0;
2338
- padding-left: 10px;
2339
- padding-right: 10px;
2340
- }
2341
-
2342
- #facets-container.expanded {
2343
- max-height: 2000px;
2344
- }
2345
-
2346
- .results-section-heading {
2347
- margin: 0.5rem 0.3rem;
2348
- font-size: 2rem;
2349
- line-height: 25px;
2350
- }
2351
-
2352
- #results-total {
2353
- display: flex;
2354
- align-items: baseline;
2355
- }
2356
-
2357
- #results-total:not(.filtered) {
2358
- padding-bottom: 2rem;
2359
- }
2360
-
2361
- .mobile #results-total {
2362
- position: absolute;
2363
- right: 10px;
2364
- }
2365
-
2366
- #big-results-count {
2367
- font-size: 2.4rem;
2368
- font-weight: 500;
2369
- margin-right: 5px;
2370
- }
2371
-
2372
- .mobile #big-results-count {
2373
- font-size: 2rem;
2374
- }
2375
-
2376
- #big-results-label {
2377
- font-size: 1.4rem;
2378
- font-weight: 200;
2379
- }
2380
-
2381
- #list-header {
2382
- max-height: 4.2rem;
2383
- }
2384
-
2385
- .loading-cover {
2386
- position: absolute;
2387
- top: 0;
2388
- left: 0;
2389
- width: 100%;
2390
- height: 100%;
2391
- display: flex;
2392
- justify-content: center;
2393
- z-index: 1;
2394
- padding-top: 50px;
2395
- }
2396
-
2397
- #tile-blur-label {
2398
- display: flex;
2399
- align-items: center;
2400
- column-gap: 5px;
2401
- }
2402
-
2403
- #tile-blur-check {
2404
- margin: 0 5px 0 0;
2405
- width: 15px;
2406
- }
2407
-
2408
- circular-activity-indicator {
2409
- width: 30px;
2410
- height: 30px;
2411
- }
2412
-
2413
- sort-filter-bar {
2414
- display: block;
2415
- margin-bottom: 4rem;
2416
- }
2417
-
2418
- infinite-scroller {
2419
- display: block;
2420
- --infiniteScrollerRowGap: var(--collectionBrowserRowGap, 1.7rem);
2421
- --infiniteScrollerColGap: var(--collectionBrowserColGap, 1.7rem);
2422
- }
2423
-
2424
- infinite-scroller.list-compact {
2425
- --infiniteScrollerCellMinWidth: var(
2426
- --collectionBrowserCellMinWidth,
2427
- 100%
2428
- );
2429
- --infiniteScrollerCellMinHeight: 45px; /* override infinite scroller component */
2430
- --infiniteScrollerCellMaxHeight: 56px;
2431
- --infiniteScrollerRowGap: 10px;
2432
- }
2433
-
2434
- infinite-scroller.list-detail {
2435
- --infiniteScrollerCellMinWidth: var(
2436
- --collectionBrowserCellMinWidth,
2437
- 100%
2438
- );
2439
- --infiniteScrollerCellMinHeight: var(
2440
- --collectionBrowserCellMinHeight,
2441
- 5rem
2442
- );
2443
- /*
2444
- 30px in spec, compensating for a -4px margin
2445
- to align title with top of item image
2446
- src/tiles/list/tile-list.ts
2447
- */
2448
- --infiniteScrollerRowGap: 34px;
2449
- }
2450
-
2451
- .mobile infinite-scroller.list-detail {
2452
- --infiniteScrollerRowGap: 24px;
2453
- }
2454
-
2455
- infinite-scroller.grid {
2456
- --infiniteScrollerCellMinWidth: var(
2457
- --collectionBrowserCellMinWidth,
2458
- 17rem
2459
- );
2460
- --infiniteScrollerCellMaxWidth: var(
2461
- --collectionBrowserCellMaxWidth,
2462
- 1fr
2463
- );
2464
- }
2465
-
2466
- /* Allow tiles to shrink a bit further at smaller viewport widths */
2467
- @media screen and (max-width: 880px) {
2468
- infinite-scroller.grid {
2469
- --infiniteScrollerCellMinWidth: var(
2470
- --collectionBrowserCellMinWidth,
2471
- 15rem
2472
- );
2473
- }
2474
- }
2475
- /* At very small widths, maintain a 2-tile layout as far as it can reasonably go */
2476
- @media screen and (max-width: 360px) {
2477
- infinite-scroller.grid {
2478
- --infiniteScrollerCellMinWidth: var(
2479
- --collectionBrowserCellMinWidth,
2480
- 12rem
2481
- );
2482
- }
2483
- }
2484
-
2485
- infinite-scroller.hidden {
2486
- display: none;
2487
- }
2108
+ css `
2109
+ :host {
2110
+ display: block;
2111
+ --leftColumnWidth: 18rem;
2112
+ --leftColumnPaddingTop: 2rem;
2113
+ --leftColumnPaddingRight: 2.5rem;
2114
+ }
2115
+
2116
+ #facet-top-view {
2117
+ display: flex;
2118
+ }
2119
+
2120
+ /**
2121
+ * When page width resizes from desktop to mobile, use this class to
2122
+ * disable expand/collapse transition when loading.
2123
+ */
2124
+ .preload * {
2125
+ transition: none !important;
2126
+ -webkit-transition: none !important;
2127
+ -moz-transition: none !important;
2128
+ -ms-transition: none !important;
2129
+ -o-transition: none !important;
2130
+ }
2131
+
2132
+ #content-container {
2133
+ display: flex;
2134
+ }
2135
+
2136
+ empty-placeholder {
2137
+ margin-top: var(--placeholderMarginTop, 0);
2138
+ }
2139
+
2140
+ .collapser-icon {
2141
+ display: inline-block;
2142
+ }
2143
+
2144
+ .collapser-icon svg {
2145
+ display: inline-block;
2146
+ width: 12px;
2147
+ height: 12px;
2148
+ transition: transform 0.2s ease-out;
2149
+ }
2150
+
2151
+ #mobile-filter-collapse {
2152
+ width: 100%;
2153
+ }
2154
+
2155
+ #mobile-filter-collapse > summary {
2156
+ cursor: pointer;
2157
+ list-style: none;
2158
+ }
2159
+
2160
+ #mobile-filter-collapse[open] > summary {
2161
+ margin-bottom: 10px;
2162
+ }
2163
+
2164
+ #mobile-filter-collapse h2 {
2165
+ display: inline-block;
2166
+ margin: 0;
2167
+ font-size: 2rem;
2168
+ }
2169
+
2170
+ #mobile-filter-collapse[open] svg {
2171
+ transform: rotate(90deg);
2172
+ }
2173
+
2174
+ #content-container.mobile {
2175
+ display: block;
2176
+ }
2177
+
2178
+ #right-column {
2179
+ flex: 1;
2180
+ position: relative;
2181
+ min-height: 90vh;
2182
+ border-right: 1px solid rgb(232, 232, 232);
2183
+ margin-top: var(--rightColumnMarginTop, 0);
2184
+ padding-top: var(--rightColumnPaddingTop, 2rem);
2185
+ background: #fff;
2186
+ }
2187
+
2188
+ #left-column:not([hidden]) + #right-column {
2189
+ border-left: 1px solid rgb(232, 232, 232);
2190
+ }
2191
+
2192
+ #right-column.smart-results-spacing {
2193
+ padding-top: 0.5rem;
2194
+ border-right: none;
2195
+ background: transparent;
2196
+ min-width: 0;
2197
+ }
2198
+
2199
+ #results {
2200
+ background: #fff;
2201
+ padding-left: 1rem;
2202
+ padding-right: 1rem;
2203
+ }
2204
+
2205
+ #right-column.smart-results-spacing #results {
2206
+ border-radius: 10px 10px 0px 0px;
2207
+ padding-top: 0.5rem;
2208
+ margin-top: 1rem;
2209
+ }
2210
+
2211
+ .mobile #right-column {
2212
+ border-left: none;
2213
+ }
2214
+
2215
+ .mobile #results {
2216
+ padding: 5px 5px 0;
2217
+ }
2218
+
2219
+ #left-column {
2220
+ width: var(--leftColumnWidth, 18rem);
2221
+ /* Prevents Safari from shrinking col at first draw */
2222
+ min-width: var(--leftColumnWidth, 18rem);
2223
+ padding-top: var(--leftColumnPaddingTop, 2rem);
2224
+ /* Reduced padding by 0.2rem to add the invisible border in the rule below */
2225
+ padding-right: calc(var(--leftColumnPaddingRight, 2.5rem) - 0.2rem);
2226
+ border-right: 0.2rem solid transparent; /* Pads to the right of the scrollbar a bit */
2227
+ z-index: 1;
2228
+ }
2229
+
2230
+ .desktop #left-column {
2231
+ top: 0;
2232
+ position: sticky;
2233
+ height: calc(100vh - 2rem);
2234
+ max-height: calc(100vh - 2rem);
2235
+ overflow-x: hidden;
2236
+ overflow-y: scroll;
2237
+
2238
+ /*
2239
+ * Firefox doesn't support any of the -webkit-scrollbar stuff below, but
2240
+ * does at least give us a tiny bit of control over width & color.
2241
+ */
2242
+ scrollbar-width: thin;
2243
+ scrollbar-color: transparent transparent;
2244
+ }
2245
+ .desktop #left-column:hover {
2246
+ scrollbar-color: auto;
2247
+ }
2248
+ .desktop #left-column::-webkit-scrollbar {
2249
+ appearance: none;
2250
+ width: 6px;
2251
+ }
2252
+ .desktop #left-column::-webkit-scrollbar-button {
2253
+ height: 3px;
2254
+ background: transparent;
2255
+ }
2256
+ .desktop #left-column::-webkit-scrollbar-corner {
2257
+ background: transparent;
2258
+ }
2259
+ .desktop #left-column::-webkit-scrollbar-thumb {
2260
+ border-radius: 4px;
2261
+ }
2262
+ .desktop #left-column:hover::-webkit-scrollbar-thumb {
2263
+ background: rgba(0, 0, 0, 0.15);
2264
+ }
2265
+ .desktop #left-column:hover::-webkit-scrollbar-thumb:hover {
2266
+ background: rgba(0, 0, 0, 0.2);
2267
+ }
2268
+ .desktop #left-column:hover::-webkit-scrollbar-thumb:active {
2269
+ background: rgba(0, 0, 0, 0.3);
2270
+ }
2271
+
2272
+ #facets-bottom-fade {
2273
+ background: linear-gradient(
2274
+ to bottom,
2275
+ #fbfbfd00 0%,
2276
+ #fbfbfdc0 50%,
2277
+ #fbfbfd 80%,
2278
+ #fbfbfd 100%
2279
+ );
2280
+ position: fixed;
2281
+ bottom: 0;
2282
+ height: 50px;
2283
+ /* Wide enough to cover the content, but leave the scrollbar uncovered */
2284
+ width: calc(
2285
+ var(--leftColumnWidth) + var(--leftColumnPaddingRight) - 10px
2286
+ );
2287
+ z-index: 2;
2288
+ pointer-events: none;
2289
+ transition: height 0.1s ease;
2290
+ }
2291
+ #facets-bottom-fade.hidden {
2292
+ height: 0;
2293
+ }
2294
+
2295
+ .facets-message {
2296
+ font-size: 1.4rem;
2297
+ }
2298
+
2299
+ .desktop-facets-dropdown > summary {
2300
+ cursor: pointer;
2301
+ list-style: none;
2302
+ }
2303
+
2304
+ .desktop-facets-dropdown h2 {
2305
+ display: inline-block;
2306
+ margin: 0;
2307
+ font-size: 1.6rem;
2308
+ }
2309
+
2310
+ .desktop-facets-dropdown[open] > summary {
2311
+ margin-bottom: 10px;
2312
+ }
2313
+
2314
+ .desktop-facets-dropdown[open] svg {
2315
+ transform: rotate(90deg);
2316
+ }
2317
+
2318
+ .desktop #left-column-scroll-sentinel {
2319
+ width: 1px;
2320
+ height: 100vh;
2321
+ background: transparent;
2322
+ }
2323
+
2324
+ .desktop #facets-scroll-sentinel {
2325
+ width: 1px;
2326
+ height: 1px;
2327
+ background: transparent;
2328
+ }
2329
+
2330
+ #facets-header-container {
2331
+ display: flex;
2332
+ justify-content: space-between;
2333
+ align-items: flex-start;
2334
+ clear: both;
2335
+ }
2336
+
2337
+ .desktop #facets-header-container {
2338
+ flex-wrap: wrap;
2339
+ }
2340
+
2341
+ .mobile #left-column {
2342
+ width: 100%;
2343
+ min-width: 0;
2344
+ padding: 5px 0;
2345
+ border: 0;
2346
+ }
2347
+
2348
+ .clear-filters-btn-row {
2349
+ display: inline-block;
2350
+ }
2351
+
2352
+ .desktop .clear-filters-btn-row {
2353
+ width: 100%;
2354
+ }
2355
+
2356
+ .clear-filters-btn {
2357
+ display: inline-block;
2358
+ appearance: none;
2359
+ margin: 0;
2360
+ padding: 0;
2361
+ border: 0;
2362
+ background: none;
2363
+ color: var(--ia-theme-link-color);
2364
+ font-size: 1.4rem;
2365
+ font-family: inherit;
2366
+ cursor: pointer;
2367
+ }
2368
+
2369
+ .clear-filters-btn:hover {
2370
+ text-decoration: underline;
2371
+ }
2372
+
2373
+ .clear-filters-btn-separator {
2374
+ display: inline-block;
2375
+ margin-left: 5px;
2376
+ border-left: 1px solid #2c2c2c;
2377
+ font-size: 1.4rem;
2378
+ line-height: 1.3rem;
2379
+ }
2380
+
2381
+ #tv-filters {
2382
+ margin-bottom: 15px;
2383
+ }
2384
+
2385
+ #tv-shows {
2386
+ --comboBoxListWidth: 300px;
2387
+ }
2388
+
2389
+ .tv-filter-dropdown {
2390
+ display: block;
2391
+ font-size: 14px;
2392
+ margin-left: 1px;
2393
+ margin-bottom: 5px;
2394
+ }
2395
+
2396
+ .tv-filter-dropdown::part(combo-box) {
2397
+ outline-offset: 1px;
2398
+ }
2399
+
2400
+ .tv-filter-dropdown::part(option) {
2401
+ line-height: 1.1;
2402
+ padding: 7px;
2403
+ }
2404
+
2405
+ .tv-filter-dropdown::part(clear-button) {
2406
+ flex: 0 0 26px;
2407
+ --combo-box-clear-icon-size: 14px;
2408
+ }
2409
+
2410
+ .tv-filter-dropdown::part(icon) {
2411
+ width: 1.4rem;
2412
+ height: 1.4rem;
2413
+ }
2414
+
2415
+ #facets-container {
2416
+ position: relative;
2417
+ max-height: 0;
2418
+ transition: max-height 0.2s ease-in-out;
2419
+ z-index: 1;
2420
+ margin-top: var(--facetsContainerMarginTop, 3rem);
2421
+ padding-bottom: 2rem;
2422
+ }
2423
+
2424
+ .desktop #facets-container {
2425
+ width: 18rem;
2426
+ }
2427
+
2428
+ .mobile #facets-container {
2429
+ overflow: hidden;
2430
+ padding-bottom: 0;
2431
+ padding-left: 10px;
2432
+ padding-right: 10px;
2433
+ }
2434
+
2435
+ #facets-container.expanded {
2436
+ max-height: 2000px;
2437
+ }
2438
+
2439
+ .results-section-heading {
2440
+ margin: 0.5rem 0.3rem;
2441
+ font-size: 2rem;
2442
+ line-height: 25px;
2443
+ }
2444
+
2445
+ #results-total {
2446
+ display: flex;
2447
+ align-items: baseline;
2448
+ }
2449
+
2450
+ #results-total:not(.filtered) {
2451
+ padding-bottom: 2rem;
2452
+ }
2453
+
2454
+ .mobile #results-total {
2455
+ position: absolute;
2456
+ right: 10px;
2457
+ }
2458
+
2459
+ #big-results-count {
2460
+ font-size: 2.4rem;
2461
+ font-weight: 500;
2462
+ margin-right: 5px;
2463
+ }
2464
+
2465
+ .mobile #big-results-count {
2466
+ font-size: 2rem;
2467
+ }
2468
+
2469
+ #big-results-label {
2470
+ font-size: 1.4rem;
2471
+ font-weight: 200;
2472
+ }
2473
+
2474
+ #list-header {
2475
+ max-height: 4.2rem;
2476
+ }
2477
+
2478
+ .loading-cover {
2479
+ position: absolute;
2480
+ top: 0;
2481
+ left: 0;
2482
+ width: 100%;
2483
+ height: 100%;
2484
+ display: flex;
2485
+ justify-content: center;
2486
+ z-index: 1;
2487
+ padding-top: 50px;
2488
+ }
2489
+
2490
+ #tile-blur-label {
2491
+ display: flex;
2492
+ align-items: center;
2493
+ column-gap: 5px;
2494
+ }
2495
+
2496
+ #tile-blur-check {
2497
+ margin: 0 5px 0 0;
2498
+ width: 15px;
2499
+ }
2500
+
2501
+ circular-activity-indicator {
2502
+ width: 30px;
2503
+ height: 30px;
2504
+ }
2505
+
2506
+ sort-filter-bar {
2507
+ display: block;
2508
+ margin-bottom: 4rem;
2509
+ }
2510
+
2511
+ infinite-scroller {
2512
+ display: block;
2513
+ --infiniteScrollerRowGap: var(--collectionBrowserRowGap, 1.7rem);
2514
+ --infiniteScrollerColGap: var(--collectionBrowserColGap, 1.7rem);
2515
+ }
2516
+
2517
+ infinite-scroller.list-compact {
2518
+ --infiniteScrollerCellMinWidth: var(
2519
+ --collectionBrowserCellMinWidth,
2520
+ 100%
2521
+ );
2522
+ --infiniteScrollerCellMinHeight: 45px; /* override infinite scroller component */
2523
+ --infiniteScrollerCellMaxHeight: 56px;
2524
+ --infiniteScrollerRowGap: 10px;
2525
+ }
2526
+
2527
+ infinite-scroller.list-detail {
2528
+ --infiniteScrollerCellMinWidth: var(
2529
+ --collectionBrowserCellMinWidth,
2530
+ 100%
2531
+ );
2532
+ --infiniteScrollerCellMinHeight: var(
2533
+ --collectionBrowserCellMinHeight,
2534
+ 5rem
2535
+ );
2536
+ /*
2537
+ 30px in spec, compensating for a -4px margin
2538
+ to align title with top of item image
2539
+ src/tiles/list/tile-list.ts
2540
+ */
2541
+ --infiniteScrollerRowGap: 34px;
2542
+ }
2543
+
2544
+ .mobile infinite-scroller.list-detail {
2545
+ --infiniteScrollerRowGap: 24px;
2546
+ }
2547
+
2548
+ infinite-scroller.grid {
2549
+ --infiniteScrollerCellMinWidth: var(
2550
+ --collectionBrowserCellMinWidth,
2551
+ 17rem
2552
+ );
2553
+ --infiniteScrollerCellMaxWidth: var(
2554
+ --collectionBrowserCellMaxWidth,
2555
+ 1fr
2556
+ );
2557
+ }
2558
+
2559
+ /* Allow tiles to shrink a bit further at smaller viewport widths */
2560
+ @media screen and (max-width: 880px) {
2561
+ infinite-scroller.grid {
2562
+ --infiniteScrollerCellMinWidth: var(
2563
+ --collectionBrowserCellMinWidth,
2564
+ 15rem
2565
+ );
2566
+ }
2567
+ }
2568
+ /* At very small widths, maintain a 2-tile layout as far as it can reasonably go */
2569
+ @media screen and (max-width: 360px) {
2570
+ infinite-scroller.grid {
2571
+ --infiniteScrollerCellMinWidth: var(
2572
+ --collectionBrowserCellMinWidth,
2573
+ 12rem
2574
+ );
2575
+ }
2576
+ }
2577
+
2578
+ infinite-scroller.hidden {
2579
+ display: none;
2580
+ }
2488
2581
  `,
2489
2582
  ];
2490
2583
  }
@@ -2717,7 +2810,7 @@ __decorate([
2717
2810
  __decorate([
2718
2811
  query('infinite-scroller')
2719
2812
  ], CollectionBrowser.prototype, "infiniteScroller", void 0);
2720
- CollectionBrowser = __decorate([
2813
+ CollectionBrowser = CollectionBrowser_1 = __decorate([
2721
2814
  customElement('collection-browser')
2722
2815
  ], CollectionBrowser);
2723
2816
  export { CollectionBrowser };