@internetarchive/collection-browser 1.14.9-alpha1 → 1.14.9-alpha10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/src/app-root.d.ts +1 -0
  2. package/dist/src/app-root.js +154 -82
  3. package/dist/src/app-root.js.map +1 -1
  4. package/dist/src/collection-browser.d.ts +2 -2
  5. package/dist/src/collection-browser.js +23 -18
  6. package/dist/src/collection-browser.js.map +1 -1
  7. package/dist/src/collection-facets/facet-row.d.ts +30 -0
  8. package/dist/src/collection-facets/facet-row.js +245 -0
  9. package/dist/src/collection-facets/facet-row.js.map +1 -0
  10. package/dist/src/collection-facets/facets-template.d.ts +1 -4
  11. package/dist/src/collection-facets/facets-template.js +40 -182
  12. package/dist/src/collection-facets/facets-template.js.map +1 -1
  13. package/dist/src/models.d.ts +18 -2
  14. package/dist/src/models.js.map +1 -1
  15. package/dist/test/collection-browser.test.js +36 -4
  16. package/dist/test/collection-browser.test.js.map +1 -1
  17. package/dist/test/collection-facets/facet-row.test.d.ts +1 -0
  18. package/dist/test/collection-facets/facet-row.test.js +235 -0
  19. package/dist/test/collection-facets/facet-row.test.js.map +1 -0
  20. package/dist/test/collection-facets/facets-template.test.js +65 -96
  21. package/dist/test/collection-facets/facets-template.test.js.map +1 -1
  22. package/dist/test/collection-facets.test.js +39 -70
  23. package/dist/test/collection-facets.test.js.map +1 -1
  24. package/package.json +2 -2
  25. package/src/app-root.ts +159 -82
  26. package/src/collection-browser.ts +23 -20
  27. package/src/collection-facets/facet-row.ts +274 -0
  28. package/src/collection-facets/facets-template.ts +49 -196
  29. package/src/models.ts +18 -2
  30. package/test/collection-browser.test.ts +36 -4
  31. package/test/collection-facets/facet-row.test.ts +328 -0
  32. package/test/collection-facets/facets-template.test.ts +72 -110
  33. package/test/collection-facets.test.ts +69 -101
