@internetarchive/collection-browser 4.0.2 → 4.1.0-alpha-webdev8186.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.
Files changed (40) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist/src/app-root.js +614 -614
  3. package/dist/src/app-root.js.map +1 -1
  4. package/dist/src/collection-browser.js +764 -774
  5. package/dist/src/collection-browser.js.map +1 -1
  6. package/dist/src/collection-facets/more-facets-content.js +121 -121
  7. package/dist/src/collection-facets/more-facets-content.js.map +1 -1
  8. package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
  9. package/dist/src/models.js.map +1 -1
  10. package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +13 -172
  11. package/dist/src/sort-filter-bar/sort-filter-bar.js +37 -546
  12. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  13. package/dist/src/tiles/grid/collection-tile.js +89 -89
  14. package/dist/src/tiles/grid/collection-tile.js.map +1 -1
  15. package/dist/src/tiles/grid/item-tile.js +138 -138
  16. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  17. package/dist/src/tiles/hover/hover-pane-controller.js +28 -28
  18. package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
  19. package/dist/src/tiles/models.js.map +1 -1
  20. package/dist/src/tiles/tile-dispatcher.js +216 -216
  21. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  22. package/dist/test/collection-browser.test.js +197 -202
  23. package/dist/test/collection-browser.test.js.map +1 -1
  24. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +86 -401
  25. package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
  26. package/index.ts +28 -28
  27. package/package.json +1 -1
  28. package/src/app-root.ts +1166 -1166
  29. package/src/collection-browser.ts +3065 -3075
  30. package/src/collection-facets/more-facets-content.ts +644 -644
  31. package/src/data-source/collection-browser-query-state.ts +59 -59
  32. package/src/models.ts +873 -873
  33. package/src/sort-filter-bar/sort-filter-bar.ts +42 -603
  34. package/src/tiles/grid/collection-tile.ts +184 -184
  35. package/src/tiles/grid/item-tile.ts +346 -346
  36. package/src/tiles/hover/hover-pane-controller.ts +627 -627
  37. package/src/tiles/models.ts +8 -8
  38. package/src/tiles/tile-dispatcher.ts +518 -518
  39. package/test/collection-browser.test.ts +2402 -2413
  40. package/test/sort-filter-bar/sort-filter-bar.test.ts +110 -566
@@ -8,26 +8,16 @@ import {
8
8
  } from 'lit';
9
9
  import { customElement, property, query, state } from 'lit/decorators.js';
10
10
  import { msg } from '@lit/localize';
11
- import type {
12
- SharedResizeObserverInterface,
13
- SharedResizeObserverResizeHandlerInterface,
14
- } from '@internetarchive/shared-resize-observer';
15
- import '@internetarchive/ia-dropdown';
16
11
  import type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';
17
12
  import type { SortDirection } from '@internetarchive/search-service';
18
13
  import {
19
- ALL_DATE_SORT_FIELDS,
20
- ALL_VIEWS_SORT_FIELDS,
21
14
  CollectionDisplayMode,
22
- DateSortField,
23
15
  defaultSortAvailability,
24
16
  PrefixFilterCounts,
25
17
  PrefixFilterType,
26
18
  SORT_OPTIONS,
27
19
  SortField,
28
- ViewsSortField,
29
20
  } from '../models';
30
- import './alpha-bar';
31
21
 
32
22
  import { sortUpIcon } from './img/sort-toggle-up';
33
23
  import { sortDownIcon } from './img/sort-toggle-down';
@@ -37,13 +27,13 @@ import { listIcon } from './img/list';
37
27
  import { compactIcon } from './img/compact';
38
28
  import { srOnlyStyle } from '../styles/sr-only';
39
29
 
30
+ import '@internetarchive/ia-dropdown';
31
+ import './alpha-bar';
32
+
40
33
  type AlphaSelector = 'creator' | 'title';
41
34
 
42
35
  @customElement('sort-filter-bar')
