@internetarchive/collection-browser 0.0.1-alpha.2 → 0.0.1-alpha.22
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/demo/app-root.ts +24 -158
- package/dist/demo/app-root.d.ts +2 -16
- package/dist/demo/app-root.js +23 -141
- package/dist/demo/app-root.js.map +1 -1
- package/dist/src/assets/img/icons/chevron.d.ts +2 -0
- package/dist/src/assets/img/icons/chevron.js +4 -0
- package/dist/src/assets/img/icons/chevron.js.map +1 -0
- package/dist/src/assets/img/icons/eye-closed.d.ts +2 -0
- package/dist/src/assets/img/icons/eye-closed.js +5 -0
- package/dist/src/assets/img/icons/eye-closed.js.map +1 -0
- package/dist/src/assets/img/icons/eye.d.ts +2 -0
- package/dist/src/assets/img/icons/eye.js +5 -0
- package/dist/src/assets/img/icons/eye.js.map +1 -0
- package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -2
- package/dist/src/assets/img/icons/mediatype/account.js +5 -4
- package/dist/src/assets/img/icons/mediatype/account.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/audio.js +7 -4
- package/dist/src/assets/img/icons/mediatype/audio.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/collection.js +7 -4
- package/dist/src/assets/img/icons/mediatype/collection.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/etree.js +10 -5
- package/dist/src/assets/img/icons/mediatype/etree.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/film.js +2 -1
- package/dist/src/assets/img/icons/mediatype/film.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/images.js +9 -6
- package/dist/src/assets/img/icons/mediatype/images.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/software.js +9 -6
- package/dist/src/assets/img/icons/mediatype/software.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/texts.js +9 -6
- package/dist/src/assets/img/icons/mediatype/texts.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/tv.js +10 -5
- package/dist/src/assets/img/icons/mediatype/tv.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/video.js +10 -6
- package/dist/src/assets/img/icons/mediatype/video.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/web.js +9 -6
- package/dist/src/assets/img/icons/mediatype/web.js.map +1 -1
- package/dist/src/async-collection-name.d.ts +11 -0
- package/dist/src/async-collection-name.js +38 -0
- package/dist/src/async-collection-name.js.map +1 -0
- package/dist/src/collection-browser.d.ts +55 -17
- package/dist/src/collection-browser.js +466 -106
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets.d.ts +24 -5
- package/dist/src/collection-facets.js +300 -78
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/collection-name-cache.d.ts +18 -0
- package/dist/src/collection-name-cache.js +89 -0
- package/dist/src/collection-name-cache.js.map +1 -0
- package/dist/src/mediatype-icon.js +10 -3
- package/dist/src/mediatype-icon.js.map +1 -1
- package/dist/src/models.d.ts +72 -14
- package/dist/src/models.js +57 -1
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +37 -0
- package/dist/src/restoration-state-handler.js +177 -0
- package/dist/src/restoration-state-handler.js.map +1 -0
- package/dist/src/sort-filter-bar/alpha-bar.d.ts +1 -2
- package/dist/src/sort-filter-bar/alpha-bar.js +19 -9
- package/dist/src/sort-filter-bar/alpha-bar.js.map +1 -1
- package/dist/src/sort-filter-bar/img/compact.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/compact.js +5 -0
- package/dist/src/sort-filter-bar/img/compact.js.map +1 -0
- package/dist/src/sort-filter-bar/img/grid.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/grid.js +5 -0
- package/dist/src/sort-filter-bar/img/grid.js.map +1 -0
- package/dist/src/sort-filter-bar/img/list.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/list.js +5 -0
- package/dist/src/sort-filter-bar/img/list.js.map +1 -0
- package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/sort-triangle.js +5 -0
- package/dist/src/sort-filter-bar/img/sort-triangle.js.map +1 -0
- package/dist/src/sort-filter-bar/img/tile.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/tile.js +5 -0
- package/dist/src/sort-filter-bar/img/tile.js.map +1 -0
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +65 -11
- package/dist/src/sort-filter-bar/sort-filter-bar.js +453 -142
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/grid/collection-tile.js +1 -2
- package/dist/src/tiles/grid/collection-tile.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.d.ts +4 -0
- package/dist/src/tiles/grid/item-tile.js +134 -45
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.d.ts +11 -0
- package/dist/src/tiles/list/tile-list-compact-header.js +79 -0
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -0
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -0
- package/dist/src/tiles/list/tile-list-compact.js +122 -31
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list-detail.d.ts +0 -10
- package/dist/src/tiles/list/tile-list-detail.js +6 -159
- package/dist/src/tiles/list/tile-list-detail.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +19 -6
- package/dist/src/tiles/list/tile-list.js +240 -108
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +8 -1
- package/dist/src/tiles/tile-dispatcher.js +46 -11
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/src/utils/format-date.js +1 -2
- package/dist/src/utils/format-date.js.map +1 -1
- package/dist/test/{utils/format-string.test.d.ts → collection-name-cache.test.d.ts} +0 -0
- package/dist/test/collection-name-cache.test.js +158 -0
- package/dist/test/collection-name-cache.test.js.map +1 -0
- package/dist/test/mocks/mock-search-response.d.ts +5 -0
- package/dist/test/mocks/mock-search-response.js +62 -0
- package/dist/test/mocks/mock-search-response.js.map +1 -0
- package/dist/test/mocks/mock-search-service.d.ts +13 -0
- package/dist/test/mocks/mock-search-service.js +20 -0
- package/dist/test/mocks/mock-search-service.js.map +1 -0
- package/package.json +9 -4
- package/src/assets/img/icons/chevron.ts +4 -0
- package/src/assets/img/icons/eye-closed.ts +5 -0
- package/src/assets/img/icons/eye.ts +5 -0
- package/src/assets/img/icons/mediatype/account.ts +5 -4
- package/src/assets/img/icons/mediatype/audio.ts +7 -4
- package/src/assets/img/icons/mediatype/collection.ts +7 -4
- package/src/assets/img/icons/mediatype/etree.ts +10 -5
- package/src/assets/img/icons/mediatype/film.ts +2 -1
- package/src/assets/img/icons/mediatype/images.ts +9 -6
- package/src/assets/img/icons/mediatype/software.ts +9 -6
- package/src/assets/img/icons/mediatype/texts.ts +9 -6
- package/src/assets/img/icons/mediatype/tv.ts +10 -5
- package/src/assets/img/icons/mediatype/video.ts +10 -6
- package/src/assets/img/icons/mediatype/web.ts +9 -6
- package/src/collection-browser.ts +490 -105
- package/src/collection-facets.ts +325 -109
- package/src/mediatype-icon.ts +10 -3
- package/src/models.ts +139 -14
- package/src/restoration-state-handler.ts +234 -0
- package/src/sort-filter-bar/alpha-bar.ts +19 -9
- package/src/sort-filter-bar/img/compact.ts +5 -0
- package/src/sort-filter-bar/img/list.ts +5 -0
- package/src/sort-filter-bar/img/sort-triangle.ts +5 -0
- package/src/sort-filter-bar/img/tile.ts +5 -0
- package/src/sort-filter-bar/sort-filter-bar.ts +499 -149
- package/src/tiles/grid/collection-tile.ts +1 -2
- package/src/tiles/grid/item-tile.ts +138 -56
- package/src/tiles/list/tile-list-compact-header.ts +75 -0
- package/src/tiles/list/tile-list-compact.ts +209 -0
- package/src/tiles/list/tile-list.ts +261 -110
- package/src/tiles/tile-dispatcher.ts +51 -11
- package/src/utils/format-date.ts +1 -2
- package/dist/src/assets/img/icons/audio.d.ts +0 -1
- package/dist/src/assets/img/icons/audio.js +0 -9
- package/dist/src/assets/img/icons/audio.js.map +0 -1
- package/dist/src/assets/img/icons/collection.d.ts +0 -1
- package/dist/src/assets/img/icons/collection.js +0 -9
- package/dist/src/assets/img/icons/collection.js.map +0 -1
- package/dist/src/assets/img/icons/etree.d.ts +0 -1
- package/dist/src/assets/img/icons/etree.js +0 -9
- package/dist/src/assets/img/icons/etree.js.map +0 -1
- package/dist/src/assets/img/icons/images.d.ts +0 -1
- package/dist/src/assets/img/icons/images.js +0 -10
- package/dist/src/assets/img/icons/images.js.map +0 -1
- package/dist/src/assets/img/icons/mediatype/etree copy.d.ts +0 -1
- package/dist/src/assets/img/icons/mediatype/etree copy.js +0 -9
- package/dist/src/assets/img/icons/mediatype/etree copy.js.map +0 -1
- package/dist/src/assets/img/icons/mediatype/livemusic.d.ts +0 -1
- package/dist/src/assets/img/icons/mediatype/livemusic.js +0 -7
- package/dist/src/assets/img/icons/mediatype/livemusic.js.map +0 -1
- package/dist/src/assets/img/icons/mediatype/photos.d.ts +0 -1
- package/dist/src/assets/img/icons/mediatype/photos.js +0 -7
- package/dist/src/assets/img/icons/mediatype/photos.js.map +0 -1
- package/dist/src/assets/img/icons/software.d.ts +0 -1
- package/dist/src/assets/img/icons/software.js +0 -10
- package/dist/src/assets/img/icons/software.js.map +0 -1
- package/dist/src/assets/img/icons/texts.d.ts +0 -1
- package/dist/src/assets/img/icons/texts.js +0 -10
- package/dist/src/assets/img/icons/texts.js.map +0 -1
- package/dist/src/assets/img/icons/tv.d.ts +0 -1
- package/dist/src/assets/img/icons/tv.js +0 -9
- package/dist/src/assets/img/icons/tv.js.map +0 -1
- package/dist/src/assets/img/icons/video.d.ts +0 -1
- package/dist/src/assets/img/icons/video.js +0 -10
- package/dist/src/assets/img/icons/video.js.map +0 -1
- package/dist/src/assets/img/icons/web.d.ts +0 -1
- package/dist/src/assets/img/icons/web.js +0 -10
- package/dist/src/assets/img/icons/web.js.map +0 -1
- package/dist/src/utils/format-string.d.ts +0 -2
- package/dist/src/utils/format-string.js +0 -7
- package/dist/src/utils/format-string.js.map +0 -1
- package/dist/test/utils/format-string.test.js +0 -17
- package/dist/test/utils/format-string.test.js.map +0 -1
- package/src/assets/img/icons/mediatype/foo.svg +0 -5
|
@@ -1,16 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
LitElement,
|
|
3
|
+
html,
|
|
4
|
+
css,
|
|
5
|
+
nothing,
|
|
6
|
+
PropertyValues,
|
|
7
|
+
TemplateResult,
|
|
8
|
+
} from 'lit';
|
|
9
|
+
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
10
|
+
import {
|
|
11
|
+
SharedResizeObserverInterface,
|
|
12
|
+
SharedResizeObserverResizeHandlerInterface,
|
|
13
|
+
} from '@internetarchive/shared-resize-observer';
|
|
14
|
+
import {
|
|
15
|
+
CollectionDisplayMode,
|
|
16
|
+
SortField,
|
|
17
|
+
SortFieldDisplayName,
|
|
18
|
+
} from '../models';
|
|
5
19
|
import './alpha-bar';
|
|
6
20
|
|
|
21
|
+
import { sortIcon } from './img/sort-triangle';
|
|
22
|
+
import { tileIcon } from './img/tile';
|
|
23
|
+
import { listIcon } from './img/list';
|
|
24
|
+
import { compactIcon } from './img/compact';
|
|
25
|
+
|
|
7
26
|
@customElement('sort-filter-bar')
|
|
8
|
-
export class SortFilterBar
|
|
9
|
-
|
|
27
|
+
export class SortFilterBar
|
|
28
|
+
extends LitElement
|
|
29
|
+
implements SharedResizeObserverResizeHandlerInterface
|
|
30
|
+
{
|
|
31
|
+
@property({ type: String }) displayMode?: CollectionDisplayMode;
|
|
32
|
+
|
|
33
|
+
@property({ type: String }) sortDirection: 'asc' | 'desc' | null = null;
|
|
34
|
+
|
|
35
|
+
@property({ type: String }) selectedSort: SortField = SortField.relevance;
|
|
36
|
+
|
|
37
|
+
@property({ type: String }) selectedTitleFilter: string | null = null;
|
|
38
|
+
|
|
39
|
+
@property({ type: String }) selectedCreatorFilter: string | null = null;
|
|
10
40
|
|
|
11
|
-
@property({ type:
|
|
41
|
+
@property({ type: Boolean }) showRelevance: boolean = true;
|
|
12
42
|
|
|
13
|
-
@property({ type:
|
|
43
|
+
@property({ type: Object }) resizeObserver?: SharedResizeObserverInterface;
|
|
14
44
|
|
|
15
45
|
@state() titleSelectorVisible: boolean = false;
|
|
16
46
|
|
|
@@ -18,90 +48,43 @@ export class SortFilterBar extends LitElement {
|
|
|
18
48
|
|
|
19
49
|
@state() dateSortSelectorVisible = false;
|
|
20
50
|
|
|
51
|
+
@state() desktopSelectorBarWidth = 0;
|
|
52
|
+
|
|
53
|
+
@state() selectorBarContainerWidth = 0;
|
|
54
|
+
|
|
55
|
+
@query('#desktop-sort-selector')
|
|
56
|
+
private desktopSortSelector!: HTMLUListElement;
|
|
57
|
+
|
|
58
|
+
@query('#sort-selector-container')
|
|
59
|
+
private sortSelectorContainer!: HTMLDivElement;
|
|
60
|
+
|
|
21
61
|
render() {
|
|
22
62
|
return html`
|
|
23
|
-
<div id="
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@click=${() => {
|
|
36
|
-
this.sortDirection = 'asc';
|
|
37
|
-
}}
|
|
38
|
-
>
|
|
39
|
-
Asc</button
|
|
40
|
-
>Sort By
|
|
41
|
-
</li>
|
|
42
|
-
<li>
|
|
43
|
-
<button
|
|
44
|
-
@click=${() => {
|
|
45
|
-
this.sortField = 'week';
|
|
46
|
-
}}
|
|
47
|
-
>
|
|
48
|
-
Views
|
|
49
|
-
</button>
|
|
50
|
-
</li>
|
|
51
|
-
<li>
|
|
52
|
-
<button
|
|
53
|
-
@click=${() => {
|
|
54
|
-
this.titleSelectorVisible = !this.titleSelectorVisible;
|
|
55
|
-
this.sortField = 'titleSorter';
|
|
56
|
-
}}
|
|
57
|
-
>
|
|
58
|
-
Title
|
|
59
|
-
</button>
|
|
60
|
-
</li>
|
|
61
|
-
<li>
|
|
62
|
-
<button
|
|
63
|
-
@click=${() => {
|
|
64
|
-
this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
|
|
65
|
-
}}
|
|
66
|
-
>
|
|
67
|
-
Date Archived
|
|
68
|
-
</button>
|
|
69
|
-
</li>
|
|
70
|
-
<li>
|
|
71
|
-
<button
|
|
72
|
-
@click=${() => {
|
|
73
|
-
this.creatorSelectorVisible = !this.creatorSelectorVisible;
|
|
74
|
-
this.sortField = 'creatorSorter';
|
|
75
|
-
}}
|
|
76
|
-
>
|
|
77
|
-
Creator
|
|
78
|
-
</button>
|
|
79
|
-
</li>
|
|
80
|
-
</ul>
|
|
81
|
-
</div>
|
|
63
|
+
<div id="container">
|
|
64
|
+
${this.titleSelectorVisible || this.selectedSort === 'title'
|
|
65
|
+
? this.titleSelectorBar
|
|
66
|
+
: nothing}
|
|
67
|
+
${this.creatorSelectorVisible || this.selectedSort === 'creator'
|
|
68
|
+
? this.creatorSelectorBar
|
|
69
|
+
: nothing}
|
|
70
|
+
|
|
71
|
+
<div id="sort-bar">
|
|
72
|
+
<div id="sort-direction-container">
|
|
73
|
+
${this.sortDirectionSelectorTemplate}
|
|
74
|
+
</div>
|
|
82
75
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
${this.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
</li>`
|
|
90
|
-
: nothing}
|
|
91
|
-
|
|
92
|
-
<li>
|
|
93
|
-
<button id="grid-button" @click=${this.gridSelected}>Grid</button>
|
|
94
|
-
</li>
|
|
95
|
-
<li>
|
|
96
|
-
<button id="list-button" @click=${this.listSelected}>List</button>
|
|
97
|
-
</li>
|
|
98
|
-
</ul>
|
|
76
|
+
<div id="sort-selector-container">
|
|
77
|
+
${this.mobileSortSelectorTemplate}
|
|
78
|
+
${this.desktopSortSelectorTemplate}
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div id="display-style-selector">${this.displayOptionTemplate}</div>
|
|
99
82
|
</div>
|
|
100
|
-
</div>
|
|
101
83
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
84
|
+
${this.dateSortSelectorVisible ? this.dateSortSelector : nothing}
|
|
85
|
+
|
|
86
|
+
<div id="bottom-shadow"></div>
|
|
87
|
+
</div>
|
|
105
88
|
`;
|
|
106
89
|
}
|
|
107
90
|
|
|
@@ -110,66 +93,318 @@ export class SortFilterBar extends LitElement {
|
|
|
110
93
|
this.displayModeChanged();
|
|
111
94
|
}
|
|
112
95
|
|
|
113
|
-
if (changed.has('
|
|
114
|
-
this.
|
|
96
|
+
if (changed.has('selectedSort') && this.sortDirection === null) {
|
|
97
|
+
this.sortDirection = 'desc';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (changed.has('selectedTitleFilter') && this.selectedTitleFilter) {
|
|
101
|
+
this.titleSelectorVisible = true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (changed.has('selectedCreatorFilter') && this.selectedCreatorFilter) {
|
|
105
|
+
this.creatorSelectorVisible = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (changed.has('resizeObserver')) {
|
|
109
|
+
const oldObserver = changed.get(
|
|
110
|
+
'resizeObserver'
|
|
111
|
+
) as SharedResizeObserverInterface;
|
|
112
|
+
if (oldObserver) this.disconnectResizeObserver(oldObserver);
|
|
113
|
+
this.setupResizeObserver();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
disconnectedCallback(): void {
|
|
118
|
+
if (this.resizeObserver) {
|
|
119
|
+
this.disconnectResizeObserver(this.resizeObserver);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private disconnectResizeObserver(
|
|
124
|
+
resizeObserver: SharedResizeObserverInterface
|
|
125
|
+
) {
|
|
126
|
+
resizeObserver.removeObserver({
|
|
127
|
+
target: this.sortSelectorContainer,
|
|
128
|
+
handler: this,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
resizeObserver.removeObserver({
|
|
132
|
+
target: this.desktopSortSelector,
|
|
133
|
+
handler: this,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private setupResizeObserver() {
|
|
138
|
+
if (!this.resizeObserver) return;
|
|
139
|
+
this.resizeObserver.addObserver({
|
|
140
|
+
target: this.sortSelectorContainer,
|
|
141
|
+
handler: this,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
this.resizeObserver.addObserver({
|
|
145
|
+
target: this.desktopSortSelector,
|
|
146
|
+
handler: this,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private get mobileSelectorVisible() {
|
|
151
|
+
return this.selectorBarContainerWidth - 10 < this.desktopSelectorBarWidth;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
handleResize(entry: ResizeObserverEntry): void {
|
|
155
|
+
if (entry.target === this.desktopSortSelector)
|
|
156
|
+
this.desktopSelectorBarWidth = entry.contentRect.width;
|
|
157
|
+
else if (entry.target === this.sortSelectorContainer)
|
|
158
|
+
this.selectorBarContainerWidth = entry.contentRect.width;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private get sortDirectionSelectorTemplate() {
|
|
162
|
+
return html`
|
|
163
|
+
<div id="sort-direction-selector">
|
|
164
|
+
<button
|
|
165
|
+
id="sort-ascending-btn"
|
|
166
|
+
class="sort-button ${this.sortDirection === 'asc' ? 'selected' : ''}"
|
|
167
|
+
?disabled=${this.selectedSort === 'relevance'}
|
|
168
|
+
@click=${() => {
|
|
169
|
+
this.setSortDirections('asc');
|
|
170
|
+
}}
|
|
171
|
+
>
|
|
172
|
+
${sortIcon}
|
|
173
|
+
</button>
|
|
174
|
+
<button
|
|
175
|
+
id="sort-descending-btn"
|
|
176
|
+
class="sort-button ${this.sortDirection === 'desc' ? 'selected' : ''}"
|
|
177
|
+
?disabled=${this.selectedSort === 'relevance'}
|
|
178
|
+
@click=${() => {
|
|
179
|
+
this.setSortDirections('desc');
|
|
180
|
+
}}
|
|
181
|
+
>
|
|
182
|
+
${sortIcon}
|
|
183
|
+
</button>
|
|
184
|
+
</div>
|
|
185
|
+
`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private get desktopSortSelectorTemplate() {
|
|
189
|
+
return html`
|
|
190
|
+
<ul
|
|
191
|
+
id="desktop-sort-selector"
|
|
192
|
+
class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}
|
|
193
|
+
>
|
|
194
|
+
<li id="sort-by-text">Sort By</li>
|
|
195
|
+
<li>
|
|
196
|
+
${this.showRelevance
|
|
197
|
+
? this.getSortDisplayOption(SortField.relevance)
|
|
198
|
+
: nothing}
|
|
199
|
+
</li>
|
|
200
|
+
<li>${this.getSortDisplayOption(SortField.views)}</li>
|
|
201
|
+
<li>${this.getSortDisplayOption(SortField.title)}</li>
|
|
202
|
+
<li>
|
|
203
|
+
${this.getSortDisplayOption(SortField.datearchived, {
|
|
204
|
+
additionalClickEvent: () => {
|
|
205
|
+
this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
|
|
206
|
+
},
|
|
207
|
+
displayName: html`${this.dateSortField}`,
|
|
208
|
+
isSelected: () => this.dateOptionSelected,
|
|
209
|
+
})}
|
|
210
|
+
</li>
|
|
211
|
+
<li>
|
|
212
|
+
${this.getSortDisplayOption(SortField.creator, {
|
|
213
|
+
additionalClickEvent: () => {
|
|
214
|
+
this.creatorSelectorVisible = !this.creatorSelectorVisible;
|
|
215
|
+
},
|
|
216
|
+
})}
|
|
217
|
+
</li>
|
|
218
|
+
</ul>
|
|
219
|
+
`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* This generates each of the sort option links.
|
|
224
|
+
*
|
|
225
|
+
* It manages the display value and the selected state of the option.
|
|
226
|
+
*
|
|
227
|
+
* @param sortField
|
|
228
|
+
* @param options {
|
|
229
|
+
* additionalClickEvent?: () => void; If this is provided, it will also be called when the option is clicked.
|
|
230
|
+
* displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.
|
|
231
|
+
* isSelected?: () => boolean; A function that returns true if the option is selected. Defaults to the selectedSort === sortField.
|
|
232
|
+
* }
|
|
233
|
+
* @returns
|
|
234
|
+
*/
|
|
235
|
+
private getSortDisplayOption(
|
|
236
|
+
sortField: SortField,
|
|
237
|
+
options?: {
|
|
238
|
+
additionalClickEvent?: (e: Event) => void;
|
|
239
|
+
isSelected?: () => boolean;
|
|
240
|
+
displayName?: TemplateResult;
|
|
115
241
|
}
|
|
242
|
+
): TemplateResult {
|
|
243
|
+
const isSelected =
|
|
244
|
+
options?.isSelected ?? (() => this.selectedSort === sortField);
|
|
245
|
+
const displayName = options?.displayName ?? SortFieldDisplayName[sortField];
|
|
246
|
+
return html`
|
|
247
|
+
<a
|
|
248
|
+
href="#"
|
|
249
|
+
@click=${(e: Event) => {
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
this.setSelectedSort(sortField);
|
|
252
|
+
options?.additionalClickEvent?.(e);
|
|
253
|
+
}}
|
|
254
|
+
class=${isSelected() ? 'selected' : ''}
|
|
255
|
+
>
|
|
256
|
+
${displayName}
|
|
257
|
+
</a>
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private get mobileSortSelectorTemplate() {
|
|
262
|
+
return html`
|
|
263
|
+
<select
|
|
264
|
+
id="mobile-sort-selector"
|
|
265
|
+
@change=${this.mobileSortChanged}
|
|
266
|
+
class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
|
|
267
|
+
>
|
|
268
|
+
${Object.keys(SortField).map(
|
|
269
|
+
field => html`
|
|
270
|
+
<option value="${field}" ?selected=${this.selectedSort === field}>
|
|
271
|
+
${SortFieldDisplayName[field as SortField]}
|
|
272
|
+
</option>
|
|
273
|
+
`
|
|
274
|
+
)}
|
|
275
|
+
</select>
|
|
276
|
+
`;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private mobileSortChanged(e: Event) {
|
|
280
|
+
const target = e.target as HTMLSelectElement;
|
|
281
|
+
this.setSelectedSort(target.value as SortField);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private get displayOptionTemplate() {
|
|
285
|
+
return html`
|
|
286
|
+
<ul>
|
|
287
|
+
<li>
|
|
288
|
+
<button
|
|
289
|
+
id="grid-button"
|
|
290
|
+
@click=${() => {
|
|
291
|
+
this.displayMode = 'grid';
|
|
292
|
+
}}
|
|
293
|
+
class=${this.displayMode === 'grid' ? 'active' : ''}
|
|
294
|
+
>
|
|
295
|
+
${tileIcon}
|
|
296
|
+
</button>
|
|
297
|
+
</li>
|
|
298
|
+
<li>
|
|
299
|
+
<button
|
|
300
|
+
id="grid-button"
|
|
301
|
+
@click=${() => {
|
|
302
|
+
this.displayMode = 'list-detail';
|
|
303
|
+
}}
|
|
304
|
+
class=${this.displayMode === 'list-detail' ? 'active' : ''}
|
|
305
|
+
>
|
|
306
|
+
${listIcon}
|
|
307
|
+
</button>
|
|
308
|
+
</li>
|
|
309
|
+
<li>
|
|
310
|
+
<button
|
|
311
|
+
id="list-button"
|
|
312
|
+
@click=${() => {
|
|
313
|
+
this.displayMode = 'list-compact';
|
|
314
|
+
}}
|
|
315
|
+
class=${this.displayMode === 'list-compact' ? 'active' : ''}
|
|
316
|
+
>
|
|
317
|
+
${compactIcon}
|
|
318
|
+
</button>
|
|
319
|
+
</li>
|
|
320
|
+
</ul>
|
|
321
|
+
`;
|
|
116
322
|
}
|
|
117
323
|
|
|
118
324
|
private get dateSortSelector() {
|
|
119
325
|
return html`
|
|
120
326
|
<div id="date-sort-selector">
|
|
121
327
|
<ul>
|
|
122
|
-
<li>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}}
|
|
127
|
-
>
|
|
128
|
-
Date Archived
|
|
129
|
-
</button>
|
|
130
|
-
</li>
|
|
131
|
-
<li>
|
|
132
|
-
<button
|
|
133
|
-
@click=${() => {
|
|
134
|
-
this.sortField = 'date';
|
|
135
|
-
}}
|
|
136
|
-
>
|
|
137
|
-
Date Published
|
|
138
|
-
</button>
|
|
139
|
-
</li>
|
|
140
|
-
<li>
|
|
141
|
-
<button
|
|
142
|
-
@click=${() => {
|
|
143
|
-
this.sortField = 'reviewdate';
|
|
144
|
-
}}
|
|
145
|
-
>
|
|
146
|
-
Date Reviewed
|
|
147
|
-
</button>
|
|
148
|
-
</li>
|
|
149
|
-
<li>
|
|
150
|
-
<button
|
|
151
|
-
@click=${() => {
|
|
152
|
-
this.sortField = 'addeddate';
|
|
153
|
-
}}
|
|
154
|
-
>
|
|
155
|
-
Date Added
|
|
156
|
-
</button>
|
|
157
|
-
</li>
|
|
328
|
+
<li>${this.getDateSortButton(SortField.datearchived)}</li>
|
|
329
|
+
<li>${this.getDateSortButton(SortField.datepublished)}</li>
|
|
330
|
+
<li>${this.getDateSortButton(SortField.datereviewed)}</li>
|
|
331
|
+
<li>${this.getDateSortButton(SortField.dateadded)}</li>
|
|
158
332
|
</ul>
|
|
159
333
|
</div>
|
|
160
334
|
`;
|
|
161
335
|
}
|
|
162
336
|
|
|
337
|
+
private getDateSortButton(sortField: SortField) {
|
|
338
|
+
return html`
|
|
339
|
+
<button
|
|
340
|
+
@click=${() => {
|
|
341
|
+
this.selectDateSort(sortField);
|
|
342
|
+
}}
|
|
343
|
+
>
|
|
344
|
+
${SortFieldDisplayName[sortField]}
|
|
345
|
+
</button>
|
|
346
|
+
`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private selectDateSort(sortField: SortField) {
|
|
350
|
+
this.dateSortSelectorVisible = false;
|
|
351
|
+
this.setSelectedSort(sortField);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private setSortDirections(sortDirection: 'asc' | 'desc') {
|
|
355
|
+
this.sortDirection = sortDirection;
|
|
356
|
+
this.emitSortChangedEvent();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
private setSelectedSort(sort: SortField) {
|
|
360
|
+
this.selectedSort = sort;
|
|
361
|
+
this.emitSortChangedEvent();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* There are four date sort options.
|
|
366
|
+
*
|
|
367
|
+
* This checks to see if the current sort is one of them.
|
|
368
|
+
*
|
|
369
|
+
* @readonly
|
|
370
|
+
* @private
|
|
371
|
+
* @type {boolean}
|
|
372
|
+
* @memberof SortFilterBar
|
|
373
|
+
*/
|
|
374
|
+
private get dateOptionSelected(): boolean {
|
|
375
|
+
return [
|
|
376
|
+
'datearchived',
|
|
377
|
+
'datepublished',
|
|
378
|
+
'datereviewed',
|
|
379
|
+
'dateadded',
|
|
380
|
+
].includes(this.selectedSort);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* The display name of the current date field
|
|
385
|
+
*
|
|
386
|
+
* @readonly
|
|
387
|
+
* @private
|
|
388
|
+
* @type {string}
|
|
389
|
+
* @memberof SortFilterBar
|
|
390
|
+
*/
|
|
391
|
+
private get dateSortField(): string {
|
|
392
|
+
const defaultSort = SortFieldDisplayName[SortField.datearchived];
|
|
393
|
+
return this.dateOptionSelected
|
|
394
|
+
? SortFieldDisplayName[this.selectedSort] ?? defaultSort
|
|
395
|
+
: defaultSort;
|
|
396
|
+
}
|
|
397
|
+
|
|
163
398
|
private get titleSelectorBar() {
|
|
164
399
|
return html` <alpha-bar
|
|
165
|
-
|
|
400
|
+
.selectedLetter=${this.selectedTitleFilter}
|
|
166
401
|
@letterChanged=${this.titleLetterChanged}
|
|
167
402
|
></alpha-bar>`;
|
|
168
403
|
}
|
|
169
404
|
|
|
170
405
|
private get creatorSelectorBar() {
|
|
171
406
|
return html` <alpha-bar
|
|
172
|
-
|
|
407
|
+
.selectedLetter=${this.selectedCreatorFilter}
|
|
173
408
|
@letterChanged=${this.creatorLetterChanged}
|
|
174
409
|
></alpha-bar>`;
|
|
175
410
|
}
|
|
@@ -192,20 +427,6 @@ export class SortFilterBar extends LitElement {
|
|
|
192
427
|
this.dispatchEvent(event);
|
|
193
428
|
}
|
|
194
429
|
|
|
195
|
-
private gridSelected() {
|
|
196
|
-
this.displayMode = 'grid';
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
private listSelected() {
|
|
200
|
-
this.displayMode = 'list-compact';
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private detailSelected(e: Event) {
|
|
204
|
-
this.displayMode = (e.target as HTMLInputElement).checked
|
|
205
|
-
? 'list-detail'
|
|
206
|
-
: 'list-compact';
|
|
207
|
-
}
|
|
208
|
-
|
|
209
430
|
private displayModeChanged() {
|
|
210
431
|
const event = new CustomEvent('displayModeChanged', {
|
|
211
432
|
detail: { displayMode: this.displayMode },
|
|
@@ -213,10 +434,15 @@ export class SortFilterBar extends LitElement {
|
|
|
213
434
|
this.dispatchEvent(event);
|
|
214
435
|
}
|
|
215
436
|
|
|
216
|
-
private
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
437
|
+
private emitSortChangedEvent() {
|
|
438
|
+
const event = new CustomEvent<{
|
|
439
|
+
selectedSort: SortField;
|
|
440
|
+
sortDirection: 'asc' | 'desc' | null;
|
|
441
|
+
}>('sortChanged', {
|
|
442
|
+
detail: {
|
|
443
|
+
selectedSort: this.selectedSort,
|
|
444
|
+
sortDirection: this.sortDirection,
|
|
445
|
+
},
|
|
220
446
|
});
|
|
221
447
|
this.dispatchEvent(event);
|
|
222
448
|
}
|
|
@@ -225,6 +451,24 @@ export class SortFilterBar extends LitElement {
|
|
|
225
451
|
#sort-bar {
|
|
226
452
|
display: flex;
|
|
227
453
|
justify-content: space-between;
|
|
454
|
+
border: 1px solid rgb(232, 232, 232);
|
|
455
|
+
align-items: center;
|
|
456
|
+
padding: 0.5rem 1.5rem;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
#sort-direction-container {
|
|
460
|
+
flex: 0;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
#sort-by-text {
|
|
464
|
+
text-transform: uppercase;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
#bottom-shadow {
|
|
468
|
+
height: 1px;
|
|
469
|
+
width: 100%;
|
|
470
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
|
471
|
+
background-color: #bbb;
|
|
228
472
|
}
|
|
229
473
|
|
|
230
474
|
ul {
|
|
@@ -236,21 +480,127 @@ export class SortFilterBar extends LitElement {
|
|
|
236
480
|
}
|
|
237
481
|
|
|
238
482
|
li {
|
|
239
|
-
padding: 0
|
|
483
|
+
padding: 0;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.sort-button {
|
|
487
|
+
background: none;
|
|
488
|
+
color: inherit;
|
|
489
|
+
border: none;
|
|
490
|
+
padding: 0;
|
|
491
|
+
cursor: pointer;
|
|
492
|
+
outline: inherit;
|
|
493
|
+
width: 12px;
|
|
494
|
+
height: 12px;
|
|
495
|
+
opacity: 0.5;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.sort-button.selected {
|
|
499
|
+
opacity: 1;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.sort-button:disabled {
|
|
503
|
+
opacity: 0.25;
|
|
504
|
+
cursor: default;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
#show-details {
|
|
508
|
+
text-transform: uppercase;
|
|
509
|
+
cursor: pointer;
|
|
510
|
+
display: flex;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
#show-details input {
|
|
514
|
+
margin-right: 0.5rem;
|
|
515
|
+
flex: 0 0 12px;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
#sort-descending-btn {
|
|
519
|
+
transform: rotate(180deg);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
#sort-direction-selector {
|
|
523
|
+
display: flex;
|
|
524
|
+
flex-direction: column;
|
|
525
|
+
gap: 3px;
|
|
526
|
+
margin-right: 1rem;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
#sort-selector-container {
|
|
530
|
+
flex: 1;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/*
|
|
534
|
+
we move the desktop sort selector offscreen instead of display: none
|
|
535
|
+
because we need to observe the width of it vs its container to determine
|
|
536
|
+
if it's wide enough to display the desktop version and if you displY: none,
|
|
537
|
+
the width becomes 0
|
|
538
|
+
*/
|
|
539
|
+
#desktop-sort-selector.hidden {
|
|
540
|
+
position: absolute;
|
|
541
|
+
top: -9999px;
|
|
542
|
+
left: -9999px;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
#mobile-sort-selector.hidden {
|
|
546
|
+
display: none;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
#desktop-sort-selector {
|
|
550
|
+
display: inline-flex;
|
|
240
551
|
}
|
|
241
552
|
|
|
242
|
-
#sort-selector li
|
|
553
|
+
#desktop-sort-selector li {
|
|
554
|
+
display: flex;
|
|
555
|
+
align-items: center;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
#desktop-sort-selector li a {
|
|
559
|
+
text-decoration: none;
|
|
560
|
+
text-transform: uppercase;
|
|
561
|
+
font-size: 1.4rem;
|
|
562
|
+
color: #333;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
#desktop-sort-selector li a.selected {
|
|
566
|
+
font-weight: bold;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
#desktop-sort-selector li::after {
|
|
243
570
|
content: '•';
|
|
244
571
|
padding-left: 1rem;
|
|
245
572
|
padding-right: 1rem;
|
|
246
573
|
}
|
|
247
574
|
|
|
248
|
-
#sort-selector li:first-child::after {
|
|
575
|
+
#desktop-sort-selector li:first-child::after {
|
|
249
576
|
content: '';
|
|
250
577
|
}
|
|
251
578
|
|
|
252
|
-
#sort-selector li:last-child::after {
|
|
579
|
+
#desktop-sort-selector li:last-child::after {
|
|
253
580
|
content: '';
|
|
254
581
|
}
|
|
582
|
+
|
|
583
|
+
#display-style-selector {
|
|
584
|
+
flex: 0;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
#display-style-selector button {
|
|
588
|
+
background: none;
|
|
589
|
+
color: inherit;
|
|
590
|
+
border: none;
|
|
591
|
+
appearance: none;
|
|
592
|
+
cursor: pointer;
|
|
593
|
+
-webkit-appearance: none;
|
|
594
|
+
opacity: 0.5;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
#display-style-selector button.active {
|
|
598
|
+
opacity: 1;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
#display-style-selector button svg {
|
|
602
|
+
width: 24px;
|
|
603
|
+
height: 24px;
|
|
604
|
+
}
|
|
255
605
|
`;
|
|
256
606
|
}
|