@@ -0,0 +1,30 @@
1
+ import { LitElement, TemplateResult, CSSResultGroup } from 'lit';
2
+ import type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
3
+ import type { FacetOption, FacetBucket, FacetState } from '../models';
4
+ export declare class FacetRow extends LitElement {
5
+ /** The name of the facet group to which this facet belongs (e.g., "mediatype") */
6
+ facetType?: FacetOption;
7
+ /** The facet bucket containing details about the state, count, and key for this row */
8
+ bucket?: FacetBucket;
9
+ /** The collection name cache for converting collection identifiers to titles */
10
+ collectionNameCache?: CollectionNameCacheInterface;
11
+ render(): TemplateResult<1>;
12
+ /**
13
+ * Template for the full facet row, including the positive/negative checks,
14
+ * the display name, and the count.
15
+ */
16
+ private get facetRowTemplate();
17
+ /**
18
+ * Handler for whenever this facet is clicked & its state changes
19
+ */
20
+ private facetClicked;
21
+ /**
22
+ * Emits a `facetClick` event with details about this facet & its current state
23
+ */
24
+ private dispatchFacetClickEvent;
25
+ /**
26
+ * Returns the composed facet state corresponding to a positive or negative facet's checked state
27
+ */
28
+ static getFacetState(checked: boolean, negative: boolean): FacetState;
29
+ static get styles(): CSSResultGroup;
30
+ }
@@ -0,0 +1,245 @@
1
+ var FacetRow_1;
2
+ import { __decorate } from "tslib";
3
+ import { css, html, LitElement, nothing, } from 'lit';
4
+ import { customElement, property } from 'lit/decorators.js';
5
+ import eyeIcon from '../assets/img/icons/eye';
6
+ import eyeClosedIcon from '../assets/img/icons/eye-closed';
7
+ let FacetRow = FacetRow_1 = class FacetRow extends LitElement {
8
+ //
9
+ // COMPONENT LIFECYCLE METHODS
10
+ //
11
+ render() {
12
+ return html `${this.facetRowTemplate}`;
13
+ }
14
+ //
15
+ // TEMPLATE GETTERS
16
+ //
17
+ /**
18
+ * Template for the full facet row, including the positive/negative checks,
19
+ * the display name, and the count.
20
+ */
21
+ get facetRowTemplate() {
22
+ var _a, _b;
23
+ const { bucket, facetType } = this;
24
+ if (!bucket || !facetType)
25
+ return nothing;
26
+ const showOnlyCheckboxId = `${facetType}:${bucket.key}-show-only`;
27
+ const negativeCheckboxId = `${facetType}:${bucket.key}-negative`;
28
+ // For collections, we need to asynchronously load the collection name
29
+ // so we use the `async-collection-name` widget.
30
+ // For other facet types, we just have a static value to use.
31
+ const bucketTextDisplay = facetType !== 'collection'
32
+ ? html `${(_a = bucket.displayText) !== null && _a !== void 0 ? _a : bucket.key}`
33
+ : html `<a href="/details/${bucket.key}">
34
+ <async-collection-name
35
+ .collectionNameCache=${this.collectionNameCache}
36
+ .identifier=${bucket.key}
37
+ placeholder="-"
38
+ ></async-collection-name>
39
+ </a> `;
40
+ const facetHidden = bucket.state === 'hidden';
41
+ const facetSelected = bucket.state === 'selected';
42
+ const titleText = `${facetType}: ${(_b = bucket.displayText) !== null && _b !== void 0 ? _b : bucket.key}`;
43
+ const onlyShowText = facetSelected
44
+ ? `Show all ${facetType}s`
45
+ : `Only show ${titleText}`;
46
+ const hideText = `Hide ${titleText}`;
47
+ const unhideText = `Unhide ${titleText}`;
48
+ const showHideText = facetHidden ? unhideText : hideText;
49
+ const ariaLabel = `${titleText}, ${bucket.count} results`;
50
+ return html `
51
+ <div class="facet-row-container">
52
+ <div class="facet-checkboxes">
53
+ <input
54
+ type="checkbox"
55
+ .name=${facetType}
56
+ .value=${bucket.key}
57
+ @click=${(e) => {
58
+ this.facetClicked(e, false);
59
+ }}
60
+ .checked=${facetSelected}
61
+ class="select-facet-checkbox"
62
+ title=${onlyShowText}
63
+ id=${showOnlyCheckboxId}
64
+ />
65
+ <input
66
+ type="checkbox"
67
+ id=${negativeCheckboxId}
68
+ .name=${facetType}
69
+ .value=${bucket.key}
70
+ @click=${(e) => {
71
+ this.facetClicked(e, true);
72
+ }}
73
+ .checked=${facetHidden}
74
+ class="hide-facet-checkbox"
75
+ />
76
+ <label
77
+ for=${negativeCheckboxId}
78
+ class="hide-facet-icon${facetHidden ? ' active' : ''}"
79
+ title=${showHideText}
80
+ >
81
+ <span class="eye">${eyeIcon}</span>
82
+ <span class="eye-closed">${eyeClosedIcon}</span>
83
+ </label>
84
+ </div>
85
+ <label
86
+ for=${showOnlyCheckboxId}
87
+ class="facet-info-display"
88
+ title=${onlyShowText}
89
+ aria-label=${ariaLabel}
90
+ >
91
+ <div class="facet-title">${bucketTextDisplay}</div>
92
+ <div class="facet-count">${bucket.count.toLocaleString()}</div>
93
+ </label>
94
+ </div>
95
+ `;
96
+ }
97
+ //
98
+ // EVENT HANDLERS & DISPATCHERS
99
+ //
100
+ /**
101
+ * Handler for whenever this facet is clicked & its state changes
102
+ */
103
+ facetClicked(e, negative) {
104
+ const { bucket, facetType } = this;
105
+ if (!bucket || !facetType)
106
+ return;
107
+ const target = e.target;
108
+ const { checked } = target;
109
+ bucket.state = FacetRow_1.getFacetState(checked, negative);
110
+ this.dispatchFacetClickEvent({
111
+ facetType,
112
+ bucket,
113
+ negative,
114
+ });
115
+ }
116
+ /**
117
+ * Emits a `facetClick` event with details about this facet & its current state
118
+ */
119
+ dispatchFacetClickEvent(detail) {
120
+ const event = new CustomEvent('facetClick', {
121
+ detail,
122
+ });
123
+ this.dispatchEvent(event);
124
+ }
125
+ //
126
+ // OTHER METHODS
127
+ //
128
+ /**
129
+ * Returns the composed facet state corresponding to a positive or negative facet's checked state
130
+ */
131
+ static getFacetState(checked, negative) {
132
+ let state;
133
+ if (checked) {
134
+ state = negative ? 'hidden' : 'selected';
135
+ }
136
+ else {
137
+ state = 'none';
138
+ }
139
+ return state;
140
+ }
141
+ //
142
+ // STYLES
143
+ //
144
+ static get styles() {
145
+ const facetRowBorderTop = css `var(--facet-row-border-top, 1px solid transparent)`;
146
+ const facetRowBorderBottom = css `var(--facet-row-border-bottom, 1px solid transparent)`;
147
+ return css `
148
+ async-collection-name {
149
+ display: contents;
150
+ }
151
+ .facet-checkboxes {
152
+ margin: 0 5px 0 0;
153
+ display: flex;
154
+ height: 15px;
155
+ }
156
+ .facet-checkboxes input:first-child {
157
+ margin-right: 5px;
158
+ }
159
+ .facet-checkboxes input {
160
+ height: 15px;
161
+ width: 15px;
162
+ margin: 0;
163
+ }
164
+ .facet-row-container {
165
+ display: flex;
166
+ font-weight: 500;
167
+ font-size: 1.2rem;
168
+ margin: 2.5px auto;
169
+ height: auto;
170
+ border-top: ${facetRowBorderTop};
171
+ border-bottom: ${facetRowBorderBottom};
172
+ overflow: hidden;
173
+ }
174
+ .facet-info-display {
175
+ display: flex;
176
+ flex: 1 1 0%;
177
+ cursor: pointer;
178
+ flex-wrap: wrap;
179
+ }
180
+ .facet-title {
181
+ word-break: break-word;
182
+ display: inline-block;
183
+ flex: 1 1 0%;
184
+ }
185
+ .facet-count {
186
+ text-align: right;
187
+ }
188
+ .select-facet-checkbox {
189
+ cursor: pointer;
190
+ display: inline-block;
191
+ }
192
+ .hide-facet-checkbox {
193
+ display: none;
194
+ }
195
+ .hide-facet-icon {
196
+ width: 15px;
197
+ height: 15px;
198
+ cursor: pointer;
199
+ opacity: 0.3;
200
+ display: inline-block;
201
+ }
202
+ .hide-facet-icon:hover,
203
+ .active {
204
+ opacity: 1;
205
+ }
206
+ .hide-facet-icon:hover .eye,
207
+ .hide-facet-icon .eye-closed {
208
+ display: none;
209
+ }
210
+ .hide-facet-icon:hover .eye-closed,
211
+ .hide-facet-icon.active .eye-closed {
212
+ display: inline;
213
+ }
214
+ .hide-facet-icon.active .eye {
215
+ display: none;
216
+ }
217
+ .sorting-icon {
218
+ cursor: pointer;
219
+ }
220
+
221
+ a:link,
222
+ a:visited {
223
+ text-decoration: none;
224
+ color: var(--ia-theme-link-color, #4b64ff);
225
+ }
226
+ a:hover {
227
+ text-decoration: underline;
228
+ }
229
+ `;
230
+ }
231
+ };
232
+ __decorate([
233
+ property({ type: String })
234
+ ], FacetRow.prototype, "facetType", void 0);
235
+ __decorate([
236
+ property({ type: Object })
237
+ ], FacetRow.prototype, "bucket", void 0);
238
+ __decorate([
239
+ property({ type: Object })
240
+ ], FacetRow.prototype, "collectionNameCache", void 0);
241
+ FacetRow = FacetRow_1 = __decorate([
242
+ customElement('facet-row')
243
+ ], FacetRow);
244
+ export { FacetRow };
245
+ //# sourceMappingURL=facet-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facet-row.js","sourceRoot":"","sources":["../../../src/collection-facets/facet-row.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n html,\n LitElement,\n TemplateResult,\n CSSResultGroup,\n nothing,\n} from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';\nimport eyeIcon from '../assets/img/icons/eye';\nimport eyeClosedIcon from '../assets/img/icons/eye-closed';\nimport type {\n FacetOption,\n FacetBucket,\n FacetEventDetails,\n FacetState,\n} from '../models';\n\n@customElement('facet-row')\nexport class FacetRow extends LitElement {\n //\n // UI STATE\n //\n\n /** The name of the facet group to which this facet belongs (e.g., \"mediatype\") */\n @property({ type: String }) facetType?: FacetOption;\n\n /** The facet bucket containing details about the state, count, and key for this row */\n @property({ type: Object }) bucket?: FacetBucket;\n\n /** The collection name cache for converting collection identifiers to titles */\n @property({ type: Object })\n collectionNameCache?: CollectionNameCacheInterface;\n\n //\n // COMPONENT LIFECYCLE METHODS\n //\n\n render() {\n return html`${this.facetRowTemplate}`;\n }\n\n //\n // TEMPLATE GETTERS\n //\n\n /**\n * Template for the full facet row, including the positive/negative checks,\n * the display name, and the count.\n */\n private get facetRowTemplate(): TemplateResult | typeof nothing {\n const { bucket, facetType } = this;\n if (!bucket || !facetType) return nothing;\n\n const showOnlyCheckboxId = `${facetType}:${bucket.key}-show-only`;\n const negativeCheckboxId = `${facetType}:${bucket.key}-negative`;\n\n // For collections, we need to asynchronously load the collection name\n // so we use the `async-collection-name` widget.\n // For other facet types, we just have a static value to use.\n const bucketTextDisplay =\n facetType !== 'collection'\n ? html`${bucket.displayText ?? bucket.key}`\n : html`<a href=\"/details/${bucket.key}\">\n <async-collection-name\n .collectionNameCache=${this.collectionNameCache}\n .identifier=${bucket.key}\n placeholder=\"-\"\n ></async-collection-name>\n </a> `;\n\n const facetHidden = bucket.state === 'hidden';\n const facetSelected = bucket.state === 'selected';\n\n const titleText = `${facetType}: ${bucket.displayText ?? bucket.key}`;\n const onlyShowText = facetSelected\n ? `Show all ${facetType}s`\n : `Only show ${titleText}`;\n const hideText = `Hide ${titleText}`;\n const unhideText = `Unhide ${titleText}`;\n const showHideText = facetHidden ? unhideText : hideText;\n const ariaLabel = `${titleText}, ${bucket.count} results`;\n\n return html`\n <div class=\"facet-row-container\">\n <div class=\"facet-checkboxes\">\n <input\n type=\"checkbox\"\n .name=${facetType}\n .value=${bucket.key}\n @click=${(e: Event) => {\n this.facetClicked(e, false);\n }}\n .checked=${facetSelected}\n class=\"select-facet-checkbox\"\n title=${onlyShowText}\n id=${showOnlyCheckboxId}\n />\n <input\n type=\"checkbox\"\n id=${negativeCheckboxId}\n .name=${facetType}\n .value=${bucket.key}\n @click=${(e: Event) => {\n this.facetClicked(e, true);\n }}\n .checked=${facetHidden}\n class=\"hide-facet-checkbox\"\n />\n <label\n for=${negativeCheckboxId}\n class=\"hide-facet-icon${facetHidden ? ' active' : ''}\"\n title=${showHideText}\n >\n <span class=\"eye\">${eyeIcon}</span>\n <span class=\"eye-closed\">${eyeClosedIcon}</span>\n </label>\n </div>\n <label\n for=${showOnlyCheckboxId}\n class=\"facet-info-display\"\n title=${onlyShowText}\n aria-label=${ariaLabel}\n >\n <div class=\"facet-title\">${bucketTextDisplay}</div>\n <div class=\"facet-count\">${bucket.count.toLocaleString()}</div>\n </label>\n </div>\n `;\n }\n\n //\n // EVENT HANDLERS & DISPATCHERS\n //\n\n /**\n * Handler for whenever this facet is clicked & its state changes\n */\n private facetClicked(e: Event, negative: boolean) {\n const { bucket, facetType } = this;\n if (!bucket || !facetType) return;\n\n const target = e.target as HTMLInputElement;\n const { checked } = target;\n bucket.state = FacetRow.getFacetState(checked, negative);\n\n this.dispatchFacetClickEvent({\n facetType,\n bucket,\n negative,\n });\n }\n\n /**\n * Emits a `facetClick` event with details about this facet & its current state\n */\n private dispatchFacetClickEvent(detail: FacetEventDetails) {\n const event = new CustomEvent<FacetEventDetails>('facetClick', {\n detail,\n });\n this.dispatchEvent(event);\n }\n\n //\n // OTHER METHODS\n //\n\n /**\n * Returns the composed facet state corresponding to a positive or negative facet's checked state\n */\n static getFacetState(checked: boolean, negative: boolean): FacetState {\n let state: FacetState;\n if (checked) {\n state = negative ? 'hidden' : 'selected';\n } else {\n state = 'none';\n }\n return state;\n }\n\n //\n // STYLES\n //\n\n static get styles(): CSSResultGroup {\n const facetRowBorderTop = css`var(--facet-row-border-top, 1px solid transparent)`;\n const facetRowBorderBottom = css`var(--facet-row-border-bottom, 1px solid transparent)`;\n\n return css`\n async-collection-name {\n display: contents;\n }\n .facet-checkboxes {\n margin: 0 5px 0 0;\n display: flex;\n height: 15px;\n }\n .facet-checkboxes input:first-child {\n margin-right: 5px;\n }\n .facet-checkboxes input {\n height: 15px;\n width: 15px;\n margin: 0;\n }\n .facet-row-container {\n display: flex;\n font-weight: 500;\n font-size: 1.2rem;\n margin: 2.5px auto;\n height: auto;\n border-top: ${facetRowBorderTop};\n border-bottom: ${facetRowBorderBottom};\n overflow: hidden;\n }\n .facet-info-display {\n display: flex;\n flex: 1 1 0%;\n cursor: pointer;\n flex-wrap: wrap;\n }\n .facet-title {\n word-break: break-word;\n display: inline-block;\n flex: 1 1 0%;\n }\n .facet-count {\n text-align: right;\n }\n .select-facet-checkbox {\n cursor: pointer;\n display: inline-block;\n }\n .hide-facet-checkbox {\n display: none;\n }\n .hide-facet-icon {\n width: 15px;\n height: 15px;\n cursor: pointer;\n opacity: 0.3;\n display: inline-block;\n }\n .hide-facet-icon:hover,\n .active {\n opacity: 1;\n }\n .hide-facet-icon:hover .eye,\n .hide-facet-icon .eye-closed {\n display: none;\n }\n .hide-facet-icon:hover .eye-closed,\n .hide-facet-icon.active .eye-closed {\n display: inline;\n }\n .hide-facet-icon.active .eye {\n display: none;\n }\n .sorting-icon {\n cursor: pointer;\n }\n\n a:link,\n a:visited {\n text-decoration: none;\n color: var(--ia-theme-link-color, #4b64ff);\n }\n a:hover {\n text-decoration: underline;\n }\n `;\n }\n}\n"]}
@@ -5,16 +5,13 @@ export declare class FacetsTemplate extends LitElement {
5
5
  facetGroup?: FacetGroup;
6
6
  selectedFacets?: SelectedFacets;
7
7
  renderOn?: string;
8
- collectionPagePath: string;
9
8
  collectionNameCache?: CollectionNameCacheInterface;
10
9
  private facetClicked;
11
10
  private facetChecked;
12
11
  private facetUnchecked;
13
- /** Returns the composed facet state corresponding to a positive or negative facet's checked state */
14
- private getFacetState;
15
12
  private dispatchFacetClickEvent;
16
13
  private dispatchSelectedFacetsChanged;
17
- private getFacetsTemplate;
14
+ private get facetsTemplate();
18
15
  render(): TemplateResult<1>;
19
16
  static get styles(): CSSResultGroup;
20
17
  }
