Hide drawers if empty.

This commit is contained in:
Dermot Duffy
2022-05-10 19:25:33 -07:00
parent 5bc1d3375c
commit 8ce15f87af
6 changed files with 49 additions and 12 deletions
+39 -4
View File
@@ -24,9 +24,18 @@ export class FrigateCardDrawer extends LitElement {
@property({ type: Boolean, reflect: true, attribute: true })
public open = false;
// The 'empty' attribute is used in the styling to change the drawer
// visibility and that of all descendants if there is no content. Styling is
// used rather than display or hidden in order to ensure the contents continue
// to have a measurable size.
@property({ type: Boolean, reflect: true, attribute: true })
public empty = true;
protected _refDrawer: Ref<HTMLElement & { open: boolean }> = createRef();
protected _refSlot: Ref<HTMLSlotElement> = createRef();
protected _resizeObserver = new ResizeObserver(() => this._hideDrawerIfNecessary());
/**
* Called on the first update.
* @param changedProps The changed properties.
@@ -42,19 +51,45 @@ export class FrigateCardDrawer extends LitElement {
this._refDrawer.value?.shadowRoot?.appendChild(style);
}
/**
* Called when the slotted children in the drawer change.
*/
protected _slotChanged(): void {
const elements = this._refSlot.value?.assignedElements({ flatten: true });
if (elements && elements.length && this._refDrawer.value) {
// Hide the drawer unless there is content.
this._refDrawer.value.hidden = false;
// Watch all slot children for size changes.
this._resizeObserver.disconnect();
for (const element of elements ?? []) {
this._resizeObserver.observe(element);
}
this._hideDrawerIfNecessary();
}
/**
* Hide the drawer if there is nothing to show.
* @returns
*/
protected _hideDrawerIfNecessary(): void {
if (!this._refDrawer.value) {
return;
}
const elements = this._refSlot.value?.assignedElements({ flatten: true });
this.empty =
!elements ||
!elements.length ||
// If the element has the special attribute 'empty' also hide it, this is
// used to hide carousels that have no actual contents.
elements.every((element) => {
const box = element.getBoundingClientRect();
return !box.width || !box.height;
});
}
protected render(): TemplateResult {
return html`
<side-drawer
${ref(this._refDrawer)}
?hidden=${true}
location="${this.location}"
?open=${this.open}
>
+1 -1
View File
@@ -512,7 +512,7 @@ export class FrigateCardLiveCarousel extends FrigateCardMediaCarousel {
protected render(): TemplateResult | void {
const [slides, cameraToSlide] = this._getSlides();
this._cameraToSlide = cameraToSlide;
if (!slides || !this.liveConfig || !this.cameras || !this.view) {
if (!slides.length || !this.liveConfig || !this.cameras || !this.view) {
return;
}
+2 -5
View File
@@ -5,10 +5,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import type {
FrigateBrowseMediaSource,
ThumbnailsControlConfig,
} from '../types.js';
import type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
import { FrigateCardCarousel } from './carousel.js';
import { View } from '../view.js';
import {
@@ -201,7 +198,7 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
*/
protected render(): TemplateResult | void {
const slides = this._getSlides();
if (!slides || !this._config || this._config.mode == 'none') {
if (!slides.length || !this._config || this._config.mode == 'none') {
return;
}
+1 -1
View File
@@ -599,7 +599,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
protected _render(): TemplateResult | void {
const [slides, slideToChild] = this._getSlides();
this._slideToChild = slideToChild;
if (!slides) {
if (!slides.length) {
return;
}