@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.
- package/dist/index.js.map +1 -1
- package/dist/src/app-root.js +614 -614
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.js +764 -774
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.js +121 -121
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
- package/dist/src/models.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +13 -172
- package/dist/src/sort-filter-bar/sort-filter-bar.js +37 -546
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/grid/collection-tile.js +89 -89
- package/dist/src/tiles/grid/collection-tile.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +138 -138
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/hover/hover-pane-controller.js +28 -28
- package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
- package/dist/src/tiles/models.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.js +216 -216
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/test/collection-browser.test.js +197 -202
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +86 -401
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
- package/index.ts +28 -28
- package/package.json +1 -1
- package/src/app-root.ts +1166 -1166
- package/src/collection-browser.ts +3065 -3075
- package/src/collection-facets/more-facets-content.ts +644 -644
- package/src/data-source/collection-browser-query-state.ts +59 -59
- package/src/models.ts +873 -873
- package/src/sort-filter-bar/sort-filter-bar.ts +42 -603
- package/src/tiles/grid/collection-tile.ts +184 -184
- package/src/tiles/grid/item-tile.ts +346 -346
- package/src/tiles/hover/hover-pane-controller.ts +627 -627
- package/src/tiles/models.ts +8 -8
- package/src/tiles/tile-dispatcher.ts +518 -518
- package/test/collection-browser.test.ts +2402 -2413
- 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
|
-
|
|
133
|
-
|
|
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.
|
|
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.
|
|
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
|
|
394
|
-
private get
|
|
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: '
|
|
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.
|
|
260
|
+
onOptionSelected: this.sortOptionSelected,
|
|
431
261
|
onDropdownClick: () => {
|
|
432
|
-
this.dropdownBackdropVisible = this.
|
|
433
|
-
this.
|
|
262
|
+
this.dropdownBackdropVisible = this.sortOptionsDropdown.open;
|
|
263
|
+
this.sortOptionsDropdown.classList.toggle(
|
|
434
264
|
'open',
|
|
435
|
-
this.
|
|
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
|
|
554
|
-
private
|
|
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.
|
|
803
|
-
@click=${this.
|
|
407
|
+
@keyup=${this.closeDropdown}
|
|
408
|
+
@click=${this.closeDropdown}
|
|
804
409
|
></div>
|
|
805
410
|
`;
|
|
806
411
|
}
|
|
807
412
|
|
|
808
|
-
/** Closes
|
|
809
|
-
private
|
|
413
|
+
/** Closes the sorting dropdown component's menus */
|
|
414
|
+
private closeDropdown() {
|
|
810
415
|
this.dropdownBackdropVisible = false;
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1096
|
-
|
|
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:
|
|
1115
|
-
height:
|
|
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
|
-
#
|
|
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
|
}
|