@@ -1,28 +1,24 @@
1
1
  import { __decorate } from "tslib";
2
- import { css, html, LitElement } from 'lit';
2
+ import { css, html, LitElement, nothing, } from 'lit';
3
3
  import { customElement, property } from 'lit/decorators.js';
4
4
  import { repeat } from 'lit/directives/repeat.js';
5
- import eyeIcon from '../assets/img/icons/eye';
6
- import eyeClosedIcon from '../assets/img/icons/eye-closed';
7
5
  import { getDefaultSelectedFacets, } from '../models';
6
+ import { FacetRow } from './facet-row';
8
7
  let FacetsTemplate = class FacetsTemplate extends LitElement {
9
- constructor() {
10
- super(...arguments);
11
- this.collectionPagePath = '/details/';
12
- }
13
- facetClicked(e, count, negative) {
14
- const target = e.target;
15
- const { checked, name, value } = target;
16
- if (checked) {
17
- this.facetChecked(name, value, count, negative);
8
+ facetClicked(e) {
9
+ const { bucket, negative } = e.detail;
10
+ if (bucket.state === 'none') {
11
+ this.facetUnchecked(bucket);
18
12
  }
19
13
  else {
20
- this.facetUnchecked(name, value);
14
+ this.facetChecked(bucket, negative);
21
15
  }
22
- this.dispatchFacetClickEvent(name, this.getFacetState(checked, negative), negative);
16
+ this.dispatchFacetClickEvent(e.detail);
23
17
  }
24
- facetChecked(key, value, count, negative) {
25
- const { selectedFacets } = this;
18
+ facetChecked(bucket, negative) {
19
+ const { facetGroup, selectedFacets } = this;
20
+ if (!facetGroup)
21
+ return;
26
22
  let newFacets;
27
23
  if (selectedFacets) {
28
24
  newFacets = {
@@ -32,15 +28,17 @@ let FacetsTemplate = class FacetsTemplate extends LitElement {
32
28
  else {
33
29
  newFacets = getDefaultSelectedFacets();
34
30
  }
35
- newFacets[key][value] = {
36
- state: this.getFacetState(true, negative),
37
- count,
31
+ newFacets[facetGroup.key][bucket.key] = {
32
+ ...bucket,
33
+ state: FacetRow.getFacetState(true, negative),
38
34
  };
39
35
  this.selectedFacets = newFacets;
40
36
  this.dispatchSelectedFacetsChanged();
41
37
  }
42
- facetUnchecked(key, value) {
43
- const { selectedFacets } = this;
38
+ facetUnchecked(bucket) {
39
+ const { facetGroup, selectedFacets } = this;
40
+ if (!facetGroup)
41
+ return;
44
42
  let newFacets;
45
43
  if (selectedFacets) {
46
44
  newFacets = {
@@ -50,24 +48,13 @@ let FacetsTemplate = class FacetsTemplate extends LitElement {
50
48
  else {
51
49
  newFacets = getDefaultSelectedFacets();
52
50
  }
53
- delete newFacets[key][value];
51
+ delete newFacets[facetGroup.key][bucket.key];
54
52
  this.selectedFacets = newFacets;
55
53
  this.dispatchSelectedFacetsChanged();
56
54
  }
57
- /** Returns the composed facet state corresponding to a positive or negative facet's checked state */
58
- getFacetState(checked, negative) {
59
- let state;
60
- if (checked) {
61
- state = negative ? 'hidden' : 'selected';
62
- }
63
- else {
64
- state = 'none';
65
- }
66
- return state;
67
- }
68
- dispatchFacetClickEvent(key, state, negative) {
55
+ dispatchFacetClickEvent(detail) {
69
56
  const event = new CustomEvent('facetClick', {
70
- detail: { key, state, negative },
57
+ detail,
71
58
  composed: true,
72
59
  });
73
60
  this.dispatchEvent(event);
@@ -80,105 +67,39 @@ let FacetsTemplate = class FacetsTemplate extends LitElement {
80
67
  });
81
68
  this.dispatchEvent(event);
82
69
  }
83
- getFacetsTemplate(facetGroup) {
84
- let facetsBucket = facetGroup === null || facetGroup === void 0 ? void 0 : facetGroup.buckets;
70
+ get facetsTemplate() {
71
+ const { facetGroup } = this;
72
+ if (!facetGroup)
73
+ return nothing;
74
+ let facetBuckets = facetGroup.buckets;
85
75
  /**
86
76
  * sorting FacetBucket before render page / modal
87
77
  * - first, selected items should be at top having sorted
88
78
  * - second, suppressed/hidden items should be after selected having sorted
89
79
  * - and then no-selected / not suppressed items should render having sorted
90
80
  */
91
- facetsBucket = [
92
- ...facetsBucket
81
+ facetBuckets = [
82
+ ...facetBuckets
93
83
  .filter(x => x.state === 'selected')
94
84
  .sort((a, b) => (a.count < b.count ? 1 : -1)),
95
- ...facetsBucket
85
+ ...facetBuckets
96
86
  .filter(x => x.state === 'hidden')
97
87
  .sort((a, b) => (a.count < b.count ? 1 : -1)),
98
- ...facetsBucket.filter(x => x.state === 'none'),
88
+ ...facetBuckets.filter(x => x.state === 'none'),
99
89
  ];
100
90
  return html `
101
91
  <div class="facets-on-${this.renderOn}">
102
- ${repeat(facetsBucket, bucket => `${facetGroup.key}:${bucket.key}`, bucket => {
103
- var _a, _b;
104
- const showOnlyCheckboxId = `${facetGroup.key}:${bucket.key}-show-only`;
105
- const negativeCheckboxId = `${facetGroup.key}:${bucket.key}-negative`;
106
- // for collections, we need to asynchronously load the collection name
107
- // so we use the `async-collection-name` widget and for the rest, we have
108
- // a static value to use
109
- const bucketTextDisplay = facetGroup.key !== 'collection'
110
- ? html `${(_a = bucket.displayText) !== null && _a !== void 0 ? _a : bucket.key}`
111
- : html `<a href="${this.collectionPagePath}${bucket.key}">
112
- <async-collection-name
113
- .collectionNameCache=${this.collectionNameCache}
114
- .identifier=${bucket.key}
115
- placeholder="-"
116
- ></async-collection-name>
117
- </a> `;
118
- const facetHidden = bucket.state === 'hidden';
119
- const facetSelected = bucket.state === 'selected';
120
- const titleText = `${facetGroup.key}: ${(_b = bucket.displayText) !== null && _b !== void 0 ? _b : bucket.key}`;
121
- const onlyShowText = facetSelected
122
- ? `Show all ${facetGroup.key}s`
123
- : `Only show ${titleText}`;
124
- const hideText = `Hide ${titleText}`;
125
- const unhideText = `Unhide ${titleText}`;
126
- const showHideText = facetHidden ? unhideText : hideText;
127
- const ariaLabel = `${titleText}, ${bucket.count} results`;
128
- return html `
129
- <div class="facet-row">
130
- <div class="facet-checkbox">
131
- <input
132
- type="checkbox"
133
- .name=${facetGroup.key}
134
- .value=${bucket.key}
135
- @click=${(e) => {
136
- this.facetClicked(e, bucket.count, false);
137
- }}
138
- .checked=${facetSelected}
139
- class="select-facet-checkbox"
140
- title=${onlyShowText}
141
- id=${showOnlyCheckboxId}
142
- />
143
- <input
144
- type="checkbox"
145
- id=${negativeCheckboxId}
146
- .name=${facetGroup.key}
147
- .value=${bucket.key}
148
- @click=${(e) => {
149
- this.facetClicked(e, bucket.count, true);
150
- }}
151
- .checked=${facetHidden}
152
- class="hide-facet-checkbox"
153
- />
154
- <label
155
- for=${negativeCheckboxId}
156
- class="hide-facet-icon${facetHidden ? ' active' : ''}"
157
- title=${showHideText}
158
- >
159
- <span class="eye">${eyeIcon}</span>
160
- <span class="eye-closed">${eyeClosedIcon}</span>
161
- </label>
162
- </div>
163
- <label
164
- for=${showOnlyCheckboxId}
165
- class="facet-info-display"
166
- title=${onlyShowText}
167
- aria-label=${ariaLabel}
168
- >
169
- <div class="facet-title">${bucketTextDisplay}</div>
170
- <div class="facet-count">
171
- ${bucket.count.toLocaleString()}
172
- </div>
173
- </label>
174
- </div>
175
- `;
176
- })}
92
+ ${repeat(facetBuckets, bucket => `${facetGroup.key}:${bucket.key}`, bucket => html `<facet-row
93
+ .facetType=${facetGroup.key}
94
+ .bucket=${bucket}
95
+ .collectionNameCache=${this.collectionNameCache}
96
+ @facetClick=${this.facetClicked}
97
+ ></facet-row>`)}
177
98
  </div>
178
99
  `;
179
100
  }
180
101
  render() {
181
- return html `${this.getFacetsTemplate(this.facetGroup)}`;
102
+ return html `${this.facetsTemplate}`;
182
103
  }
183
104
  static get styles() {
184
105
  return css `
@@ -191,9 +112,7 @@ let FacetsTemplate = class FacetsTemplate extends LitElement {
191
112
  column-gap: 15px;
192
113
  column-count: 3;
193
114
  }
194
- async-collection-name {
195
- display: contents;
196
- }
115
+
197
116
  ul.facet-list {
198
117
  list-style: none;
199
118
  margin: 0;
@@ -203,19 +122,7 @@ let FacetsTemplate = class FacetsTemplate extends LitElement {
203
122
  margin-bottom: 0.2rem;
204
123
  display: grid;
205
124
  }
206
- .facet-checkbox {
207
- margin: 0 5px 0 0;
208
- display: flex;
209
- height: 15px;
210
- }
211
- .facet-checkbox input:first-child {
212
- margin-right: 5px;
213
- }
214
- .facet-checkbox input {
215
- height: 15px;
216
- width: 15px;
217
- margin: 0;
218
- }
125
+
219
126
  .facet-row {
220
127
  display: flex;
221
128
  font-weight: 500;
@@ -226,52 +133,6 @@ let FacetsTemplate = class FacetsTemplate extends LitElement {
226
133
  border-bottom: var(--facet-row-border-bottom, 1px solid transparent);
227
134
  overflow: hidden;
228
135
  }
229
- .facet-info-display {
230
- display: flex;
231
- flex: 1 1 0%;
232
- cursor: pointer;
233
- flex-wrap: wrap;
234
- }
235
- .facet-title {
236
- word-break: break-word;
237
- display: inline-block;
238
- flex: 1 1 0%;
239
- }
240
- .facet-count {
241
- text-align: right;
242
- }
243
- .select-facet-checkbox {
244
- cursor: pointer;
245
- display: inline-block;
246
- }
247
- .hide-facet-checkbox {
248
- display: none;
249
- }
250
- .hide-facet-icon {
251
- width: 15px;
252
- height: 15px;
253
- cursor: pointer;
254
- opacity: 0.3;
255
- display: inline-block;
256
- }
257
- .hide-facet-icon:hover,
258
- .active {
259
- opacity: 1;
260
- }
261
- .hide-facet-icon:hover .eye,
262
- .hide-facet-icon .eye-closed {
263
- display: none;
264
- }
265
- .hide-facet-icon:hover .eye-closed,
266
- .hide-facet-icon.active .eye-closed {
267
- display: inline;
268
- }
269
- .hide-facet-icon.active .eye {
270
- display: none;
271
- }
272
- .sorting-icon {
273
- cursor: pointer;
274
- }
275
136
 
276
137
  a:link,
277
138
  a:visited {
@@ -293,9 +154,6 @@ __decorate([
293
154
  __decorate([
294
155
  property({ type: String })
295
156
  ], FacetsTemplate.prototype, "renderOn", void 0);
296
- __decorate([
297
- property({ type: String })
298
- ], FacetsTemplate.prototype, "collectionPagePath", void 0);
299
157
  __decorate([
300
158
  property({ type: Object })
301
159
  ], FacetsTemplate.prototype, "collectionNameCache", void 0);