43
- export class SortFilterBar
44
- extends LitElement
45
- implements SharedResizeObserverResizeHandlerInterface
46
- {
36
+ export class SortFilterBar extends LitElement {
47
37
  /** Which display mode the tiles are being rendered with (grid/list-detail/list-compact) */
48
38
  @property({ type: String }) displayMode?: CollectionDisplayMode;
49
39
 
@@ -56,13 +46,6 @@ export class SortFilterBar
56
46
  SortField.default
57
47
  > = SortField.relevance;
58
48
 
59
- /** Which view sort option to expose by default. */
60
- @property({ type: String }) defaultViewSort: ViewsSortField =
61
- SortField.weeklyview;
62
-
63
- /** Which date sort option to expose by default */
64
- @property({ type: String }) defaultDateSort: DateSortField = SortField.date;
65
-
66
49
  /** The current sort direction (asc/desc), or null if none is set */
67
50
  @property({ type: String }) sortDirection: SortDirection | null = null;
68
51
 
@@ -104,18 +87,6 @@ export class SortFilterBar
104
87
  PrefixFilterCounts
105
88
  >;
106
89
 
107
- @property({ type: Object }) resizeObserver?: SharedResizeObserverInterface;
108
-
109
- /**
110
- * The Views sort option that was most recently selected (or the default, if none has been selected yet)
111
- */
112
- @state() private lastSelectedViewSort = this.defaultViewSort;
113
-
114
- /**
115
- * The Date sort option that was most recently selected (or the default, if none has been selected yet)
116
- */
117
- @state() private lastSelectedDateSort = this.defaultDateSort;
118
-
119
90
  /**
120
91
  * Which of the alphabet bars (title/creator) should be shown, or null if one
121
92
  * should not currently be rendered.
@@ -128,43 +99,9 @@ export class SortFilterBar
128
99
  */
129
100
  @state() dropdownBackdropVisible = false;
130
101
 
131
- /**
132
- * The width of the desktop view sort option container, updated upon each resize.
133
- * Used for dynamically determining whether to use desktop or mobile view.
134
- */
135
- @state() desktopSortContainerWidth = 0;
136
-
137
- /**
138
- * The width of the full sort bar, updated upon each resize.
139
- * Used for dynamically determining whether to use desktop or mobile view.
140
- */
141
- @state() selectorBarContainerWidth = 0;
142
-
143
- /**
144
- * The container for all the desktop view's sort options.
145
- * Used for dynamically determining whether to use desktop or mobile view.
146
- */
147
- @query('#desktop-sort-container')
148
- private desktopSortContainer!: HTMLUListElement;
149
-
150
- /**
151
- * The container for the full sort bar.
152
- * Used for dynamically determining whether to use desktop or mobile view.
153
- */
154
- @query('#sort-selector-container')
155
- private sortSelectorContainer!: HTMLDivElement;
156
-
157
- /** The dropdown component containing options for weekly and all-time views */
158
- @query('#views-dropdown')
159
- private viewsDropdown?: IaDropdown;
160
-
161
- /** The dropdown component containing all the available date options */
162
- @query('#date-dropdown')
163
- private dateDropdown?: IaDropdown;
164
-
165
- /** The single, consolidated dropdown component shown in mobile view */
166
- @query('#mobile-dropdown')
167
- private mobileDropdown!: IaDropdown;
102
+ /** The single, consolidated dropdown component containing all available options */
103
+ @query('#sort-dropdown')
104
+ private sortOptionsDropdown!: IaDropdown;
168
105
 
169
106
  render() {
170
107
  return html`
@@ -179,8 +116,7 @@ export class SortFilterBar
179
116
  </div>
180
117
  <span class="sort-by-text">${msg('Sort by:')}</span>
181
118
  <div id="sort-selector-container">
182
- ${this.mobileSortSelectorTemplate}
183
- ${this.desktopSortSelectorTemplate}
119
+ ${this.sortSelectorTemplate}
184
120
  </div>
185
121
  `
186
122
  : html`<slot name="sort-options"></slot>`}
@@ -212,20 +148,6 @@ export class SortFilterBar
212
148
  const sortOption = SORT_OPTIONS[this.finalizedSortField];
213
149
  this.sortDirection = sortOption.defaultSortDirection;
214
150
  }
215
-
216
- if (this.viewOptionSelected) {
217
- this.lastSelectedViewSort = this.finalizedSortField as ViewsSortField;
218
- } else if (this.dateOptionSelected) {
219
- this.lastSelectedDateSort = this.finalizedSortField as DateSortField;
220
- }
221
- }
222
-
223
- // If we change which dropdown options are defaulted, update the default selections
224
- if (changed.has('defaultViewSort')) {
225
- this.lastSelectedViewSort = this.defaultViewSort;
226
- }
227
- if (changed.has('defaultDateSort')) {
228
- this.lastSelectedDateSort = this.defaultDateSort;
229
151
  }
