@internetarchive/collection-browser 1.0.0 → 1.1.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/app-root.js +11 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/assets/img/icons/expand.d.ts +2 -0
- package/dist/src/assets/img/icons/expand.js +9 -0
- package/dist/src/assets/img/icons/expand.js.map +1 -0
- package/dist/src/collection-browser.d.ts +35 -4
- package/dist/src/collection-browser.js +118 -44
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facets-template.d.ts +1 -1
- package/dist/src/collection-facets/facets-template.js +3 -3
- package/dist/src/collection-facets/facets-template.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.d.ts +1 -1
- package/dist/src/collection-facets/more-facets-content.js +3 -3
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets/more-facets-pagination.js +3 -3
- package/dist/src/collection-facets/more-facets-pagination.js.map +1 -1
- package/dist/src/collection-facets/toggle-switch.js +1 -1
- package/dist/src/collection-facets/toggle-switch.js.map +1 -1
- package/dist/src/collection-facets.d.ts +19 -2
- package/dist/src/collection-facets.js +118 -15
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/empty-placeholder.js +2 -2
- package/dist/src/empty-placeholder.js.map +1 -1
- package/dist/src/expanded-date-picker.d.ts +41 -0
- package/dist/src/expanded-date-picker.js +146 -0
- package/dist/src/expanded-date-picker.js.map +1 -0
- package/dist/src/language-code-handler/language-code-handler.js +1 -1
- package/dist/src/language-code-handler/language-code-handler.js.map +1 -1
- package/dist/src/mediatype/mediatype-config.js +13 -13
- package/dist/src/mediatype/mediatype-config.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +1 -1
- package/dist/src/restoration-state-handler.js +18 -2
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/sort-filter-bar/alpha-bar.d.ts +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 +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.js +8 -8
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/grid/account-tile.d.ts +1 -1
- package/dist/src/tiles/grid/account-tile.js +1 -1
- package/dist/src/tiles/grid/account-tile.js.map +1 -1
- package/dist/src/tiles/grid/collection-tile.d.ts +1 -1
- package/dist/src/tiles/grid/collection-tile.js +3 -3
- package/dist/src/tiles/grid/collection-tile.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.d.ts +1 -1
- package/dist/src/tiles/grid/item-tile.js +3 -3
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js +1 -1
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js.map +1 -1
- package/dist/src/tiles/grid/tile-stats.js +6 -6
- package/dist/src/tiles/grid/tile-stats.js.map +1 -1
- package/dist/src/tiles/hover/hover-pane-controller.d.ts +1 -1
- package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
- package/dist/src/tiles/hover/tile-hover-pane.d.ts +1 -1
- package/dist/src/tiles/hover/tile-hover-pane.js.map +1 -1
- package/dist/src/tiles/image-block.d.ts +1 -1
- package/dist/src/tiles/image-block.js.map +1 -1
- package/dist/src/tiles/item-image.d.ts +1 -1
- package/dist/src/tiles/item-image.js +1 -1
- package/dist/src/tiles/item-image.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.d.ts +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -1
- package/dist/src/tiles/list/tile-list-compact.js +4 -4
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +1 -1
- package/dist/src/tiles/list/tile-list.js +6 -6
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/mediatype-icon.js +1 -1
- package/dist/src/tiles/mediatype-icon.js.map +1 -1
- package/dist/src/tiles/overlay/icon-overlay.js +2 -2
- package/dist/src/tiles/overlay/icon-overlay.js.map +1 -1
- package/dist/src/tiles/overlay/icon-text-overlay.js +2 -2
- package/dist/src/tiles/overlay/icon-text-overlay.js.map +1 -1
- package/dist/src/tiles/overlay/text-overlay.js +2 -2
- package/dist/src/tiles/overlay/text-overlay.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +4 -3
- package/dist/src/tiles/tile-dispatcher.js +7 -1
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/test/collection-facets.test.js +54 -0
- package/dist/test/collection-facets.test.js.map +1 -1
- package/dist/test/expanded-date-picker.test.d.ts +1 -0
- package/dist/test/expanded-date-picker.test.js +93 -0
- package/dist/test/expanded-date-picker.test.js.map +1 -0
- package/dist/test/restoration-state-handler.test.js +28 -0
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/index.html +3 -2
- package/package.json +14 -13
- package/src/app-root.ts +12 -1
- package/src/assets/img/icons/expand.ts +9 -0
- package/src/collection-browser.ts +119 -44
- package/src/collection-facets/facets-template.ts +3 -3
- package/src/collection-facets/more-facets-content.ts +3 -3
- package/src/collection-facets/more-facets-pagination.ts +3 -3
- package/src/collection-facets/toggle-switch.ts +1 -1
- package/src/collection-facets.ts +113 -10
- package/src/empty-placeholder.ts +2 -2
- package/src/expanded-date-picker.ts +144 -0
- package/src/language-code-handler/language-code-handler.ts +1 -1
- package/src/mediatype/mediatype-config.ts +13 -13
- package/src/restoration-state-handler.ts +19 -2
- package/src/sort-filter-bar/alpha-bar.ts +2 -2
- package/src/sort-filter-bar/sort-filter-bar.ts +8 -8
- package/src/tiles/grid/account-tile.ts +2 -2
- package/src/tiles/grid/collection-tile.ts +4 -4
- package/src/tiles/grid/item-tile.ts +4 -4
- package/src/tiles/grid/styles/tile-grid-shared-styles.ts +1 -1
- package/src/tiles/grid/tile-stats.ts +6 -6
- package/src/tiles/hover/hover-pane-controller.ts +1 -1
- package/src/tiles/hover/tile-hover-pane.ts +1 -1
- package/src/tiles/image-block.ts +1 -1
- package/src/tiles/item-image.ts +2 -2
- package/src/tiles/list/tile-list-compact-header.ts +2 -2
- package/src/tiles/list/tile-list-compact.ts +5 -5
- package/src/tiles/list/tile-list.ts +6 -6
- package/src/tiles/mediatype-icon.ts +1 -1
- package/src/tiles/overlay/icon-overlay.ts +2 -2
- package/src/tiles/overlay/icon-text-overlay.ts +2 -2
- package/src/tiles/overlay/text-overlay.ts +2 -2
- package/src/tiles/tile-dispatcher.ts +6 -3
- package/test/collection-facets.test.ts +74 -0
- package/test/expanded-date-picker.test.ts +137 -0
- package/test/restoration-state-handler.test.ts +44 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { accountIcon } from '../assets/img/icons/mediatype/account';
|
|
2
|
-
import { audioIcon } from '../assets/img/icons/mediatype/audio';
|
|
3
|
-
import { collectionIcon } from '../assets/img/icons/mediatype/collection';
|
|
4
|
-
import { dataIcon } from '../assets/img/icons/mediatype/data';
|
|
5
|
-
import { etreeIcon } from '../assets/img/icons/mediatype/etree';
|
|
6
|
-
import { imagesIcon } from '../assets/img/icons/mediatype/images';
|
|
7
|
-
import { filmIcon } from '../assets/img/icons/mediatype/film';
|
|
8
|
-
import { radioIcon } from '../assets/img/icons/mediatype/radio';
|
|
9
|
-
import { softwareIcon } from '../assets/img/icons/mediatype/software';
|
|
10
|
-
import { textsIcon } from '../assets/img/icons/mediatype/texts';
|
|
11
|
-
import { tvIcon } from '../assets/img/icons/mediatype/tv';
|
|
12
|
-
import { videoIcon } from '../assets/img/icons/mediatype/video';
|
|
13
|
-
import { webIcon } from '../assets/img/icons/mediatype/web';
|
|
1
|
+
import { accountIcon } from '../assets/img/icons/mediatype/account.js';
|
|
2
|
+
import { audioIcon } from '../assets/img/icons/mediatype/audio.js';
|
|
3
|
+
import { collectionIcon } from '../assets/img/icons/mediatype/collection.js';
|
|
4
|
+
import { dataIcon } from '../assets/img/icons/mediatype/data.js';
|
|
5
|
+
import { etreeIcon } from '../assets/img/icons/mediatype/etree.js';
|
|
6
|
+
import { imagesIcon } from '../assets/img/icons/mediatype/images.js';
|
|
7
|
+
import { filmIcon } from '../assets/img/icons/mediatype/film.js';
|
|
8
|
+
import { radioIcon } from '../assets/img/icons/mediatype/radio.js';
|
|
9
|
+
import { softwareIcon } from '../assets/img/icons/mediatype/software.js';
|
|
10
|
+
import { textsIcon } from '../assets/img/icons/mediatype/texts.js';
|
|
11
|
+
import { tvIcon } from '../assets/img/icons/mediatype/tv.js';
|
|
12
|
+
import { videoIcon } from '../assets/img/icons/mediatype/video.js';
|
|
13
|
+
import { webIcon } from '../assets/img/icons/mediatype/web.js';
|
|
14
14
|
export const mediatypeConfig = {
|
|
15
15
|
account: {
|
|
16
16
|
color: '#000000',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mediatype-config.js","sourceRoot":"","sources":["../../../src/mediatype/mediatype-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"mediatype-config.js","sourceRoot":"","sources":["../../../src/mediatype/mediatype-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAE/D,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;KAChB;IACD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,OAAO;KACd;IACD,UAAU,EAAE;QACV,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,YAAY;KACnB;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,MAAM;KACb;IACD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,QAAQ;KACf;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,MAAM;KACb;IACD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,OAAO;KACd;IACD,MAAM,EAAE;QACN,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO;KACd;IACD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,OAAO;KACd;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,UAAU;KACjB;IACD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,MAAM;KACb;IACD,EAAE,EAAE;QACF,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,IAAI;KACX;IACD,KAAK,EAAE;QACL,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,OAAO;KACd;IACD,GAAG,EAAE;QACH,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,KAAK;KACZ;CACF,CAAC","sourcesContent":["import { accountIcon } from '../assets/img/icons/mediatype/account.js';\nimport { audioIcon } from '../assets/img/icons/mediatype/audio.js';\nimport { collectionIcon } from '../assets/img/icons/mediatype/collection.js';\nimport { dataIcon } from '../assets/img/icons/mediatype/data.js';\nimport { etreeIcon } from '../assets/img/icons/mediatype/etree.js';\nimport { imagesIcon } from '../assets/img/icons/mediatype/images.js';\nimport { filmIcon } from '../assets/img/icons/mediatype/film.js';\nimport { radioIcon } from '../assets/img/icons/mediatype/radio.js';\nimport { softwareIcon } from '../assets/img/icons/mediatype/software.js';\nimport { textsIcon } from '../assets/img/icons/mediatype/texts.js';\nimport { tvIcon } from '../assets/img/icons/mediatype/tv.js';\nimport { videoIcon } from '../assets/img/icons/mediatype/video.js';\nimport { webIcon } from '../assets/img/icons/mediatype/web.js';\n\nexport const mediatypeConfig: { [key: string]: any } = {\n account: {\n color: '#000000',\n icon: accountIcon,\n text: 'Account',\n },\n audio: {\n color: '#00adef',\n icon: audioIcon,\n text: 'Audio',\n },\n collection: {\n color: '#4666ff',\n icon: collectionIcon,\n text: 'Collection',\n },\n data: {\n color: '#333333',\n icon: dataIcon,\n text: 'Data',\n },\n etree: {\n color: '#00adef',\n icon: etreeIcon,\n text: 'E-tree',\n },\n film: {\n color: '#bf1b2c',\n icon: filmIcon,\n text: 'Film',\n },\n image: {\n color: '#aa99c9',\n icon: imagesIcon,\n text: 'Image',\n },\n movies: {\n color: '#f1644b',\n icon: filmIcon,\n text: 'Movie',\n },\n radio: {\n color: '#8fdaef',\n icon: radioIcon,\n text: 'Radio',\n },\n software: {\n color: '#9ecc4f',\n icon: softwareIcon,\n text: 'Software',\n },\n texts: {\n color: '#faab3c',\n icon: textsIcon,\n text: 'Text',\n },\n tv: {\n color: '#f1644b',\n icon: tvIcon,\n text: 'TV',\n },\n video: {\n color: '#f1644b',\n icon: videoIcon,\n text: 'Video',\n },\n web: {\n color: '#ffcd27',\n icon: webIcon,\n text: 'Web',\n },\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SearchType, SortDirection, SortParam } from '@internetarchive/search-service';
|
|
2
|
-
import { CollectionBrowserContext, CollectionDisplayMode, SelectedFacets, SortField } from './models';
|
|
2
|
+
import { CollectionBrowserContext, CollectionDisplayMode, SelectedFacets, SortField } from './models.js';
|
|
3
3
|
export interface RestorationState {
|
|
4
4
|
displayMode?: CollectionDisplayMode;
|
|
5
5
|
searchType?: SearchType;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SearchType, } from '@internetarchive/search-service';
|
|
2
2
|
import { getCookie, setCookie } from 'typescript-cookie';
|
|
3
|
-
import { URLFieldToSortField, getDefaultSelectedFacets, MetadataFieldToURLField, } from './models';
|
|
4
|
-
import { arrayEquals } from './utils/array-equals';
|
|
3
|
+
import { URLFieldToSortField, getDefaultSelectedFacets, MetadataFieldToURLField, } from './models.js';
|
|
4
|
+
import { arrayEquals } from './utils/array-equals.js';
|
|
5
5
|
export class RestorationStateHandler {
|
|
6
6
|
constructor(options) {
|
|
7
7
|
this.cookieDomain = '.archive.org';
|
|
@@ -148,6 +148,16 @@ export class RestorationStateHandler {
|
|
|
148
148
|
const sortQuery = url.searchParams.get('sort');
|
|
149
149
|
const facetAnds = url.searchParams.getAll('and[]');
|
|
150
150
|
const facetNots = url.searchParams.getAll('not[]');
|
|
151
|
+
// We also need to check for the presence of params like 'and[0]', 'not[1]', etc.
|
|
152
|
+
// since Facebook automatically converts URLs with [] into those forms.
|
|
153
|
+
for (const [key, val] of url.searchParams.entries()) {
|
|
154
|
+
if (/and\[\d+\]/.test(key)) {
|
|
155
|
+
facetAnds.push(val);
|
|
156
|
+
}
|
|
157
|
+
else if (/not\[\d+\]/.test(key)) {
|
|
158
|
+
facetNots.push(val);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
151
161
|
// Legacy search allowed `q` and `search` params for the query, so in the interest
|
|
152
162
|
// of backwards-compatibility with old bookmarks, we recognize those here too.
|
|
153
163
|
// (However, they still get upgraded to a `query` param when we persist our state
|
|
@@ -273,6 +283,12 @@ export class RestorationStateHandler {
|
|
|
273
283
|
searchParams.delete('sort');
|
|
274
284
|
searchParams.delete('and[]');
|
|
275
285
|
searchParams.delete('not[]');
|
|
286
|
+
// Remove any and/not facet params that contain numbers in their square brackets
|
|
287
|
+
for (const key of searchParams.keys()) {
|
|
288
|
+
if (/(and|not)\[\d+\]/.test(key)) {
|
|
289
|
+
searchParams.delete(key);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
276
292
|
// Also remove some legacy params that should have been upgraded to the ones above
|
|
277
293
|
searchParams.delete('q');
|
|
278
294
|
searchParams.delete('search');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SearchType,\n SortDirection,\n SortParam,\n} from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n MetadataSortField,\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n URLFieldToSortField,\n URLSortField,\n getDefaultSelectedFacets,\n MetadataFieldToURLField,\n} from './models';\nimport { arrayEquals } from './utils/array-equals';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n sortParam?: SortParam;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(state: RestorationState): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(state: RestorationState): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(state: RestorationState) {\n const url = new URL(window.location.href);\n const oldParams = new URLSearchParams(url.searchParams);\n const newParams = this.removeRecognizedParams(url.searchParams);\n\n let replaceEmptySin = false;\n\n if (state.baseQuery) {\n newParams.set('query', state.baseQuery);\n }\n\n if (state.searchType === SearchType.FULLTEXT) {\n newParams.set('sin', 'TXT');\n }\n if (oldParams.get('sin') === '') {\n // Treat empty sin the same as no sin at all\n oldParams.delete('sin');\n replaceEmptySin = true;\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n newParams.set('page', state.currentPage.toString());\n } else {\n newParams.delete('page');\n }\n }\n\n if (state.sortParam) {\n const prefix = state.sortParam.direction === 'desc' ? '-' : '';\n const readableSortField =\n MetadataFieldToURLField[state.sortParam.field as MetadataSortField];\n newParams.set('sort', `${prefix}${readableSortField}`);\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets\n )) {\n const facetEntries = Object.entries(facetValues);\n // eslint-disable-next-line no-continue\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n newParams.append('not[]', paramValue);\n } else {\n newParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n newParams.append(\n 'and[]',\n `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`\n );\n }\n\n if (state.titleQuery) {\n newParams.append('and[]', state.titleQuery);\n }\n\n if (state.creatorQuery) {\n newParams.append('and[]', state.creatorQuery);\n }\n\n // Ensure we aren't pushing consecutive identical states to the history stack.\n // - If the state has changed, we push a new history entry.\n // - If only the page number has changed, we replace the current history entry.\n // - If the state hasn't changed, then do nothing.\n let historyMethod: 'pushState' | 'replaceState' = 'pushState';\n const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [\n 'sin',\n 'sort',\n 'and[]',\n 'not[]',\n ]);\n\n if (\n nonQueryParamsMatch &&\n this.paramsMatch(oldParams, newParams, ['query'])\n ) {\n if (replaceEmptySin) {\n // Get rid of any empty sin param\n newParams.delete('sin');\n } else if (this.paramsMatch(oldParams, newParams, ['page'])) {\n // For page number, we want to replace the page state when it changes,\n // not push a new history entry. If it hasn't changed, then we're done.\n return;\n }\n historyMethod = 'replaceState';\n } else if (nonQueryParamsMatch && this.hasLegacyParam(oldParams)) {\n // Similarly, if the only non-matching param was a legacy query param, then\n // we just want to overwrite it.\n historyMethod = 'replaceState';\n }\n\n window.history[historyMethod]?.(\n {\n query: state.baseQuery,\n searchType: state.searchType,\n page: state.currentPage,\n sort: state.sortParam,\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n facets: state.selectedFacets,\n },\n '',\n url\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n // Legacy search allowed `q` and `search` params for the query, so in the interest\n // of backwards-compatibility with old bookmarks, we recognize those here too.\n // (However, they still get upgraded to a `query` param when we persist our state\n // to the URL).\n const legacySearchQuery =\n url.searchParams.get('q') ?? url.searchParams.get('search');\n\n const restorationState: RestorationState = {\n selectedFacets: getDefaultSelectedFacets(),\n };\n\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n } else if (legacySearchQuery) {\n restorationState.baseQuery = legacySearchQuery;\n }\n\n switch (searchInside) {\n // Eventually there will be TV/Radio search types here too.\n case 'TXT':\n restorationState.searchType = SearchType.FULLTEXT;\n break;\n default:\n restorationState.searchType = SearchType.METADATA;\n break;\n }\n\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n\n if (sortQuery) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortQuery.indexOf(' ') > -1;\n if (hasSpace) {\n const [field, direction] = sortQuery.split(' ');\n const metadataField = URLFieldToSortField[field as URLSortField];\n\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n }\n if (direction === 'desc' || direction === 'asc') {\n restorationState.sortDirection = direction as SortDirection;\n }\n } else {\n const direction = sortQuery.startsWith('-') ? 'desc' : 'asc';\n const field = sortQuery.startsWith('-')\n ? sortQuery.slice(1)\n : sortQuery;\n\n const metadataField = URLFieldToSortField[field as URLSortField];\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n restorationState.sortDirection = direction as SortDirection;\n }\n }\n }\n\n if (facetAnds) {\n facetAnds.forEach(and => {\n // eslint-disable-next-line prefer-const\n let [field, value] = and.split(':');\n\n // Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.\n // which we want to normalize to 'creator', 'language', etc. if redirected here.\n field = field.replace(/Sorter$/, '');\n\n switch (field) {\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n });\n }\n\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden'\n );\n });\n }\n\n return restorationState;\n }\n\n // remove optional opening and closing quotes from a string\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n\n return value;\n }\n\n /**\n * Returns whether the two given URLSearchParams objects have\n * identical values for all of the given param keys. If either\n * object contains more than one value for a given key, then\n * all of the values for that key must match (disregarding order).\n */\n private paramsMatch(\n searchParams1: URLSearchParams,\n searchParams2: URLSearchParams,\n keys: string[]\n ): boolean {\n return keys.every(key =>\n arrayEquals(\n searchParams1.getAll(key).sort(),\n searchParams2.getAll(key).sort()\n )\n );\n }\n\n /**\n * Deletes any params from the given URLSearchParams object that are recognized\n * when loading state from the URL.\n */\n private removeRecognizedParams(\n searchParams: URLSearchParams\n ): URLSearchParams {\n // Remove all of our standard params\n searchParams.delete('query');\n searchParams.delete('sin');\n searchParams.delete('page');\n searchParams.delete('sort');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n // Also remove some legacy params that should have been upgraded to the ones above\n searchParams.delete('q');\n searchParams.delete('search');\n\n return searchParams;\n }\n\n /**\n * Returns whether the given URLSearchParams object contains a param that is\n * only recognized as a holdover from legacy search, and should not be\n * persisted to the URL.\n */\n private hasLegacyParam(searchParams: URLSearchParams): boolean {\n return searchParams.has('q') || searchParams.has('search');\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState\n ): void {\n const facet = selectedFacets[field];\n if (!facet) return; // Unrecognized facet group, ignore it.\n\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SearchType,\n SortDirection,\n SortParam,\n} from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n MetadataSortField,\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n URLFieldToSortField,\n URLSortField,\n getDefaultSelectedFacets,\n MetadataFieldToURLField,\n} from './models.js';\nimport { arrayEquals } from './utils/array-equals.js';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n sortParam?: SortParam;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(state: RestorationState): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(state: RestorationState): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(state: RestorationState) {\n const url = new URL(window.location.href);\n const oldParams = new URLSearchParams(url.searchParams);\n const newParams = this.removeRecognizedParams(url.searchParams);\n\n let replaceEmptySin = false;\n\n if (state.baseQuery) {\n newParams.set('query', state.baseQuery);\n }\n\n if (state.searchType === SearchType.FULLTEXT) {\n newParams.set('sin', 'TXT');\n }\n if (oldParams.get('sin') === '') {\n // Treat empty sin the same as no sin at all\n oldParams.delete('sin');\n replaceEmptySin = true;\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n newParams.set('page', state.currentPage.toString());\n } else {\n newParams.delete('page');\n }\n }\n\n if (state.sortParam) {\n const prefix = state.sortParam.direction === 'desc' ? '-' : '';\n const readableSortField =\n MetadataFieldToURLField[state.sortParam.field as MetadataSortField];\n newParams.set('sort', `${prefix}${readableSortField}`);\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets\n )) {\n const facetEntries = Object.entries(facetValues);\n // eslint-disable-next-line no-continue\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n newParams.append('not[]', paramValue);\n } else {\n newParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n newParams.append(\n 'and[]',\n `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`\n );\n }\n\n if (state.titleQuery) {\n newParams.append('and[]', state.titleQuery);\n }\n\n if (state.creatorQuery) {\n newParams.append('and[]', state.creatorQuery);\n }\n\n // Ensure we aren't pushing consecutive identical states to the history stack.\n // - If the state has changed, we push a new history entry.\n // - If only the page number has changed, we replace the current history entry.\n // - If the state hasn't changed, then do nothing.\n let historyMethod: 'pushState' | 'replaceState' = 'pushState';\n const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [\n 'sin',\n 'sort',\n 'and[]',\n 'not[]',\n ]);\n\n if (\n nonQueryParamsMatch &&\n this.paramsMatch(oldParams, newParams, ['query'])\n ) {\n if (replaceEmptySin) {\n // Get rid of any empty sin param\n newParams.delete('sin');\n } else if (this.paramsMatch(oldParams, newParams, ['page'])) {\n // For page number, we want to replace the page state when it changes,\n // not push a new history entry. If it hasn't changed, then we're done.\n return;\n }\n historyMethod = 'replaceState';\n } else if (nonQueryParamsMatch && this.hasLegacyParam(oldParams)) {\n // Similarly, if the only non-matching param was a legacy query param, then\n // we just want to overwrite it.\n historyMethod = 'replaceState';\n }\n\n window.history[historyMethod]?.(\n {\n query: state.baseQuery,\n searchType: state.searchType,\n page: state.currentPage,\n sort: state.sortParam,\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n facets: state.selectedFacets,\n },\n '',\n url\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n // We also need to check for the presence of params like 'and[0]', 'not[1]', etc.\n // since Facebook automatically converts URLs with [] into those forms.\n for (const [key, val] of url.searchParams.entries()) {\n if (/and\\[\\d+\\]/.test(key)) {\n facetAnds.push(val);\n } else if (/not\\[\\d+\\]/.test(key)) {\n facetNots.push(val);\n }\n }\n\n // Legacy search allowed `q` and `search` params for the query, so in the interest\n // of backwards-compatibility with old bookmarks, we recognize those here too.\n // (However, they still get upgraded to a `query` param when we persist our state\n // to the URL).\n const legacySearchQuery =\n url.searchParams.get('q') ?? url.searchParams.get('search');\n\n const restorationState: RestorationState = {\n selectedFacets: getDefaultSelectedFacets(),\n };\n\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n } else if (legacySearchQuery) {\n restorationState.baseQuery = legacySearchQuery;\n }\n\n switch (searchInside) {\n // Eventually there will be TV/Radio search types here too.\n case 'TXT':\n restorationState.searchType = SearchType.FULLTEXT;\n break;\n default:\n restorationState.searchType = SearchType.METADATA;\n break;\n }\n\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n\n if (sortQuery) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortQuery.indexOf(' ') > -1;\n if (hasSpace) {\n const [field, direction] = sortQuery.split(' ');\n const metadataField = URLFieldToSortField[field as URLSortField];\n\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n }\n if (direction === 'desc' || direction === 'asc') {\n restorationState.sortDirection = direction as SortDirection;\n }\n } else {\n const direction = sortQuery.startsWith('-') ? 'desc' : 'asc';\n const field = sortQuery.startsWith('-')\n ? sortQuery.slice(1)\n : sortQuery;\n\n const metadataField = URLFieldToSortField[field as URLSortField];\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n restorationState.sortDirection = direction as SortDirection;\n }\n }\n }\n\n if (facetAnds) {\n facetAnds.forEach(and => {\n // eslint-disable-next-line prefer-const\n let [field, value] = and.split(':');\n\n // Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.\n // which we want to normalize to 'creator', 'language', etc. if redirected here.\n field = field.replace(/Sorter$/, '');\n\n switch (field) {\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n });\n }\n\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden'\n );\n });\n }\n\n return restorationState;\n }\n\n // remove optional opening and closing quotes from a string\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n\n return value;\n }\n\n /**\n * Returns whether the two given URLSearchParams objects have\n * identical values for all of the given param keys. If either\n * object contains more than one value for a given key, then\n * all of the values for that key must match (disregarding order).\n */\n private paramsMatch(\n searchParams1: URLSearchParams,\n searchParams2: URLSearchParams,\n keys: string[]\n ): boolean {\n return keys.every(key =>\n arrayEquals(\n searchParams1.getAll(key).sort(),\n searchParams2.getAll(key).sort()\n )\n );\n }\n\n /**\n * Deletes any params from the given URLSearchParams object that are recognized\n * when loading state from the URL.\n */\n private removeRecognizedParams(\n searchParams: URLSearchParams\n ): URLSearchParams {\n // Remove all of our standard params\n searchParams.delete('query');\n searchParams.delete('sin');\n searchParams.delete('page');\n searchParams.delete('sort');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n // Remove any and/not facet params that contain numbers in their square brackets\n for (const key of searchParams.keys()) {\n if (/(and|not)\\[\\d+\\]/.test(key)) {\n searchParams.delete(key);\n }\n }\n\n // Also remove some legacy params that should have been upgraded to the ones above\n searchParams.delete('q');\n searchParams.delete('search');\n\n return searchParams;\n }\n\n /**\n * Returns whether the given URLSearchParams object contains a param that is\n * only recognized as a holdover from legacy search, and should not be\n * persisted to the URL.\n */\n private hasLegacyParam(searchParams: URLSearchParams): boolean {\n return searchParams.has('q') || searchParams.has('search');\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState\n ): void {\n const facet = selectedFacets[field];\n if (!facet) return; // Unrecognized facet group, ignore it.\n\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, TemplateResult } from 'lit';
|
|
2
|
-
import type { PrefixFilterCounts } from '../models';
|
|
2
|
+
import type { PrefixFilterCounts } from '../models.js';
|
|
3
3
|
import './alpha-bar-tooltip';
|
|
4
4
|
export declare class AlphaBar extends LitElement {
|
|
5
5
|
selectedLetter: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha-bar.js","sourceRoot":"","sources":["../../../src/sort-filter-bar/alpha-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css, nothing, TemplateResult } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport type { PrefixFilterCounts } from '../models';\n\nimport './alpha-bar-tooltip';\nimport type { AlphaBarTooltip } from './alpha-bar-tooltip';\n\n@customElement('alpha-bar')\nexport class AlphaBar extends LitElement {\n @property({ type: String }) selectedLetter: string | null = null;\n\n @property({ type: Object }) letterCounts?: PrefixFilterCounts;\n\n @property({ type: String }) ariaLandmarkLabel?: string;\n\n @state()\n private tooltipShown: boolean = false;\n\n @state()\n private hoveredLetter?: string;\n\n @query('alpha-bar-tooltip')\n private tooltip?: AlphaBarTooltip;\n\n private readonly alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');\n\n private get selectedUppercaseLetter(): string | undefined {\n return this.selectedLetter?.toUpperCase();\n }\n\n render() {\n return html`\n <section id=\"container\" aria-label=${this.ariaLandmarkLabel ?? nothing}>\n <ul>\n ${this.alphabet.map(\n letter =>\n html`\n <li\n class=${letter === this.selectedUppercaseLetter\n ? 'selected'\n : nothing}\n @mousemove=${this.handleMouseMove}\n @mouseleave=${this.handleMouseLeave}\n >\n ${this.letterButtonTemplate(letter)}\n ${this.tooltipTemplate(letter)}\n </li>\n `\n )}\n </ul>\n </section>\n `;\n }\n\n private letterButtonTemplate(letter: string) {\n const ariaLabel = `${letter}: ${this.letterCounts?.[letter] ?? 0} results`;\n return html`\n <button\n aria-label=${ariaLabel}\n ?disabled=${!this.letterCounts?.[letter]}\n @click=${() => {\n this.letterClicked(letter);\n }}\n >\n ${letter}\n </button>\n `;\n }\n\n private tooltipTemplate(letter: string): TemplateResult | typeof nothing {\n if (this.hoveredLetter !== letter) return nothing;\n\n return this.tooltipShown\n ? html`<alpha-bar-tooltip\n data-letter=${letter}\n .numResults=${this.letterCounts?.[this.hoveredLetter] ?? 0}\n ></alpha-bar-tooltip>`\n : nothing;\n }\n\n private letterClicked(letter: string) {\n if (letter === this.selectedUppercaseLetter) {\n this.selectedLetter = null;\n } else {\n this.selectedLetter = letter;\n }\n this.dispatchEvent(\n new CustomEvent('letterChanged', {\n detail: { selectedLetter: this.selectedUppercaseLetter },\n })\n );\n }\n\n private async handleMouseMove(e: MouseEvent) {\n const target = e.target as HTMLLIElement;\n if (target && !this.tooltipShown) {\n const targetLetter = target.textContent?.trim() ?? undefined;\n this.tooltipShown = true;\n this.hoveredLetter = targetLetter;\n\n await this.updateComplete;\n await new Promise(resolve => {\n setTimeout(resolve, 0);\n });\n\n if (this.tooltip && this.tooltip.dataset.letter === targetLetter) {\n this.positionTooltip(target);\n }\n }\n }\n\n private handleMouseLeave() {\n this.tooltipShown = false;\n this.hoveredLetter = undefined;\n }\n\n private positionTooltip(targetElmt: HTMLElement) {\n if (!this.tooltip) return;\n\n // Basic positioning is just to center the whole tooltip on the letter box.\n const tooltipWidth = this.tooltip.clientWidth;\n const letterWidth = targetElmt.clientWidth;\n let left = letterWidth / 2 - tooltipWidth / 2;\n\n // But we also need to ensure the tooltip doesn't flow outside the viewport.\n // First, calculate the full width of the document body, including margins\n // (but not including any scrollbar).\n const bodyStyle = getComputedStyle(document.body);\n const bodyMarginLeft = parseFloat(\n bodyStyle.getPropertyValue('margin-left')\n );\n const bodyMarginRight = parseFloat(\n bodyStyle.getPropertyValue('margin-right')\n );\n const bodyWidthWithMargin =\n document.body.clientWidth + bodyMarginLeft + bodyMarginRight;\n\n // Calculate the positions of the tooltip's left/right edges, and determine\n // how much they overflow the viewport by (if at all).\n const targetRect = targetElmt.getBoundingClientRect();\n const tooltipLeft = targetRect.left + left;\n const tooltipRight = tooltipLeft + tooltipWidth;\n const offset = 1; // How many pixels the tooltip must be offset from the left/right edges\n let overflowAmt;\n if (tooltipLeft < offset) {\n // Tooltip overflows left edge of viewport\n overflowAmt = tooltipLeft - offset;\n } else if (tooltipRight > bodyWidthWithMargin - offset) {\n // Tooltip overflows right edge of viewport\n overflowAmt = tooltipRight - bodyWidthWithMargin + offset;\n }\n\n // Apply any needed adjustment to the tooltip and its arrow to keep it in the viewport\n if (overflowAmt) {\n left -= overflowAmt;\n this.tooltip.style.setProperty(\n '--tooltipArrowOffset',\n `${overflowAmt}px`\n );\n }\n\n this.tooltip.style.left = `${left}px`;\n this.tooltip.classList.add('fade-in');\n }\n\n static styles = css`\n h1 {\n font-size: 1.2rem;\n }\n\n #container {\n background-color: #ddd;\n color: #333;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);\n }\n\n ul {\n list-style: none;\n display: flex;\n margin: 0;\n padding: 0.5rem 1rem;\n justify-content: space-between;\n }\n\n ul li {\n position: relative;\n flex: 1;\n text-align: center;\n max-width: 2.5rem;\n border-radius: 4px;\n }\n\n li:hover:not(.selected) button:not(:disabled) {\n background-color: #c0c0c0;\n }\n\n button {\n display: flex;\n justify-content: center;\n align-items: center;\n aspect-ratio: 1 / 1;\n }\n\n button {\n width: 100%;\n height: 100%;\n color: #333;\n appearance: none;\n background: none;\n border: none;\n border-radius: 4px;\n font-family: inherit;\n font-size: inherit;\n cursor: pointer;\n }\n\n button:disabled {\n color: #aaa;\n cursor: default;\n }\n\n .selected {\n background-color: #2c2c2c;\n }\n\n .selected button {\n color: white;\n }\n\n alpha-bar-tooltip {\n position: absolute;\n top: 100%;\n left: -9999px;\n margin-top: 3px;\n z-index: 1;\n\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n\n alpha-bar-tooltip.fade-in {\n opacity: 1;\n }\n\n /* Make alphabet bar a 2-row container in small screen widths */\n @media screen and (max-width: 768px) {\n ul {\n display: grid;\n grid-template-columns: repeat(13, 1fr);\n }\n }\n `;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"alpha-bar.js","sourceRoot":"","sources":["../../../src/sort-filter-bar/alpha-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css, nothing, TemplateResult } from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport type { PrefixFilterCounts } from '../models.js';\n\nimport './alpha-bar-tooltip';\nimport type { AlphaBarTooltip } from './alpha-bar-tooltip.js';\n\n@customElement('alpha-bar')\nexport class AlphaBar extends LitElement {\n @property({ type: String }) selectedLetter: string | null = null;\n\n @property({ type: Object }) letterCounts?: PrefixFilterCounts;\n\n @property({ type: String }) ariaLandmarkLabel?: string;\n\n @state()\n private tooltipShown: boolean = false;\n\n @state()\n private hoveredLetter?: string;\n\n @query('alpha-bar-tooltip')\n private tooltip?: AlphaBarTooltip;\n\n private readonly alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');\n\n private get selectedUppercaseLetter(): string | undefined {\n return this.selectedLetter?.toUpperCase();\n }\n\n render() {\n return html`\n <section id=\"container\" aria-label=${this.ariaLandmarkLabel ?? nothing}>\n <ul>\n ${this.alphabet.map(\n letter =>\n html`\n <li\n class=${letter === this.selectedUppercaseLetter\n ? 'selected'\n : nothing}\n @mousemove=${this.handleMouseMove}\n @mouseleave=${this.handleMouseLeave}\n >\n ${this.letterButtonTemplate(letter)}\n ${this.tooltipTemplate(letter)}\n </li>\n `\n )}\n </ul>\n </section>\n `;\n }\n\n private letterButtonTemplate(letter: string) {\n const ariaLabel = `${letter}: ${this.letterCounts?.[letter] ?? 0} results`;\n return html`\n <button\n aria-label=${ariaLabel}\n ?disabled=${!this.letterCounts?.[letter]}\n @click=${() => {\n this.letterClicked(letter);\n }}\n >\n ${letter}\n </button>\n `;\n }\n\n private tooltipTemplate(letter: string): TemplateResult | typeof nothing {\n if (this.hoveredLetter !== letter) return nothing;\n\n return this.tooltipShown\n ? html`<alpha-bar-tooltip\n data-letter=${letter}\n .numResults=${this.letterCounts?.[this.hoveredLetter] ?? 0}\n ></alpha-bar-tooltip>`\n : nothing;\n }\n\n private letterClicked(letter: string) {\n if (letter === this.selectedUppercaseLetter) {\n this.selectedLetter = null;\n } else {\n this.selectedLetter = letter;\n }\n this.dispatchEvent(\n new CustomEvent('letterChanged', {\n detail: { selectedLetter: this.selectedUppercaseLetter },\n })\n );\n }\n\n private async handleMouseMove(e: MouseEvent) {\n const target = e.target as HTMLLIElement;\n if (target && !this.tooltipShown) {\n const targetLetter = target.textContent?.trim() ?? undefined;\n this.tooltipShown = true;\n this.hoveredLetter = targetLetter;\n\n await this.updateComplete;\n await new Promise(resolve => {\n setTimeout(resolve, 0);\n });\n\n if (this.tooltip && this.tooltip.dataset.letter === targetLetter) {\n this.positionTooltip(target);\n }\n }\n }\n\n private handleMouseLeave() {\n this.tooltipShown = false;\n this.hoveredLetter = undefined;\n }\n\n private positionTooltip(targetElmt: HTMLElement) {\n if (!this.tooltip) return;\n\n // Basic positioning is just to center the whole tooltip on the letter box.\n const tooltipWidth = this.tooltip.clientWidth;\n const letterWidth = targetElmt.clientWidth;\n let left = letterWidth / 2 - tooltipWidth / 2;\n\n // But we also need to ensure the tooltip doesn't flow outside the viewport.\n // First, calculate the full width of the document body, including margins\n // (but not including any scrollbar).\n const bodyStyle = getComputedStyle(document.body);\n const bodyMarginLeft = parseFloat(\n bodyStyle.getPropertyValue('margin-left')\n );\n const bodyMarginRight = parseFloat(\n bodyStyle.getPropertyValue('margin-right')\n );\n const bodyWidthWithMargin =\n document.body.clientWidth + bodyMarginLeft + bodyMarginRight;\n\n // Calculate the positions of the tooltip's left/right edges, and determine\n // how much they overflow the viewport by (if at all).\n const targetRect = targetElmt.getBoundingClientRect();\n const tooltipLeft = targetRect.left + left;\n const tooltipRight = tooltipLeft + tooltipWidth;\n const offset = 1; // How many pixels the tooltip must be offset from the left/right edges\n let overflowAmt;\n if (tooltipLeft < offset) {\n // Tooltip overflows left edge of viewport\n overflowAmt = tooltipLeft - offset;\n } else if (tooltipRight > bodyWidthWithMargin - offset) {\n // Tooltip overflows right edge of viewport\n overflowAmt = tooltipRight - bodyWidthWithMargin + offset;\n }\n\n // Apply any needed adjustment to the tooltip and its arrow to keep it in the viewport\n if (overflowAmt) {\n left -= overflowAmt;\n this.tooltip.style.setProperty(\n '--tooltipArrowOffset',\n `${overflowAmt}px`\n );\n }\n\n this.tooltip.style.left = `${left}px`;\n this.tooltip.classList.add('fade-in');\n }\n\n static styles = css`\n h1 {\n font-size: 1.2rem;\n }\n\n #container {\n background-color: #ddd;\n color: #333;\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);\n }\n\n ul {\n list-style: none;\n display: flex;\n margin: 0;\n padding: 0.5rem 1rem;\n justify-content: space-between;\n }\n\n ul li {\n position: relative;\n flex: 1;\n text-align: center;\n max-width: 2.5rem;\n border-radius: 4px;\n }\n\n li:hover:not(.selected) button:not(:disabled) {\n background-color: #c0c0c0;\n }\n\n button {\n display: flex;\n justify-content: center;\n align-items: center;\n aspect-ratio: 1 / 1;\n }\n\n button {\n width: 100%;\n height: 100%;\n color: #333;\n appearance: none;\n background: none;\n border: none;\n border-radius: 4px;\n font-family: inherit;\n font-size: inherit;\n cursor: pointer;\n }\n\n button:disabled {\n color: #aaa;\n cursor: default;\n }\n\n .selected {\n background-color: #2c2c2c;\n }\n\n .selected button {\n color: white;\n }\n\n alpha-bar-tooltip {\n position: absolute;\n top: 100%;\n left: -9999px;\n margin-top: 3px;\n z-index: 1;\n\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n\n alpha-bar-tooltip.fade-in {\n opacity: 1;\n }\n\n /* Make alphabet bar a 2-row container in small screen widths */\n @media screen and (max-width: 768px) {\n ul {\n display: grid;\n grid-template-columns: repeat(13, 1fr);\n }\n }\n `;\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { LitElement, PropertyValues, TemplateResult } from 'lit';
|
|
|
2
2
|
import type { SharedResizeObserverInterface, SharedResizeObserverResizeHandlerInterface } from '@internetarchive/shared-resize-observer';
|
|
3
3
|
import '@internetarchive/ia-dropdown';
|
|
4
4
|
import type { SortDirection } from '@internetarchive/search-service';
|
|
5
|
-
import { CollectionDisplayMode, PrefixFilterCounts, PrefixFilterType, SortField } from '../models';
|
|
5
|
+
import { CollectionDisplayMode, PrefixFilterCounts, PrefixFilterType, SortField } from '../models.js';
|
|
6
6
|
import './alpha-bar';
|
|
7
7
|
declare type AlphaSelector = 'creator' | 'title';
|
|
8
8
|
export declare class SortFilterBar extends LitElement implements SharedResizeObserverResizeHandlerInterface {
|
|
@@ -2,15 +2,15 @@ import { __decorate } from "tslib";
|
|
|
2
2
|
import { LitElement, html, css, nothing, } from 'lit';
|
|
3
3
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
4
4
|
import '@internetarchive/ia-dropdown';
|
|
5
|
-
import { DefaultSortDirection, SortField, SortFieldDisplayName, } from '../models';
|
|
5
|
+
import { DefaultSortDirection, SortField, SortFieldDisplayName, } from '../models.js';
|
|
6
6
|
import './alpha-bar';
|
|
7
|
-
import { sortUpIcon } from './img/sort-toggle-up';
|
|
8
|
-
import { sortDownIcon } from './img/sort-toggle-down';
|
|
9
|
-
import { sortDisabledIcon } from './img/sort-toggle-disabled';
|
|
10
|
-
import { tileIcon } from './img/tile';
|
|
11
|
-
import { listIcon } from './img/list';
|
|
12
|
-
import { compactIcon } from './img/compact';
|
|
13
|
-
import { srOnlyStyle } from '../styles/sr-only';
|
|
7
|
+
import { sortUpIcon } from './img/sort-toggle-up.js';
|
|
8
|
+
import { sortDownIcon } from './img/sort-toggle-down.js';
|
|
9
|
+
import { sortDisabledIcon } from './img/sort-toggle-disabled.js';
|
|
10
|
+
import { tileIcon } from './img/tile.js';
|
|
11
|
+
import { listIcon } from './img/list.js';
|
|
12
|
+
import { compactIcon } from './img/compact.js';
|
|
13
|
+
import { srOnlyStyle } from '../styles/sr-only.js';
|
|
14
14
|
let SortFilterBar = class SortFilterBar extends LitElement {
|
|
15
15
|
constructor() {
|
|
16
16
|
super(...arguments);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort-filter-bar.js","sourceRoot":"","sources":["../../../src/sort-filter-bar/sort-filter-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LitElement,\n html,\n css,\n nothing,\n PropertyValues,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type {\n SharedResizeObserverInterface,\n SharedResizeObserverResizeHandlerInterface,\n} from '@internetarchive/shared-resize-observer';\nimport '@internetarchive/ia-dropdown';\nimport type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';\nimport type { SortDirection } from '@internetarchive/search-service';\nimport {\n CollectionDisplayMode,\n DefaultSortDirection,\n PrefixFilterCounts,\n PrefixFilterType,\n SortField,\n SortFieldDisplayName,\n} from '../models';\nimport './alpha-bar';\n\nimport { sortUpIcon } from './img/sort-toggle-up';\nimport { sortDownIcon } from './img/sort-toggle-down';\nimport { sortDisabledIcon } from './img/sort-toggle-disabled';\nimport { tileIcon } from './img/tile';\nimport { listIcon } from './img/list';\nimport { compactIcon } from './img/compact';\nimport { srOnlyStyle } from '../styles/sr-only';\n\ntype AlphaSelector = 'creator' | 'title';\n\n@customElement('sort-filter-bar')\nexport class SortFilterBar\n extends LitElement\n implements SharedResizeObserverResizeHandlerInterface\n{\n /** Which display mode the tiles are being rendered with (grid/list-detail/list-compact) */\n @property({ type: String }) displayMode?: CollectionDisplayMode;\n\n /** The current sort direction (asc/desc), or null if none is set */\n @property({ type: String }) sortDirection: SortDirection | null = null;\n\n /** The field currently being sorted on (e.g., 'title'). Defaults to relevance. */\n @property({ type: String }) selectedSort: SortField = SortField.relevance;\n\n /** The currently selected title letter filter, or null if none is set */\n @property({ type: String }) selectedTitleFilter: string | null = null;\n\n /** The currently selected creator letter filter, or null if none is set */\n @property({ type: String }) selectedCreatorFilter: string | null = null;\n\n /** Whether to show the Relevance sort option (default `true`) */\n @property({ type: Boolean }) showRelevance: boolean = true;\n\n /** Maps of result counts for letters on the alphabet bar, for each letter filter type */\n @property({ type: Object }) prefixFilterCountMap?: Record<\n PrefixFilterType,\n PrefixFilterCounts\n >;\n\n @property({ type: Object }) resizeObserver?: SharedResizeObserverInterface;\n\n /**\n * Which of the alphabet bars (title/creator) should be shown, or null if one\n * should not currently be rendered.\n */\n @state() alphaSelectorVisible: AlphaSelector | null = null;\n\n /**\n * Whether the transparent backdrop to catch clicks outside the dropdown menu\n * should be rendered.\n */\n @state() dropdownBackdropVisible = false;\n\n /**\n * The width of the desktop view sort option container, updated upon each resize.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @state() desktopSortContainerWidth = 0;\n\n /**\n * The width of the full sort bar, updated upon each resize.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @state() selectorBarContainerWidth = 0;\n\n /**\n * The container for all the desktop view's sort options.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @query('#desktop-sort-container')\n private desktopSortContainer!: HTMLUListElement;\n\n /**\n * The container for the full sort bar.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @query('#sort-selector-container')\n private sortSelectorContainer!: HTMLDivElement;\n\n /** The dropdown component containing options for weekly and all-time views */\n @query('#views-dropdown')\n private viewsDropdown!: IaDropdown;\n\n /** The dropdown component containing the four date options */\n @query('#date-dropdown')\n private dateDropdown!: IaDropdown;\n\n /** The single, consolidated dropdown component shown in mobile view */\n @query('#mobile-dropdown')\n private mobileDropdown!: IaDropdown;\n\n render() {\n return html`\n <div id=\"container\">\n <section id=\"sort-bar\" aria-label=\"Sorting options\">\n <div class=\"sort-direction-container\">\n ${this.sortDirectionSelectorTemplate}\n </div>\n <span class=\"sort-by-text\">Sort by:</span>\n\n <div id=\"sort-selector-container\">\n ${this.mobileSortSelectorTemplate}\n ${this.desktopSortSelectorTemplate}\n </div>\n\n <div id=\"display-style-selector\">${this.displayOptionTemplate}</div>\n </section>\n\n ${this.dropdownBackdropVisible ? this.dropdownBackdrop : nothing}\n ${this.alphaBarTemplate}\n </div>\n `;\n }\n\n updated(changed: PropertyValues) {\n if (changed.has('displayMode')) {\n this.displayModeChanged();\n }\n\n if (changed.has('selectedSort') && this.sortDirection === null) {\n this.sortDirection = DefaultSortDirection[this.selectedSort];\n }\n\n if (changed.has('selectedTitleFilter') && this.selectedTitleFilter) {\n this.alphaSelectorVisible = 'title';\n }\n\n if (changed.has('selectedCreatorFilter') && this.selectedCreatorFilter) {\n this.alphaSelectorVisible = 'creator';\n }\n\n if (changed.has('dropdownBackdropVisible')) {\n this.setupEscapeListeners();\n }\n\n if (changed.has('resizeObserver')) {\n const oldObserver = changed.get(\n 'resizeObserver'\n ) as SharedResizeObserverInterface;\n if (oldObserver) this.disconnectResizeObserver(oldObserver);\n this.setupResizeObserver();\n }\n }\n\n private setupEscapeListeners() {\n if (this.dropdownBackdropVisible) {\n document.addEventListener(\n 'keydown',\n this.boundSortBarSelectorEscapeListener\n );\n } else {\n document.removeEventListener(\n 'keydown',\n this.boundSortBarSelectorEscapeListener\n );\n }\n }\n\n private boundSortBarSelectorEscapeListener = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n this.closeDropdowns();\n }\n };\n\n disconnectedCallback(): void {\n if (this.resizeObserver) {\n this.disconnectResizeObserver(this.resizeObserver);\n }\n }\n\n private disconnectResizeObserver(\n resizeObserver: SharedResizeObserverInterface\n ) {\n resizeObserver.removeObserver({\n target: this.sortSelectorContainer,\n handler: this,\n });\n\n resizeObserver.removeObserver({\n target: this.desktopSortContainer,\n handler: this,\n });\n }\n\n private setupResizeObserver() {\n if (!this.resizeObserver) return;\n this.resizeObserver.addObserver({\n target: this.sortSelectorContainer,\n handler: this,\n });\n\n this.resizeObserver.addObserver({\n target: this.desktopSortContainer,\n handler: this,\n });\n }\n\n handleResize(entry: ResizeObserverEntry): void {\n if (entry.target === this.desktopSortContainer) {\n this.desktopSortContainerWidth = entry.contentRect.width;\n } else if (entry.target === this.sortSelectorContainer) {\n this.selectorBarContainerWidth = entry.contentRect.width;\n }\n }\n\n /**\n * Whether to show the mobile sort bar because there is not enough space\n * for the desktop sort bar.\n */\n private get mobileSelectorVisible() {\n return this.selectorBarContainerWidth - 10 < this.desktopSortContainerWidth;\n }\n\n /**\n * Template to render the alphabet bar, or `nothing` if it should not be rendered\n * for the current sort\n */\n private get alphaBarTemplate(): TemplateResult | typeof nothing {\n if (!['title', 'creator'].includes(this.selectedSort)) return nothing;\n\n if (this.alphaSelectorVisible === null) {\n if (this.selectedSort === 'creator') return this.creatorSelectorBar;\n if (this.selectedSort === 'title') return this.titleSelectorBar;\n } else {\n return this.alphaSelectorVisible === 'creator'\n ? this.creatorSelectorBar\n : this.titleSelectorBar;\n }\n\n return nothing;\n }\n\n /** Template to render the sort direction toggle button */\n private get sortDirectionSelectorTemplate(): TemplateResult {\n const oppositeSortDirectionReadable =\n this.sortDirection === 'asc' ? 'descending' : 'ascending';\n const srLabel = `Change to ${oppositeSortDirectionReadable} sort`;\n\n return html`\n <button\n class=\"sort-direction-selector\"\n ?disabled=${this.selectedSort === 'relevance'}\n @click=${this.toggleSortDirection}\n >\n <span class=\"sr-only\">${srLabel}</span>\n ${this.sortDirectionIcon}\n </button>\n `;\n }\n\n /** Template to render the sort direction button's icon in the correct current state */\n private get sortDirectionIcon(): TemplateResult {\n // For relevance sort, show a fully disabled icon\n if (this.selectedSort === 'relevance') {\n return html`<div class=\"sort-direction-icon\">${sortDisabledIcon}</div>`;\n }\n\n // For all other sorts, show the ascending/descending direction\n return html`\n <div class=\"sort-direction-icon\">\n ${this.sortDirection === 'asc' ? sortUpIcon : sortDownIcon}\n </div>\n `;\n }\n\n /** The template to render all the sort options in desktop view */\n private get desktopSortSelectorTemplate() {\n return html`\n <div\n id=\"desktop-sort-container\"\n class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}\n >\n <ul id=\"desktop-sort-selector\">\n <li>\n ${this.showRelevance\n ? this.getSortDisplayOption(SortField.relevance, {\n onClick: () => {\n this.dropdownBackdropVisible = false;\n if (this.selectedSort !== SortField.relevance) {\n this.clearAlphaBarFilters();\n this.setSelectedSort(SortField.relevance);\n }\n },\n })\n : nothing}\n </li>\n <li>${this.viewsDropdownTemplate}</li>\n <li>\n ${this.getSortDisplayOption(SortField.title, {\n onClick: () => {\n this.dropdownBackdropVisible = false;\n if (this.selectedSort !== SortField.title) {\n this.alphaSelectorVisible = 'title';\n this.selectedCreatorFilter = null;\n this.setSelectedSort(SortField.title);\n this.emitCreatorLetterChangedEvent();\n }\n },\n })}\n </li>\n <li>${this.dateDropdownTemplate}</li>\n <li>\n ${this.getSortDisplayOption(SortField.creator, {\n onClick: () => {\n this.dropdownBackdropVisible = false;\n if (this.selectedSort !== SortField.creator) {\n this.alphaSelectorVisible = 'creator';\n this.selectedTitleFilter = null;\n this.setSelectedSort(SortField.creator);\n this.emitTitleLetterChangedEvent();\n }\n },\n })}\n </li>\n </ul>\n </div>\n `;\n }\n\n /** The template to render all the sort options in mobile view */\n private get mobileSortSelectorTemplate() {\n return html`\n <div\n id=\"mobile-sort-container\"\n class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}\n >\n ${this.getSortDropdown({\n displayName: html`${SortFieldDisplayName[this.selectedSort] ?? ''}`,\n id: 'mobile-dropdown',\n selected: true,\n dropdownOptions: Object.keys(SortField).map(field =>\n this.getDropdownOption(field as SortField)\n ),\n selectedOption: this.selectedSort ?? SortField.relevance,\n onOptionSelected: this.mobileSortChanged,\n onDropdownClick: () => {\n this.dropdownBackdropVisible = this.mobileDropdown.open;\n this.mobileDropdown.classList.toggle(\n 'open',\n this.mobileDropdown.open\n );\n },\n })}\n </div>\n `;\n }\n\n /**\n * This generates each of the non-dropdown sort option links.\n *\n * It manages the display value and the selected state of the option.\n *\n * @param sortField\n * @param options {\n * onClick?: (e: Event) => void; If this is provided, it will also be called when the option is clicked.\n * displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.\n * selected?: boolean; true if the option is selected. Defaults to the selectedSort === sortField.\n * }\n * @returns\n */\n private getSortDisplayOption(\n sortField: SortField,\n options?: {\n displayName?: TemplateResult;\n selected?: boolean;\n onClick?: (e: Event) => void;\n }\n ): TemplateResult {\n const isSelected = options?.selected ?? this.selectedSort === sortField;\n const displayName = options?.displayName ?? SortFieldDisplayName[sortField];\n return html`\n <button\n class=${isSelected ? 'selected' : nothing}\n @click=${(e: Event) => {\n e.preventDefault();\n options?.onClick?.(e);\n }}\n >\n ${displayName}\n </button>\n `;\n }\n\n /**\n * Generates a dropdown component containing multiple grouped sort options.\n *\n * @param options.displayName The name to use for the dropdown's visible label\n * @param options.id The id to apply to the dropdown element\n * @param options.dropdownOptions An array of option objects used to populate the dropdown\n * @param options.selectedOption The id of the option that should be initially selected\n * @param options.selected A boolean indicating whether this dropdown should use its\n * selected appearance\n * @param options.onOptionSelected A handler for optionSelected events coming from the dropdown\n * @param options.onDropdownClick A handler for click events on the dropdown\n * @param options.onLabelInteraction A handler for click events and Enter/Space keydown events\n * on the dropdown's label\n */\n private getSortDropdown(options: {\n displayName: TemplateResult;\n id?: string;\n dropdownOptions: optionInterface[];\n selectedOption?: string;\n selected: boolean;\n onOptionSelected?: (e: CustomEvent<{ option: optionInterface }>) => void;\n onDropdownClick?: (e: PointerEvent) => void;\n onLabelInteraction?: (e: Event) => void;\n }): TemplateResult {\n return html`\n <ia-dropdown\n id=${options.id ?? nothing}\n class=${options.selected ? 'selected' : nothing}\n displayCaret\n closeOnSelect\n includeSelectedOption\n .openViaButton=${options.selected}\n .options=${options.dropdownOptions}\n .selectedOption=${options.selectedOption ?? ''}\n @optionSelected=${options.onOptionSelected ?? nothing}\n @click=${options.onDropdownClick ?? nothing}\n >\n <span\n class=\"dropdown-label\"\n slot=\"dropdown-label\"\n @click=${options.onLabelInteraction ?? nothing}\n @keydown=${options.onLabelInteraction\n ? (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n options.onLabelInteraction?.(e);\n }\n }\n : nothing}\n >\n ${options.displayName}\n </span>\n </ia-dropdown>\n `;\n }\n\n /** Generates a single dropdown option object for the given sort field */\n private getDropdownOption(sortField: SortField): optionInterface {\n return {\n id: sortField,\n selectedHandler: () => {\n this.selectDropdownSortField(sortField);\n },\n label: html`\n <span class=\"dropdown-option-label\">\n ${SortFieldDisplayName[sortField]}\n </span>\n `,\n };\n }\n\n /** Handler for when any sort dropdown option is selected */\n private dropdownOptionSelected(e: CustomEvent<{ option: optionInterface }>) {\n this.dropdownBackdropVisible = false;\n this.clearAlphaBarFilters();\n this.setSelectedSort(e.detail.option.id as SortField);\n }\n\n /** The template to render for the views dropdown */\n private get viewsDropdownTemplate(): TemplateResult {\n return this.getSortDropdown({\n displayName: html`${this.viewSortField}`,\n id: 'views-dropdown',\n selected: this.viewOptionSelected,\n dropdownOptions: [\n this.getDropdownOption(SortField.weeklyview),\n this.getDropdownOption(SortField.alltimeview),\n ],\n selectedOption: this.viewOptionSelected ? this.selectedSort : '',\n onOptionSelected: this.dropdownOptionSelected,\n onDropdownClick: () => {\n this.dateDropdown.open = false;\n this.dropdownBackdropVisible = this.viewsDropdown.open;\n this.viewsDropdown.classList.toggle('open', this.viewsDropdown.open);\n },\n onLabelInteraction: (e: Event) => {\n if (!this.viewsDropdown.open && !this.viewOptionSelected) {\n e.stopPropagation();\n this.clearAlphaBarFilters();\n this.setSelectedSort(SortField.weeklyview);\n }\n },\n });\n }\n\n /** The template to render for the date dropdown */\n private get dateDropdownTemplate(): TemplateResult {\n return this.getSortDropdown({\n displayName: html`${this.dateSortField}`,\n id: 'date-dropdown',\n selected: this.dateOptionSelected,\n dropdownOptions: [\n this.getDropdownOption(SortField.date),\n this.getDropdownOption(SortField.datearchived),\n this.getDropdownOption(SortField.datereviewed),\n this.getDropdownOption(SortField.dateadded),\n ],\n selectedOption: this.dateOptionSelected ? this.selectedSort : '',\n onOptionSelected: this.dropdownOptionSelected,\n onDropdownClick: () => {\n this.viewsDropdown.open = false;\n this.dropdownBackdropVisible = this.dateDropdown.open;\n this.dateDropdown.classList.toggle('open', this.dateDropdown.open);\n },\n onLabelInteraction: (e: Event) => {\n if (!this.dateDropdown.open && !this.dateOptionSelected) {\n e.stopPropagation();\n this.clearAlphaBarFilters();\n this.setSelectedSort(SortField.date);\n }\n },\n });\n }\n\n /** Handler for when a new mobile sort dropdown option is selected */\n private mobileSortChanged(e: CustomEvent<{ option: optionInterface }>) {\n this.dropdownBackdropVisible = false;\n\n const sortField = e.detail.option.id as SortField;\n this.setSelectedSort(sortField);\n\n this.alphaSelectorVisible = null;\n if (sortField !== 'title' && this.selectedTitleFilter) {\n this.selectedTitleFilter = null;\n this.emitTitleLetterChangedEvent();\n }\n if (sortField !== 'creator' && this.selectedCreatorFilter) {\n this.selectedCreatorFilter = null;\n this.emitCreatorLetterChangedEvent();\n }\n }\n\n /** Template for rendering the three display mode options */\n private get displayOptionTemplate() {\n return html`\n <ul>\n <li>\n <button\n id=\"grid-button\"\n @click=${() => {\n this.displayMode = 'grid';\n }}\n class=${this.displayMode === 'grid' ? 'active' : ''}\n title=\"Tile view\"\n >\n ${tileIcon}\n </button>\n </li>\n <li>\n <button\n id=\"list-detail-button\"\n @click=${() => {\n this.displayMode = 'list-detail';\n }}\n class=${this.displayMode === 'list-detail' ? 'active' : ''}\n title=\"List view\"\n >\n ${listIcon}\n </button>\n </li>\n <li>\n <button\n id=\"list-compact-button\"\n @click=${() => {\n this.displayMode = 'list-compact';\n }}\n class=${this.displayMode === 'list-compact' ? 'active' : ''}\n title=\"Compact list view\"\n >\n ${compactIcon}\n </button>\n </li>\n </ul>\n `;\n }\n\n /**\n * Template for rendering the transparent backdrop to capture clicks outside the\n * dropdown menu while it is open.\n */\n private get dropdownBackdrop() {\n return html`\n <div\n id=\"sort-selector-backdrop\"\n @keyup=${this.closeDropdowns}\n @click=${this.closeDropdowns}\n ></div>\n `;\n }\n\n /** Closes all of the sorting dropdown components' menus */\n private closeDropdowns() {\n this.dropdownBackdropVisible = false;\n const allDropdowns = [\n this.viewsDropdown,\n this.dateDropdown,\n this.mobileDropdown,\n ];\n for (const dropdown of allDropdowns) {\n dropdown.open = false;\n dropdown.classList.remove('open');\n }\n }\n\n private selectDropdownSortField(sortField: SortField) {\n // When a dropdown sort option is selected, we additionally need to clear the backdrop\n this.dropdownBackdropVisible = false;\n this.setSelectedSort(sortField);\n }\n\n private clearAlphaBarFilters() {\n this.alphaSelectorVisible = null;\n this.selectedTitleFilter = null;\n this.selectedCreatorFilter = null;\n this.emitTitleLetterChangedEvent();\n this.emitCreatorLetterChangedEvent();\n }\n\n private setSortDirection(sortDirection: SortDirection) {\n this.sortDirection = sortDirection;\n this.emitSortChangedEvent();\n }\n\n /** Toggles the current sort direction between 'asc' and 'desc' */\n private toggleSortDirection() {\n this.setSortDirection(this.sortDirection === 'desc' ? 'asc' : 'desc');\n }\n\n private setSelectedSort(sort: SortField) {\n this.selectedSort = sort;\n // Apply this field's default sort direction\n this.sortDirection = DefaultSortDirection[this.selectedSort];\n this.emitSortChangedEvent();\n }\n\n /**\n * There are four date sort options.\n *\n * This checks to see if the current sort is one of them.\n *\n * @readonly\n * @private\n * @type {boolean}\n * @memberof SortFilterBar\n */\n private get dateOptionSelected(): boolean {\n const dateSortFields: SortField[] = [\n SortField.datearchived,\n SortField.date,\n SortField.datereviewed,\n SortField.dateadded,\n ];\n return dateSortFields.includes(this.selectedSort);\n }\n\n /**\n * There are two view sort options.\n *\n * This checks to see if the current sort is one of them.\n *\n * @readonly\n * @private\n * @type {boolean}\n * @memberof SortFilterBar\n */\n private get viewOptionSelected(): boolean {\n const viewSortFields: SortField[] = [\n SortField.alltimeview,\n SortField.weeklyview,\n ];\n return viewSortFields.includes(this.selectedSort);\n }\n\n /**\n * The display name of the current date field\n *\n * @readonly\n * @private\n * @type {string}\n * @memberof SortFilterBar\n */\n private get dateSortField(): string {\n const defaultSort = SortFieldDisplayName[SortField.date];\n const name = this.dateOptionSelected\n ? SortFieldDisplayName[this.selectedSort] ?? defaultSort\n : defaultSort;\n return name;\n }\n\n /**\n * The display name of the current view field\n *\n * @readonly\n * @private\n * @type {string}\n * @memberof SortFilterBar\n */\n private get viewSortField(): string {\n const defaultSort = SortFieldDisplayName[SortField.weeklyview];\n const name = this.viewOptionSelected\n ? SortFieldDisplayName[this.selectedSort] ?? defaultSort\n : defaultSort;\n return name;\n }\n\n private get titleSelectorBar() {\n return html` <alpha-bar\n .selectedLetter=${this.selectedTitleFilter}\n .letterCounts=${this.prefixFilterCountMap?.title}\n ariaLandmarkLabel=\"Filter by title letter\"\n @letterChanged=${this.titleLetterChanged}\n ></alpha-bar>`;\n }\n\n private get creatorSelectorBar() {\n return html` <alpha-bar\n .selectedLetter=${this.selectedCreatorFilter}\n .letterCounts=${this.prefixFilterCountMap?.creator}\n ariaLandmarkLabel=\"Filter by creator letter\"\n @letterChanged=${this.creatorLetterChanged}\n ></alpha-bar>`;\n }\n\n private titleLetterChanged(\n e: CustomEvent<{ selectedLetter: string | undefined }>\n ) {\n this.selectedTitleFilter = e.detail.selectedLetter ?? null;\n this.emitTitleLetterChangedEvent();\n }\n\n private creatorLetterChanged(\n e: CustomEvent<{ selectedLetter: string | undefined }>\n ) {\n this.selectedCreatorFilter = e.detail.selectedLetter ?? null;\n this.emitCreatorLetterChangedEvent();\n }\n\n private emitTitleLetterChangedEvent() {\n const event = new CustomEvent<{ selectedLetter: string | null }>(\n 'titleLetterChanged',\n {\n detail: { selectedLetter: this.selectedTitleFilter },\n }\n );\n this.dispatchEvent(event);\n }\n\n private emitCreatorLetterChangedEvent() {\n const event = new CustomEvent<{ selectedLetter: string | null }>(\n 'creatorLetterChanged',\n {\n detail: { selectedLetter: this.selectedCreatorFilter },\n }\n );\n this.dispatchEvent(event);\n }\n\n private displayModeChanged() {\n const event = new CustomEvent<{\n displayMode?: CollectionDisplayMode;\n }>('displayModeChanged', {\n detail: { displayMode: this.displayMode },\n });\n this.dispatchEvent(event);\n }\n\n private emitSortChangedEvent() {\n const event = new CustomEvent<{\n selectedSort: SortField;\n sortDirection: SortDirection | null;\n }>('sortChanged', {\n detail: {\n selectedSort: this.selectedSort,\n sortDirection: this.sortDirection,\n },\n });\n this.dispatchEvent(event);\n }\n\n static get styles() {\n return [\n srOnlyStyle,\n css`\n #container {\n position: relative;\n }\n\n #sort-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-bottom: 1px solid #2c2c2c;\n font-size: 1.4rem;\n }\n\n ul {\n list-style: none;\n display: flex;\n align-items: center;\n margin: 0;\n padding: 0;\n }\n\n li {\n padding: 0;\n }\n\n .sort-by-text {\n margin-right: 5px;\n font-weight: bold;\n white-space: nowrap;\n }\n\n .sort-direction-container {\n display: flex;\n align-self: stretch;\n flex: 0;\n margin: 0 5px;\n }\n\n .sort-direction-selector {\n padding: 0;\n border: none;\n appearance: none;\n background: transparent;\n cursor: pointer;\n }\n\n .sort-direction-selector:disabled {\n cursor: default;\n }\n\n .sort-direction-icon {\n display: flex;\n align-items: center;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n outline: inherit;\n width: 14px;\n height: 14px;\n }\n\n .sort-direction-icon > svg {\n flex: 1;\n }\n\n #date-sort-selector,\n #view-sort-selector {\n position: absolute;\n left: 150px;\n top: 45px;\n\n z-index: 1;\n padding: 1rem;\n background-color: white;\n border-radius: 2.5rem;\n border: 1px solid #404142;\n }\n\n #sort-selector-container {\n flex: 1;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n }\n\n #desktop-sort-container,\n #mobile-sort-container {\n display: flex;\n justify-content: flex-start;\n align-items: center;\n }\n\n /*\n we move the desktop sort selector offscreen instead of display: none\n because we need to observe the width of it vs its container to determine\n if it's wide enough to display the desktop version and if you display: none,\n the width becomes 0\n */\n #desktop-sort-container.hidden {\n position: absolute;\n top: -9999px;\n left: -9999px;\n visibility: hidden;\n }\n\n #mobile-sort-container.hidden {\n display: none;\n }\n\n #sort-selector-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n z-index: 1;\n background-color: transparent;\n }\n\n #desktop-sort-selector {\n display: inline-flex;\n }\n\n #desktop-sort-selector li {\n display: flex;\n align-items: center;\n padding-left: 5px;\n padding-right: 5px;\n }\n\n #desktop-sort-selector li a {\n padding: 0 5px;\n text-decoration: none;\n color: #333;\n line-height: 2;\n }\n\n #desktop-sort-selector li button {\n padding: 0px 5px;\n border: none;\n background: none;\n font-family: inherit;\n font-size: inherit;\n color: #333;\n line-height: 2;\n cursor: pointer;\n appearance: none;\n }\n\n #desktop-sort-selector li button.selected {\n font-weight: bold;\n }\n\n #display-style-selector {\n flex: 0;\n }\n\n #display-style-selector button {\n background: none;\n color: inherit;\n border: none;\n appearance: none;\n cursor: pointer;\n -webkit-appearance: none;\n fill: #bbbbbb;\n }\n\n #display-style-selector button.active {\n fill: var(--ia-theme-primary-text-color, #2c2c2c);\n }\n\n #display-style-selector button svg {\n width: 24px;\n height: 24px;\n }\n\n ia-dropdown {\n --dropdownTextColor: white;\n --dropdownOffsetTop: 0;\n --dropdownBorderTopWidth: 0;\n --dropdownBorderTopLeftRadius: 0;\n --dropdownBorderTopRightRadius: 0;\n --dropdownWhiteSpace: nowrap;\n --dropdownListZIndex: 2;\n --dropdownCaretColor: var(--ia-theme-primary-text-color, #2c2c2c);\n --dropdownSelectedTextColor: white;\n --dropdownSelectedBgColor: rgba(255, 255, 255, 0.3);\n --dropdownHoverBgColor: rgba(255, 255, 255, 0.3);\n --caretHeight: 9px;\n --caretWidth: 12px;\n --caretPadding: 0 5px 0 0;\n }\n ia-dropdown.selected .dropdown-label {\n font-weight: bold;\n }\n ia-dropdown.open {\n z-index: 2;\n }\n\n .dropdown-label {\n display: inline-block;\n height: 100%;\n padding-left: 5px;\n font-size: 1.4rem;\n line-height: 2;\n color: var(--ia-theme-primary-text-color, #2c2c2c);\n white-space: nowrap;\n user-select: none;\n }\n `,\n ];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sort-filter-bar.js","sourceRoot":"","sources":["../../../src/sort-filter-bar/sort-filter-bar.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,UAAU,EACV,IAAI,EACJ,GAAG,EACH,OAAO,GAGR,MAAM,KAAK,CAAC;AACb,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1E,OAAO,8BAA8B,CAAC;AAGtC,OAAO,EAEL,oBAAoB,EAGpB,SAAS,EACT,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKnD,IAAa,aAAa,GAA1B,MAAa,aACX,SAAQ,UAAU;IADpB;;QAOE,oEAAoE;QACxC,kBAAa,GAAyB,IAAI,CAAC;QAEvE,kFAAkF;QACtD,iBAAY,GAAc,SAAS,CAAC,SAAS,CAAC;QAE1E,yEAAyE;QAC7C,wBAAmB,GAAkB,IAAI,CAAC;QAEtE,2EAA2E;QAC/C,0BAAqB,GAAkB,IAAI,CAAC;QAExE,iEAAiE;QACpC,kBAAa,GAAY,IAAI,CAAC;QAU3D;;;WAGG;QACM,yBAAoB,GAAyB,IAAI,CAAC;QAE3D;;;WAGG;QACM,4BAAuB,GAAG,KAAK,CAAC;QAEzC;;;WAGG;QACM,8BAAyB,GAAG,CAAC,CAAC;QAEvC;;;WAGG;QACM,8BAAyB,GAAG,CAAC,CAAC;QA+F/B,uCAAkC,GAAG,CAAC,CAAgB,EAAE,EAAE;YAChE,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE;gBACtB,IAAI,CAAC,cAAc,EAAE,CAAC;aACvB;QACH,CAAC,CAAC;IAm0BJ,CAAC;IA14BC,MAAM;QACJ,OAAO,IAAI,CAAA;;;;cAID,IAAI,CAAC,6BAA6B;;;;;cAKlC,IAAI,CAAC,0BAA0B;cAC/B,IAAI,CAAC,2BAA2B;;;6CAGD,IAAI,CAAC,qBAAqB;;;UAG7D,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO;UAC9D,IAAI,CAAC,gBAAgB;;KAE1B,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,OAAuB;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE;YAC9B,IAAI,CAAC,kBAAkB,EAAE,CAAC;SAC3B;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE;YAC9D,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC9D;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAClE,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC;SACrC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE;YACtE,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;SACvC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE;YAC1C,IAAI,CAAC,oBAAoB,EAAE,CAAC;SAC7B;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE;YACjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAC7B,gBAAgB,CACgB,CAAC;YACnC,IAAI,WAAW;gBAAE,IAAI,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAC;YAC5D,IAAI,CAAC,mBAAmB,EAAE,CAAC;SAC5B;IACH,CAAC;IAEO,oBAAoB;QAC1B,IAAI,IAAI,CAAC,uBAAuB,EAAE;YAChC,QAAQ,CAAC,gBAAgB,CACvB,SAAS,EACT,IAAI,CAAC,kCAAkC,CACxC,CAAC;SACH;aAAM;YACL,QAAQ,CAAC,mBAAmB,CAC1B,SAAS,EACT,IAAI,CAAC,kCAAkC,CACxC,CAAC;SACH;IACH,CAAC;IAQD,oBAAoB;QAClB,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;SACpD;IACH,CAAC;IAEO,wBAAwB,CAC9B,cAA6C;QAE7C,cAAc,CAAC,cAAc,CAAC;YAC5B,MAAM,EAAE,IAAI,CAAC,qBAAqB;YAClC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,cAAc,CAAC,cAAc,CAAC;YAC5B,MAAM,EAAE,IAAI,CAAC,oBAAoB;YACjC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAEO,mBAAmB;QACzB,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC;YAC9B,MAAM,EAAE,IAAI,CAAC,qBAAqB;YAClC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC;YAC9B,MAAM,EAAE,IAAI,CAAC,oBAAoB;YACjC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAED,YAAY,CAAC,KAA0B;QACrC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,oBAAoB,EAAE;YAC9C,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC;SAC1D;aAAM,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,qBAAqB,EAAE;YACtD,IAAI,CAAC,yBAAyB,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC;SAC1D;IACH,CAAC;IAED;;;OAGG;IACH,IAAY,qBAAqB;QAC/B,OAAO,IAAI,CAAC,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC,yBAAyB,CAAC;IAC9E,CAAC;IAED;;;OAGG;IACH,IAAY,gBAAgB;QAC1B,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,OAAO,OAAO,CAAC;QAEtE,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI,EAAE;YACtC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC,kBAAkB,CAAC;YACpE,IAAI,IAAI,CAAC,YAAY,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC,gBAAgB,CAAC;SACjE;aAAM;YACL,OAAO,IAAI,CAAC,oBAAoB,KAAK,SAAS;gBAC5C,CAAC,CAAC,IAAI,CAAC,kBAAkB;gBACzB,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;SAC3B;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,0DAA0D;IAC1D,IAAY,6BAA6B;QACvC,MAAM,6BAA6B,GACjC,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;QAC5D,MAAM,OAAO,GAAG,aAAa,6BAA6B,OAAO,CAAC;QAElE,OAAO,IAAI,CAAA;;;oBAGK,IAAI,CAAC,YAAY,KAAK,WAAW;iBACpC,IAAI,CAAC,mBAAmB;;gCAET,OAAO;UAC7B,IAAI,CAAC,iBAAiB;;KAE3B,CAAC;IACJ,CAAC;IAED,uFAAuF;IACvF,IAAY,iBAAiB;QAC3B,iDAAiD;QACjD,IAAI,IAAI,CAAC,YAAY,KAAK,WAAW,EAAE;YACrC,OAAO,IAAI,CAAA,oCAAoC,gBAAgB,QAAQ,CAAC;SACzE;QAED,+DAA+D;QAC/D,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY;;KAE7D,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,IAAY,2BAA2B;QACrC,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;;;;cAInD,IAAI,CAAC,aAAa;YAClB,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,SAAS,EAAE;gBAC7C,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;oBACrC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,SAAS,EAAE;wBAC7C,IAAI,CAAC,oBAAoB,EAAE,CAAC;wBAC5B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;qBAC3C;gBACH,CAAC;aACF,CAAC;YACJ,CAAC,CAAC,OAAO;;gBAEP,IAAI,CAAC,qBAAqB;;cAE5B,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,KAAK,EAAE;YAC3C,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;gBACrC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,KAAK,EAAE;oBACzC,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC;oBACpC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;oBAClC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;oBACtC,IAAI,CAAC,6BAA6B,EAAE,CAAC;iBACtC;YACH,CAAC;SACF,CAAC;;gBAEE,IAAI,CAAC,oBAAoB;;cAE3B,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,OAAO,EAAE;YAC7C,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;gBACrC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC,OAAO,EAAE;oBAC3C,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;oBACtC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;oBAChC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;oBACxC,IAAI,CAAC,2BAA2B,EAAE,CAAC;iBACpC;YACH,CAAC;SACF,CAAC;;;;KAIT,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,IAAY,0BAA0B;;QACpC,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;;UAEvD,IAAI,CAAC,eAAe,CAAC;YACrB,WAAW,EAAE,IAAI,CAAA,GAAG,MAAA,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,mCAAI,EAAE,EAAE;YACnE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,IAAI;YACd,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAClD,IAAI,CAAC,iBAAiB,CAAC,KAAkB,CAAC,CAC3C;YACD,cAAc,EAAE,MAAA,IAAI,CAAC,YAAY,mCAAI,SAAS,CAAC,SAAS;YACxD,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;YACxC,eAAe,EAAE,GAAG,EAAE;gBACpB,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBACxD,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAClC,MAAM,EACN,IAAI,CAAC,cAAc,CAAC,IAAI,CACzB,CAAC;YACJ,CAAC;SACF,CAAC;;KAEL,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;OAYG;IACK,oBAAoB,CAC1B,SAAoB,EACpB,OAIC;;QAED,MAAM,UAAU,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,mCAAI,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC;QACxE,MAAM,WAAW,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,mCAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAA;;gBAEC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO;iBAChC,CAAC,CAAQ,EAAE,EAAE;;YACpB,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,wDAAG,CAAC,CAAC,CAAC;QACxB,CAAC;;UAEC,WAAW;;KAEhB,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,eAAe,CAAC,OASvB;;QACC,OAAO,IAAI,CAAA;;aAEF,MAAA,OAAO,CAAC,EAAE,mCAAI,OAAO;gBAClB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO;;;;yBAI9B,OAAO,CAAC,QAAQ;mBACtB,OAAO,CAAC,eAAe;0BAChB,MAAA,OAAO,CAAC,cAAc,mCAAI,EAAE;0BAC5B,MAAA,OAAO,CAAC,gBAAgB,mCAAI,OAAO;iBAC5C,MAAA,OAAO,CAAC,eAAe,mCAAI,OAAO;;;;;mBAKhC,MAAA,OAAO,CAAC,kBAAkB,mCAAI,OAAO;qBACnC,OAAO,CAAC,kBAAkB;YACnC,CAAC,CAAC,CAAC,CAAgB,EAAE,EAAE;;gBACnB,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE;oBACtC,MAAA,OAAO,CAAC,kBAAkB,wDAAG,CAAC,CAAC,CAAC;iBACjC;YACH,CAAC;YACH,CAAC,CAAC,OAAO;;YAET,OAAO,CAAC,WAAW;;;KAG1B,CAAC;IACJ,CAAC;IAED,yEAAyE;IACjE,iBAAiB,CAAC,SAAoB;QAC5C,OAAO;YACL,EAAE,EAAE,SAAS;YACb,eAAe,EAAE,GAAG,EAAE;gBACpB,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;YAC1C,CAAC;YACD,KAAK,EAAE,IAAI,CAAA;;YAEL,oBAAoB,CAAC,SAAS,CAAC;;OAEpC;SACF,CAAC;IACJ,CAAC;IAED,4DAA4D;IACpD,sBAAsB,CAAC,CAA2C;QACxE,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;QACrC,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAe,CAAC,CAAC;IACxD,CAAC;IAED,oDAAoD;IACpD,IAAY,qBAAqB;QAC/B,OAAO,IAAI,CAAC,eAAe,CAAC;YAC1B,WAAW,EAAE,IAAI,CAAA,GAAG,IAAI,CAAC,aAAa,EAAE;YACxC,EAAE,EAAE,gBAAgB;YACpB,QAAQ,EAAE,IAAI,CAAC,kBAAkB;YACjC,eAAe,EAAE;gBACf,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC;gBAC5C,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC;aAC9C;YACD,cAAc,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;YAChE,gBAAgB,EAAE,IAAI,CAAC,sBAAsB;YAC7C,eAAe,EAAE,GAAG,EAAE;gBACpB,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,KAAK,CAAC;gBAC/B,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBACvD,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACvE,CAAC;YACD,kBAAkB,EAAE,CAAC,CAAQ,EAAE,EAAE;gBAC/B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;oBACxD,CAAC,CAAC,eAAe,EAAE,CAAC;oBACpB,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBAC5B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;iBAC5C;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,mDAAmD;IACnD,IAAY,oBAAoB;QAC9B,OAAO,IAAI,CAAC,eAAe,CAAC;YAC1B,WAAW,EAAE,IAAI,CAAA,GAAG,IAAI,CAAC,aAAa,EAAE;YACxC,EAAE,EAAE,eAAe;YACnB,QAAQ,EAAE,IAAI,CAAC,kBAAkB;YACjC,eAAe,EAAE;gBACf,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC;gBACtC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC;gBAC9C,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC;gBAC9C,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC;aAC5C;YACD,cAAc,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;YAChE,gBAAgB,EAAE,IAAI,CAAC,sBAAsB;YAC7C,eAAe,EAAE,GAAG,EAAE;gBACpB,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,KAAK,CAAC;gBAChC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACtD,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACrE,CAAC;YACD,kBAAkB,EAAE,CAAC,CAAQ,EAAE,EAAE;gBAC/B,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;oBACvD,CAAC,CAAC,eAAe,EAAE,CAAC;oBACpB,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBAC5B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;iBACtC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,qEAAqE;IAC7D,iBAAiB,CAAC,CAA2C;QACnE,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;QAErC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAe,CAAC;QAClD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAEhC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,SAAS,KAAK,OAAO,IAAI,IAAI,CAAC,mBAAmB,EAAE;YACrD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,2BAA2B,EAAE,CAAC;SACpC;QACD,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,qBAAqB,EAAE;YACzD,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAClC,IAAI,CAAC,6BAA6B,EAAE,CAAC;SACtC;IACH,CAAC;IAED,4DAA4D;IAC5D,IAAY,qBAAqB;QAC/B,OAAO,IAAI,CAAA;;;;;qBAKM,GAAG,EAAE;YACZ,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;QAC5B,CAAC;oBACO,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;;;cAGjD,QAAQ;;;;;;qBAMD,GAAG,EAAE;YACZ,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC;QACnC,CAAC;oBACO,IAAI,CAAC,WAAW,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;;;cAGxD,QAAQ;;;;;;qBAMD,GAAG,EAAE;YACZ,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC;QACpC,CAAC;oBACO,IAAI,CAAC,WAAW,KAAK,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;;;cAGzD,WAAW;;;;KAIpB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAY,gBAAgB;QAC1B,OAAO,IAAI,CAAA;;;iBAGE,IAAI,CAAC,cAAc;iBACnB,IAAI,CAAC,cAAc;;KAE/B,CAAC;IACJ,CAAC;IAED,2DAA2D;IACnD,cAAc;QACpB,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;QACrC,MAAM,YAAY,GAAG;YACnB,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,YAAY;YACjB,IAAI,CAAC,cAAc;SACpB,CAAC;QACF,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE;YACnC,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC;YACtB,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SACnC;IACH,CAAC;IAEO,uBAAuB,CAAC,SAAoB;QAClD,sFAAsF;QACtF,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;QACrC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACnC,IAAI,CAAC,6BAA6B,EAAE,CAAC;IACvC,CAAC;IAEO,gBAAgB,CAAC,aAA4B;QACnD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED,kEAAkE;IAC1D,mBAAmB;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACxE,CAAC;IAEO,eAAe,CAAC,IAAe;QACrC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,4CAA4C;QAC5C,IAAI,CAAC,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;;;;OASG;IACH,IAAY,kBAAkB;QAC5B,MAAM,cAAc,GAAgB;YAClC,SAAS,CAAC,YAAY;YACtB,SAAS,CAAC,IAAI;YACd,SAAS,CAAC,YAAY;YACtB,SAAS,CAAC,SAAS;SACpB,CAAC;QACF,OAAO,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;;OASG;IACH,IAAY,kBAAkB;QAC5B,MAAM,cAAc,GAAgB;YAClC,SAAS,CAAC,WAAW;YACrB,SAAS,CAAC,UAAU;SACrB,CAAC;QACF,OAAO,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACH,IAAY,aAAa;;QACvB,MAAM,WAAW,GAAG,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB;YAClC,CAAC,CAAC,MAAA,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,mCAAI,WAAW;YACxD,CAAC,CAAC,WAAW,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,IAAY,aAAa;;QACvB,MAAM,WAAW,GAAG,oBAAoB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB;YAClC,CAAC,CAAC,MAAA,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,mCAAI,WAAW;YACxD,CAAC,CAAC,WAAW,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAY,gBAAgB;;QAC1B,OAAO,IAAI,CAAA;wBACS,IAAI,CAAC,mBAAmB;sBAC1B,MAAA,IAAI,CAAC,oBAAoB,0CAAE,KAAK;;uBAE/B,IAAI,CAAC,kBAAkB;kBAC5B,CAAC;IACjB,CAAC;IAED,IAAY,kBAAkB;;QAC5B,OAAO,IAAI,CAAA;wBACS,IAAI,CAAC,qBAAqB;sBAC5B,MAAA,IAAI,CAAC,oBAAoB,0CAAE,OAAO;;uBAEjC,IAAI,CAAC,oBAAoB;kBAC9B,CAAC;IACjB,CAAC;IAEO,kBAAkB,CACxB,CAAsD;;QAEtD,IAAI,CAAC,mBAAmB,GAAG,MAAA,CAAC,CAAC,MAAM,CAAC,cAAc,mCAAI,IAAI,CAAC;QAC3D,IAAI,CAAC,2BAA2B,EAAE,CAAC;IACrC,CAAC;IAEO,oBAAoB,CAC1B,CAAsD;;QAEtD,IAAI,CAAC,qBAAqB,GAAG,MAAA,CAAC,CAAC,MAAM,CAAC,cAAc,mCAAI,IAAI,CAAC;QAC7D,IAAI,CAAC,6BAA6B,EAAE,CAAC;IACvC,CAAC;IAEO,2BAA2B;QACjC,MAAM,KAAK,GAAG,IAAI,WAAW,CAC3B,oBAAoB,EACpB;YACE,MAAM,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE;SACrD,CACF,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEO,6BAA6B;QACnC,MAAM,KAAK,GAAG,IAAI,WAAW,CAC3B,sBAAsB,EACtB;YACE,MAAM,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,qBAAqB,EAAE;SACvD,CACF,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEO,kBAAkB;QACxB,MAAM,KAAK,GAAG,IAAI,WAAW,CAE1B,oBAAoB,EAAE;YACvB,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;SAC1C,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEO,oBAAoB;QAC1B,MAAM,KAAK,GAAG,IAAI,WAAW,CAG1B,aAAa,EAAE;YAChB,MAAM,EAAE;gBACN,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC;SACF,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO;YACL,WAAW;YACX,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkNF;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAr9B6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDAAqC;AAGpC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDAA4C;AAG3C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;mDAA+C;AAG9C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0DAA2C;AAG1C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4DAA6C;AAG3C;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oDAA+B;AAG/B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2DAGzB;AAE0B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qDAAgD;AAMlE;IAAR,KAAK,EAAE;2DAAmD;AAMlD;IAAR,KAAK,EAAE;8DAAiC;AAMhC;IAAR,KAAK,EAAE;gEAA+B;AAM9B;IAAR,KAAK,EAAE;gEAA+B;AAOvC;IADC,KAAK,CAAC,yBAAyB,CAAC;2DACe;AAOhD;IADC,KAAK,CAAC,0BAA0B,CAAC;4DACa;AAI/C;IADC,KAAK,CAAC,iBAAiB,CAAC;oDACU;AAInC;IADC,KAAK,CAAC,gBAAgB,CAAC;mDACU;AAIlC;IADC,KAAK,CAAC,kBAAkB,CAAC;qDACU;AA9EzB,aAAa;IADzB,aAAa,CAAC,iBAAiB,CAAC;GACpB,aAAa,CA09BzB;SA19BY,aAAa","sourcesContent":["import {\n LitElement,\n html,\n css,\n nothing,\n PropertyValues,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type {\n SharedResizeObserverInterface,\n SharedResizeObserverResizeHandlerInterface,\n} from '@internetarchive/shared-resize-observer';\nimport '@internetarchive/ia-dropdown';\nimport type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';\nimport type { SortDirection } from '@internetarchive/search-service';\nimport {\n CollectionDisplayMode,\n DefaultSortDirection,\n PrefixFilterCounts,\n PrefixFilterType,\n SortField,\n SortFieldDisplayName,\n} from '../models.js';\nimport './alpha-bar';\n\nimport { sortUpIcon } from './img/sort-toggle-up.js';\nimport { sortDownIcon } from './img/sort-toggle-down.js';\nimport { sortDisabledIcon } from './img/sort-toggle-disabled.js';\nimport { tileIcon } from './img/tile.js';\nimport { listIcon } from './img/list.js';\nimport { compactIcon } from './img/compact.js';\nimport { srOnlyStyle } from '../styles/sr-only.js';\n\ntype AlphaSelector = 'creator' | 'title';\n\n@customElement('sort-filter-bar')\nexport class SortFilterBar\n extends LitElement\n implements SharedResizeObserverResizeHandlerInterface\n{\n /** Which display mode the tiles are being rendered with (grid/list-detail/list-compact) */\n @property({ type: String }) displayMode?: CollectionDisplayMode;\n\n /** The current sort direction (asc/desc), or null if none is set */\n @property({ type: String }) sortDirection: SortDirection | null = null;\n\n /** The field currently being sorted on (e.g., 'title'). Defaults to relevance. */\n @property({ type: String }) selectedSort: SortField = SortField.relevance;\n\n /** The currently selected title letter filter, or null if none is set */\n @property({ type: String }) selectedTitleFilter: string | null = null;\n\n /** The currently selected creator letter filter, or null if none is set */\n @property({ type: String }) selectedCreatorFilter: string | null = null;\n\n /** Whether to show the Relevance sort option (default `true`) */\n @property({ type: Boolean }) showRelevance: boolean = true;\n\n /** Maps of result counts for letters on the alphabet bar, for each letter filter type */\n @property({ type: Object }) prefixFilterCountMap?: Record<\n PrefixFilterType,\n PrefixFilterCounts\n >;\n\n @property({ type: Object }) resizeObserver?: SharedResizeObserverInterface;\n\n /**\n * Which of the alphabet bars (title/creator) should be shown, or null if one\n * should not currently be rendered.\n */\n @state() alphaSelectorVisible: AlphaSelector | null = null;\n\n /**\n * Whether the transparent backdrop to catch clicks outside the dropdown menu\n * should be rendered.\n */\n @state() dropdownBackdropVisible = false;\n\n /**\n * The width of the desktop view sort option container, updated upon each resize.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @state() desktopSortContainerWidth = 0;\n\n /**\n * The width of the full sort bar, updated upon each resize.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @state() selectorBarContainerWidth = 0;\n\n /**\n * The container for all the desktop view's sort options.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @query('#desktop-sort-container')\n private desktopSortContainer!: HTMLUListElement;\n\n /**\n * The container for the full sort bar.\n * Used for dynamically determining whether to use desktop or mobile view.\n */\n @query('#sort-selector-container')\n private sortSelectorContainer!: HTMLDivElement;\n\n /** The dropdown component containing options for weekly and all-time views */\n @query('#views-dropdown')\n private viewsDropdown!: IaDropdown;\n\n /** The dropdown component containing the four date options */\n @query('#date-dropdown')\n private dateDropdown!: IaDropdown;\n\n /** The single, consolidated dropdown component shown in mobile view */\n @query('#mobile-dropdown')\n private mobileDropdown!: IaDropdown;\n\n render() {\n return html`\n <div id=\"container\">\n <section id=\"sort-bar\" aria-label=\"Sorting options\">\n <div class=\"sort-direction-container\">\n ${this.sortDirectionSelectorTemplate}\n </div>\n <span class=\"sort-by-text\">Sort by:</span>\n\n <div id=\"sort-selector-container\">\n ${this.mobileSortSelectorTemplate}\n ${this.desktopSortSelectorTemplate}\n </div>\n\n <div id=\"display-style-selector\">${this.displayOptionTemplate}</div>\n </section>\n\n ${this.dropdownBackdropVisible ? this.dropdownBackdrop : nothing}\n ${this.alphaBarTemplate}\n </div>\n `;\n }\n\n updated(changed: PropertyValues) {\n if (changed.has('displayMode')) {\n this.displayModeChanged();\n }\n\n if (changed.has('selectedSort') && this.sortDirection === null) {\n this.sortDirection = DefaultSortDirection[this.selectedSort];\n }\n\n if (changed.has('selectedTitleFilter') && this.selectedTitleFilter) {\n this.alphaSelectorVisible = 'title';\n }\n\n if (changed.has('selectedCreatorFilter') && this.selectedCreatorFilter) {\n this.alphaSelectorVisible = 'creator';\n }\n\n if (changed.has('dropdownBackdropVisible')) {\n this.setupEscapeListeners();\n }\n\n if (changed.has('resizeObserver')) {\n const oldObserver = changed.get(\n 'resizeObserver'\n ) as SharedResizeObserverInterface;\n if (oldObserver) this.disconnectResizeObserver(oldObserver);\n this.setupResizeObserver();\n }\n }\n\n private setupEscapeListeners() {\n if (this.dropdownBackdropVisible) {\n document.addEventListener(\n 'keydown',\n this.boundSortBarSelectorEscapeListener\n );\n } else {\n document.removeEventListener(\n 'keydown',\n this.boundSortBarSelectorEscapeListener\n );\n }\n }\n\n private boundSortBarSelectorEscapeListener = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n this.closeDropdowns();\n }\n };\n\n disconnectedCallback(): void {\n if (this.resizeObserver) {\n this.disconnectResizeObserver(this.resizeObserver);\n }\n }\n\n private disconnectResizeObserver(\n resizeObserver: SharedResizeObserverInterface\n ) {\n resizeObserver.removeObserver({\n target: this.sortSelectorContainer,\n handler: this,\n });\n\n resizeObserver.removeObserver({\n target: this.desktopSortContainer,\n handler: this,\n });\n }\n\n private setupResizeObserver() {\n if (!this.resizeObserver) return;\n this.resizeObserver.addObserver({\n target: this.sortSelectorContainer,\n handler: this,\n });\n\n this.resizeObserver.addObserver({\n target: this.desktopSortContainer,\n handler: this,\n });\n }\n\n handleResize(entry: ResizeObserverEntry): void {\n if (entry.target === this.desktopSortContainer) {\n this.desktopSortContainerWidth = entry.contentRect.width;\n } else if (entry.target === this.sortSelectorContainer) {\n this.selectorBarContainerWidth = entry.contentRect.width;\n }\n }\n\n /**\n * Whether to show the mobile sort bar because there is not enough space\n * for the desktop sort bar.\n */\n private get mobileSelectorVisible() {\n return this.selectorBarContainerWidth - 10 < this.desktopSortContainerWidth;\n }\n\n /**\n * Template to render the alphabet bar, or `nothing` if it should not be rendered\n * for the current sort\n */\n private get alphaBarTemplate(): TemplateResult | typeof nothing {\n if (!['title', 'creator'].includes(this.selectedSort)) return nothing;\n\n if (this.alphaSelectorVisible === null) {\n if (this.selectedSort === 'creator') return this.creatorSelectorBar;\n if (this.selectedSort === 'title') return this.titleSelectorBar;\n } else {\n return this.alphaSelectorVisible === 'creator'\n ? this.creatorSelectorBar\n : this.titleSelectorBar;\n }\n\n return nothing;\n }\n\n /** Template to render the sort direction toggle button */\n private get sortDirectionSelectorTemplate(): TemplateResult {\n const oppositeSortDirectionReadable =\n this.sortDirection === 'asc' ? 'descending' : 'ascending';\n const srLabel = `Change to ${oppositeSortDirectionReadable} sort`;\n\n return html`\n <button\n class=\"sort-direction-selector\"\n ?disabled=${this.selectedSort === 'relevance'}\n @click=${this.toggleSortDirection}\n >\n <span class=\"sr-only\">${srLabel}</span>\n ${this.sortDirectionIcon}\n </button>\n `;\n }\n\n /** Template to render the sort direction button's icon in the correct current state */\n private get sortDirectionIcon(): TemplateResult {\n // For relevance sort, show a fully disabled icon\n if (this.selectedSort === 'relevance') {\n return html`<div class=\"sort-direction-icon\">${sortDisabledIcon}</div>`;\n }\n\n // For all other sorts, show the ascending/descending direction\n return html`\n <div class=\"sort-direction-icon\">\n ${this.sortDirection === 'asc' ? sortUpIcon : sortDownIcon}\n </div>\n `;\n }\n\n /** The template to render all the sort options in desktop view */\n private get desktopSortSelectorTemplate() {\n return html`\n <div\n id=\"desktop-sort-container\"\n class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}\n >\n <ul id=\"desktop-sort-selector\">\n <li>\n ${this.showRelevance\n ? this.getSortDisplayOption(SortField.relevance, {\n onClick: () => {\n this.dropdownBackdropVisible = false;\n if (this.selectedSort !== SortField.relevance) {\n this.clearAlphaBarFilters();\n this.setSelectedSort(SortField.relevance);\n }\n },\n })\n : nothing}\n </li>\n <li>${this.viewsDropdownTemplate}</li>\n <li>\n ${this.getSortDisplayOption(SortField.title, {\n onClick: () => {\n this.dropdownBackdropVisible = false;\n if (this.selectedSort !== SortField.title) {\n this.alphaSelectorVisible = 'title';\n this.selectedCreatorFilter = null;\n this.setSelectedSort(SortField.title);\n this.emitCreatorLetterChangedEvent();\n }\n },\n })}\n </li>\n <li>${this.dateDropdownTemplate}</li>\n <li>\n ${this.getSortDisplayOption(SortField.creator, {\n onClick: () => {\n this.dropdownBackdropVisible = false;\n if (this.selectedSort !== SortField.creator) {\n this.alphaSelectorVisible = 'creator';\n this.selectedTitleFilter = null;\n this.setSelectedSort(SortField.creator);\n this.emitTitleLetterChangedEvent();\n }\n },\n })}\n </li>\n </ul>\n </div>\n `;\n }\n\n /** The template to render all the sort options in mobile view */\n private get mobileSortSelectorTemplate() {\n return html`\n <div\n id=\"mobile-sort-container\"\n class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}\n >\n ${this.getSortDropdown({\n displayName: html`${SortFieldDisplayName[this.selectedSort] ?? ''}`,\n id: 'mobile-dropdown',\n selected: true,\n dropdownOptions: Object.keys(SortField).map(field =>\n this.getDropdownOption(field as SortField)\n ),\n selectedOption: this.selectedSort ?? SortField.relevance,\n onOptionSelected: this.mobileSortChanged,\n onDropdownClick: () => {\n this.dropdownBackdropVisible = this.mobileDropdown.open;\n this.mobileDropdown.classList.toggle(\n 'open',\n this.mobileDropdown.open\n );\n },\n })}\n </div>\n `;\n }\n\n /**\n * This generates each of the non-dropdown sort option links.\n *\n * It manages the display value and the selected state of the option.\n *\n * @param sortField\n * @param options {\n * onClick?: (e: Event) => void; If this is provided, it will also be called when the option is clicked.\n * displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.\n * selected?: boolean; true if the option is selected. Defaults to the selectedSort === sortField.\n * }\n * @returns\n */\n private getSortDisplayOption(\n sortField: SortField,\n options?: {\n displayName?: TemplateResult;\n selected?: boolean;\n onClick?: (e: Event) => void;\n }\n ): TemplateResult {\n const isSelected = options?.selected ?? this.selectedSort === sortField;\n const displayName = options?.displayName ?? SortFieldDisplayName[sortField];\n return html`\n <button\n class=${isSelected ? 'selected' : nothing}\n @click=${(e: Event) => {\n e.preventDefault();\n options?.onClick?.(e);\n }}\n >\n ${displayName}\n </button>\n `;\n }\n\n /**\n * Generates a dropdown component containing multiple grouped sort options.\n *\n * @param options.displayName The name to use for the dropdown's visible label\n * @param options.id The id to apply to the dropdown element\n * @param options.dropdownOptions An array of option objects used to populate the dropdown\n * @param options.selectedOption The id of the option that should be initially selected\n * @param options.selected A boolean indicating whether this dropdown should use its\n * selected appearance\n * @param options.onOptionSelected A handler for optionSelected events coming from the dropdown\n * @param options.onDropdownClick A handler for click events on the dropdown\n * @param options.onLabelInteraction A handler for click events and Enter/Space keydown events\n * on the dropdown's label\n */\n private getSortDropdown(options: {\n displayName: TemplateResult;\n id?: string;\n dropdownOptions: optionInterface[];\n selectedOption?: string;\n selected: boolean;\n onOptionSelected?: (e: CustomEvent<{ option: optionInterface }>) => void;\n onDropdownClick?: (e: PointerEvent) => void;\n onLabelInteraction?: (e: Event) => void;\n }): TemplateResult {\n return html`\n <ia-dropdown\n id=${options.id ?? nothing}\n class=${options.selected ? 'selected' : nothing}\n displayCaret\n closeOnSelect\n includeSelectedOption\n .openViaButton=${options.selected}\n .options=${options.dropdownOptions}\n .selectedOption=${options.selectedOption ?? ''}\n @optionSelected=${options.onOptionSelected ?? nothing}\n @click=${options.onDropdownClick ?? nothing}\n >\n <span\n class=\"dropdown-label\"\n slot=\"dropdown-label\"\n @click=${options.onLabelInteraction ?? nothing}\n @keydown=${options.onLabelInteraction\n ? (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n options.onLabelInteraction?.(e);\n }\n }\n : nothing}\n >\n ${options.displayName}\n </span>\n </ia-dropdown>\n `;\n }\n\n /** Generates a single dropdown option object for the given sort field */\n private getDropdownOption(sortField: SortField): optionInterface {\n return {\n id: sortField,\n selectedHandler: () => {\n this.selectDropdownSortField(sortField);\n },\n label: html`\n <span class=\"dropdown-option-label\">\n ${SortFieldDisplayName[sortField]}\n </span>\n `,\n };\n }\n\n /** Handler for when any sort dropdown option is selected */\n private dropdownOptionSelected(e: CustomEvent<{ option: optionInterface }>) {\n this.dropdownBackdropVisible = false;\n this.clearAlphaBarFilters();\n this.setSelectedSort(e.detail.option.id as SortField);\n }\n\n /** The template to render for the views dropdown */\n private get viewsDropdownTemplate(): TemplateResult {\n return this.getSortDropdown({\n displayName: html`${this.viewSortField}`,\n id: 'views-dropdown',\n selected: this.viewOptionSelected,\n dropdownOptions: [\n this.getDropdownOption(SortField.weeklyview),\n this.getDropdownOption(SortField.alltimeview),\n ],\n selectedOption: this.viewOptionSelected ? this.selectedSort : '',\n onOptionSelected: this.dropdownOptionSelected,\n onDropdownClick: () => {\n this.dateDropdown.open = false;\n this.dropdownBackdropVisible = this.viewsDropdown.open;\n this.viewsDropdown.classList.toggle('open', this.viewsDropdown.open);\n },\n onLabelInteraction: (e: Event) => {\n if (!this.viewsDropdown.open && !this.viewOptionSelected) {\n e.stopPropagation();\n this.clearAlphaBarFilters();\n this.setSelectedSort(SortField.weeklyview);\n }\n },\n });\n }\n\n /** The template to render for the date dropdown */\n private get dateDropdownTemplate(): TemplateResult {\n return this.getSortDropdown({\n displayName: html`${this.dateSortField}`,\n id: 'date-dropdown',\n selected: this.dateOptionSelected,\n dropdownOptions: [\n this.getDropdownOption(SortField.date),\n this.getDropdownOption(SortField.datearchived),\n this.getDropdownOption(SortField.datereviewed),\n this.getDropdownOption(SortField.dateadded),\n ],\n selectedOption: this.dateOptionSelected ? this.selectedSort : '',\n onOptionSelected: this.dropdownOptionSelected,\n onDropdownClick: () => {\n this.viewsDropdown.open = false;\n this.dropdownBackdropVisible = this.dateDropdown.open;\n this.dateDropdown.classList.toggle('open', this.dateDropdown.open);\n },\n onLabelInteraction: (e: Event) => {\n if (!this.dateDropdown.open && !this.dateOptionSelected) {\n e.stopPropagation();\n this.clearAlphaBarFilters();\n this.setSelectedSort(SortField.date);\n }\n },\n });\n }\n\n /** Handler for when a new mobile sort dropdown option is selected */\n private mobileSortChanged(e: CustomEvent<{ option: optionInterface }>) {\n this.dropdownBackdropVisible = false;\n\n const sortField = e.detail.option.id as SortField;\n this.setSelectedSort(sortField);\n\n this.alphaSelectorVisible = null;\n if (sortField !== 'title' && this.selectedTitleFilter) {\n this.selectedTitleFilter = null;\n this.emitTitleLetterChangedEvent();\n }\n if (sortField !== 'creator' && this.selectedCreatorFilter) {\n this.selectedCreatorFilter = null;\n this.emitCreatorLetterChangedEvent();\n }\n }\n\n /** Template for rendering the three display mode options */\n private get displayOptionTemplate() {\n return html`\n <ul>\n <li>\n <button\n id=\"grid-button\"\n @click=${() => {\n this.displayMode = 'grid';\n }}\n class=${this.displayMode === 'grid' ? 'active' : ''}\n title=\"Tile view\"\n >\n ${tileIcon}\n </button>\n </li>\n <li>\n <button\n id=\"list-detail-button\"\n @click=${() => {\n this.displayMode = 'list-detail';\n }}\n class=${this.displayMode === 'list-detail' ? 'active' : ''}\n title=\"List view\"\n >\n ${listIcon}\n </button>\n </li>\n <li>\n <button\n id=\"list-compact-button\"\n @click=${() => {\n this.displayMode = 'list-compact';\n }}\n class=${this.displayMode === 'list-compact' ? 'active' : ''}\n title=\"Compact list view\"\n >\n ${compactIcon}\n </button>\n </li>\n </ul>\n `;\n }\n\n /**\n * Template for rendering the transparent backdrop to capture clicks outside the\n * dropdown menu while it is open.\n */\n private get dropdownBackdrop() {\n return html`\n <div\n id=\"sort-selector-backdrop\"\n @keyup=${this.closeDropdowns}\n @click=${this.closeDropdowns}\n ></div>\n `;\n }\n\n /** Closes all of the sorting dropdown components' menus */\n private closeDropdowns() {\n this.dropdownBackdropVisible = false;\n const allDropdowns = [\n this.viewsDropdown,\n this.dateDropdown,\n this.mobileDropdown,\n ];\n for (const dropdown of allDropdowns) {\n dropdown.open = false;\n dropdown.classList.remove('open');\n }\n }\n\n private selectDropdownSortField(sortField: SortField) {\n // When a dropdown sort option is selected, we additionally need to clear the backdrop\n this.dropdownBackdropVisible = false;\n this.setSelectedSort(sortField);\n }\n\n private clearAlphaBarFilters() {\n this.alphaSelectorVisible = null;\n this.selectedTitleFilter = null;\n this.selectedCreatorFilter = null;\n this.emitTitleLetterChangedEvent();\n this.emitCreatorLetterChangedEvent();\n }\n\n private setSortDirection(sortDirection: SortDirection) {\n this.sortDirection = sortDirection;\n this.emitSortChangedEvent();\n }\n\n /** Toggles the current sort direction between 'asc' and 'desc' */\n private toggleSortDirection() {\n this.setSortDirection(this.sortDirection === 'desc' ? 'asc' : 'desc');\n }\n\n private setSelectedSort(sort: SortField) {\n this.selectedSort = sort;\n // Apply this field's default sort direction\n this.sortDirection = DefaultSortDirection[this.selectedSort];\n this.emitSortChangedEvent();\n }\n\n /**\n * There are four date sort options.\n *\n * This checks to see if the current sort is one of them.\n *\n * @readonly\n * @private\n * @type {boolean}\n * @memberof SortFilterBar\n */\n private get dateOptionSelected(): boolean {\n const dateSortFields: SortField[] = [\n SortField.datearchived,\n SortField.date,\n SortField.datereviewed,\n SortField.dateadded,\n ];\n return dateSortFields.includes(this.selectedSort);\n }\n\n /**\n * There are two view sort options.\n *\n * This checks to see if the current sort is one of them.\n *\n * @readonly\n * @private\n * @type {boolean}\n * @memberof SortFilterBar\n */\n private get viewOptionSelected(): boolean {\n const viewSortFields: SortField[] = [\n SortField.alltimeview,\n SortField.weeklyview,\n ];\n return viewSortFields.includes(this.selectedSort);\n }\n\n /**\n * The display name of the current date field\n *\n * @readonly\n * @private\n * @type {string}\n * @memberof SortFilterBar\n */\n private get dateSortField(): string {\n const defaultSort = SortFieldDisplayName[SortField.date];\n const name = this.dateOptionSelected\n ? SortFieldDisplayName[this.selectedSort] ?? defaultSort\n : defaultSort;\n return name;\n }\n\n /**\n * The display name of the current view field\n *\n * @readonly\n * @private\n * @type {string}\n * @memberof SortFilterBar\n */\n private get viewSortField(): string {\n const defaultSort = SortFieldDisplayName[SortField.weeklyview];\n const name = this.viewOptionSelected\n ? SortFieldDisplayName[this.selectedSort] ?? defaultSort\n : defaultSort;\n return name;\n }\n\n private get titleSelectorBar() {\n return html` <alpha-bar\n .selectedLetter=${this.selectedTitleFilter}\n .letterCounts=${this.prefixFilterCountMap?.title}\n ariaLandmarkLabel=\"Filter by title letter\"\n @letterChanged=${this.titleLetterChanged}\n ></alpha-bar>`;\n }\n\n private get creatorSelectorBar() {\n return html` <alpha-bar\n .selectedLetter=${this.selectedCreatorFilter}\n .letterCounts=${this.prefixFilterCountMap?.creator}\n ariaLandmarkLabel=\"Filter by creator letter\"\n @letterChanged=${this.creatorLetterChanged}\n ></alpha-bar>`;\n }\n\n private titleLetterChanged(\n e: CustomEvent<{ selectedLetter: string | undefined }>\n ) {\n this.selectedTitleFilter = e.detail.selectedLetter ?? null;\n this.emitTitleLetterChangedEvent();\n }\n\n private creatorLetterChanged(\n e: CustomEvent<{ selectedLetter: string | undefined }>\n ) {\n this.selectedCreatorFilter = e.detail.selectedLetter ?? null;\n this.emitCreatorLetterChangedEvent();\n }\n\n private emitTitleLetterChangedEvent() {\n const event = new CustomEvent<{ selectedLetter: string | null }>(\n 'titleLetterChanged',\n {\n detail: { selectedLetter: this.selectedTitleFilter },\n }\n );\n this.dispatchEvent(event);\n }\n\n private emitCreatorLetterChangedEvent() {\n const event = new CustomEvent<{ selectedLetter: string | null }>(\n 'creatorLetterChanged',\n {\n detail: { selectedLetter: this.selectedCreatorFilter },\n }\n );\n this.dispatchEvent(event);\n }\n\n private displayModeChanged() {\n const event = new CustomEvent<{\n displayMode?: CollectionDisplayMode;\n }>('displayModeChanged', {\n detail: { displayMode: this.displayMode },\n });\n this.dispatchEvent(event);\n }\n\n private emitSortChangedEvent() {\n const event = new CustomEvent<{\n selectedSort: SortField;\n sortDirection: SortDirection | null;\n }>('sortChanged', {\n detail: {\n selectedSort: this.selectedSort,\n sortDirection: this.sortDirection,\n },\n });\n this.dispatchEvent(event);\n }\n\n static get styles() {\n return [\n srOnlyStyle,\n css`\n #container {\n position: relative;\n }\n\n #sort-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-bottom: 1px solid #2c2c2c;\n font-size: 1.4rem;\n }\n\n ul {\n list-style: none;\n display: flex;\n align-items: center;\n margin: 0;\n padding: 0;\n }\n\n li {\n padding: 0;\n }\n\n .sort-by-text {\n margin-right: 5px;\n font-weight: bold;\n white-space: nowrap;\n }\n\n .sort-direction-container {\n display: flex;\n align-self: stretch;\n flex: 0;\n margin: 0 5px;\n }\n\n .sort-direction-selector {\n padding: 0;\n border: none;\n appearance: none;\n background: transparent;\n cursor: pointer;\n }\n\n .sort-direction-selector:disabled {\n cursor: default;\n }\n\n .sort-direction-icon {\n display: flex;\n align-items: center;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n outline: inherit;\n width: 14px;\n height: 14px;\n }\n\n .sort-direction-icon > svg {\n flex: 1;\n }\n\n #date-sort-selector,\n #view-sort-selector {\n position: absolute;\n left: 150px;\n top: 45px;\n\n z-index: 1;\n padding: 1rem;\n background-color: white;\n border-radius: 2.5rem;\n border: 1px solid #404142;\n }\n\n #sort-selector-container {\n flex: 1;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n }\n\n #desktop-sort-container,\n #mobile-sort-container {\n display: flex;\n justify-content: flex-start;\n align-items: center;\n }\n\n /*\n we move the desktop sort selector offscreen instead of display: none\n because we need to observe the width of it vs its container to determine\n if it's wide enough to display the desktop version and if you display: none,\n the width becomes 0\n */\n #desktop-sort-container.hidden {\n position: absolute;\n top: -9999px;\n left: -9999px;\n visibility: hidden;\n }\n\n #mobile-sort-container.hidden {\n display: none;\n }\n\n #sort-selector-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n z-index: 1;\n background-color: transparent;\n }\n\n #desktop-sort-selector {\n display: inline-flex;\n }\n\n #desktop-sort-selector li {\n display: flex;\n align-items: center;\n padding-left: 5px;\n padding-right: 5px;\n }\n\n #desktop-sort-selector li a {\n padding: 0 5px;\n text-decoration: none;\n color: #333;\n line-height: 2;\n }\n\n #desktop-sort-selector li button {\n padding: 0px 5px;\n border: none;\n background: none;\n font-family: inherit;\n font-size: inherit;\n color: #333;\n line-height: 2;\n cursor: pointer;\n appearance: none;\n }\n\n #desktop-sort-selector li button.selected {\n font-weight: bold;\n }\n\n #display-style-selector {\n flex: 0;\n }\n\n #display-style-selector button {\n background: none;\n color: inherit;\n border: none;\n appearance: none;\n cursor: pointer;\n -webkit-appearance: none;\n fill: #bbbbbb;\n }\n\n #display-style-selector button.active {\n fill: var(--ia-theme-primary-text-color, #2c2c2c);\n }\n\n #display-style-selector button svg {\n width: 24px;\n height: 24px;\n }\n\n ia-dropdown {\n --dropdownTextColor: white;\n --dropdownOffsetTop: 0;\n --dropdownBorderTopWidth: 0;\n --dropdownBorderTopLeftRadius: 0;\n --dropdownBorderTopRightRadius: 0;\n --dropdownWhiteSpace: nowrap;\n --dropdownListZIndex: 2;\n --dropdownCaretColor: var(--ia-theme-primary-text-color, #2c2c2c);\n --dropdownSelectedTextColor: white;\n --dropdownSelectedBgColor: rgba(255, 255, 255, 0.3);\n --dropdownHoverBgColor: rgba(255, 255, 255, 0.3);\n --caretHeight: 9px;\n --caretWidth: 12px;\n --caretPadding: 0 5px 0 0;\n }\n ia-dropdown.selected .dropdown-label {\n font-weight: bold;\n }\n ia-dropdown.open {\n z-index: 2;\n }\n\n .dropdown-label {\n display: inline-block;\n height: 100%;\n padding-left: 5px;\n font-size: 1.4rem;\n line-height: 2;\n color: var(--ia-theme-primary-text-color, #2c2c2c);\n white-space: nowrap;\n user-select: none;\n }\n `,\n ];\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { css, html, LitElement, nothing } from 'lit';
|
|
3
3
|
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
-
import { baseTileStyles } from './styles/tile-grid-shared-styles';
|
|
4
|
+
import { baseTileStyles } from './styles/tile-grid-shared-styles.js';
|
|
5
5
|
import '../image-block';
|
|
6
6
|
import './tile-stats';
|
|
7
7
|
let AccountTile = class AccountTile extends LitElement {
|