Add drawer component and support side thumbnails.

This commit is contained in:
Dermot Duffy
2022-03-20 18:07:48 -07:00
parent 3d3967318b
commit 304abcd82b
8 changed files with 149 additions and 7 deletions
+12 -1
View File
@@ -1,4 +1,6 @@
import { CSSResultGroup, LitElement, unsafeCSS, PropertyValues } from 'lit';
import { property } from 'lit/decorators.js';
import EmblaCarousel, {
EmblaCarouselType,
EmblaOptionsType,
@@ -15,6 +17,9 @@ export interface CarouselSelect {
}
export class FrigateCardCarousel extends LitElement {
@property({ attribute: true, reflect: true })
public direction: 'vertical' | 'horizontal' = 'horizontal';
protected _carousel?: EmblaCarouselType;
protected _plugins: Record<string, EmblaPluginType> = {};
@@ -98,7 +103,13 @@ export class FrigateCardCarousel extends LitElement {
return acc;
}, {});
this._carousel = EmblaCarousel(carouselNode, this._getOptions(), plugins);
this._carousel = EmblaCarousel(
carouselNode,
{
axis: this.direction == 'horizontal' ? 'x' : 'y',
...this._getOptions()
},
plugins);
this._carousel.on('init', () => dispatchFrigateCardEvent(this, 'carousel:init'));
this._carousel.on('select', () => {
const selected = this.carouselSelected();
+63
View File
@@ -0,0 +1,63 @@
import {
CSSResultGroup,
LitElement,
TemplateResult,
html,
unsafeCSS,
PropertyValues,
} from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { createRef, ref, Ref } from 'lit/directives/ref.js';
import 'side-drawer';
import drawerStyle from '../scss/drawer.scss';
import drawerInjectStyle from '../scss/drawer-inject.scss';
@customElement('frigate-card-drawer')
export class FrigateCardDrawer extends LitElement {
@property({ attribute: true, reflect: true })
public location: 'left' | 'right' = 'left';
/**
* Set the timeline configuration.
*/
@property({ type: Boolean, reflect: true, attribute: true })
set open(open: boolean) {
if (this._drawerRef.value) {
const old = this._drawerRef.value.open;
this._drawerRef.value.open = open;
this.requestUpdate('open', old);
}
}
get open(): boolean {
return this._drawerRef.value?.open ?? false;
}
protected _drawerRef: Ref<HTMLElement & { open: boolean }> = createRef();
/**
* Called on the first update.
* @param changedProps The changed properties.
*/
protected firstUpdated(changedProps: PropertyValues): void {
super.firstUpdated(changedProps);
// The `side-drawer` component (and the material drawer for that matter)
// only do fixed drawers (i.e. a drawer for the whole viewport). Hackily
// override the style to customize the drawer to be absolute within the div.
const style = document.createElement('style');
style.innerHTML = drawerInjectStyle;
this._drawerRef.value?.shadowRoot?.appendChild(style);
}
protected render(): TemplateResult {
return html` <side-drawer location="${this.location}" ${ref(this._drawerRef)}>
<slot></slot>
</side-drawer>`;
}
static get styles(): CSSResultGroup {
return unsafeCSS(drawerStyle);
}
}
+17 -3
View File
@@ -1,11 +1,14 @@
import { BrowseMediaUtil } from '../browse-media-util.js';
import { CSSResultGroup, TemplateResult, html, unsafeCSS } from 'lit';
import { CSSResultGroup, TemplateResult, html, unsafeCSS, PropertyValues } from 'lit';
import { EmblaOptionsType } from 'embla-carousel';
import { customElement, property } from 'lit/decorators.js';
import type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
import { FrigateCardCarousel } from './carousel.js';
import { dispatchFrigateCardEvent, stopEventFromActivatingCardWideActions } from '../common.js';
import {
dispatchFrigateCardEvent,
stopEventFromActivatingCardWideActions,
} from '../common.js';
import thumbnailCarouselStyle from '../scss/thumbnail-carousel.scss';
@@ -18,7 +21,7 @@ export interface ThumbnailCarouselTap {
@customElement('frigate-card-thumbnail-carousel')
export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
@property({ attribute: false })
protected target?: FrigateBrowseMediaSource;
public target?: FrigateBrowseMediaSource;
protected _tapSelected?;
@@ -90,6 +93,17 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
return slides;
}
/**
* The updated lifecycle callback for this element.
* @param changedProperties The properties that were changed in this render.
*/
updated(changedProperties: PropertyValues): void {
if (this._carousel && changedProperties.has('target')) {
this._destroyCarousel();
}
super.updated(changedProperties);
}
/**
* Render a given thumbnail.
* @param mediaToRender The media item to render.