230
152
  }
231
153
 
@@ -245,14 +167,6 @@ export class SortFilterBar
245
167
  if (changed.has('dropdownBackdropVisible')) {
246
168
  this.setupEscapeListeners();
247
169
  }
248
-
249
- if (changed.has('resizeObserver') || changed.has('enableSortOptionsSlot')) {
250
- const oldObserver = changed.get(
251
- 'resizeObserver',
252
- ) as SharedResizeObserverInterface;
253
- if (oldObserver) this.disconnectResizeObserver(oldObserver);
254
- this.setupResizeObserver();
255
- }
256
170
  }
257
171
 
258
172
  private setupEscapeListeners() {
@@ -271,73 +185,10 @@ export class SortFilterBar
271
185
 
272
186
  private boundSortBarSelectorEscapeListener = (e: KeyboardEvent) => {
273
187
  if (e.key === 'Escape') {
274
- this.closeDropdowns();
188
+ this.closeDropdown();
275
189
  }
276
190
  };
277
191
 
278
- connectedCallback(): void {
279
- super.connectedCallback?.();
280
- this.setupResizeObserver();
281
- }
282
-
283
- disconnectedCallback(): void {
284
- if (this.resizeObserver) {
285
- this.disconnectResizeObserver(this.resizeObserver);
286
- }
287
- }
288
-
289
- private disconnectResizeObserver(
290
- resizeObserver: SharedResizeObserverInterface,
291
- ) {
292
- if (this.sortSelectorContainer) {
293
- resizeObserver.removeObserver({
294
- target: this.sortSelectorContainer,
295
- handler: this,
296
- });
297
- }
298
-
299
- if (this.desktopSortContainer) {
300
- resizeObserver.removeObserver({
301
- target: this.desktopSortContainer,
302
- handler: this,
303
- });
304
- }
305
- }
306
-
307
- private setupResizeObserver() {
308
- if (!this.resizeObserver) return;
309
-
310
- if (this.sortSelectorContainer) {
311
- this.resizeObserver.addObserver({
312
- target: this.sortSelectorContainer,
313
- handler: this,
314
- });
315
- }
316
-
317
- if (this.desktopSortContainer) {
318
- this.resizeObserver.addObserver({
319
- target: this.desktopSortContainer,
320
- handler: this,
321
- });
322
- }
323
- }
324
-
325
- handleResize(entry: ResizeObserverEntry): void {
326
- if (entry.target === this.desktopSortContainer) {
327
- this.desktopSortContainerWidth = entry.contentRect.width;
328
- } else if (entry.target === this.sortSelectorContainer) {
329
- this.selectorBarContainerWidth = entry.contentRect.width;
330
- }
331
- }
332
-
333
- /**
334
- * Whether to show the mobile sort bar because there is not enough space
335
- * for the desktop sort bar.
336
- */
337
- private get mobileSelectorVisible() {
338
- return this.selectorBarContainerWidth - 10 < this.desktopSortContainerWidth;
339
- }
340
-
341
192
  /**
342
193
  * Template to render the alphabet bar, or `nothing` if it should not be rendered
343
194
  * for the current sort
@@ -390,49 +241,28 @@ export class SortFilterBar
390
241
  `;
391
242
  }
392
243
 
393
- /** The template to render all the sort options in desktop view */
394
- private get desktopSortSelectorTemplate() {
395
- return html`
396
- <div
397
- id="desktop-sort-container"
398
- class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}
399
- >
400
- <ul id="desktop-sort-selector">
401
- <li>${this.relevanceSortSelectorTemplate}</li>
402
- <li>${this.allViewsSortOptionsTemplate}</li>
403
- <li>${this.titleSortSelectorTemplate}</li>
404
- <li>${this.allDateSortOptionsTemplate}</li>
405
- <li>${this.creatorSortSelectorTemplate}</li>
406
- </ul>
407
- </div>
408
- `;
409
- }
410
-
411
- /** The template to render all the sort options in mobile view */
412
- private get mobileSortSelectorTemplate() {
244
+ /** The template to render all the sort options in a single dropdown */
245
+ private get sortSelectorTemplate() {
413
246
  const displayedOptions = Object.values(SORT_OPTIONS).filter(
414
247
  opt => opt.shownInSortBar && this.sortFieldAvailability[opt.field],
415
248
  );
416
249
 
417
250
  return html`
418
- <div
419
- id="mobile-sort-container"
420
- class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
421
- >
251
+ <div id="sort-dropdown-container">
422
252
  ${this.getSortDropdown({
423
253
  displayName: SORT_OPTIONS[this.finalizedSortField].displayName,
424
- id: 'mobile-dropdown',
254
+ id: 'sort-dropdown',
425
255
  selected: true,
426
256
  dropdownOptions: displayedOptions.map(opt =>
427
257
  this.getDropdownOption(opt.field),
428
258
  ),
429
259
  selectedOption: this.finalizedSortField,
430
- onOptionSelected: this.mobileSortChanged,
260
+ onOptionSelected: this.sortOptionSelected,
431
261
  onDropdownClick: () => {
432
- this.dropdownBackdropVisible = this.mobileDropdown.open;
433
- this.mobileDropdown.classList.toggle(
262
+ this.dropdownBackdropVisible = this.sortOptionsDropdown.open;
263
+ this.sortOptionsDropdown.classList.toggle(
434
264
  'open',
435
- this.mobileDropdown.open,
265
+ this.sortOptionsDropdown.open,
436
266
  );
437
267
  },
438
268
  })}
@@ -440,45 +270,6 @@ export class SortFilterBar
440
270
  `;
441
271
  }
442
272
 
443
- /**
444
- * This generates each of the non-dropdown sort option buttons.
445
- *
446
- * It manages the display value and the selected state of the option.
447
- *
448
- * @param sortField Which sort field the button represents
449
- * @param options Additional options:
450
- * - `onSelected?: (e: Event) => void;` If this is provided, it will also be called when the option is selected.
451
- * Default is to clear any selected alphabetical filters.
452
- */
453
- private getSortSelectorButton(
454
- sortField: SortField,
455
- options?: {
456
- onSelected?: (e: Event) => void;
457
- },
458
- ): TemplateResult {
459
- const isSelected = this.finalizedSortField === sortField;
460
- const displayName = SORT_OPTIONS[sortField].displayName;
461
- const onSelected =
462
- options?.onSelected ?? (() => this.clearAlphaBarFilters());
463
-
464
- return html`
465
- <button
466
- class=${isSelected ? 'selected' : ''}
467
- data-title=${displayName}
468
- @click=${(e: Event) => {
469
- e.preventDefault();
470
- this.dropdownBackdropVisible = false;
471
- if (this.finalizedSortField !== sortField) {
472
- onSelected?.(e);
473
- this.setSelectedSort(sortField);
474
- }
475
- }}
476
- >
477
- ${displayName}
478
- </button>
479
- `;
480
- }
481
-
482
273
  /**
483
274
  * Generates a dropdown component containing multiple grouped sort options.
484
275
  *
@@ -490,8 +281,6 @@ export class SortFilterBar
490
281
  * selected appearance
491
282
  * @param options.onOptionSelected A handler for optionSelected events coming from the dropdown
492
283
  * @param options.onDropdownClick A handler for click events on the dropdown
493
- * @param options.onLabelInteraction A handler for click events and Enter/Space keydown events
494
- * on the dropdown's label
495
284
  */
496
285
  private getSortDropdown(options: {
497
286
  displayName: string;
@@ -501,7 +290,6 @@ export class SortFilterBar
501
290
  selected: boolean;
502
291
  onOptionSelected?: (e: CustomEvent<{ option: optionInterface }>) => void;
503
292
  onDropdownClick?: (e: PointerEvent) => void;
504
- onLabelInteraction?: (e: Event) => void;
505
293
  }): TemplateResult {
506
294
  return html`
507
295
  <ia-dropdown
@@ -520,14 +308,6 @@ export class SortFilterBar
520
308
  class="dropdown-label"
521
309
  slot="dropdown-label"
522
310
  data-title=${options.displayName}
523
- @click=${options.onLabelInteraction ?? nothing}
524
- @keydown=${options.onLabelInteraction
525
- ? (e: KeyboardEvent) => {
526
- if (e.key === 'Enter' || e.key === ' ') {
527
- options.onLabelInteraction?.(e);
528
- }
529
- }
530
- : nothing}
531
311
  >
532
312
  ${options.displayName}
533
313
  </span>
@@ -550,183 +330,8 @@ export class SortFilterBar
550
330
  };
551
331
  }
552
332
 
553
- /** Handler for when any sort dropdown option is selected */
554
- private dropdownOptionSelected(e: CustomEvent<{ option: optionInterface }>) {
555
- this.dropdownBackdropVisible = false;
556
- this.clearAlphaBarFilters();
557
-
558
- const sortField = e.detail.option.id as SortField;
559
- this.setSelectedSort(sortField);
560
- if (this.viewOptionSelected) {
561
- this.lastSelectedViewSort = sortField as ViewsSortField;
562
- } else if (this.dateOptionSelected) {
563
- this.lastSelectedDateSort = sortField as DateSortField;
564
- }
565
- }
566
-
567
- //
568
- // SORT OPTION TEMPLATES
569
- //
570
-
571
- /**
572
- * Template for the Relevance sort selector button, or `nothing` if the relevance
573
- * field is not available for display.
574
- */
575
- private get relevanceSortSelectorTemplate(): TemplateResult | typeof nothing {
576
- if (!this.sortFieldAvailability.relevance) return nothing;
577
- return this.getSortSelectorButton(SortField.relevance);
578
- }
579
-
580
- /**
581
- * Template for the Views sort selector button.
582
- * This is shown instead of the views dropdown when only a single views sort field
583
- * is available.
584
- */
585
- private get viewsSortSelectorTemplate(): TemplateResult | typeof nothing {
586
- const { availableViewsFields } = this;
587
- if (availableViewsFields.length < 1) return nothing;
588
- return this.getSortSelectorButton(availableViewsFields[0]);
589
- }
590
-
591
- /**
592
- * Template for the Title sort selector button, or `nothing` if the title field is
593
- * not available for display.
594
- */
595
- private get titleSortSelectorTemplate(): TemplateResult | typeof nothing {
596
- if (!this.sortFieldAvailability.title) return nothing;
597
-
598
- return this.getSortSelectorButton(SortField.title, {
599
- onSelected: () => {
600
- this.alphaSelectorVisible = 'title';
601
- this.selectedCreatorFilter = null;
602
- this.emitCreatorLetterChangedEvent();
603
- },
604
- });
605
- }
606
-
607
- /**
608
- * Template for the Date sort selector button.
609
- * This is shown instead of the dates dropdown when only a single date sort field
610
- * is available.
611
- */
612
- private get dateSortSelectorTemplate(): TemplateResult | typeof nothing {
613
- const { availableDateFields } = this;
614
- if (availableDateFields.length < 1) return nothing;
615
- return this.getSortSelectorButton(availableDateFields[0]);
616
- }
617
-
618
- /**
619
- * Template for the Creator sort selector button, or `nothing` if the creator field
620
- * is not available for display.
621
- */
622
- private get creatorSortSelectorTemplate(): TemplateResult | typeof nothing {
623
- if (!this.sortFieldAvailability.creator) return nothing;
624
-
625
- return this.getSortSelectorButton(SortField.creator, {
626
- onSelected: () => {
627
- this.alphaSelectorVisible = 'creator';
628
- this.selectedTitleFilter = null;
629
- this.emitTitleLetterChangedEvent();
630
- },
631
- });
632
- }
633
-
634
- /**
635
- * Template for the Views dropdown, shown when 2+ views sort fields are available.
636
- */
637
- private get viewsDropdownTemplate(): TemplateResult {
638
- const displayedOptions = ALL_VIEWS_SORT_FIELDS.filter(
639
- field => this.sortFieldAvailability[field],
640
- ).map(field => this.getDropdownOption(field));
641
-
642
- return this.getSortDropdown({
643
- displayName: this.viewSortDisplayName,
644
- id: 'views-dropdown',
645
- selected: this.viewOptionSelected,
646
- dropdownOptions: displayedOptions,
647
- selectedOption: this.viewOptionSelected ? this.finalizedSortField : '',
648
- onOptionSelected: this.dropdownOptionSelected,
649
- onDropdownClick: () => {
650
- if (this.dateDropdown) this.dateDropdown.open = false;
651
- const viewsDropdown = this.viewsDropdown as IaDropdown;
652
- this.dropdownBackdropVisible = viewsDropdown.open;
653
- viewsDropdown.classList.toggle('open', viewsDropdown.open);
654
- },
655
- onLabelInteraction: (e: Event) => {
656
- if (!this.viewsDropdown?.open && !this.viewOptionSelected) {
657
- e.stopPropagation();
658
- this.clearAlphaBarFilters();
659
- this.setSelectedSort(this.lastSelectedViewSort);
660
- }
661
- },
662
- });
663
- }
664
-
665
- /**
666
- * Template for the Date dropdown, shown when 2+ date sort fields are available.
667
- */
668
- private get dateDropdownTemplate(): TemplateResult {
669
- const displayedOptions = ALL_DATE_SORT_FIELDS.filter(
670
- field => this.sortFieldAvailability[field],
671
- ).map(field => this.getDropdownOption(field));
672
-
673
- return this.getSortDropdown({
674
- displayName: this.dateSortDisplayName,
675
- id: 'date-dropdown',
676
- selected: this.dateOptionSelected,
677
- dropdownOptions: displayedOptions,
678
- selectedOption: this.dateOptionSelected ? this.finalizedSortField : '',
679
- onOptionSelected: this.dropdownOptionSelected,
680
- onDropdownClick: () => {
681
- if (this.viewsDropdown) this.viewsDropdown.open = false;
682
- const dateDropdown = this.dateDropdown as IaDropdown;
683
- this.dropdownBackdropVisible = dateDropdown.open;
684
- dateDropdown.classList.toggle('open', dateDropdown.open);
685
- },
686
- onLabelInteraction: (e: Event) => {
687
- if (!this.dateDropdown?.open && !this.dateOptionSelected) {
688
- e.stopPropagation();
689
- this.clearAlphaBarFilters();
690
- this.setSelectedSort(this.lastSelectedDateSort);
691
- }
692
- },
693
- });
694
- }
695
-
696
- /**
697
- * Provides the appropriate template to use for Views sorting, depending on how many
698
- * views sort fields are available.
699
- */
700
- private get allViewsSortOptionsTemplate(): TemplateResult | typeof nothing {
701
- const numViewsSortOptions = this.availableViewsFields.length;
702
- switch (numViewsSortOptions) {
703
- case 0:
704
- return nothing;
705
- case 1:
706
- return this.viewsSortSelectorTemplate;
707
- default:
708
- return this.viewsDropdownTemplate;
709
- }
710
- }
711
-
712
- /**
713
- * Provides the appropriate template to use for Date sorting, depending on how many
714
- * date sort fields are available.
715
- */
716
- private get allDateSortOptionsTemplate(): TemplateResult | typeof nothing {
717
- const numDateSortOptions = this.availableDateFields.length;
718
- switch (numDateSortOptions) {
719
- case 0:
720
- return nothing;
721
- case 1:
722
- return this.dateSortSelectorTemplate;
723
- default:
724
- return this.dateDropdownTemplate;
725
- }
726
- }
727
-
728
- /** Handler for when a new mobile sort dropdown option is selected */
729
- private mobileSortChanged(e: CustomEvent<{ option: optionInterface }>) {
333
+ /** Handler for when a new sort dropdown option is selected */
334
+ private sortOptionSelected(e: CustomEvent<{ option: optionInterface }>) {
730
335
  this.dropdownBackdropVisible = false;
731
336
 
732
337
  const sortField = e.detail.option.id as SortField;
@@ -799,25 +404,19 @@ export class SortFilterBar
799
404
  return html`
800
405
  <div
801
406
  id="sort-selector-backdrop"
802
- @keyup=${this.closeDropdowns}
803
- @click=${this.closeDropdowns}
407
+ @keyup=${this.closeDropdown}
408
+ @click=${this.closeDropdown}
804
409
  ></div>
805
410
  `;
806
411
  }
807
412
 
808
- /** Closes all of the sorting dropdown components' menus */
809
- private closeDropdowns() {
413
+ /** Closes the sorting dropdown component's menus */
414
+ private closeDropdown() {
810
415
  this.dropdownBackdropVisible = false;
811
- const allDropdowns = [
812
- this.viewsDropdown,
813
- this.dateDropdown,
814
- this.mobileDropdown,
815
- ];
816
- for (const dropdown of allDropdowns) {
817
- if (!dropdown) continue;
818
- dropdown.open = false;
819
- dropdown.classList.remove('open');
820
- }
416
+
417
+ if (!this.sortOptionsDropdown) return;
418
+ this.sortOptionsDropdown.open = false;
419
+ this.sortOptionsDropdown.classList.remove('open');
821
420
  }
822
421
 
823
422
  private selectDropdownSortField(sortField: SortField) {
@@ -826,15 +425,7 @@ export class SortFilterBar
826
425
  this.setSelectedSort(sortField);
827
426
  }
828
427
 
829
- private clearAlphaBarFilters() {
830
- this.alphaSelectorVisible = null;
831
- this.selectedTitleFilter = null;
832
- this.selectedCreatorFilter = null;
833
- this.emitTitleLetterChangedEvent();
834
- this.emitCreatorLetterChangedEvent();
835
- }
836
-
837
- private setSortDirection(sortDirection: SortDirection) {
428
+ setSortDirection(sortDirection: SortDirection) {
838
429
  this.sortDirection = sortDirection;
839
430
  this.emitSortChangedEvent();
840
431
  }
@@ -862,7 +453,7 @@ export class SortFilterBar
862
453
  this.toggleSortDirection();
863
454
  }
864
455
 
865
- private setSelectedSort(sort: SortField) {
456
+ setSelectedSort(sort: SortField) {
866
457
  this.selectedSort = sort;
867
458
  // Apply this field's default sort direction
868
459
  const sortOption = SORT_OPTIONS[sort];
@@ -889,87 +480,6 @@ export class SortFilterBar
889
480
  return SORT_OPTIONS[this.finalizedSortField].canSetDirection;
890
481
  }
891
482
 
892
- /**
893
- * There are four date sort options.
894
- *
895
- * This checks to see if the current sort is one of them.
896
- *
897
- * @readonly
898
- * @private
899
- * @type {boolean}
900
- * @memberof SortFilterBar
901
- */
902
- private get dateOptionSelected(): boolean {
903
- const dateSortFields: SortField[] = [
904
- SortField.datefavorited,
905
- SortField.datearchived,
906
- SortField.date,
907
- SortField.datereviewed,
908
- SortField.dateadded,
909
- ];
910
- return dateSortFields.includes(this.finalizedSortField);
911
- }
912
-
913
- /**
914
- * There are two view sort options.
915
- *
916
- * This checks to see if the current sort is one of them.
917
- *
918
- * @readonly
919
- * @private
920
- * @type {boolean}
921
- * @memberof SortFilterBar
922
- */
923
- private get viewOptionSelected(): boolean {
924
- const viewSortFields: SortField[] = [
925
- SortField.alltimeview,
926
- SortField.weeklyview,
927
- ];
928
- return viewSortFields.includes(this.finalizedSortField);
929
- }
930
-
931
- /**
932
- * The display name of the last selected date field
933
- *
934
- * @readonly
935
- * @private
936
- * @type {string}
937
- * @memberof SortFilterBar
938
- */
939
- private get dateSortDisplayName(): string {
940
- return SORT_OPTIONS[this.lastSelectedDateSort].displayName;
941
- }
942
-
943
- /**
944
- * The display name of the last selected view field
945
- *
946
- * @readonly
947
- * @private
948
- * @type {string}
949
- * @memberof SortFilterBar
950
- */
951
- private get viewSortDisplayName(): string {
952
- return SORT_OPTIONS[this.lastSelectedViewSort].displayName;
953
- }
954
-
955
- /**
956
- * Array of all the views sorts that should be shown
957
- */
958
- private get availableViewsFields(): SortField[] {
959
- return ALL_VIEWS_SORT_FIELDS.filter(
960
- field => this.sortFieldAvailability[field],
961
- );
962
- }
963
-
964
- /**
965
- * Array of all the date sorts that should be shown
966
- */
967
- private get availableDateFields(): SortField[] {
968
- return ALL_DATE_SORT_FIELDS.filter(
969
- field => this.sortFieldAvailability[field],
970
- );
971
- }
972
-
973
483
  private get titleSelectorBar() {
974
484
  return html` <alpha-bar
975
485
  .selectedLetter=${this.selectedTitleFilter}
@@ -1056,6 +566,7 @@ export class SortFilterBar
1056
566
  display: flex;
1057
567
  justify-content: flex-start;
1058
568
  align-items: center;
569
+ padding-bottom: 1px;
1059
570
  border-bottom: 1px solid #2c2c2c;
1060
571
  font-size: 1.4rem;
1061
572
  }
@@ -1092,10 +603,16 @@ export class SortFilterBar
1092
603
  }
1093
604
 
1094
605
  .sort-direction-selector {
1095
- padding: 0;
1096
- border: none;
606
+ display: flex;
607
+ justify-content: center;
608
+ width: 30px;
609
+ margin: 0 5px 0 3px;
610
+ padding: 7px 8px;
611
+ max-height: fit-content;
612
+ border-radius: 5px;
613
+ background: white;
614
+ border: 1px solid rgb(25, 72, 128);
1097
615
  appearance: none;
1098
- background: transparent;
1099
616
  cursor: pointer;
1100
617
  }
1101
618
 
@@ -1111,27 +628,14 @@ export class SortFilterBar
1111
628
  border: none;
1112
629
  padding: 0;
1113
630
  outline: inherit;
1114
- width: 14px;
1115
- height: 14px;
631
+ width: 12px;
632
+ height: 12px;
1116
633
  }
