Hide drawers if empty.
This commit is contained in:
@@ -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}
|
||||
>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#d {
|
||||
// Need to allow drawer controls to be visible.
|
||||
overflow: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
:host([location=right]) #d {
|
||||
|
||||
@@ -27,6 +27,12 @@ div.control-surround {
|
||||
}
|
||||
right: 100%;
|
||||
}
|
||||
:host([empty]), :host([empty]) > * {
|
||||
visibility: hidden;
|
||||
}
|
||||
:host(:not([empty])), :host(:not([empty])) > * {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
ha-icon.control {
|
||||
color: var(--secondary-color, white);
|
||||
|
||||
Reference in New Issue
Block a user