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 }) @property({ type: Boolean, reflect: true, attribute: true })
public open = false; 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 _refDrawer: Ref<HTMLElement & { open: boolean }> = createRef();
protected _refSlot: Ref<HTMLSlotElement> = createRef(); protected _refSlot: Ref<HTMLSlotElement> = createRef();
protected _resizeObserver = new ResizeObserver(() => this._hideDrawerIfNecessary());
/** /**
* Called on the first update. * Called on the first update.
* @param changedProps The changed properties. * @param changedProps The changed properties.
@@ -42,19 +51,45 @@ export class FrigateCardDrawer extends LitElement {
this._refDrawer.value?.shadowRoot?.appendChild(style); this._refDrawer.value?.shadowRoot?.appendChild(style);
} }
/**
* Called when the slotted children in the drawer change.
*/
protected _slotChanged(): void { protected _slotChanged(): void {
const elements = this._refSlot.value?.assignedElements({ flatten: true }); const elements = this._refSlot.value?.assignedElements({ flatten: true });
if (elements && elements.length && this._refDrawer.value) {
// Hide the drawer unless there is content. // Watch all slot children for size changes.
this._refDrawer.value.hidden = false; 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 { protected render(): TemplateResult {
return html` return html`
<side-drawer <side-drawer
${ref(this._refDrawer)} ${ref(this._refDrawer)}
?hidden=${true}
location="${this.location}" location="${this.location}"
?open=${this.open} ?open=${this.open}
> >
+1 -1
View File
@@ -512,7 +512,7 @@ export class FrigateCardLiveCarousel extends FrigateCardMediaCarousel {
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
const [slides, cameraToSlide] = this._getSlides(); const [slides, cameraToSlide] = this._getSlides();
this._cameraToSlide = cameraToSlide; this._cameraToSlide = cameraToSlide;
if (!slides || !this.liveConfig || !this.cameras || !this.view) { if (!slides.length || !this.liveConfig || !this.cameras || !this.view) {
return; 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 { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import type { import type { FrigateBrowseMediaSource, ThumbnailsControlConfig } from '../types.js';
FrigateBrowseMediaSource,
ThumbnailsControlConfig,
} from '../types.js';
import { FrigateCardCarousel } from './carousel.js'; import { FrigateCardCarousel } from './carousel.js';
import { View } from '../view.js'; import { View } from '../view.js';
import { import {
@@ -201,7 +198,7 @@ export class FrigateCardThumbnailCarousel extends FrigateCardCarousel {
*/ */
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
const slides = this._getSlides(); const slides = this._getSlides();
if (!slides || !this._config || this._config.mode == 'none') { if (!slides.length || !this._config || this._config.mode == 'none') {
return; return;
} }
+1 -1
View File
@@ -599,7 +599,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
protected _render(): TemplateResult | void { protected _render(): TemplateResult | void {
const [slides, slideToChild] = this._getSlides(); const [slides, slideToChild] = this._getSlides();
this._slideToChild = slideToChild; this._slideToChild = slideToChild;
if (!slides) { if (!slides.length) {
return; return;
} }
-1
View File
@@ -22,7 +22,6 @@
#d { #d {
// Need to allow drawer controls to be visible. // Need to allow drawer controls to be visible.
overflow: visible; overflow: visible;
visibility: visible;
} }
:host([location=right]) #d { :host([location=right]) #d {
+6
View File
@@ -27,6 +27,12 @@ div.control-surround {
} }
right: 100%; right: 100%;
} }
:host([empty]), :host([empty]) > * {
visibility: hidden;
}
:host(:not([empty])), :host(:not([empty])) > * {
visibility: visible;
}
ha-icon.control { ha-icon.control {
color: var(--secondary-color, white); color: var(--secondary-color, white);