1117
634
 
1118
635
  .sort-direction-icon > svg {
1119
636
  flex: 1;
1120
637
  }
1121
638
 
1122
- #date-sort-selector,
1123
- #view-sort-selector {
1124
- position: absolute;
1125
- left: 150px;
1126
- top: 45px;
1127
-
1128
- z-index: 1;
1129
- padding: 1rem;
1130
- background-color: white;
1131
- border-radius: 2.5rem;
1132
- border: 1px solid #404142;
1133
- }
1134
-
1135
639
  #sort-selector-container {
1136
640
  flex: 1;
1137
641
  display: flex;
@@ -1139,30 +643,12 @@ export class SortFilterBar
1139
643
  align-items: center;
1140
644
  }
1141
645
 
1142
- #desktop-sort-container,
1143
- #mobile-sort-container {
646
+ #sort-dropdown-container {
1144
647
  display: flex;
1145
648
  justify-content: flex-start;
1146
649
  align-items: center;
1147
650
  }
1148
651
 
1149
- /*
1150
- we move the desktop sort selector offscreen instead of display: none
1151
- because we need to observe the width of it vs its container to determine
1152
- if it's wide enough to display the desktop version and if you display: none,
1153
- the width becomes 0
1154
- */
1155
- #desktop-sort-container.hidden {
1156
- position: absolute;
1157
- top: -9999px;
1158
- left: -9999px;
1159
- visibility: hidden;
1160
- }
1161
-
1162
- #mobile-sort-container.hidden {
1163
- display: none;
1164
- }
1165
-
1166
652
  #sort-selector-backdrop {
