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