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 })
|
@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}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user