@internetarchive/collection-browser 4.2.0-alpha-webdev8164.2 → 4.2.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/.claude/settings.local.json +11 -0
- package/.editorconfig +29 -29
- package/.github/workflows/ci.yml +27 -27
- package/.github/workflows/gh-pages-main.yml +39 -39
- package/.github/workflows/npm-publish.yml +39 -39
- package/.github/workflows/pr-preview.yml +38 -38
- package/.husky/pre-commit +1 -1
- package/.prettierignore +1 -1
- package/LICENSE +661 -661
- package/README.md +83 -83
- package/dist/src/app-root.js +4 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.js +32 -27
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facets-template.js +0 -5
- package/dist/src/collection-facets/facets-template.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.d.ts +8 -102
- package/dist/src/collection-facets/more-facets-content.js +102 -610
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets/more-facets-pagination.d.ts +3 -12
- package/dist/src/collection-facets/more-facets-pagination.js +9 -71
- package/dist/src/collection-facets/more-facets-pagination.js.map +1 -1
- package/dist/src/collection-facets/toggle-switch.js +0 -1
- package/dist/src/collection-facets/toggle-switch.js.map +1 -1
- package/dist/src/collection-facets.js +9 -10
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source.js +3 -2
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/mediatype/mediatype-config.js +1 -1
- package/dist/src/mediatype/mediatype-config.js.map +1 -1
- package/dist/src/models.d.ts +12 -2
- package/dist/src/models.js +13 -8
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.js +9 -3
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/tiles/hover/hover-pane-controller.js +2 -1
- package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +6 -0
- package/dist/src/tiles/tile-dispatcher.js +11 -3
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/test/collection-browser.test.js +72 -0
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/more-facets-content.test.js +3 -212
- package/dist/test/collection-facets/more-facets-content.test.js.map +1 -1
- package/dist/test/collection-facets/more-facets-pagination.test.js +3 -63
- package/dist/test/collection-facets/more-facets-pagination.test.js.map +1 -1
- package/dist/test/mocks/mock-search-responses.d.ts +0 -5
- package/dist/test/mocks/mock-search-responses.js +0 -44
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.js +1 -2
- package/dist/test/mocks/mock-search-service.js.map +1 -1
- package/dist/test/tiles/tile-dispatcher.test.js +14 -0
- package/dist/test/tiles/tile-dispatcher.test.js.map +1 -1
- package/dist/test/tiles/tile-mediatype-icon.test.js +4 -4
- package/dist/test/tiles/tile-mediatype-icon.test.js.map +1 -1
- package/eslint.config.mjs +53 -53
- package/index.html +24 -24
- package/local.archive.org.cert +86 -86
- package/local.archive.org.key +27 -27
- package/package.json +120 -121
- package/renovate.json +6 -6
- package/src/app-root.ts +4 -0
- package/src/collection-browser.ts +43 -36
- package/src/collection-facets/facets-template.ts +0 -5
- package/src/collection-facets/more-facets-content.ts +113 -664
- package/src/collection-facets/more-facets-pagination.ts +10 -84
- package/src/collection-facets/toggle-switch.ts +0 -1
- package/src/collection-facets.ts +13 -10
- package/src/data-source/collection-browser-data-source.ts +3 -2
- package/src/mediatype/mediatype-config.ts +1 -1
- package/src/models.ts +30 -8
- package/src/restoration-state-handler.ts +7 -3
- package/src/tiles/hover/hover-pane-controller.ts +2 -1
- package/src/tiles/tile-dispatcher.ts +12 -3
- package/test/collection-browser.test.ts +105 -0
- package/test/collection-facets/more-facets-content.test.ts +4 -326
- package/test/collection-facets/more-facets-pagination.test.ts +3 -87
- package/test/mocks/mock-search-responses.ts +0 -48
- package/test/mocks/mock-search-service.ts +0 -2
- package/test/tiles/tile-dispatcher.test.ts +17 -0
- package/test/tiles/tile-mediatype-icon.test.ts +4 -4
- package/tsconfig.json +25 -25
- package/web-dev-server.config.mjs +30 -30
- package/web-test-runner.config.mjs +52 -52
|
@@ -7,9 +7,7 @@ import {
|
|
|
7
7
|
PropertyValues,
|
|
8
8
|
TemplateResult,
|
|
9
9
|
} from 'lit';
|
|
10
|
-
import { customElement, property,
|
|
11
|
-
import { classMap } from 'lit/directives/class-map.js';
|
|
12
|
-
import { when } from 'lit/directives/when.js';
|
|
10
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
13
11
|
import {
|
|
14
12
|
Aggregation,
|
|
15
13
|
Bucket,
|
|
@@ -42,16 +40,13 @@ import type {
|
|
|
42
40
|
TVChannelAliases,
|
|
43
41
|
} from '../data-source/models';
|
|
44
42
|
import '@internetarchive/elements/ia-status-indicator/ia-status-indicator';
|
|
43
|
+
import './more-facets-pagination';
|
|
45
44
|
import './facets-template';
|
|
46
45
|
import {
|
|
47
46
|
analyticsActions,
|
|
48
47
|
analyticsCategories,
|
|
49
48
|
} from '../utils/analytics-events';
|
|
50
49
|
import './toggle-switch';
|
|
51
|
-
import './more-facets-pagination';
|
|
52
|
-
import '@internetarchive/ia-clearable-text-input';
|
|
53
|
-
import arrowLeftIcon from '../assets/img/icons/arrow-left';
|
|
54
|
-
import arrowRightIcon from '../assets/img/icons/arrow-right';
|
|
55
50
|
import { srOnlyStyle } from '../styles/sr-only';
|
|
56
51
|
import {
|
|
57
52
|
mergeSelectedFacets,
|
|
@@ -63,12 +58,6 @@ import {
|
|
|
63
58
|
MORE_FACETS__MAX_AGGREGATIONS,
|
|
64
59
|
} from './models';
|
|
65
60
|
|
|
66
|
-
/**
|
|
67
|
-
* Threshold for switching from horizontal scroll to pagination.
|
|
68
|
-
* If facet count >= this value, use pagination. Otherwise use horizontal scroll.
|
|
69
|
-
*/
|
|
70
|
-
const PAGINATION_THRESHOLD = 1000;
|
|
71
|
-
|
|
72
61
|
@customElement('more-facets-content')
|
|
73
62
|
export class MoreFacetsContent extends LitElement {
|
|
74
63
|
@property({ type: String }) facetKey?: FacetOption;
|
|
@@ -137,38 +126,10 @@ export class MoreFacetsContent extends LitElement {
|
|
|
137
126
|
getDefaultSelectedFacets();
|
|
138
127
|
|
|
139
128
|
/**
|
|
140
|
-
*
|
|
141
|
-
* Applied to bucket.key for case-insensitive matching.
|
|
142
|
-
*/
|
|
143
|
-
@state() private filterText = '';
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Current page number for pagination (when facet count >= PAGINATION_THRESHOLD).
|
|
129
|
+
* Which page of facets we are showing.
|
|
147
130
|
*/
|
|
148
131
|
@state() private pageNumber = 1;
|
|
149
132
|
|
|
150
|
-
/**
|
|
151
|
-
* Whether the component is narrow enough to warrant compact pagination.
|
|
152
|
-
* Updated via a ResizeObserver-based container query approach.
|
|
153
|
-
*/
|
|
154
|
-
@state() private isCompactView = false;
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Whether the horizontal scroll is at the leftmost position.
|
|
158
|
-
*/
|
|
159
|
-
@state() private atScrollStart = true;
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Whether the horizontal scroll is at the rightmost position.
|
|
163
|
-
*/
|
|
164
|
-
@state() private atScrollEnd = true;
|
|
165
|
-
|
|
166
|
-
@query('ia-clearable-text-input')
|
|
167
|
-
private filterInput!: HTMLElement;
|
|
168
|
-
|
|
169
|
-
@query('.facets-content')
|
|
170
|
-
private facetsContentEl!: HTMLElement;
|
|
171
|
-
|
|
172
133
|
willUpdate(changed: PropertyValues): void {
|
|
173
134
|
if (
|
|
174
135
|
changed.has('aggregations') ||
|
|
@@ -182,13 +143,6 @@ export class MoreFacetsContent extends LitElement {
|
|
|
182
143
|
this.facetGroup = this.mergedFacets;
|
|
183
144
|
}
|
|
184
145
|
|
|
185
|
-
// Reset to page 1 when filter text changes (only matters for pagination mode)
|
|
186
|
-
if (changed.has('filterText')) {
|
|
187
|
-
this.pageNumber = 1;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
updated(changed: PropertyValues): void {
|
|
192
146
|
// If any of the search properties change, it triggers a facet fetch
|
|
193
147
|
if (
|
|
194
148
|
changed.has('facetKey') ||
|
|
@@ -205,206 +159,24 @@ export class MoreFacetsContent extends LitElement {
|
|
|
205
159
|
|
|
206
160
|
this.updateSpecificFacets();
|
|
207
161
|
}
|
|
208
|
-
|
|
209
|
-
// Reset horizontal scroll when filter text changes (e.g., switching from
|
|
210
|
-
// horizontal-scroll mode back to pagination mode)
|
|
211
|
-
if (changed.has('filterText')) {
|
|
212
|
-
const facetsContent = this.shadowRoot?.querySelector('.facets-content');
|
|
213
|
-
if (facetsContent) {
|
|
214
|
-
facetsContent.scrollLeft = 0;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Manage scroll listener for horizontal scroll mode arrows.
|
|
219
|
-
// Only re-evaluate when properties that affect the displayed content change.
|
|
220
|
-
if (
|
|
221
|
-
changed.has('filterText') ||
|
|
222
|
-
changed.has('aggregations') ||
|
|
223
|
-
changed.has('facetKey') ||
|
|
224
|
-
changed.has('sortedBy') ||
|
|
225
|
-
changed.has('selectedFacets') ||
|
|
226
|
-
changed.has('unappliedFacetChanges')
|
|
227
|
-
) {
|
|
228
|
-
if (!this.usePagination) {
|
|
229
|
-
this.attachScrollListener();
|
|
230
|
-
// Refresh scroll state whenever content may have changed (e.g., filtering)
|
|
231
|
-
requestAnimationFrame(() => this.updateScrollState());
|
|
232
|
-
} else {
|
|
233
|
-
this.removeScrollListener();
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
162
|
}
|
|
237
163
|
|
|
238
|
-
private resizeObserver?: ResizeObserver;
|
|
239
|
-
|
|
240
164
|
firstUpdated(): void {
|
|
241
165
|
this.setupEscapeListeners();
|
|
242
|
-
this.setupCompactViewObserver();
|
|
243
|
-
this.constrainToScrollContainer();
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
disconnectedCallback(): void {
|
|
247
|
-
super.disconnectedCallback();
|
|
248
|
-
this.resizeObserver?.disconnect();
|
|
249
|
-
this.removeScrollListener();
|
|
250
|
-
document.removeEventListener('keydown', this.escapeHandler);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private scrollHandler = () => this.updateScrollState();
|
|
254
|
-
|
|
255
|
-
private scrollListenerAttached = false;
|
|
256
|
-
|
|
257
|
-
private scrollListenerTarget?: HTMLElement;
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Attaches a scroll event listener to the facets content element
|
|
261
|
-
* to track horizontal scroll position for arrow button states.
|
|
262
|
-
*/
|
|
263
|
-
private attachScrollListener(): void {
|
|
264
|
-
if (this.scrollListenerAttached || !this.facetsContentEl) return;
|
|
265
|
-
this.scrollListenerTarget = this.facetsContentEl;
|
|
266
|
-
this.scrollListenerTarget.addEventListener('scroll', this.scrollHandler, {
|
|
267
|
-
passive: true,
|
|
268
|
-
});
|
|
269
|
-
this.scrollListenerAttached = true;
|
|
270
|
-
// Defer initial state check until after browser layout, so scrollWidth
|
|
271
|
-
// reflects the actual content dimensions.
|
|
272
|
-
requestAnimationFrame(() => this.updateScrollState());
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
private removeScrollListener(): void {
|
|
276
|
-
if (!this.scrollListenerAttached || !this.scrollListenerTarget) return;
|
|
277
|
-
this.scrollListenerTarget.removeEventListener('scroll', this.scrollHandler);
|
|
278
|
-
this.scrollListenerTarget = undefined;
|
|
279
|
-
this.scrollListenerAttached = false;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Updates the scroll arrow disabled states based on current scroll position.
|
|
284
|
-
*/
|
|
285
|
-
private updateScrollState(): void {
|
|
286
|
-
const el = this.facetsContentEl;
|
|
287
|
-
if (!el) return;
|
|
288
|
-
this.atScrollStart = el.scrollLeft <= 0;
|
|
289
|
-
this.atScrollEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Calculates the width of one column step (column width + gap) based on
|
|
294
|
-
* the CSS multi-column layout of the scroll container.
|
|
295
|
-
*/
|
|
296
|
-
private getColumnStep(): number {
|
|
297
|
-
const el = this.facetsContentEl;
|
|
298
|
-
if (!el) return 0;
|
|
299
|
-
|
|
300
|
-
const facetRows = el.querySelector('.facet-rows') as HTMLElement;
|
|
301
|
-
const styles = facetRows
|
|
302
|
-
? getComputedStyle(facetRows)
|
|
303
|
-
: getComputedStyle(el);
|
|
304
|
-
|
|
305
|
-
const columnCount = parseInt(styles.columnCount, 10) || 3;
|
|
306
|
-
const columnGap = parseInt(styles.columnGap, 10) || 15;
|
|
307
|
-
|
|
308
|
-
// Column width = (visible width - total gaps) / column count
|
|
309
|
-
// Column step = column width + gap = (visible width + gap) / column count
|
|
310
|
-
return (el.clientWidth + columnGap) / columnCount;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Snaps a scroll target to the nearest column boundary.
|
|
315
|
-
*/
|
|
316
|
-
private snapToColumn(target: number): number {
|
|
317
|
-
const step = this.getColumnStep();
|
|
318
|
-
if (step <= 0) return target;
|
|
319
|
-
return Math.round(target / step) * step;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Scrolls the facet content left by approximately one page, snapping to
|
|
324
|
-
* the nearest column boundary.
|
|
325
|
-
*/
|
|
326
|
-
private onScrollLeft(): void {
|
|
327
|
-
const el = this.facetsContentEl;
|
|
328
|
-
if (!el) return;
|
|
329
|
-
const rawTarget = el.scrollLeft - el.clientWidth;
|
|
330
|
-
const snapped = Math.max(0, this.snapToColumn(rawTarget));
|
|
331
|
-
el.scrollTo({ left: snapped, behavior: 'smooth' });
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Scrolls the facet content right by approximately one page, snapping to
|
|
336
|
-
* the nearest column boundary.
|
|
337
|
-
*/
|
|
338
|
-
private onScrollRight(): void {
|
|
339
|
-
const el = this.facetsContentEl;
|
|
340
|
-
if (!el) return;
|
|
341
|
-
const maxScroll = el.scrollWidth - el.clientWidth;
|
|
342
|
-
const rawTarget = el.scrollLeft + el.clientWidth;
|
|
343
|
-
const snapped = Math.min(maxScroll, this.snapToColumn(rawTarget));
|
|
344
|
-
el.scrollTo({ left: snapped, behavior: 'smooth' });
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Sets up a ResizeObserver to toggle compact pagination based on component width.
|
|
349
|
-
*/
|
|
350
|
-
private setupCompactViewObserver(): void {
|
|
351
|
-
this.resizeObserver = new ResizeObserver(entries => {
|
|
352
|
-
for (const entry of entries) {
|
|
353
|
-
const compact = entry.contentRect.width <= 560;
|
|
354
|
-
if (this.isCompactView !== compact) this.isCompactView = compact;
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
this.resizeObserver.observe(this);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Constrains the section's max-height to fit within the nearest
|
|
362
|
-
* scroll-container ancestor (e.g., the modal's content area).
|
|
363
|
-
* This is a safety net for cases where the CSS max-height calculation
|
|
364
|
-
* doesn't perfectly match the container's available space.
|
|
365
|
-
*/
|
|
366
|
-
private constrainToScrollContainer(): void {
|
|
367
|
-
requestAnimationFrame(() => {
|
|
368
|
-
const section = this.shadowRoot?.querySelector(
|
|
369
|
-
'section#more-facets',
|
|
370
|
-
) as HTMLElement;
|
|
371
|
-
if (!section) return;
|
|
372
|
-
|
|
373
|
-
// Walk up from the assigned slot to find the nearest overflow container
|
|
374
|
-
let el = this.assignedSlot?.parentElement;
|
|
375
|
-
while (el) {
|
|
376
|
-
const cs = getComputedStyle(el);
|
|
377
|
-
if (
|
|
378
|
-
cs.overflowY === 'auto' ||
|
|
379
|
-
cs.overflowY === 'scroll' ||
|
|
380
|
-
cs.overflowY === 'hidden'
|
|
381
|
-
) {
|
|
382
|
-
const containerBottom = el.getBoundingClientRect().bottom;
|
|
383
|
-
const sectionTop = section.getBoundingClientRect().top;
|
|
384
|
-
const available = containerBottom - sectionTop;
|
|
385
|
-
// Compare against the CSS max-height rather than actual height,
|
|
386
|
-
// since content may not have loaded yet at firstUpdated time
|
|
387
|
-
const computedMax = parseFloat(getComputedStyle(section).maxHeight);
|
|
388
|
-
if (available > 0 && available < computedMax) {
|
|
389
|
-
section.style.maxHeight = `${available}px`;
|
|
390
|
-
}
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
el = el.parentElement;
|
|
394
|
-
}
|
|
395
|
-
});
|
|
396
166
|
}
|
|
397
167
|
|
|
398
168
|
/**
|
|
399
169
|
* Close more facets modal on Escape click
|
|
400
170
|
*/
|
|
401
|
-
private escapeHandler = (e: KeyboardEvent) => {
|
|
402
|
-
if (e.key === 'Escape') this.modalManager?.closeModal();
|
|
403
|
-
};
|
|
404
|
-
|
|
405
171
|
private setupEscapeListeners() {
|
|
406
172
|
if (this.modalManager) {
|
|
407
|
-
document.addEventListener('keydown',
|
|
173
|
+
document.addEventListener('keydown', (e: KeyboardEvent) => {
|
|
174
|
+
if (e.key === 'Escape') {
|
|
175
|
+
this.modalManager?.closeModal();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
document.removeEventListener('keydown', () => {});
|
|
408
180
|
}
|
|
409
181
|
}
|
|
410
182
|
|
|
@@ -443,21 +215,34 @@ export class MoreFacetsContent extends LitElement {
|
|
|
443
215
|
rows: 0, // todo - do we want server-side pagination with offset/page/limit flag?
|
|
444
216
|
};
|
|
445
217
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
218
|
+
const results = await this.searchService?.search(params, this.searchType);
|
|
219
|
+
this.aggregations = results?.success?.response.aggregations;
|
|
220
|
+
this.facetsLoading = false;
|
|
449
221
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
222
|
+
const collectionTitles = results?.success?.response?.collectionTitles;
|
|
223
|
+
if (collectionTitles) {
|
|
224
|
+
for (const [id, title] of Object.entries(collectionTitles)) {
|
|
225
|
+
this.collectionTitles?.set(id, title);
|
|
455
226
|
}
|
|
456
|
-
} finally {
|
|
457
|
-
this.facetsLoading = false;
|
|
458
227
|
}
|
|
459
228
|
}
|
|
460
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Handler for page number changes from the pagination widget.
|
|
232
|
+
*/
|
|
233
|
+
private pageNumberClicked(e: CustomEvent<{ page: number }>) {
|
|
234
|
+
const page = e?.detail?.page;
|
|
235
|
+
if (page) {
|
|
236
|
+
this.pageNumber = Number(page);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
this.analyticsHandler?.sendEvent({
|
|
240
|
+
category: analyticsCategories.default,
|
|
241
|
+
action: analyticsActions.moreFacetsPageChange,
|
|
242
|
+
label: `${this.pageNumber}`,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
461
246
|
/**
|
|
462
247
|
* Combines the selected facets with the aggregations to create a single list of facets
|
|
463
248
|
*/
|
|
@@ -539,10 +324,7 @@ export class MoreFacetsContent extends LitElement {
|
|
|
539
324
|
|
|
540
325
|
const buckets: FacetBucket[] = Object.entries(selectedFacetsForKey).map(
|
|
541
326
|
([value, data]) => {
|
|
542
|
-
const displayText =
|
|
543
|
-
(this.facetKey === 'collection'
|
|
544
|
-
? this.collectionTitles?.get(value)
|
|
545
|
-
: undefined) ?? value;
|
|
327
|
+
const displayText: string = value;
|
|
546
328
|
return {
|
|
547
329
|
displayText,
|
|
548
330
|
key: value,
|
|
@@ -586,33 +368,17 @@ export class MoreFacetsContent extends LitElement {
|
|
|
586
368
|
});
|
|
587
369
|
}
|
|
588
370
|
|
|
589
|
-
// Construct the array of facet buckets from the aggregation buckets
|
|
590
|
-
// using collection display titles where available.
|
|
371
|
+
// Construct the array of facet buckets from the aggregation buckets
|
|
591
372
|
const facetBuckets: FacetBucket[] = sortedBuckets.map(bucket => {
|
|
592
373
|
const bucketKeyStr = `${bucket.key}`;
|
|
593
|
-
const displayText =
|
|
594
|
-
(this.facetKey === 'collection'
|
|
595
|
-
? this.collectionTitles?.get(bucketKeyStr)
|
|
596
|
-
: undefined) ?? bucketKeyStr;
|
|
597
374
|
return {
|
|
598
|
-
displayText
|
|
375
|
+
displayText: `${bucketKeyStr}`,
|
|
599
376
|
key: `${bucketKeyStr}`,
|
|
600
377
|
count: bucket.doc_count,
|
|
601
378
|
state: 'none',
|
|
602
379
|
};
|
|
603
380
|
});
|
|
604
381
|
|
|
605
|
-
// For collection facets sorted alphabetically, re-sort by display title
|
|
606
|
-
// instead of the raw identifier used by getSortedBuckets.
|
|
607
|
-
if (
|
|
608
|
-
this.facetKey === 'collection' &&
|
|
609
|
-
this.sortedBy === AggregationSortType.ALPHABETICAL
|
|
610
|
-
) {
|
|
611
|
-
facetBuckets.sort((a, b) =>
|
|
612
|
-
(a.displayText ?? a.key).localeCompare(b.displayText ?? b.key),
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
382
|
return {
|
|
617
383
|
title: facetGroupTitle,
|
|
618
384
|
key: this.facetKey,
|
|
@@ -621,81 +387,29 @@ export class MoreFacetsContent extends LitElement {
|
|
|
621
387
|
}
|
|
622
388
|
|
|
623
389
|
/**
|
|
624
|
-
* Returns
|
|
625
|
-
* Filters are applied to the full bucket list before pagination.
|
|
390
|
+
* Returns a FacetGroup representing only the current page of facet buckets to show.
|
|
626
391
|
*/
|
|
627
|
-
private get
|
|
628
|
-
const { facetGroup
|
|
392
|
+
private get facetGroupForCurrentPage(): FacetGroup | undefined {
|
|
393
|
+
const { facetGroup } = this;
|
|
629
394
|
if (!facetGroup) return undefined;
|
|
630
395
|
|
|
631
|
-
//
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
// For collections, match against the displayed collection title (not the identifier).
|
|
638
|
-
// For other facet types, match against the bucket key (which is also the display text).
|
|
639
|
-
const lowerFilter = filterText.toLowerCase().trim();
|
|
640
|
-
const filteredBuckets = facetGroup.buckets.filter(bucket => {
|
|
641
|
-
const displayText = this.collectionTitles?.get(bucket.key) ?? bucket.key;
|
|
642
|
-
return displayText.toLowerCase().includes(lowerFilter);
|
|
643
|
-
});
|
|
396
|
+
// Slice out only the current page of facet buckets
|
|
397
|
+
const firstBucketIndexOnPage = (this.pageNumber - 1) * this.facetsPerPage;
|
|
398
|
+
const truncatedBuckets = facetGroup.buckets.slice(
|
|
399
|
+
firstBucketIndexOnPage,
|
|
400
|
+
firstBucketIndexOnPage + this.facetsPerPage,
|
|
401
|
+
);
|
|
644
402
|
|
|
645
403
|
return {
|
|
646
404
|
...facetGroup,
|
|
647
|
-
buckets:
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
/**
|
|
652
|
-
* Determines whether to use pagination based on the number of filtered facets.
|
|
653
|
-
* Returns true if facet count >= PAGINATION_THRESHOLD, false otherwise.
|
|
654
|
-
*/
|
|
655
|
-
private get usePagination(): boolean {
|
|
656
|
-
const facetCount = this.filteredFacetGroup?.buckets.length ?? 0;
|
|
657
|
-
return facetCount >= PAGINATION_THRESHOLD;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Returns the facet group for the current page.
|
|
662
|
-
* If using pagination (>= 1000 facets), slices to show only the current page.
|
|
663
|
-
* Otherwise, returns all facets for horizontal scrolling.
|
|
664
|
-
*/
|
|
665
|
-
private get facetGroupForCurrentPage(): FacetGroup | undefined {
|
|
666
|
-
const filteredGroup = this.filteredFacetGroup;
|
|
667
|
-
if (!filteredGroup) return undefined;
|
|
668
|
-
|
|
669
|
-
// If facet count is below threshold, show all facets with horizontal scroll
|
|
670
|
-
if (!this.usePagination) {
|
|
671
|
-
return filteredGroup;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
// Otherwise, use pagination - slice to current page
|
|
675
|
-
const startIndex = (this.pageNumber - 1) * this.facetsPerPage;
|
|
676
|
-
const endIndex = startIndex + this.facetsPerPage;
|
|
677
|
-
const slicedBuckets = filteredGroup.buckets.slice(startIndex, endIndex);
|
|
678
|
-
|
|
679
|
-
return {
|
|
680
|
-
...filteredGroup,
|
|
681
|
-
buckets: slicedBuckets,
|
|
405
|
+
buckets: truncatedBuckets,
|
|
682
406
|
};
|
|
683
407
|
}
|
|
684
408
|
|
|
685
409
|
private get moreFacetsTemplate(): TemplateResult {
|
|
686
|
-
const facetGroup = this.facetGroupForCurrentPage;
|
|
687
|
-
|
|
688
|
-
// Show empty state if filtering returned no results
|
|
689
|
-
if (
|
|
690
|
-
this.filterText.trim() &&
|
|
691
|
-
(!facetGroup || facetGroup.buckets.length === 0)
|
|
692
|
-
) {
|
|
693
|
-
return this.emptyFilterResultsTemplate;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
410
|
return html`
|
|
697
411
|
<facets-template
|
|
698
|
-
.facetGroup=${
|
|
412
|
+
.facetGroup=${this.facetGroupForCurrentPage}
|
|
699
413
|
.selectedFacets=${this.selectedFacets}
|
|
700
414
|
.collectionTitles=${this.collectionTitles}
|
|
701
415
|
@facetClick=${(e: CustomEvent<FacetEventDetails>) => {
|
|
@@ -720,51 +434,50 @@ export class MoreFacetsContent extends LitElement {
|
|
|
720
434
|
`;
|
|
721
435
|
}
|
|
722
436
|
|
|
723
|
-
private get emptyFilterResultsTemplate(): TemplateResult {
|
|
724
|
-
return html`
|
|
725
|
-
<div class="empty-results">
|
|
726
|
-
<p>${msg('No matching values found.')}</p>
|
|
727
|
-
<p class="hint">${msg('Try a different search term.')}</p>
|
|
728
|
-
</div>
|
|
729
|
-
`;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
437
|
/**
|
|
733
|
-
*
|
|
438
|
+
* How many pages of facets to show in the modal pagination widget
|
|
734
439
|
*/
|
|
735
440
|
private get paginationSize(): number {
|
|
736
|
-
|
|
737
|
-
|
|
441
|
+
if (!this.aggregations || !this.facetKey) return 0;
|
|
442
|
+
|
|
443
|
+
// Calculate the appropriate number of pages to show in the modal pagination widget
|
|
444
|
+
const length = this.aggregations[this.facetKey]?.buckets.length;
|
|
445
|
+
return Math.ceil(length / this.facetsPerPage);
|
|
738
446
|
}
|
|
739
447
|
|
|
740
|
-
|
|
741
|
-
* Template for pagination component.
|
|
742
|
-
*/
|
|
448
|
+
// render pagination if more then 1 page
|
|
743
449
|
private get facetsPaginationTemplate() {
|
|
744
|
-
return
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
450
|
+
return this.paginationSize > 1
|
|
451
|
+
? html`<more-facets-pagination
|
|
452
|
+
.size=${this.paginationSize}
|
|
453
|
+
.currentPage=${1}
|
|
454
|
+
@pageNumberClicked=${this.pageNumberClicked}
|
|
455
|
+
></more-facets-pagination>`
|
|
456
|
+
: nothing;
|
|
750
457
|
}
|
|
751
458
|
|
|
752
459
|
private get footerTemplate() {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
460
|
+
if (this.paginationSize > 0) {
|
|
461
|
+
return html`${this.facetsPaginationTemplate}
|
|
462
|
+
<div class="footer">
|
|
463
|
+
<button
|
|
464
|
+
class="btn btn-cancel"
|
|
465
|
+
type="button"
|
|
466
|
+
@click=${this.cancelClick}
|
|
467
|
+
>
|
|
468
|
+
Cancel
|
|
469
|
+
</button>
|
|
470
|
+
<button
|
|
471
|
+
class="btn btn-submit"
|
|
472
|
+
type="button"
|
|
473
|
+
@click=${this.applySearchFacetsClicked}
|
|
474
|
+
>
|
|
475
|
+
Apply filters
|
|
476
|
+
</button>
|
|
477
|
+
</div> `;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return nothing;
|
|
768
481
|
}
|
|
769
482
|
|
|
770
483
|
private sortFacetAggregation(facetSortType: AggregationSortType) {
|
|
@@ -774,44 +487,6 @@ export class MoreFacetsContent extends LitElement {
|
|
|
774
487
|
);
|
|
775
488
|
}
|
|
776
489
|
|
|
777
|
-
/**
|
|
778
|
-
* Handler for filter input changes. Updates the filter text and triggers re-render.
|
|
779
|
-
*/
|
|
780
|
-
private handleFilterInput(e: Event): void {
|
|
781
|
-
const input = e.target as HTMLElement & { value: string };
|
|
782
|
-
this.filterText = input.value;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* Handler for when the filter input is cleared via the clear button.
|
|
787
|
-
*/
|
|
788
|
-
private handleFilterClear(): void {
|
|
789
|
-
this.filterText = '';
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
/**
|
|
793
|
-
* Handler for pagination page number clicks.
|
|
794
|
-
* Only used when facet count >= PAGINATION_THRESHOLD.
|
|
795
|
-
*/
|
|
796
|
-
private pageNumberClicked(e: CustomEvent<{ page: number }>) {
|
|
797
|
-
this.pageNumber = e.detail.page;
|
|
798
|
-
|
|
799
|
-
// Track page navigation in analytics
|
|
800
|
-
this.analyticsHandler?.sendEvent({
|
|
801
|
-
category: analyticsCategories.default,
|
|
802
|
-
action: analyticsActions.moreFacetsPageChange,
|
|
803
|
-
label: `${this.pageNumber}`,
|
|
804
|
-
});
|
|
805
|
-
|
|
806
|
-
this.dispatchEvent(
|
|
807
|
-
new CustomEvent('pageChanged', {
|
|
808
|
-
detail: this.pageNumber,
|
|
809
|
-
bubbles: true,
|
|
810
|
-
composed: true,
|
|
811
|
-
}),
|
|
812
|
-
);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
490
|
private get modalHeaderTemplate(): TemplateResult {
|
|
816
491
|
const facetSort =
|
|
817
492
|
this.sortedBy ?? defaultFacetSort[this.facetKey as FacetOption];
|
|
@@ -819,103 +494,36 @@ export class MoreFacetsContent extends LitElement {
|
|
|
819
494
|
facetSort === AggregationSortType.COUNT ? 'left' : 'right';
|
|
820
495
|
|
|
821
496
|
return html`<span class="sr-only">${msg('More facets for:')}</span>
|
|
822
|
-
<span class="title">
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
</span>
|
|
842
|
-
|
|
843
|
-
<span class="filter-controls">
|
|
844
|
-
<label class="filter-label">${msg('Filter by:')}</label>
|
|
845
|
-
<ia-clearable-text-input
|
|
846
|
-
class="filter-input"
|
|
847
|
-
.value=${this.filterText}
|
|
848
|
-
.placeholder=${msg('Search...')}
|
|
849
|
-
.screenReaderLabel=${msg('Filter facets')}
|
|
850
|
-
.clearButtonScreenReaderLabel=${msg('Clear filter')}
|
|
851
|
-
@input=${this.handleFilterInput}
|
|
852
|
-
@clear=${this.handleFilterClear}
|
|
853
|
-
></ia-clearable-text-input>
|
|
854
|
-
</span>
|
|
497
|
+
<span class="title">
|
|
498
|
+
${this.facetGroup?.title}
|
|
499
|
+
|
|
500
|
+
<label class="sort-label">${msg('Sort by:')}</label>
|
|
501
|
+
${this.facetKey
|
|
502
|
+
? html`<toggle-switch
|
|
503
|
+
class="sort-toggle"
|
|
504
|
+
leftValue=${AggregationSortType.COUNT}
|
|
505
|
+
leftLabel="Count"
|
|
506
|
+
rightValue=${valueFacetSort[this.facetKey]}
|
|
507
|
+
.rightLabel=${this.facetGroup?.title}
|
|
508
|
+
side=${defaultSwitchSide}
|
|
509
|
+
@change=${(e: CustomEvent<string>) => {
|
|
510
|
+
this.sortFacetAggregation(
|
|
511
|
+
Number(e.detail) as AggregationSortType,
|
|
512
|
+
);
|
|
513
|
+
}}
|
|
514
|
+
></toggle-switch>`
|
|
515
|
+
: nothing}
|
|
855
516
|
</span>`;
|
|
856
517
|
}
|
|
857
518
|
|
|
858
|
-
private get horizontalScrollTemplate(): TemplateResult {
|
|
859
|
-
const contentClasses = classMap({
|
|
860
|
-
'facets-content': true,
|
|
861
|
-
'horizontal-scroll-mode': true,
|
|
862
|
-
});
|
|
863
|
-
const showArrows = !this.atScrollStart || !this.atScrollEnd;
|
|
864
|
-
|
|
865
|
-
return html`<div class="scroll-nav-container">
|
|
866
|
-
${when(
|
|
867
|
-
showArrows,
|
|
868
|
-
() =>
|
|
869
|
-
html`<button
|
|
870
|
-
class="scroll-arrow scroll-left"
|
|
871
|
-
@click=${this.onScrollLeft}
|
|
872
|
-
?disabled=${this.atScrollStart}
|
|
873
|
-
aria-label="Scroll facets left"
|
|
874
|
-
>
|
|
875
|
-
${arrowLeftIcon}
|
|
876
|
-
</button>`,
|
|
877
|
-
)}
|
|
878
|
-
<div class=${contentClasses}>
|
|
879
|
-
<div class="facets-horizontal-container">
|
|
880
|
-
${this.moreFacetsTemplate}
|
|
881
|
-
</div>
|
|
882
|
-
</div>
|
|
883
|
-
${when(
|
|
884
|
-
showArrows,
|
|
885
|
-
() =>
|
|
886
|
-
html`<button
|
|
887
|
-
class="scroll-arrow scroll-right"
|
|
888
|
-
@click=${this.onScrollRight}
|
|
889
|
-
?disabled=${this.atScrollEnd}
|
|
890
|
-
aria-label="Scroll facets right"
|
|
891
|
-
>
|
|
892
|
-
${arrowRightIcon}
|
|
893
|
-
</button>`,
|
|
894
|
-
)}
|
|
895
|
-
</div>`;
|
|
896
|
-
}
|
|
897
|
-
|
|
898
519
|
render() {
|
|
899
|
-
const sectionClasses = classMap({
|
|
900
|
-
'pagination-mode': this.usePagination,
|
|
901
|
-
'horizontal-scroll-mode': !this.usePagination,
|
|
902
|
-
});
|
|
903
|
-
const contentClasses = classMap({
|
|
904
|
-
'facets-content': true,
|
|
905
|
-
'pagination-mode': this.usePagination,
|
|
906
|
-
});
|
|
907
|
-
|
|
908
520
|
return html`
|
|
909
521
|
${this.facetsLoading
|
|
910
522
|
? this.loaderTemplate
|
|
911
523
|
: html`
|
|
912
|
-
<section id="more-facets"
|
|
524
|
+
<section id="more-facets">
|
|
913
525
|
<div class="header-content">${this.modalHeaderTemplate}</div>
|
|
914
|
-
|
|
915
|
-
? html`<div class=${contentClasses}>
|
|
916
|
-
${this.moreFacetsTemplate}
|
|
917
|
-
</div>`
|
|
918
|
-
: this.horizontalScrollTemplate}
|
|
526
|
+
<div class="facets-content">${this.moreFacetsTemplate}</div>
|
|
919
527
|
${this.footerTemplate}
|
|
920
528
|
</section>
|
|
921
529
|
`}
|
|
@@ -938,9 +546,6 @@ export class MoreFacetsContent extends LitElement {
|
|
|
938
546
|
// Reset the unapplied changes back to default, now that they have been applied
|
|
939
547
|
this.unappliedFacetChanges = getDefaultSelectedFacets();
|
|
940
548
|
|
|
941
|
-
// Reset filter text
|
|
942
|
-
this.filterText = '';
|
|
943
|
-
|
|
944
549
|
this.modalManager?.closeModal();
|
|
945
550
|
this.analyticsHandler?.sendEvent({
|
|
946
551
|
category: analyticsCategories.default,
|
|
@@ -953,9 +558,6 @@ export class MoreFacetsContent extends LitElement {
|
|
|
953
558
|
// Reset the unapplied changes back to default
|
|
954
559
|
this.unappliedFacetChanges = getDefaultSelectedFacets();
|
|
955
560
|
|
|
956
|
-
// Reset filter text
|
|
957
|
-
this.filterText = '';
|
|
958
|
-
|
|
959
561
|
this.modalManager?.closeModal();
|
|
960
562
|
this.analyticsHandler?.sendEvent({
|
|
961
563
|
category: analyticsCategories.default,
|
|
@@ -971,26 +573,10 @@ export class MoreFacetsContent extends LitElement {
|
|
|
971
573
|
srOnlyStyle,
|
|
972
574
|
css`
|
|
973
575
|
section#more-facets {
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
max-height: calc(100vh - 16.5rem - var(--modalBottomMargin, 2.5rem));
|
|
977
|
-
padding: 10px;
|
|
978
|
-
box-sizing: border-box;
|
|
576
|
+
overflow: auto;
|
|
577
|
+
padding: 10px; /* leaves room for scroll bar to appear without overlaying on content */
|
|
979
578
|
--facetsColumnCount: 3;
|
|
980
579
|
}
|
|
981
|
-
|
|
982
|
-
/* Both modes need a height constraint for proper column flow */
|
|
983
|
-
section#more-facets.horizontal-scroll-mode,
|
|
984
|
-
section#more-facets.pagination-mode {
|
|
985
|
-
--facetsMaxHeight: 280px;
|
|
986
|
-
}
|
|
987
|
-
.header-content {
|
|
988
|
-
flex-shrink: 0;
|
|
989
|
-
position: relative;
|
|
990
|
-
z-index: 1;
|
|
991
|
-
background: #fff;
|
|
992
|
-
}
|
|
993
|
-
|
|
994
580
|
.header-content .title {
|
|
995
581
|
display: block;
|
|
996
582
|
text-align: left;
|
|
@@ -999,22 +585,8 @@ export class MoreFacetsContent extends LitElement {
|
|
|
999
585
|
font-weight: bold;
|
|
1000
586
|
}
|
|
1001
587
|
|
|
1002
|
-
.header-controls {
|
|
1003
|
-
display: flex;
|
|
1004
|
-
flex-wrap: wrap;
|
|
1005
|
-
align-items: center;
|
|
1006
|
-
gap: 8px 20px;
|
|
1007
|
-
padding: 0 10px 8px;
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
.sort-controls {
|
|
1011
|
-
display: inline-flex;
|
|
1012
|
-
align-items: center;
|
|
1013
|
-
white-space: nowrap;
|
|
1014
|
-
gap: 5px;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
588
|
.sort-label {
|
|
589
|
+
margin-left: 20px;
|
|
1018
590
|
font-size: 1.3rem;
|
|
1019
591
|
}
|
|
1020
592
|
|
|
@@ -1022,115 +594,11 @@ export class MoreFacetsContent extends LitElement {
|
|
|
1022
594
|
font-weight: normal;
|
|
1023
595
|
}
|
|
1024
596
|
|
|
1025
|
-
.filter-controls {
|
|
1026
|
-
display: inline-flex;
|
|
1027
|
-
align-items: center;
|
|
1028
|
-
white-space: nowrap;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
.filter-label {
|
|
1032
|
-
font-size: 1.3rem;
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
.filter-input {
|
|
1036
|
-
--input-height: 2.5rem;
|
|
1037
|
-
--input-font-size: 1.3rem;
|
|
1038
|
-
--input-border-radius: 4px;
|
|
1039
|
-
--input-padding: 4px 8px;
|
|
1040
|
-
--input-focused-border-color: ${modalSubmitButton};
|
|
1041
|
-
width: 150px;
|
|
1042
|
-
margin-left: 5px;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
.empty-results {
|
|
1046
|
-
text-align: center;
|
|
1047
|
-
padding: 40px 20px;
|
|
1048
|
-
color: #666;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
.empty-results .hint {
|
|
1052
|
-
margin-top: 10px;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
597
|
.facets-content {
|
|
1056
598
|
font-size: 1.2rem;
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
overflow-y: auto;
|
|
1060
|
-
overflow-x: hidden;
|
|
599
|
+
max-height: 300px;
|
|
600
|
+
overflow: auto;
|
|
1061
601
|
padding: 10px;
|
|
1062
|
-
/* Force scrollbar to always be visible */
|
|
1063
|
-
scrollbar-width: thin; /* Firefox */
|
|
1064
|
-
scrollbar-color: #888 #f1f1f1; /* Firefox - thumb and track colors */
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
/* Horizontal scroll mode: horizontal scrolling only */
|
|
1068
|
-
.facets-content.horizontal-scroll-mode {
|
|
1069
|
-
overflow-x: auto;
|
|
1070
|
-
overflow-y: hidden;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
/* Webkit browsers scrollbar styling - always visible */
|
|
1074
|
-
.facets-content::-webkit-scrollbar {
|
|
1075
|
-
width: 12px; /* Vertical scrollbar width */
|
|
1076
|
-
height: 12px; /* Horizontal scrollbar height */
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
.facets-content::-webkit-scrollbar-track {
|
|
1080
|
-
background: #f1f1f1;
|
|
1081
|
-
border-radius: 6px;
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
.facets-content::-webkit-scrollbar-thumb {
|
|
1085
|
-
background: #888;
|
|
1086
|
-
border-radius: 6px;
|
|
1087
|
-
min-height: 30px; /* Ensure thumb is always visible when scrolling is possible */
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
.facets-content::-webkit-scrollbar-thumb:hover {
|
|
1091
|
-
background: #555;
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
/* Force corner to match track color */
|
|
1095
|
-
.facets-content::-webkit-scrollbar-corner {
|
|
1096
|
-
background: #f1f1f1;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
.facets-horizontal-container {
|
|
1100
|
-
display: inline-block;
|
|
1101
|
-
min-width: 100%;
|
|
1102
|
-
/* Allow natural width expansion based on content */
|
|
1103
|
-
width: fit-content;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
.scroll-nav-container {
|
|
1107
|
-
display: flex;
|
|
1108
|
-
align-items: center;
|
|
1109
|
-
flex: 1 1 auto;
|
|
1110
|
-
min-height: 0;
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
.scroll-nav-container .facets-content {
|
|
1114
|
-
flex: 1 1 auto;
|
|
1115
|
-
min-width: 0;
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
.scroll-arrow {
|
|
1119
|
-
background: none;
|
|
1120
|
-
border: none;
|
|
1121
|
-
cursor: pointer;
|
|
1122
|
-
padding: 5px;
|
|
1123
|
-
flex-shrink: 0;
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
.scroll-arrow svg {
|
|
1127
|
-
height: 14px;
|
|
1128
|
-
fill: #2c2c2c;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
.scroll-arrow:disabled {
|
|
1132
|
-
opacity: 0.3;
|
|
1133
|
-
cursor: default;
|
|
1134
602
|
}
|
|
1135
603
|
.facets-loader {
|
|
1136
604
|
--icon-width: 70px;
|
|
@@ -1146,7 +614,6 @@ export class MoreFacetsContent extends LitElement {
|
|
|
1146
614
|
width: auto;
|
|
1147
615
|
border-radius: 4px;
|
|
1148
616
|
cursor: pointer;
|
|
1149
|
-
font-family: inherit;
|
|
1150
617
|
}
|
|
1151
618
|
.btn-cancel {
|
|
1152
619
|
background-color: #2c2c2c;
|
|
@@ -1156,37 +623,19 @@ export class MoreFacetsContent extends LitElement {
|
|
|
1156
623
|
background-color: ${modalSubmitButton};
|
|
1157
624
|
color: white;
|
|
1158
625
|
}
|
|
1159
|
-
more-facets-pagination {
|
|
1160
|
-
flex-shrink: 0;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
626
|
.footer {
|
|
1164
627
|
text-align: center;
|
|
1165
628
|
margin-top: 10px;
|
|
1166
|
-
flex-shrink: 0;
|
|
1167
629
|
}
|
|
1168
630
|
|
|
1169
631
|
@media (max-width: 560px) {
|
|
1170
|
-
section#more-facets
|
|
1171
|
-
|
|
1172
|
-
--facetsColumnCount: 1;
|
|
1173
|
-
--facetsMaxHeight: none; /* Remove fixed height for vertical scrolling */
|
|
632
|
+
section#more-facets {
|
|
633
|
+
max-height: 450px;
|
|
634
|
+
--facetsColumnCount: 1;
|
|
1174
635
|
}
|
|
1175
|
-
|
|
1176
|
-
.facets-content,
|
|
1177
|
-
.facets-content.horizontal-scroll-mode {
|
|
636
|
+
.facets-content {
|
|
1178
637
|
overflow-y: auto;
|
|
1179
|
-
|
|
1180
|
-
}
|
|
1181
|
-
.scroll-nav-container {
|
|
1182
|
-
display: contents; /* Remove wrapper from layout so section flex-column works */
|
|
1183
|
-
}
|
|
1184
|
-
.scroll-arrow {
|
|
1185
|
-
display: none;
|
|
1186
|
-
}
|
|
1187
|
-
.filter-input {
|
|
1188
|
-
width: 120px;
|
|
1189
|
-
--input-font-size: 1.2rem;
|
|
638
|
+
height: 300px;
|
|
1190
639
|
}
|
|
1191
640
|
}
|
|
1192
641
|
`,
|