1167
653
  position: fixed;
1168
654
  top: 0;
@@ -1173,53 +659,6 @@ export class SortFilterBar
1173
659
  background-color: transparent;
1174
660
  }
1175
661
 
1176
- #desktop-sort-selector {
1177
- display: inline-flex;
1178
- }
1179
-
1180
- #desktop-sort-selector li {
1181
- display: flex;
1182
- align-items: center;
1183
- padding-left: 5px;
1184
- padding-right: 5px;
1185
- }
1186
-
1187
- #desktop-sort-selector li a {
1188
- padding: 0 5px;
1189
- text-decoration: none;
1190
- color: #333;
1191
- line-height: 2;
1192
- }
1193
-
1194
- #desktop-sort-selector li button {
1195
- padding: 0px 5px;
1196
- border: none;
1197
- background: none;
1198
- font-family: inherit;
1199
- font-size: inherit;
1200
- color: #333;
1201
- line-height: 2;
1202
- cursor: pointer;
1203
- appearance: none;
1204
- }
1205
-
1206
- #desktop-sort-selector li button.selected {
1207
- font-weight: bold;
1208
- }
1209
-
1210
- /**
1211
- * Fix to not shift the sort-bar options when get selected
1212
- */
1213
- #desktop-sort-selector li button::before,
1214
- #desktop-sort-selector .dropdown-label::before {
1215
- display: block;
1216
- content: attr(data-title);
1217
- font-weight: bold;
1218
- height: 0;
1219
- overflow: hidden;
1220
- visibility: hidden;
1221
- }
1222
-
1223
662
  #display-style-selector {
1224
663
  flex: 0;
1225
664
  }