Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@internetarchive/collection-browser

Package Overview
Dependencies
Maintainers
15
Versions
601
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@internetarchive/collection-browser - npm Package Compare versions

Comparing version 0.0.1-alpha.14 to 0.0.1-alpha.15

dist/src/assets/img/icons/arrow-right.d.ts

4

demo/app-root.ts

@@ -238,6 +238,2 @@ import { SearchService } from '@internetarchive/search-service';

#collection-browser-container {
padding: 0 2rem;
}
collection-browser {

@@ -244,0 +240,0 @@ margin-top: 30rem;

@@ -196,6 +196,2 @@ import { __decorate } from "tslib";

#collection-browser-container {
padding: 0 2rem;
}
collection-browser {

@@ -202,0 +198,0 @@ margin-top: 30rem;

@@ -5,3 +5,3 @@ import { LitElement, PropertyValues, TemplateResult } from 'lit';

import { SortParam } from '@internetarchive/search-service';
import { SharedResizeObserverInterface } from '@internetarchive/shared-resize-observer';
import { SharedResizeObserverInterface, SharedResizeObserverResizeHandlerInterface } from '@internetarchive/shared-resize-observer';
import type { CollectionDisplayMode } from './models';

@@ -17,3 +17,3 @@ import '@internetarchive/infinite-scroller';

import { RestorationStateHandlerInterface } from './restoration-state-handler';
export declare class CollectionBrowser extends LitElement implements InfiniteScrollerCellProviderInterface {
export declare class CollectionBrowser extends LitElement implements InfiniteScrollerCellProviderInterface, SharedResizeObserverResizeHandlerInterface {
baseNavigationUrl?: string;

@@ -40,2 +40,3 @@ searchService?: SearchServiceInterface;

restorationStateHandler: RestorationStateHandlerInterface;
mobileBreakpoint: number;
/**

@@ -58,2 +59,5 @@ * The page that the consumer wants to load.

private totalResults?;
private mobileView;
private mobileFacetsVisible;
private contentContainer;
/**

@@ -97,3 +101,5 @@ * When we're animated scrolling to the page, we don't want to fetch

private get facetDataLoading();
private get facetsTemplate();
private get loadingTemplate();
private get listHeaderTemplate();
private get queryDebuggingTemplate();

@@ -103,2 +109,6 @@ private histogramDateRangeUpdated;

updated(changed: PropertyValues): void;
disconnectedCallback(): void;
handleResize(entry: ResizeObserverEntry): void;
private disconnectResizeObserver;
private setupResizeObserver;
/**

@@ -105,0 +115,0 @@ * When the visible cells change from the infinite scroller, we want to emit

@@ -15,4 +15,5 @@ import { __decorate } from "tslib";

import './sort-filter-bar/sort-filter-bar';
import { SortFieldToMetadataField, defaultSelectedFacets, } from './models';
import { SortField, SortFieldToMetadataField, defaultSelectedFacets, } from './models';
import { RestorationStateHandler, } from './restoration-state-handler';
import chevronIcon from './assets/img/icons/chevron';
let CollectionBrowser = class CollectionBrowser extends LitElement {

@@ -23,3 +24,3 @@ constructor() {

this.sortParam = null;
this.selectedSort = 'relevance';
this.selectedSort = SortField.relevance;
this.selectedTitleFilter = null;

@@ -33,2 +34,3 @@ this.selectedCreatorFilter = null;

});
this.mobileBreakpoint = 530;
/**

@@ -48,2 +50,4 @@ * The page that the consumer wants to load.

this.fullYearAggregationLoading = false;
this.mobileView = false;
this.mobileFacetsVisible = false;
/**

@@ -119,26 +123,44 @@ * When we're animated scrolling to the page, we don't want to fetch

return html `
<div id="content-container">
<div id="content-container" class=${this.mobileView ? 'mobile' : ''}>
<div id="left-column" class="column">
<div id="results-total">
<span id="big-results-count"
>${this.totalResults
<div id="mobile-header-container">
${this.mobileView
? html `
<div id="mobile-filter-collapse">
<h1
@click=${() => {
this.mobileFacetsVisible = !this.mobileFacetsVisible;
}}
@keyup=${() => {
this.mobileFacetsVisible = !this.mobileFacetsVisible;
}}
>
<span
class="collapser ${this.mobileFacetsVisible
? 'open'
: ''}"
>
${chevronIcon}
</span>
Filters
</h1>
</div>
`
: nothing}
<div id="results-total">
<span id="big-results-count"
>${this.totalResults
? this.totalResults.toLocaleString()
: '-'}</span
>
<span id="big-results-label">Results</span>
>
<span id="big-results-label">Results</span>
</div>
</div>
<div id="facets-container">
${this.facetsLoading ? this.loadingTemplate : nothing}
<collection-facets
@facetsChanged=${this.facetsChanged}
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
.aggregations=${this.aggregations}
.fullYearsHistogramAggregation=${this
.fullYearsHistogramAggregation}
.minSelectedDate=${this.minSelectedDate}
.maxSelectedDate=${this.maxSelectedDate}
.selectedFacets=${this.selectedFacets}
?facetsLoading=${this.facetDataLoading}
?fullYearAggregationLoading=${this.fullYearAggregationLoading}
></collection-facets>
<div
id="facets-container"
class=${!this.mobileView || this.mobileFacetsVisible
? 'expanded'
: ''}
>
${this.facetsTemplate}
</div>

@@ -154,2 +176,3 @@ </div>

.selectedCreatorFilter=${this.selectedCreatorFilter}
.resizeObserver=${this.resizeObserver}
@sortChanged=${this.userChangedSort}

@@ -161,2 +184,6 @@ @displayModeChanged=${this.displayModeChanged}

${this.displayMode === `list-compact`
? this.listHeaderTemplate
: nothing}
<infinite-scroller

@@ -216,2 +243,19 @@ class="${ifDefined(this.displayMode)}"

}
get facetsTemplate() {
return html `
${this.facetsLoading ? this.loadingTemplate : nothing}
<collection-facets
@facetsChanged=${this.facetsChanged}
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
.aggregations=${this.aggregations}
.fullYearsHistogramAggregation=${this.fullYearsHistogramAggregation}
.minSelectedDate=${this.minSelectedDate}
.maxSelectedDate=${this.maxSelectedDate}
.selectedFacets=${this.selectedFacets}
?collapsableFacets=${this.mobileView}
?facetsLoading=${this.facetDataLoading}
?fullYearAggregationLoading=${this.fullYearAggregationLoading}
></collection-facets>
`;
}
get loadingTemplate() {

@@ -224,2 +268,12 @@ return html `

}
get listHeaderTemplate() {
return html `
<tile-dispatcher
.displayMode=${'list-header'}
.resizeObserver=${this.resizeObserver}
.sortParam=${this.sortParam}
>
</tile-dispatcher>
`;
}
get queryDebuggingTemplate() {

@@ -279,3 +333,33 @@ var _a, _b;

}
if (changed.has('resizeObserver')) {
const oldObserver = changed.get('resizeObserver');
if (oldObserver)
this.disconnectResizeObserver(oldObserver);
this.setupResizeObserver();
}
}
disconnectedCallback() {
if (this.resizeObserver) {
this.disconnectResizeObserver(this.resizeObserver);
}
}
handleResize(entry) {
if (entry.target === this.contentContainer) {
this.mobileView = entry.contentRect.width < 600;
}
}
disconnectResizeObserver(resizeObserver) {
resizeObserver.removeObserver({
target: this.contentContainer,
handler: this,
});
}
setupResizeObserver() {
if (!this.resizeObserver)
return;
this.resizeObserver.addObserver({
target: this.contentContainer,
handler: this,
});
}
/**

@@ -330,3 +414,3 @@ * When the visible cells change from the infinite scroller, we want to emit

this.displayMode = restorationState.displayMode;
this.selectedSort = (_a = restorationState.selectedSort) !== null && _a !== void 0 ? _a : 'relevance';
this.selectedSort = (_a = restorationState.selectedSort) !== null && _a !== void 0 ? _a : SortField.relevance;
this.sortDirection = (_b = restorationState.sortDirection) !== null && _b !== void 0 ? _b : null;

@@ -702,2 +786,28 @@ this.selectedTitleFilter = (_c = restorationState.selectedTitleFilter) !== null && _c !== void 0 ? _c : null;

.collapser {
display: inline-block;
}
.collapser svg {
width: 10px;
height: 10px;
transition: transform 0.2s ease-out;
}
.collapser.open svg {
transform: rotate(90deg);
}
#mobile-filter-collapse h1 {
cursor: pointer;
}
#content-container.mobile {
display: block;
}
.column {
padding-top: 2rem;
}
#right-column {

@@ -707,17 +817,37 @@ flex: 1;

border-left: 1px solid rgb(232, 232, 232);
padding-left: 1rem;
}
.mobile #right-column {
border-left: none;
padding: 0;
}
#left-column {
width: 18rem;
padding-right: 12px;
padding-right: 1rem;
}
.column {
padding: 2rem 1rem;
.mobile #left-column {
width: 100%;
padding: 0;
}
#mobile-header-container {
display: flex;
justify-content: space-between;
}
#facets-container {
position: relative;
max-height: 0;
transition: max-height 0.2s ease-in-out;
overflow: hidden;
}
#facets-container.expanded {
max-height: 2000px;
}
#results-total {

@@ -729,2 +859,6 @@ display: flex;

.mobile #results-total {
margin-bottom: 0;
}
#big-results-count {

@@ -871,2 +1005,5 @@ font-size: 2.4rem;

__decorate([
property({ type: Number })
], CollectionBrowser.prototype, "mobileBreakpoint", void 0);
__decorate([
state()

@@ -893,2 +1030,11 @@ ], CollectionBrowser.prototype, "pagesToRender", void 0);

__decorate([
state()
], CollectionBrowser.prototype, "mobileView", void 0);
__decorate([
state()
], CollectionBrowser.prototype, "mobileFacetsVisible", void 0);
__decorate([
query('#content-container')
], CollectionBrowser.prototype, "contentContainer", void 0);
__decorate([
query('infinite-scroller')

@@ -895,0 +1041,0 @@ ], CollectionBrowser.prototype, "infiniteScroller", void 0);

@@ -5,3 +5,3 @@ import { LitElement, PropertyValues } from 'lit';

import '@internetarchive/feature-feedback';
import { SelectedFacets } from './models';
import { FacetOption, SelectedFacets } from './models';
export declare class CollectionFacets extends LitElement {

@@ -15,2 +15,4 @@ aggregations?: Record<string, Aggregation>;

selectedFacets?: SelectedFacets;
collapsableFacets: boolean;
openFacets: Record<FacetOption, boolean>;
render(): import("lit-html").TemplateResult<1>;

@@ -35,2 +37,3 @@ updated(changed: PropertyValues): void;

private get aggregationFacetGroups();
private getFacetGroupTemplate;
private getFacetTemplate;

@@ -37,0 +40,0 @@ private facetClicked;

import { __decorate } from "tslib";
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';

@@ -9,2 +9,3 @@ import '@internetarchive/histogram-date-range';

import eyeClosedIcon from './assets/img/icons/eye-closed';
import chevronIcon from './assets/img/icons/chevron';
import { defaultSelectedFacets, } from './models';

@@ -40,2 +41,11 @@ const facetDisplayOrder = [

this.fullYearAggregationLoading = false;
this.collapsableFacets = false;
this.openFacets = {
subject: false,
mediatype: false,
language: false,
creator: false,
collection: false,
year: false,
};
}

@@ -50,8 +60,3 @@ render() {

${this.mergedFacets.map(facetGroup => html `
<div class="facet-group">
<h1>${facetGroup.title}</h1>
${this.getFacetTemplate(facetGroup)}
</div>
`)}
${this.mergedFacets.map(facetGroup => this.getFacetGroupTemplate(facetGroup))}
</div>

@@ -189,2 +194,30 @@ `;

}
getFacetGroupTemplate(facetGroup) {
const { key } = facetGroup;
const isOpen = this.openFacets[key];
const collapser = html `
<span class="collapser ${isOpen ? 'open' : ''}"> ${chevronIcon} </span>
`;
return html `
<div class="facet-group ${this.collapsableFacets ? 'mobile' : ''}">
<h1
@click=${() => {
const newOpenFacets = { ...this.openFacets };
newOpenFacets[key] = !isOpen;
this.openFacets = newOpenFacets;
}}
@keyup=${() => {
const newOpenFacets = { ...this.openFacets };
newOpenFacets[key] = !isOpen;
this.openFacets = newOpenFacets;
}}
>
${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}
</h1>
<div class="facet-group-content ${isOpen ? 'open' : ''}">
${this.getFacetTemplate(facetGroup)}
</div>
</div>
`;
}
getFacetTemplate(facetGroup) {

@@ -295,2 +328,42 @@ return html `

.collapser {
display: inline-block;
cursor: pointer;
width: 10px;
height: 10px;
}
.collapser svg {
transition: transform 0.2s ease-in-out;
}
.collapser.open svg {
transform: rotate(90deg);
}
.facet-group {
margin-bottom: 2rem;
}
.facet-group h1 {
margin-bottom: 0.7rem;
}
.facet-group.mobile h1 {
cursor: pointer;
}
.facet-group-content {
transition: max-height 0.2s ease-in-out;
}
.facet-group.mobile .facet-group-content {
max-height: 0;
overflow: hidden;
}
.facet-group.mobile .facet-group-content.open {
max-height: 2000px;
}
h1 {

@@ -301,3 +374,3 @@ font-size: 1.4rem;

padding-bottom: 3px;
margin: 24px 0 14px 0;
margin: 0;
}

@@ -373,2 +446,8 @@

], CollectionFacets.prototype, "selectedFacets", void 0);
__decorate([
property({ type: Boolean })
], CollectionFacets.prototype, "collapsableFacets", void 0);
__decorate([
state()
], CollectionFacets.prototype, "openFacets", void 0);
CollectionFacets = __decorate([

@@ -375,0 +454,0 @@ customElement('collection-facets')

@@ -76,4 +76,4 @@ import { __decorate } from "tslib";

svg {
height: var(--iconHeight);
width: var(--iconWidth);
height: var(--iconHeight, 10px);
width: var(--iconWidth, 10px);
}

@@ -80,0 +80,0 @@

@@ -23,3 +23,3 @@ import type { MediaType } from '@internetarchive/field-parsers';

}
export declare type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';
export declare type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail' | 'list-header';
/**

@@ -34,3 +34,12 @@ * This is mainly used to set the cookies for the collection display mode.

*/
export declare type SortField = 'relevance' | 'views' | 'title' | 'datearchived' | 'datepublished' | 'datereviewed' | 'dateadded' | 'creator';
export declare enum SortField {
'relevance' = "relevance",
'views' = "views",
'title' = "title",
'datearchived' = "datearchived",
'datepublished' = "datepublished",
'datereviewed' = "datereviewed",
'dateadded' = "dateadded",
'creator' = "creator"
}
/**

@@ -40,2 +49,5 @@ * The metadata fields we sort by that map to the SortFields above

export declare type MetadataSortField = 'week' | 'titleSorter' | 'date' | 'creatorSorter' | 'publicdate' | 'reviewdate' | 'addeddate';
export declare const SortFieldDisplayName: {
[key in SortField]: string;
};
/**

@@ -42,0 +54,0 @@ * Maps the SortField above to the corresponding Metadata field in the API.

/**
* The sort fields shown in the sort filter bar
*/
export var SortField;
(function (SortField) {
SortField["relevance"] = "relevance";
SortField["views"] = "views";
SortField["title"] = "title";
SortField["datearchived"] = "datearchived";
SortField["datepublished"] = "datepublished";
SortField["datereviewed"] = "datereviewed";
SortField["dateadded"] = "dateadded";
SortField["creator"] = "creator";
})(SortField || (SortField = {}));
export const SortFieldDisplayName = {
relevance: 'Relevance',
views: 'Views',
title: 'Title',
datearchived: 'Date Archived',
datepublished: 'Date Published',
datereviewed: 'Date Reviewed',
dateadded: 'Date Added',
creator: 'Creator',
};
/**
* Maps the SortField above to the corresponding Metadata field in the API.

@@ -18,9 +42,9 @@ */

export const MetadataFieldToSortField = {
titleSorter: 'title',
date: 'datearchived',
publicdate: 'datepublished',
reviewdate: 'datereviewed',
addeddate: 'dateadded',
creatorSorter: 'creator',
week: 'views',
titleSorter: SortField.title,
date: SortField.datearchived,
publicdate: SortField.datepublished,
reviewdate: SortField.datereviewed,
addeddate: SortField.dateadded,
creatorSorter: SortField.creator,
week: SortField.views,
};

@@ -27,0 +51,0 @@ export const defaultSelectedFacets = {

@@ -73,3 +73,3 @@ import { __decorate } from "tslib";

text-decoration: none;
padding: 0.5rem 0.7rem;
padding: 0.5rem 0;
display: block;

@@ -76,0 +76,0 @@ }

@@ -1,5 +0,6 @@

import { LitElement, PropertyValues } from 'lit';
import { LitElement, PropertyValues, TemplateResult } from 'lit';
import { SharedResizeObserverInterface, SharedResizeObserverResizeHandlerInterface } from '@internetarchive/shared-resize-observer';
import { CollectionDisplayMode, SortField } from '../models';
import './alpha-bar';
export declare class SortFilterBar extends LitElement {
export declare class SortFilterBar extends LitElement implements SharedResizeObserverResizeHandlerInterface {
displayMode?: CollectionDisplayMode;

@@ -11,8 +12,38 @@ sortDirection: 'asc' | 'desc' | null;

showRelevance: boolean;
resizeObserver?: SharedResizeObserverInterface;
titleSelectorVisible: boolean;
creatorSelectorVisible: boolean;
dateSortSelectorVisible: boolean;
render(): import("lit-html").TemplateResult<1>;
desktopSelectorBarWidth: number;
selectorBarContainerWidth: number;
private desktopSortSelector;
private sortSelectorContainer;
render(): TemplateResult<1>;
updated(changed: PropertyValues): void;
disconnectedCallback(): void;
private disconnectResizeObserver;
private setupResizeObserver;
private get mobileSelectorVisible();
handleResize(entry: ResizeObserverEntry): void;
private get sortDirectionSelectorTemplate();
private get desktopSortSelectorTemplate();
/**
* This generates each of the sort option links.
*
* It manages the display value and the selected state of the option.
*
* @param sortField
* @param options {
* additionalClickEvent?: () => void; If this is provided, it will also be called when the option is clicked.
* displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.
* isSelected?: () => boolean; A function that returns true if the option is selected. Defaults to the selectedSort === sortField.
* }
* @returns
*/
private getSortDisplayOption;
private get mobileSortSelectorTemplate();
private mobileSortChanged;
private get displayOptionTemplate();
private get dateSortSelector();
private getDateSortButton;
private selectDateSort;

@@ -19,0 +50,0 @@ private setSortDirections;

import { __decorate } from "tslib";
import { LitElement, html, css, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { LitElement, html, css, nothing, } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import { SortField, SortFieldDisplayName, } from '../models';
import './alpha-bar';

@@ -8,9 +9,2 @@ import { sortIcon } from './img/sort-triangle';

import { listIcon } from './img/list';
var SortFieldName;
(function (SortFieldName) {
SortFieldName["datearchived"] = "Date Archived";
SortFieldName["datepublished"] = "Date Published";
SortFieldName["datereviewed"] = "Date Reviewed";
SortFieldName["dateadded"] = "Date Added";
})(SortFieldName || (SortFieldName = {}));
let SortFilterBar = class SortFilterBar extends LitElement {

@@ -20,3 +14,3 @@ constructor() {

this.sortDirection = null;
this.selectedSort = 'relevance';
this.selectedSort = SortField.relevance;
this.selectedTitleFilter = null;

@@ -28,2 +22,4 @@ this.selectedCreatorFilter = null;

this.dateSortSelectorVisible = false;
this.desktopSelectorBarWidth = 0;
this.selectorBarContainerWidth = 0;
}

@@ -41,139 +37,12 @@ render() {

<div id="sort-bar">
<div id="sort-selector">
<ul>
<li>
<div id="sort-direction-container">
<button
id="sort-ascending-btn"
class="sort-button ${this.sortDirection === 'asc'
? 'selected'
: ''}"
@click=${() => {
this.setSortDirections('asc');
}}
>
${sortIcon}
</button>
<button
id="sort-descending-btn"
class="sort-button ${this.sortDirection === 'desc'
? 'selected'
: ''}"
@click=${() => {
this.setSortDirections('desc');
}}
>
${sortIcon}
</button>
</div>
</li>
<li id="sort-by-text">Sort By</li>
${this.showRelevance
? html `
<li>
<a
href="#"
@click=${(e) => {
e.preventDefault();
this.setSelectedSort('relevance');
}}
class=${this.selectedSort === 'relevance'
? 'selected'
: ''}
>
Relevance
</a>
</li>
`
: nothing}
<li>
<a
href="#"
@click=${(e) => {
e.preventDefault();
this.setSelectedSort('views');
}}
class=${this.selectedSort === 'views' ? 'selected' : ''}
>
Views
</a>
</li>
<li>
<a
href="#"
@click=${(e) => {
e.preventDefault();
this.titleSelectorVisible = !this.titleSelectorVisible;
this.setSelectedSort('title');
}}
class=${this.selectedSort === 'title' ? 'selected' : ''}
>
Title
</a>
</li>
<li>
<a
href="#"
@click=${(e) => {
e.preventDefault();
this.dateSortSelectorVisible =
!this.dateSortSelectorVisible;
this.setSelectedSort('datearchived');
}}
class=${this.dateOptionSelected ? 'selected' : ''}
>
${this.dateSortField}
</a>
</li>
<li>
<a
href="#"
@click=${(e) => {
e.preventDefault();
this.creatorSelectorVisible = !this.creatorSelectorVisible;
this.setSelectedSort('creator');
}}
class=${this.selectedSort === 'creator' ? 'selected' : ''}
>
Creator
</a>
</li>
</ul>
<div id="sort-direction-container">
${this.sortDirectionSelectorTemplate}
</div>
<div id="display-style">
<ul>
${this.displayMode !== 'grid'
? html `<li>
<label id="show-details">
<input
type="checkbox"
@click=${this.detailSelected}
?checked=${this.displayMode === 'list-detail'}
/>
Show Details
</label>
</li>`
: nothing}
<div id="sort-selector-container">
${this.mobileSortSelectorTemplate}
${this.desktopSortSelectorTemplate}
</div>
<li>
<button
id="grid-button"
@click=${this.gridSelected}
class=${this.displayMode === 'grid' ? 'active' : ''}
>
${gridIcon}
</button>
</li>
<li>
<button
id="list-button"
@click=${this.listSelected}
class=${this.displayMode !== 'grid' ? 'active' : ''}
>
${listIcon}
</button>
</li>
</ul>
</div>
<div id="display-style-selector">${this.displayOptionTemplate}</div>
</div>

@@ -200,3 +69,192 @@

}
if (changed.has('resizeObserver')) {
const oldObserver = changed.get('resizeObserver');
if (oldObserver)
this.disconnectResizeObserver(oldObserver);
this.setupResizeObserver();
}
}
disconnectedCallback() {
if (this.resizeObserver) {
this.disconnectResizeObserver(this.resizeObserver);
}
}
disconnectResizeObserver(resizeObserver) {
resizeObserver.removeObserver({
target: this.sortSelectorContainer,
handler: this,
});
resizeObserver.removeObserver({
target: this.desktopSortSelector,
handler: this,
});
}
setupResizeObserver() {
if (!this.resizeObserver)
return;
this.resizeObserver.addObserver({
target: this.sortSelectorContainer,
handler: this,
});
this.resizeObserver.addObserver({
target: this.desktopSortSelector,
handler: this,
});
}
get mobileSelectorVisible() {
return this.selectorBarContainerWidth - 10 < this.desktopSelectorBarWidth;
}
handleResize(entry) {
if (entry.target === this.desktopSortSelector)
this.desktopSelectorBarWidth = entry.contentRect.width;
else if (entry.target === this.sortSelectorContainer)
this.selectorBarContainerWidth = entry.contentRect.width;
}
get sortDirectionSelectorTemplate() {
return html `
<div id="sort-direction-selector">
<button
id="sort-ascending-btn"
class="sort-button ${this.sortDirection === 'asc' ? 'selected' : ''}"
?disabled=${this.selectedSort === 'relevance'}
@click=${() => {
this.setSortDirections('asc');
}}
>
${sortIcon}
</button>
<button
id="sort-descending-btn"
class="sort-button ${this.sortDirection === 'desc' ? 'selected' : ''}"
?disabled=${this.selectedSort === 'relevance'}
@click=${() => {
this.setSortDirections('desc');
}}
>
${sortIcon}
</button>
</div>
`;
}
get desktopSortSelectorTemplate() {
return html `
<ul
id="desktop-sort-selector"
class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}
>
<li id="sort-by-text">Sort By</li>
<li>
${this.showRelevance
? this.getSortDisplayOption(SortField.relevance)
: nothing}
</li>
<li>${this.getSortDisplayOption(SortField.views)}</li>
<li>${this.getSortDisplayOption(SortField.title)}</li>
<li>
${this.getSortDisplayOption(SortField.datearchived, {
additionalClickEvent: () => {
this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
},
displayName: html `${this.dateSortField}`,
isSelected: () => this.dateOptionSelected,
})}
</li>
<li>
${this.getSortDisplayOption(SortField.creator, {
additionalClickEvent: () => {
this.creatorSelectorVisible = !this.creatorSelectorVisible;
},
})}
</li>
</ul>
`;
}
/**
* This generates each of the sort option links.
*
* It manages the display value and the selected state of the option.
*
* @param sortField
* @param options {
* additionalClickEvent?: () => void; If this is provided, it will also be called when the option is clicked.
* displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.
* isSelected?: () => boolean; A function that returns true if the option is selected. Defaults to the selectedSort === sortField.
* }
* @returns
*/
getSortDisplayOption(sortField, options) {
var _a, _b;
const isSelected = (_a = options === null || options === void 0 ? void 0 : options.isSelected) !== null && _a !== void 0 ? _a : (() => this.selectedSort === sortField);
const displayName = (_b = options === null || options === void 0 ? void 0 : options.displayName) !== null && _b !== void 0 ? _b : SortFieldDisplayName[sortField];
return html `
<a
href="#"
@click=${(e) => {
var _a;
e.preventDefault();
this.setSelectedSort(sortField);
(_a = options === null || options === void 0 ? void 0 : options.additionalClickEvent) === null || _a === void 0 ? void 0 : _a.call(options, e);
}}
class=${isSelected() ? 'selected' : ''}
>
${displayName}
</a>
`;
}
get mobileSortSelectorTemplate() {
return html `
<select
id="mobile-sort-selector"
@change=${this.mobileSortChanged}
class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
>
${Object.keys(SortField).map(field => html `
<option value="${field}" ?selected=${this.selectedSort === field}>
${SortFieldDisplayName[field]}
</option>
`)}
</select>
`;
}
mobileSortChanged(e) {
const target = e.target;
this.setSelectedSort(target.value);
}
get displayOptionTemplate() {
return html `
<ul>
${this.displayMode !== 'grid'
? html `<li>
<label id="show-details">
<input
type="checkbox"
@click=${this.detailSelected}
?checked=${this.displayMode === 'list-detail'}
/>
Show Details
</label>
</li>`
: nothing}
<li>
<button
id="grid-button"
@click=${this.gridSelected}
class=${this.displayMode === 'grid' ? 'active' : ''}
>
${gridIcon}
</button>
</li>
<li>
<button
id="list-button"
@click=${this.listSelected}
class=${this.displayMode !== 'grid' ? 'active' : ''}
>
${listIcon}
</button>
</li>
</ul>
`;
}
get dateSortSelector() {

@@ -206,38 +264,6 @@ return html `

<ul>
<li>
<button
@click=${() => {
this.selectDateSort('datearchived');
}}
>
Date Archived
</button>
</li>
<li>
<button
@click=${() => {
this.selectDateSort('datepublished');
}}
>
Date Published
</button>
</li>
<li>
<button
@click=${() => {
this.selectDateSort('datereviewed');
}}
>
Date Reviewed
</button>
</li>
<li>
<button
@click=${() => {
this.selectDateSort('dateadded');
}}
>
Date Added
</button>
</li>
<li>${this.getDateSortButton(SortField.datearchived)}</li>
<li>${this.getDateSortButton(SortField.datepublished)}</li>
<li>${this.getDateSortButton(SortField.datereviewed)}</li>
<li>${this.getDateSortButton(SortField.dateadded)}</li>
</ul>

@@ -247,2 +273,13 @@ </div>

}
getDateSortButton(sortField) {
return html `
<button
@click=${() => {
this.selectDateSort(sortField);
}}
>
${SortFieldDisplayName[sortField]}
</button>
`;
}
selectDateSort(sortField) {

@@ -288,3 +325,3 @@ this.dateSortSelectorVisible = false;

var _a;
return ((_a = SortFieldName[this.selectedSort]) !== null && _a !== void 0 ? _a : 'Date Archived');
return (_a = SortFieldDisplayName[this.selectedSort]) !== null && _a !== void 0 ? _a : 'Date Archived';
}

@@ -358,2 +395,6 @@ get titleSelectorBar() {

#sort-direction-container {
flex: 0;
}
#sort-by-text {

@@ -398,2 +439,7 @@ text-transform: uppercase;

.sort-button:disabled {
opacity: 0.25;
cursor: default;
}
#show-details {

@@ -408,9 +454,34 @@ text-transform: uppercase;

#sort-direction-container {
#sort-direction-selector {
display: flex;
flex-direction: column;
gap: 3px;
margin-right: 1rem;
}
#sort-selector li {
#sort-selector-container {
flex: 1;
}
/*
we move the desktop sort selector offscreen instead of display: none
because we need to observe the width of it vs its container to determine
if it's wide enough to display the desktop version and if you displY: none,
the width becomes 0
*/
#desktop-sort-selector.hidden {
position: absolute;
top: -9999px;
left: -9999px;
}
#mobile-sort-selector.hidden {
display: none;
}
#desktop-sort-selector {
display: inline-flex;
}
#desktop-sort-selector li {
display: flex;

@@ -420,3 +491,3 @@ align-items: center;

#sort-selector li a {
#desktop-sort-selector li a {
text-decoration: none;

@@ -428,7 +499,7 @@ text-transform: uppercase;

#sort-selector li a.selected {
#desktop-sort-selector li a.selected {
font-weight: bold;
}
#sort-selector li::after {
#desktop-sort-selector li::after {
content: '•';

@@ -439,11 +510,15 @@ padding-left: 1rem;

#sort-selector li:first-child::after {
#desktop-sort-selector li:first-child::after {
content: '';
}
#sort-selector li:last-child::after {
#desktop-sort-selector li:last-child::after {
content: '';
}
#display-style button {
#display-style-selector {
flex: 0;
}
#display-style-selector button {
background: none;

@@ -458,7 +533,7 @@ color: inherit;

#display-style button.active {
#display-style-selector button.active {
opacity: 1;
}
#display-style button svg {
#display-style-selector button svg {
width: 24px;

@@ -487,2 +562,5 @@ height: 24px;

__decorate([
property({ type: Object })
], SortFilterBar.prototype, "resizeObserver", void 0);
__decorate([
state()

@@ -496,2 +574,14 @@ ], SortFilterBar.prototype, "titleSelectorVisible", void 0);

], SortFilterBar.prototype, "dateSortSelectorVisible", void 0);
__decorate([
state()
], SortFilterBar.prototype, "desktopSelectorBarWidth", void 0);
__decorate([
state()
], SortFilterBar.prototype, "selectorBarContainerWidth", void 0);
__decorate([
query('#desktop-sort-selector')
], SortFilterBar.prototype, "desktopSortSelector", void 0);
__decorate([
query('#sort-selector-container')
], SortFilterBar.prototype, "sortSelectorContainer", void 0);
SortFilterBar = __decorate([

@@ -498,0 +588,0 @@ customElement('sort-filter-bar')

@@ -12,3 +12,3 @@ import { LitElement } from 'lit';

render(): import("lit-html").TemplateResult<1>;
private img;
private get imageTemplate();
private get date();

@@ -15,0 +15,0 @@ private get classSize();

import { __decorate } from "tslib";
import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@@ -13,3 +13,3 @@ import DOMPurify from 'dompurify';

<div id="list-line" class="${this.classSize}">
<div id="thumb">${this.img()}</div>
<div id="thumb">${this.imageTemplate}</div>
<div id="title">${DOMPurify.sanitize((_b = (_a = this.model) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : '')}</div>

@@ -27,12 +27,12 @@ <div id="date">${formatDate(this.date, this.formatSize)}</div>

}
img() {
get imageTemplate() {
var _a, _b;
if ((_a = this.model) === null || _a === void 0 ? void 0 : _a.identifier) {
return html ` <img
src="${this.baseNavigationUrl}/services/img/${this.model.identifier}"
alt="${this.model.identifier}"
class=${(_b = this.model) === null || _b === void 0 ? void 0 : _b.mediatype}
/>`;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.identifier)) {
return nothing;
}
return html ``;
return html ` <img
src="${this.baseNavigationUrl}/services/img/${this.model.identifier}"
alt="${this.model.identifier}"
class="${(_b = this.model) === null || _b === void 0 ? void 0 : _b.mediatype}"
/>`;
}

@@ -152,3 +152,3 @@ /*

column-gap: 10px;
border-top: 1px solid #ddd !important;
border-top: 1px solid #ddd;
align-items: center;

@@ -188,3 +188,3 @@ line-height: 20px;

}
*/
*/

@@ -191,0 +191,0 @@ #list-line:hover #title {

@@ -12,12 +12,12 @@ import { LitElement } from 'lit';

render(): import("lit-html").TemplateResult<1>;
private img;
private iconLeft;
private creator;
private itemLine;
private views;
private rating;
private reviews;
private description;
private topics;
private source;
private get imgTemplate();
private get iconLeftTemplate();
private get creatorTemplate();
private get itemLineTemplate();
private get viewsTemplate();
private get ratingTemplate();
private get reviewsTemplate();
private get descriptionTemplate();
private get topicsTemplate();
private get sourceTemplate();
private searchLink;

@@ -24,0 +24,0 @@ private get date();

import { __decorate } from "tslib";
/* eslint-disable lit/no-invalid-html */
import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@@ -15,8 +15,8 @@ import DOMPurify from 'dompurify';

<div id="list-line-left">
<div id="thumb">${this.img()}</div>
${this.iconLeft()}
<div id="thumb">${this.imgTemplate}</div>
${this.iconLeftTemplate}
</div>
<div id="list-line-right">
<div id="title">${DOMPurify.sanitize((_b = (_a = this.model) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : '')}</div>
${this.itemLine()} ${this.creator()}
${this.itemLineTemplate} ${this.creatorTemplate}
<div id="date">

@@ -26,5 +26,5 @@ <span class="label">Published:</span> ${formatDate(this.date, this.formatSize)}

<div id="views-line">
${this.views()} ${this.rating()} ${this.reviews()}
${this.viewsTemplate} ${this.ratingTemplate} ${this.reviewsTemplate}
</div>
${this.topics()} ${this.description()}
${this.topicsTemplate} ${this.descriptionTemplate}
</div>

@@ -34,6 +34,6 @@ </div>

}
img() {
get imgTemplate() {
var _a, _b;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.identifier)) {
return html ``;
return nothing;
}

@@ -46,6 +46,6 @@ return html ` <img

}
iconLeft() {
get iconLeftTemplate() {
var _a;
if (this.classSize !== 'desktop') {
return html ``;
return nothing;
}

@@ -59,6 +59,6 @@ return html `

}
creator() {
get creatorTemplate() {
var _a, _b, _c;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.creator)) {
return html ``;
return nothing;
}

@@ -72,10 +72,10 @@ return html `

}
itemLine() {
const source = this.source();
get itemLineTemplate() {
const source = this.sourceTemplate;
if (!source) {
return html ``;
return nothing;
}
return html ` <div id="item-line">${source}</div> `;
}
views() {
get viewsTemplate() {
var _a, _b;

@@ -89,6 +89,6 @@ return html `

}
rating() {
get ratingTemplate() {
var _a, _b;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.averageRating)) {
return html ``;
return nothing;
}

@@ -102,6 +102,6 @@ return html `

}
reviews() {
get reviewsTemplate() {
var _a, _b;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.commentCount)) {
return html ``;
return nothing;
}

@@ -115,32 +115,37 @@ return html `

}
description() {
get descriptionTemplate() {
var _a, _b;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.description)) {
return html ``;
return nothing;
}
const description = DOMPurify.sanitize(`${(_b = this.model) === null || _b === void 0 ? void 0 : _b.description}`);
return html `<div id="description">${description}</div>`;
return html ` <div id="description">${description}</div> `;
}
topics() {
get topicsTemplate() {
var _a, _b;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.subject)) {
return html ``;
return nothing;
}
return html ` <div id="topics">
<span class="label">Topics: </span>
${DOMPurify.sanitize((_b = this.model) === null || _b === void 0 ? void 0 : _b.subject)}
</div>`;
return html `
<div id="topics">
<span class="label">Topics: </span>
${DOMPurify.sanitize((_b = this.model) === null || _b === void 0 ? void 0 : _b.subject)}
</div>
`;
}
source() {
get sourceTemplate() {
var _a;
if ((_a = this.model) === null || _a === void 0 ? void 0 : _a.source) {
return html `<div id="source">
<span class="label">Source: </span>${this.searchLink('source', this.model.source)}
</div>`;
if (!((_a = this.model) === null || _a === void 0 ? void 0 : _a.source)) {
return nothing;
}
return html ``;
return html `
<div id="source">
<span class="label">Source: </span>
${this.searchLink('source', this.model.source)}
</div>
`;
}
searchLink(field, searchTerm) {
if (!field || !searchTerm) {
return html ``;
return nothing;
}

@@ -147,0 +152,0 @@ const query = encodeURIComponent(`${field}:"${searchTerm}"`);

@@ -10,2 +10,3 @@ import { LitElement, PropertyValues } from 'lit';

import './list/tile-list-compact';
import './list/tile-list-compact-header';
export declare class TileDispatcher extends LitElement implements SharedResizeObserverResizeHandlerInterface {

@@ -22,2 +23,4 @@ displayMode?: CollectionDisplayMode;

render(): import("lit-html").TemplateResult<1>;
private get headerTemplate();
private get tileTemplate();
handleResize(entry: ResizeObserverEntry): void;

@@ -24,0 +27,0 @@ disconnectedCallback(): void;

@@ -10,2 +10,3 @@ import { __decorate } from "tslib";

import './list/tile-list-compact';
import './list/tile-list-compact-header';
let TileDispatcher = class TileDispatcher extends LitElement {

@@ -17,15 +18,33 @@ constructor() {

render() {
return html `
<div id="container">
${this.displayMode === 'list-header'
? this.headerTemplate
: this.tileTemplate}
</div>
`;
}
get headerTemplate() {
const { currentWidth, sortParam } = this;
return html `
<tile-list-compact-header
class="header"
.currentWidth=${currentWidth}
.sortParam=${sortParam}
>
</tile-list-compact-header>
`;
}
get tileTemplate() {
var _a, _b;
return html `
<div id="container">
${this.showDeleteButton
${this.showDeleteButton
? html `<button id="delete-button">X</button>`
: nothing}
<a
href="${this.baseNavigationUrl}/details/${(_a = this.model) === null || _a === void 0 ? void 0 : _a.identifier}"
title=${ifDefined((_b = this.model) === null || _b === void 0 ? void 0 : _b.title)}
>
${this.tile}
</a>
</div>
<a
href="${this.baseNavigationUrl}/details/${(_a = this.model) === null || _a === void 0 ? void 0 : _a.identifier}"
title=${ifDefined((_b = this.model) === null || _b === void 0 ? void 0 : _b.title)}
>
${this.tile}
</a>
`;

@@ -84,5 +103,5 @@ }

.model=${model}
.baseNavigationUrl=${this.baseNavigationUrl}
.currentWidth=${this.currentWidth}
.currentHeight=${this.currentHeight}
.baseNavigationUrl=${baseNavigationUrl}
.currentWidth=${currentWidth}
.currentHeight=${currentHeight}
></item-tile>`;

@@ -114,3 +133,2 @@ }

display: block;
height: 100%;
}

@@ -117,0 +135,0 @@

@@ -6,3 +6,3 @@ {

"author": "Internet Archive",
"version": "0.0.1-alpha.14",
"version": "0.0.1-alpha.15",
"main": "dist/index.js",

@@ -9,0 +9,0 @@ "module": "dist/index.js",

@@ -27,3 +27,6 @@ /* eslint-disable import/no-duplicates */

} from '@internetarchive/search-service';
import { SharedResizeObserverInterface } from '@internetarchive/shared-resize-observer';
import {
SharedResizeObserverInterface,
SharedResizeObserverResizeHandlerInterface,
} from '@internetarchive/shared-resize-observer';
import type { TileModel, CollectionDisplayMode } from './models';

@@ -49,2 +52,3 @@ import '@internetarchive/infinite-scroller';

} from './restoration-state-handler';
import chevronIcon from './assets/img/icons/chevron';

@@ -54,3 +58,5 @@ @customElement('collection-browser')

extends LitElement
implements InfiniteScrollerCellProviderInterface
implements
InfiniteScrollerCellProviderInterface,
SharedResizeObserverResizeHandlerInterface
{

@@ -69,3 +75,3 @@ @property({ type: String }) baseNavigationUrl?: string;

@property({ type: String }) selectedSort: SortField = 'relevance';
@property({ type: String }) selectedSort: SortField = SortField.relevance;

@@ -105,2 +111,4 @@ @property({ type: String }) selectedTitleFilter: string | null = null;

@property({ type: Number }) mobileBreakpoint = 530;
/**

@@ -131,2 +139,8 @@ * The page that the consumer wants to load.

@state() private mobileView = false;
@state() private mobileFacetsVisible = false;
@query('#content-container') private contentContainer!: HTMLDivElement;
/**

@@ -210,26 +224,44 @@ * When we're animated scrolling to the page, we don't want to fetch

return html`
<div id="content-container">
<div id="content-container" class=${this.mobileView ? 'mobile' : ''}>
<div id="left-column" class="column">
<div id="results-total">
<span id="big-results-count"
>${this.totalResults
? this.totalResults.toLocaleString()
: '-'}</span
>
<span id="big-results-label">Results</span>
<div id="mobile-header-container">
${this.mobileView
? html`
<div id="mobile-filter-collapse">
<h1
@click=${() => {
this.mobileFacetsVisible = !this.mobileFacetsVisible;
}}
@keyup=${() => {
this.mobileFacetsVisible = !this.mobileFacetsVisible;
}}
>
<span
class="collapser ${this.mobileFacetsVisible
? 'open'
: ''}"
>
${chevronIcon}
</span>
Filters
</h1>
</div>
`
: nothing}
<div id="results-total">
<span id="big-results-count"
>${this.totalResults
? this.totalResults.toLocaleString()
: '-'}</span
>
<span id="big-results-label">Results</span>
</div>
</div>
<div id="facets-container">
${this.facetsLoading ? this.loadingTemplate : nothing}
<collection-facets
@facetsChanged=${this.facetsChanged}
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
.aggregations=${this.aggregations}
.fullYearsHistogramAggregation=${this
.fullYearsHistogramAggregation}
.minSelectedDate=${this.minSelectedDate}
.maxSelectedDate=${this.maxSelectedDate}
.selectedFacets=${this.selectedFacets}
?facetsLoading=${this.facetDataLoading}
?fullYearAggregationLoading=${this.fullYearAggregationLoading}
></collection-facets>
<div
id="facets-container"
class=${!this.mobileView || this.mobileFacetsVisible
? 'expanded'
: ''}
>
${this.facetsTemplate}
</div>

@@ -245,2 +277,3 @@ </div>

.selectedCreatorFilter=${this.selectedCreatorFilter}
.resizeObserver=${this.resizeObserver}
@sortChanged=${this.userChangedSort}

@@ -252,2 +285,6 @@ @displayModeChanged=${this.displayModeChanged}

${this.displayMode === `list-compact`
? this.listHeaderTemplate
: nothing}
<infinite-scroller

@@ -322,2 +359,20 @@ class="${ifDefined(this.displayMode)}"

private get facetsTemplate() {
return html`
${this.facetsLoading ? this.loadingTemplate : nothing}
<collection-facets
@facetsChanged=${this.facetsChanged}
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
.aggregations=${this.aggregations}
.fullYearsHistogramAggregation=${this.fullYearsHistogramAggregation}
.minSelectedDate=${this.minSelectedDate}
.maxSelectedDate=${this.maxSelectedDate}
.selectedFacets=${this.selectedFacets}
?collapsableFacets=${this.mobileView}
?facetsLoading=${this.facetDataLoading}
?fullYearAggregationLoading=${this.fullYearAggregationLoading}
></collection-facets>
`;
}
private get loadingTemplate() {

@@ -331,2 +386,13 @@ return html`

private get listHeaderTemplate() {
return html`
<tile-dispatcher
.displayMode=${'list-header'}
.resizeObserver=${this.resizeObserver}
.sortParam=${this.sortParam}
>
</tile-dispatcher>
`;
}
private get queryDebuggingTemplate() {

@@ -397,4 +463,40 @@ return html`

}
if (changed.has('resizeObserver')) {
const oldObserver = changed.get(
'resizeObserver'
) as SharedResizeObserverInterface;
if (oldObserver) this.disconnectResizeObserver(oldObserver);
this.setupResizeObserver();
}
}
disconnectedCallback(): void {
if (this.resizeObserver) {
this.disconnectResizeObserver(this.resizeObserver);
}
}
handleResize(entry: ResizeObserverEntry): void {
if (entry.target === this.contentContainer) {
this.mobileView = entry.contentRect.width < 600;
}
}
private disconnectResizeObserver(
resizeObserver: SharedResizeObserverInterface
) {
resizeObserver.removeObserver({
target: this.contentContainer,
handler: this,
});
}
private setupResizeObserver() {
if (!this.resizeObserver) return;
this.resizeObserver.addObserver({
target: this.contentContainer,
handler: this,
});
}
/**

@@ -461,3 +563,3 @@ * When the visible cells change from the infinite scroller, we want to emit

this.displayMode = restorationState.displayMode;
this.selectedSort = restorationState.selectedSort ?? 'relevance';
this.selectedSort = restorationState.selectedSort ?? SortField.relevance;
this.sortDirection = restorationState.sortDirection ?? null;

@@ -873,2 +975,28 @@ this.selectedTitleFilter = restorationState.selectedTitleFilter ?? null;

.collapser {
display: inline-block;
}
.collapser svg {
width: 10px;
height: 10px;
transition: transform 0.2s ease-out;
}
.collapser.open svg {
transform: rotate(90deg);
}
#mobile-filter-collapse h1 {
cursor: pointer;
}
#content-container.mobile {
display: block;
}
.column {
padding-top: 2rem;
}
#right-column {

@@ -878,17 +1006,37 @@ flex: 1;

border-left: 1px solid rgb(232, 232, 232);
padding-left: 1rem;
}
.mobile #right-column {
border-left: none;
padding: 0;
}
#left-column {
width: 18rem;
padding-right: 12px;
padding-right: 1rem;
}
.column {
padding: 2rem 1rem;
.mobile #left-column {
width: 100%;
padding: 0;
}
#mobile-header-container {
display: flex;
justify-content: space-between;
}
#facets-container {
position: relative;
max-height: 0;
transition: max-height 0.2s ease-in-out;
overflow: hidden;
}
#facets-container.expanded {
max-height: 2000px;
}
#results-total {

@@ -900,2 +1048,6 @@ display: flex;

.mobile #results-total {
margin-bottom: 0;
}
#big-results-count {

@@ -902,0 +1054,0 @@ font-size: 2.4rem;

@@ -1,3 +0,3 @@

import { css, html, LitElement, PropertyValues } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { css, html, LitElement, PropertyValues, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';

@@ -9,2 +9,3 @@ import { Aggregation, Bucket } from '@internetarchive/search-service';

import eyeClosedIcon from './assets/img/icons/eye-closed';
import chevronIcon from './assets/img/icons/chevron';
import {

@@ -61,2 +62,13 @@ FacetOption,

@property({ type: Boolean }) collapsableFacets = false;
@state() openFacets: Record<FacetOption, boolean> = {
subject: false,
mediatype: false,
language: false,
creator: false,
collection: false,
year: false,
};
render() {

@@ -70,10 +82,4 @@ return html`

${this.mergedFacets.map(
facetGroup =>
html`
<div class="facet-group">
<h1>${facetGroup.title}</h1>
${this.getFacetTemplate(facetGroup)}
</div>
`
${this.mergedFacets.map(facetGroup =>
this.getFacetGroupTemplate(facetGroup)
)}

@@ -242,2 +248,32 @@ </div>

private getFacetGroupTemplate(facetGroup: FacetGroup) {
const { key } = facetGroup;
const isOpen = this.openFacets[key];
const collapser = html`
<span class="collapser ${isOpen ? 'open' : ''}"> ${chevronIcon} </span>
`;
return html`
<div class="facet-group ${this.collapsableFacets ? 'mobile' : ''}">
<h1
@click=${() => {
const newOpenFacets = { ...this.openFacets };
newOpenFacets[key] = !isOpen;
this.openFacets = newOpenFacets;
}}
@keyup=${() => {
const newOpenFacets = { ...this.openFacets };
newOpenFacets[key] = !isOpen;
this.openFacets = newOpenFacets;
}}
>
${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}
</h1>
<div class="facet-group-content ${isOpen ? 'open' : ''}">
${this.getFacetTemplate(facetGroup)}
</div>
</div>
`;
}
private getFacetTemplate(facetGroup: FacetGroup) {

@@ -355,2 +391,42 @@ return html`

.collapser {
display: inline-block;
cursor: pointer;
width: 10px;
height: 10px;
}
.collapser svg {
transition: transform 0.2s ease-in-out;
}
.collapser.open svg {
transform: rotate(90deg);
}
.facet-group {
margin-bottom: 2rem;
}
.facet-group h1 {
margin-bottom: 0.7rem;
}
.facet-group.mobile h1 {
cursor: pointer;
}
.facet-group-content {
transition: max-height 0.2s ease-in-out;
}
.facet-group.mobile .facet-group-content {
max-height: 0;
overflow: hidden;
}
.facet-group.mobile .facet-group-content.open {
max-height: 2000px;
}
h1 {

@@ -361,3 +437,3 @@ font-size: 1.4rem;

padding-bottom: 3px;
margin: 24px 0 14px 0;
margin: 0;
}

@@ -364,0 +440,0 @@

@@ -81,4 +81,4 @@ import { css, CSSResultGroup, html, LitElement } from 'lit';

svg {
height: var(--iconHeight);
width: var(--iconWidth);
height: var(--iconHeight, 10px);
width: var(--iconWidth, 10px);
}

@@ -85,0 +85,0 @@

@@ -25,3 +25,7 @@ import type { MediaType } from '@internetarchive/field-parsers';

export type CollectionDisplayMode = 'grid' | 'list-compact' | 'list-detail';
export type CollectionDisplayMode =
| 'grid'
| 'list-compact'
| 'list-detail'
| 'list-header';

@@ -38,11 +42,12 @@ /**

*/
export type SortField =
| 'relevance'
| 'views'
| 'title'
| 'datearchived'
| 'datepublished'
| 'datereviewed'
| 'dateadded'
| 'creator';
export enum SortField {
'relevance' = 'relevance',
'views' = 'views',
'title' = 'title',
'datearchived' = 'datearchived',
'datepublished' = 'datepublished',
'datereviewed' = 'datereviewed',
'dateadded' = 'dateadded',
'creator' = 'creator',
}

@@ -61,2 +66,15 @@ /**

export const SortFieldDisplayName: {
[key in SortField]: string;
} = {
relevance: 'Relevance',
views: 'Views',
title: 'Title',
datearchived: 'Date Archived',
datepublished: 'Date Published',
datereviewed: 'Date Reviewed',
dateadded: 'Date Added',
creator: 'Creator',
};
/**

@@ -84,9 +102,9 @@ * Maps the SortField above to the corresponding Metadata field in the API.

} = {
titleSorter: 'title',
date: 'datearchived',
publicdate: 'datepublished',
reviewdate: 'datereviewed',
addeddate: 'dateadded',
creatorSorter: 'creator',
week: 'views',
titleSorter: SortField.title,
date: SortField.datearchived,
publicdate: SortField.datepublished,
reviewdate: SortField.datereviewed,
addeddate: SortField.dateadded,
creatorSorter: SortField.creator,
week: SortField.views,
};

@@ -93,0 +111,0 @@

@@ -78,3 +78,3 @@ import { LitElement, html, css } from 'lit';

text-decoration: none;
padding: 0.5rem 0.7rem;
padding: 0.5rem 0;
display: block;

@@ -81,0 +81,0 @@ }

@@ -1,4 +0,19 @@

import { LitElement, html, css, nothing, PropertyValues } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { CollectionDisplayMode, SortField } from '../models';
import {
LitElement,
html,
css,
nothing,
PropertyValues,
TemplateResult,
} from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import {
SharedResizeObserverInterface,
SharedResizeObserverResizeHandlerInterface,
} from '@internetarchive/shared-resize-observer';
import {
CollectionDisplayMode,
SortField,
SortFieldDisplayName,
} from '../models';
import './alpha-bar';

@@ -10,11 +25,7 @@

enum SortFieldName {
datearchived = 'Date Archived',
datepublished = 'Date Published',
datereviewed = 'Date Reviewed',
dateadded = 'Date Added',
}
@customElement('sort-filter-bar')
export class SortFilterBar extends LitElement {
export class SortFilterBar
extends LitElement
implements SharedResizeObserverResizeHandlerInterface
{
@property({ type: String }) displayMode?: CollectionDisplayMode;

@@ -24,3 +35,3 @@

@property({ type: String }) selectedSort: SortField = 'relevance';
@property({ type: String }) selectedSort: SortField = SortField.relevance;

@@ -33,2 +44,4 @@ @property({ type: String }) selectedTitleFilter: string | null = null;

@property({ type: Object }) resizeObserver?: SharedResizeObserverInterface;
@state() titleSelectorVisible: boolean = false;

@@ -40,2 +53,12 @@

@state() desktopSelectorBarWidth = 0;
@state() selectorBarContainerWidth = 0;
@query('#desktop-sort-selector')
private desktopSortSelector!: HTMLUListElement;
@query('#sort-selector-container')
private sortSelectorContainer!: HTMLDivElement;
render() {

@@ -52,139 +75,12 @@ return html`

<div id="sort-bar">
<div id="sort-selector">
<ul>
<li>
<div id="sort-direction-container">
<button
id="sort-ascending-btn"
class="sort-button ${this.sortDirection === 'asc'
? 'selected'
: ''}"
@click=${() => {
this.setSortDirections('asc');
}}
>
${sortIcon}
</button>
<button
id="sort-descending-btn"
class="sort-button ${this.sortDirection === 'desc'
? 'selected'
: ''}"
@click=${() => {
this.setSortDirections('desc');
}}
>
${sortIcon}
</button>
</div>
</li>
<li id="sort-by-text">Sort By</li>
${this.showRelevance
? html`
<li>
<a
href="#"
@click=${(e: Event) => {
e.preventDefault();
this.setSelectedSort('relevance');
}}
class=${this.selectedSort === 'relevance'
? 'selected'
: ''}
>
Relevance
</a>
</li>
`
: nothing}
<li>
<a
href="#"
@click=${(e: Event) => {
e.preventDefault();
this.setSelectedSort('views');
}}
class=${this.selectedSort === 'views' ? 'selected' : ''}
>
Views
</a>
</li>
<li>
<a
href="#"
@click=${(e: Event) => {
e.preventDefault();
this.titleSelectorVisible = !this.titleSelectorVisible;
this.setSelectedSort('title');
}}
class=${this.selectedSort === 'title' ? 'selected' : ''}
>
Title
</a>
</li>
<li>
<a
href="#"
@click=${(e: Event) => {
e.preventDefault();
this.dateSortSelectorVisible =
!this.dateSortSelectorVisible;
this.setSelectedSort('datearchived');
}}
class=${this.dateOptionSelected ? 'selected' : ''}
>
${this.dateSortField}
</a>
</li>
<li>
<a
href="#"
@click=${(e: Event) => {
e.preventDefault();
this.creatorSelectorVisible = !this.creatorSelectorVisible;
this.setSelectedSort('creator');
}}
class=${this.selectedSort === 'creator' ? 'selected' : ''}
>
Creator
</a>
</li>
</ul>
<div id="sort-direction-container">
${this.sortDirectionSelectorTemplate}
</div>
<div id="display-style">
<ul>
${this.displayMode !== 'grid'
? html`<li>
<label id="show-details">
<input
type="checkbox"
@click=${this.detailSelected}
?checked=${this.displayMode === 'list-detail'}
/>
Show Details
</label>
</li>`
: nothing}
<div id="sort-selector-container">
${this.mobileSortSelectorTemplate}
${this.desktopSortSelectorTemplate}
</div>
<li>
<button
id="grid-button"
@click=${this.gridSelected}
class=${this.displayMode === 'grid' ? 'active' : ''}
>
${gridIcon}
</button>
</li>
<li>
<button
id="list-button"
@click=${this.listSelected}
class=${this.displayMode !== 'grid' ? 'active' : ''}
>
${listIcon}
</button>
</li>
</ul>
</div>
<div id="display-style-selector">${this.displayOptionTemplate}</div>
</div>

@@ -215,4 +111,217 @@

}
if (changed.has('resizeObserver')) {
const oldObserver = changed.get(
'resizeObserver'
) as SharedResizeObserverInterface;
if (oldObserver) this.disconnectResizeObserver(oldObserver);
this.setupResizeObserver();
}
}
disconnectedCallback(): void {
if (this.resizeObserver) {
this.disconnectResizeObserver(this.resizeObserver);
}
}
private disconnectResizeObserver(
resizeObserver: SharedResizeObserverInterface
) {
resizeObserver.removeObserver({
target: this.sortSelectorContainer,
handler: this,
});
resizeObserver.removeObserver({
target: this.desktopSortSelector,
handler: this,
});
}
private setupResizeObserver() {
if (!this.resizeObserver) return;
this.resizeObserver.addObserver({
target: this.sortSelectorContainer,
handler: this,
});
this.resizeObserver.addObserver({
target: this.desktopSortSelector,
handler: this,
});
}
private get mobileSelectorVisible() {
return this.selectorBarContainerWidth - 10 < this.desktopSelectorBarWidth;
}
handleResize(entry: ResizeObserverEntry): void {
if (entry.target === this.desktopSortSelector)
this.desktopSelectorBarWidth = entry.contentRect.width;
else if (entry.target === this.sortSelectorContainer)
this.selectorBarContainerWidth = entry.contentRect.width;
}
private get sortDirectionSelectorTemplate() {
return html`
<div id="sort-direction-selector">
<button
id="sort-ascending-btn"
class="sort-button ${this.sortDirection === 'asc' ? 'selected' : ''}"
?disabled=${this.selectedSort === 'relevance'}
@click=${() => {
this.setSortDirections('asc');
}}
>
${sortIcon}
</button>
<button
id="sort-descending-btn"
class="sort-button ${this.sortDirection === 'desc' ? 'selected' : ''}"
?disabled=${this.selectedSort === 'relevance'}
@click=${() => {
this.setSortDirections('desc');
}}
>
${sortIcon}
</button>
</div>
`;
}
private get desktopSortSelectorTemplate() {
return html`
<ul
id="desktop-sort-selector"
class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}
>
<li id="sort-by-text">Sort By</li>
<li>
${this.showRelevance
? this.getSortDisplayOption(SortField.relevance)
: nothing}
</li>
<li>${this.getSortDisplayOption(SortField.views)}</li>
<li>${this.getSortDisplayOption(SortField.title)}</li>
<li>
${this.getSortDisplayOption(SortField.datearchived, {
additionalClickEvent: () => {
this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
},
displayName: html`${this.dateSortField}`,
isSelected: () => this.dateOptionSelected,
})}
</li>
<li>
${this.getSortDisplayOption(SortField.creator, {
additionalClickEvent: () => {
this.creatorSelectorVisible = !this.creatorSelectorVisible;
},
})}
</li>
</ul>
`;
}
/**
* This generates each of the sort option links.
*
* It manages the display value and the selected state of the option.
*
* @param sortField
* @param options {
* additionalClickEvent?: () => void; If this is provided, it will also be called when the option is clicked.
* displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.
* isSelected?: () => boolean; A function that returns true if the option is selected. Defaults to the selectedSort === sortField.
* }
* @returns
*/
private getSortDisplayOption(
sortField: SortField,
options?: {
additionalClickEvent?: (e: Event) => void;
isSelected?: () => boolean;
displayName?: TemplateResult;
}
): TemplateResult {
const isSelected =
options?.isSelected ?? (() => this.selectedSort === sortField);
const displayName = options?.displayName ?? SortFieldDisplayName[sortField];
return html`
<a
href="#"
@click=${(e: Event) => {
e.preventDefault();
this.setSelectedSort(sortField);
options?.additionalClickEvent?.(e);
}}
class=${isSelected() ? 'selected' : ''}
>
${displayName}
</a>
`;
}
private get mobileSortSelectorTemplate() {
return html`
<select
id="mobile-sort-selector"
@change=${this.mobileSortChanged}
class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
>
${Object.keys(SortField).map(
field => html`
<option value="${field}" ?selected=${this.selectedSort === field}>
${SortFieldDisplayName[field as SortField]}
</option>
`
)}
</select>
`;
}
private mobileSortChanged(e: Event) {
const target = e.target as HTMLSelectElement;
this.setSelectedSort(target.value as SortField);
}
private get displayOptionTemplate() {
return html`
<ul>
${this.displayMode !== 'grid'
? html`<li>
<label id="show-details">
<input
type="checkbox"
@click=${this.detailSelected}
?checked=${this.displayMode === 'list-detail'}
/>
Show Details
</label>
</li>`
: nothing}
<li>
<button
id="grid-button"
@click=${this.gridSelected}
class=${this.displayMode === 'grid' ? 'active' : ''}
>
${gridIcon}
</button>
</li>
<li>
<button
id="list-button"
@click=${this.listSelected}
class=${this.displayMode !== 'grid' ? 'active' : ''}
>
${listIcon}
</button>
</li>
</ul>
`;
}
private get dateSortSelector() {

@@ -222,38 +331,6 @@ return html`

<ul>
<li>
<button
@click=${() => {
this.selectDateSort('datearchived');
}}
>
Date Archived
</button>
</li>
<li>
<button
@click=${() => {
this.selectDateSort('datepublished');
}}
>
Date Published
</button>
</li>
<li>
<button
@click=${() => {
this.selectDateSort('datereviewed');
}}
>
Date Reviewed
</button>
</li>
<li>
<button
@click=${() => {
this.selectDateSort('dateadded');
}}
>
Date Added
</button>
</li>
<li>${this.getDateSortButton(SortField.datearchived)}</li>
<li>${this.getDateSortButton(SortField.datepublished)}</li>
<li>${this.getDateSortButton(SortField.datereviewed)}</li>
<li>${this.getDateSortButton(SortField.dateadded)}</li>
</ul>

@@ -264,2 +341,14 @@ </div>

private getDateSortButton(sortField: SortField) {
return html`
<button
@click=${() => {
this.selectDateSort(sortField);
}}
>
${SortFieldDisplayName[sortField]}
</button>
`;
}
private selectDateSort(sortField: SortField) {

@@ -308,6 +397,3 @@ this.dateSortSelectorVisible = false;

private get dateSortField(): string {
return (
SortFieldName[this.selectedSort as keyof typeof SortFieldName] ??
'Date Archived'
);
return SortFieldDisplayName[this.selectedSort] ?? 'Date Archived';
}

@@ -397,2 +483,6 @@

#sort-direction-container {
flex: 0;
}
#sort-by-text {

@@ -437,2 +527,7 @@ text-transform: uppercase;

.sort-button:disabled {
opacity: 0.25;
cursor: default;
}
#show-details {

@@ -447,9 +542,34 @@ text-transform: uppercase;

#sort-direction-container {
#sort-direction-selector {
display: flex;
flex-direction: column;
gap: 3px;
margin-right: 1rem;
}
#sort-selector li {
#sort-selector-container {
flex: 1;
}
/*
we move the desktop sort selector offscreen instead of display: none
because we need to observe the width of it vs its container to determine
if it's wide enough to display the desktop version and if you displY: none,
the width becomes 0
*/
#desktop-sort-selector.hidden {
position: absolute;
top: -9999px;
left: -9999px;
}
#mobile-sort-selector.hidden {
display: none;
}
#desktop-sort-selector {
display: inline-flex;
}
#desktop-sort-selector li {
display: flex;

@@ -459,3 +579,3 @@ align-items: center;

#sort-selector li a {
#desktop-sort-selector li a {
text-decoration: none;

@@ -467,7 +587,7 @@ text-transform: uppercase;

#sort-selector li a.selected {
#desktop-sort-selector li a.selected {
font-weight: bold;
}
#sort-selector li::after {
#desktop-sort-selector li::after {
content: '•';

@@ -478,11 +598,15 @@ padding-left: 1rem;

#sort-selector li:first-child::after {
#desktop-sort-selector li:first-child::after {
content: '';
}
#sort-selector li:last-child::after {
#desktop-sort-selector li:last-child::after {
content: '';
}
#display-style button {
#display-style-selector {
flex: 0;
}
#display-style-selector button {
background: none;

@@ -497,7 +621,7 @@ color: inherit;

#display-style button.active {
#display-style-selector button.active {
opacity: 1;
}
#display-style button svg {
#display-style-selector button svg {
width: 24px;

@@ -504,0 +628,0 @@ height: 24px;

@@ -1,2 +0,2 @@

import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@@ -25,3 +25,3 @@ import { SortParam } from '@internetarchive/search-service';

<div id="list-line" class="${this.classSize}">
<div id="thumb">${this.img()}</div>
<div id="thumb">${this.imageTemplate}</div>
<div id="title">${DOMPurify.sanitize(this.model?.title ?? '')}</div>

@@ -40,11 +40,11 @@ <div id="date">${formatDate(this.date, this.formatSize)}</div>

private img() {
if (this.model?.identifier) {
return html` <img
src="${this.baseNavigationUrl}/services/img/${this.model.identifier}"
alt="${this.model.identifier}"
class=${this.model?.mediatype}
/>`;
private get imageTemplate() {
if (!this.model?.identifier) {
return nothing;
}
return html``;
return html` <img
src="${this.baseNavigationUrl}/services/img/${this.model.identifier}"
alt="${this.model.identifier}"
class="${this.model?.mediatype}"
/>`;
}

@@ -165,3 +165,3 @@

column-gap: 10px;
border-top: 1px solid #ddd !important;
border-top: 1px solid #ddd;
align-items: center;

@@ -201,3 +201,3 @@ line-height: 20px;

}
*/
*/

@@ -204,0 +204,0 @@ #list-line:hover #title {

/* eslint-disable lit/no-invalid-html */
import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@@ -27,8 +27,8 @@ import { SortParam } from '@internetarchive/search-service';

<div id="list-line-left">
<div id="thumb">${this.img()}</div>
${this.iconLeft()}
<div id="thumb">${this.imgTemplate}</div>
${this.iconLeftTemplate}
</div>
<div id="list-line-right">
<div id="title">${DOMPurify.sanitize(this.model?.title ?? '')}</div>
${this.itemLine()} ${this.creator()}
${this.itemLineTemplate} ${this.creatorTemplate}
<div id="date">

@@ -41,5 +41,5 @@ <span class="label">Published:</span> ${formatDate(

<div id="views-line">
${this.views()} ${this.rating()} ${this.reviews()}
${this.viewsTemplate} ${this.ratingTemplate} ${this.reviewsTemplate}
</div>
${this.topics()} ${this.description()}
${this.topicsTemplate} ${this.descriptionTemplate}
</div>

@@ -50,5 +50,5 @@ </div>

private img() {
private get imgTemplate() {
if (!this.model?.identifier) {
return html``;
return nothing;
}

@@ -62,5 +62,5 @@ return html` <img

private iconLeft() {
private get iconLeftTemplate() {
if (this.classSize !== 'desktop') {
return html``;
return nothing;
}

@@ -75,5 +75,5 @@ return html`

private creator() {
private get creatorTemplate() {
if (!this.model?.creator) {
return html``;
return nothing;
}

@@ -88,6 +88,6 @@ return html`

private itemLine() {
const source = this.source();
private get itemLineTemplate() {
const source = this.sourceTemplate;
if (!source) {
return html``;
return nothing;
}

@@ -97,3 +97,3 @@ return html` <div id="item-line">${source}</div> `;

private views() {
private get viewsTemplate() {
return html`

@@ -107,5 +107,5 @@ <div id="views">

private rating() {
private get ratingTemplate() {
if (!this.model?.averageRating) {
return html``;
return nothing;
}

@@ -120,5 +120,5 @@ return html`

private reviews() {
private get reviewsTemplate() {
if (!this.model?.commentCount) {
return html``;
return nothing;
}

@@ -133,30 +133,32 @@ return html`

private description() {
private get descriptionTemplate() {
if (!this.model?.description) {
return html``;
return nothing;
}
const description = DOMPurify.sanitize(`${this.model?.description}`);
return html`<div id="description">${description}</div>`;
return html` <div id="description">${description}</div> `;
}
private topics() {
private get topicsTemplate() {
if (!this.model?.subject) {
return html``;
return nothing;
}
return html` <div id="topics">
<span class="label">Topics: </span>
${DOMPurify.sanitize(this.model?.subject)}
</div>`;
return html`
<div id="topics">
<span class="label">Topics: </span>
${DOMPurify.sanitize(this.model?.subject)}
</div>
`;
}
private source() {
if (this.model?.source) {
return html`<div id="source">
<span class="label">Source: </span>${this.searchLink(
'source',
this.model.source
)}
</div>`;
private get sourceTemplate() {
if (!this.model?.source) {
return nothing;
}
return html``;
return html`
<div id="source">
<span class="label">Source: </span>
${this.searchLink('source', this.model.source)}
</div>
`;
}

@@ -166,3 +168,3 @@

if (!field || !searchTerm) {
return html``;
return nothing;
}

@@ -169,0 +171,0 @@ const query = encodeURIComponent(`${field}:"${searchTerm}"`);

@@ -15,2 +15,3 @@ import { css, html, LitElement, nothing, PropertyValues } from 'lit';

import './list/tile-list-compact';
import './list/tile-list-compact-header';

@@ -43,11 +44,5 @@ @customElement('tile-dispatcher')

<div id="container">
${this.showDeleteButton
? html`<button id="delete-button">X</button>`
: nothing}
<a
href="${this.baseNavigationUrl}/details/${this.model?.identifier}"
title=${ifDefined(this.model?.title)}
>
${this.tile}
</a>
${this.displayMode === 'list-header'
? this.headerTemplate
: this.tileTemplate}
</div>

@@ -57,2 +52,28 @@ `;

private get headerTemplate() {
const { currentWidth, sortParam } = this;
return html`
<tile-list-compact-header
class="header"
.currentWidth=${currentWidth}
.sortParam=${sortParam}
>
</tile-list-compact-header>
`;
}
private get tileTemplate() {
return html`
${this.showDeleteButton
? html`<button id="delete-button">X</button>`
: nothing}
<a
href="${this.baseNavigationUrl}/details/${this.model?.identifier}"
title=${ifDefined(this.model?.title)}
>
${this.tile}
</a>
`;
}
handleResize(entry: ResizeObserverEntry): void {

@@ -117,5 +138,5 @@ this.currentWidth = entry.contentRect.width;

.model=${model}
.baseNavigationUrl=${this.baseNavigationUrl}
.currentWidth=${this.currentWidth}
.currentHeight=${this.currentHeight}
.baseNavigationUrl=${baseNavigationUrl}
.currentWidth=${currentWidth}
.currentHeight=${currentHeight}
></item-tile>`;

@@ -148,3 +169,2 @@ }

display: block;
height: 100%;
}

@@ -151,0 +171,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc