Sidebar tweaks (#6994)

This commit is contained in:
Bram Kragten 2020-09-14 23:46:40 +02:00 committed by GitHub
parent 3030b8d476
commit de95c92e2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 54 deletions

View File

@ -159,8 +159,6 @@ const computePanels = memoizeOne(
let Sortable; let Sortable;
let sortStyles: CSSResult;
@customElement("ha-sidebar") @customElement("ha-sidebar")
class HaSidebar extends LitElement { class HaSidebar extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@ -171,12 +169,12 @@ class HaSidebar extends LitElement {
@property({ type: Boolean, reflect: true }) public expanded = false; @property({ type: Boolean, reflect: true }) public expanded = false;
@property({ type: Boolean }) public editMode = false;
@internalProperty() private _externalConfig?: ExternalConfig; @internalProperty() private _externalConfig?: ExternalConfig;
@internalProperty() private _notifications?: PersistentNotification[]; @internalProperty() private _notifications?: PersistentNotification[];
@internalProperty() private _editMode = false;
// property used only in css // property used only in css
// @ts-ignore // @ts-ignore
@property({ type: Boolean, reflect: true }) public rtl = false; @property({ type: Boolean, reflect: true }) public rtl = false;
@ -227,19 +225,12 @@ class HaSidebar extends LitElement {
} }
return html` return html`
${this._editMode
? html`
<style>
${sortStyles?.cssText}
</style>
`
: ""}
<div <div
class="menu" class="menu"
@action=${this._handleAction} @action=${this._handleAction}
.actionHandler=${actionHandler({ .actionHandler=${actionHandler({
hasHold: !this._editMode, hasHold: !this.editMode,
disabled: this._editMode, disabled: this.editMode,
})} })}
> >
${!this.narrow ${!this.narrow
@ -257,7 +248,7 @@ class HaSidebar extends LitElement {
` `
: ""} : ""}
<div class="title"> <div class="title">
${this._editMode ${this.editMode
? html`<mwc-button outlined @click=${this._closeEditMode}> ? html`<mwc-button outlined @click=${this._closeEditMode}>
${hass.localize("ui.sidebar.done")} ${hass.localize("ui.sidebar.done")}
</mwc-button>` </mwc-button>`
@ -273,7 +264,7 @@ class HaSidebar extends LitElement {
@scroll=${this._listboxScroll} @scroll=${this._listboxScroll}
@keydown=${this._listboxKeydown} @keydown=${this._listboxKeydown}
> >
${this._editMode ${this.editMode
? html`<div id="sortable"> ? html`<div id="sortable">
${guard([this._hiddenPanels, this._renderEmptySortable], () => ${guard([this._hiddenPanels, this._renderEmptySortable], () =>
this._renderEmptySortable this._renderEmptySortable
@ -283,7 +274,7 @@ class HaSidebar extends LitElement {
</div>` </div>`
: this._renderPanels(beforeSpacer)} : this._renderPanels(beforeSpacer)}
<div class="spacer" disabled></div> <div class="spacer" disabled></div>
${this._editMode && this._hiddenPanels.length ${this.editMode && this._hiddenPanels.length
? html` ? html`
${this._hiddenPanels.map((url) => { ${this._hiddenPanels.map((url) => {
const panel = this.hass.panels[url]; const panel = this.hass.panels[url];
@ -307,7 +298,7 @@ class HaSidebar extends LitElement {
: hass.localize(`panel.${panel.title}`) || : hass.localize(`panel.${panel.title}`) ||
panel.title}</span panel.title}</span
> >
<mwc-icon-button class="hide-panel"> <mwc-icon-button class="show-panel">
<ha-svg-icon .path=${mdiPlus}></ha-svg-icon> <ha-svg-icon .path=${mdiPlus}></ha-svg-icon>
</mwc-icon-button> </mwc-icon-button>
</paper-icon-item>`; </paper-icon-item>`;
@ -412,10 +403,10 @@ class HaSidebar extends LitElement {
changedProps.has("alwaysExpand") || changedProps.has("alwaysExpand") ||
changedProps.has("_externalConfig") || changedProps.has("_externalConfig") ||
changedProps.has("_notifications") || changedProps.has("_notifications") ||
changedProps.has("_editMode") || changedProps.has("editMode") ||
changedProps.has("_renderEmptySortable") || changedProps.has("_renderEmptySortable") ||
changedProps.has("_hiddenPanels") || changedProps.has("_hiddenPanels") ||
(changedProps.has("_panelOrder") && !this._editMode) (changedProps.has("_panelOrder") && !this.editMode)
) { ) {
return true; return true;
} }
@ -449,9 +440,6 @@ class HaSidebar extends LitElement {
subscribeNotifications(this.hass.connection, (notifications) => { subscribeNotifications(this.hass.connection, (notifications) => {
this._notifications = notifications; this._notifications = notifications;
}); });
window.addEventListener("hass-edit-sidebar", () =>
this._activateEditMode()
);
} }
protected updated(changedProps) { protected updated(changedProps) {
@ -459,6 +447,13 @@ class HaSidebar extends LitElement {
if (changedProps.has("alwaysExpand")) { if (changedProps.has("alwaysExpand")) {
this.expanded = this.alwaysExpand; this.expanded = this.alwaysExpand;
} }
if (changedProps.has("editMode")) {
if (this.editMode) {
this._activateEditMode();
} else {
this._deactivateEditMode();
}
}
if (!changedProps.has("hass")) { if (!changedProps.has("hass")) {
return; return;
} }
@ -489,7 +484,7 @@ class HaSidebar extends LitElement {
return; return;
} }
this._activateEditMode(); fireEvent(this, "hass-edit-sidebar", { editMode: true });
} }
private async _activateEditMode() { private async _activateEditMode() {
@ -499,15 +494,14 @@ class HaSidebar extends LitElement {
import("../resources/ha-sortable-style"), import("../resources/ha-sortable-style"),
]); ]);
sortStyles = sortStylesImport.sortableStyles; const style = document.createElement("style");
style.innerHTML = sortStylesImport.sortableStyles.cssText;
this.shadowRoot!.appendChild(style);
Sortable = sortableImport.Sortable; Sortable = sortableImport.Sortable;
Sortable.mount(sortableImport.OnSpill); Sortable.mount(sortableImport.OnSpill);
Sortable.mount(sortableImport.AutoScroll()); Sortable.mount(sortableImport.AutoScroll());
} }
this._editMode = true;
fireEvent(this, "hass-open-menu");
await this.updateComplete; await this.updateComplete;
@ -519,16 +513,20 @@ class HaSidebar extends LitElement {
animation: 150, animation: 150,
fallbackClass: "sortable-fallback", fallbackClass: "sortable-fallback",
dataIdAttr: "data-panel", dataIdAttr: "data-panel",
handle: "paper-icon-item",
onSort: async () => { onSort: async () => {
this._panelOrder = this._sortable.toArray(); this._panelOrder = this._sortable.toArray();
}, },
}); });
} }
private _closeEditMode() { private _deactivateEditMode() {
this._sortable?.destroy(); this._sortable?.destroy();
this._sortable = undefined; this._sortable = undefined;
this._editMode = false; }
private _closeEditMode() {
fireEvent(this, "hass-edit-sidebar", { editMode: false });
} }
private async _hidePanel(ev: Event) { private async _hidePanel(ev: Event) {
@ -692,16 +690,16 @@ class HaSidebar extends LitElement {
></ha-svg-icon>` ></ha-svg-icon>`
: html`<ha-icon slot="item-icon" .icon=${icon}></ha-icon>`} : html`<ha-icon slot="item-icon" .icon=${icon}></ha-icon>`}
<span class="item-text">${title}</span> <span class="item-text">${title}</span>
${this._editMode
? html`<mwc-icon-button
class="hide-panel"
.panel=${urlPath}
@click=${this._hidePanel}
>
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
</mwc-icon-button>`
: ""}
</paper-icon-item> </paper-icon-item>
${this.editMode
? html`<mwc-icon-button
class="hide-panel"
.panel=${urlPath}
@click=${this._hidePanel}
>
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
</mwc-icon-button>`
: ""}
</a> </a>
`; `;
} }
@ -778,6 +776,11 @@ class HaSidebar extends LitElement {
width: 100%; width: 100%;
} }
#sortable,
.hidden-panel {
display: none;
}
paper-listbox { paper-listbox {
padding: 4px 0; padding: 4px 0;
display: flex; display: flex;

View File

@ -7,12 +7,13 @@ import {
CSSResult, CSSResult,
customElement, customElement,
html, html,
internalProperty,
LitElement, LitElement,
property, property,
PropertyValues, PropertyValues,
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent, HASSDomEvent } from "../common/dom/fire_event";
import { listenMediaQuery } from "../common/dom/media_query"; import { listenMediaQuery } from "../common/dom/media_query";
import { toggleAttribute } from "../common/dom/toggle_attribute"; import { toggleAttribute } from "../common/dom/toggle_attribute";
import { showNotificationDrawer } from "../dialogs/notifications/show-notification-drawer"; import { showNotificationDrawer } from "../dialogs/notifications/show-notification-drawer";
@ -24,10 +25,17 @@ const NON_SWIPABLE_PANELS = ["map"];
declare global { declare global {
// for fire event // for fire event
interface HASSDomEvents { interface HASSDomEvents {
"hass-open-menu": undefined;
"hass-toggle-menu": undefined; "hass-toggle-menu": undefined;
"hass-edit-sidebar": EditSideBarEvent;
"hass-show-notifications": undefined; "hass-show-notifications": undefined;
} }
interface HTMLElementEventMap {
"hass-edit-sidebar": HASSDomEvent<EditSideBarEvent>;
}
}
interface EditSideBarEvent {
editMode: boolean;
} }
@customElement("home-assistant-main") @customElement("home-assistant-main")
@ -36,7 +44,9 @@ class HomeAssistantMain extends LitElement {
@property() public route?: Route; @property() public route?: Route;
@property({ type: Boolean }) private narrow?: boolean; @property({ type: Boolean }) public narrow?: boolean;
@internalProperty() private _sidebarEditMode = false;
protected render(): TemplateResult { protected render(): TemplateResult {
const hass = this.hass; const hass = this.hass;
@ -48,7 +58,9 @@ class HomeAssistantMain extends LitElement {
const sidebarNarrow = this._sidebarNarrow; const sidebarNarrow = this._sidebarNarrow;
const disableSwipe = const disableSwipe =
!sidebarNarrow || NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1; this._sidebarEditMode ||
!sidebarNarrow ||
NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
// Style block in render because of the mixin that is not supported // Style block in render because of the mixin that is not supported
return html` return html`
@ -76,6 +88,7 @@ class HomeAssistantMain extends LitElement {
<ha-sidebar <ha-sidebar
.hass=${hass} .hass=${hass}
.narrow=${sidebarNarrow} .narrow=${sidebarNarrow}
.editMode=${this._sidebarEditMode}
.alwaysExpand=${sidebarNarrow || .alwaysExpand=${sidebarNarrow ||
this.hass.dockedSidebar === "docked"} this.hass.dockedSidebar === "docked"}
></ha-sidebar> ></ha-sidebar>
@ -93,18 +106,28 @@ class HomeAssistantMain extends LitElement {
protected firstUpdated() { protected firstUpdated() {
import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar"); import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar");
this.addEventListener("hass-open-menu", () => { this.addEventListener(
if (this._sidebarNarrow) { "hass-edit-sidebar",
this.drawer.open(); (ev: HASSDomEvent<EditSideBarEvent>) => {
} else { this._sidebarEditMode = ev.detail.editMode;
fireEvent(this, "hass-dock-sidebar", {
dock: "docked", if (this._sidebarEditMode) {
}); if (this._sidebarNarrow) {
setTimeout(() => this.appLayout.resetLayout()); this.drawer.open();
} else {
fireEvent(this, "hass-dock-sidebar", {
dock: "docked",
});
setTimeout(() => this.appLayout.resetLayout());
}
}
} }
}); );
this.addEventListener("hass-toggle-menu", () => { this.addEventListener("hass-toggle-menu", () => {
if (this._sidebarEditMode) {
return;
}
if (this._sidebarNarrow) { if (this._sidebarNarrow) {
if (this.drawer.opened) { if (this.drawer.opened) {
this.drawer.close(); this.drawer.close();

View File

@ -201,7 +201,7 @@ class HaPanelProfile extends LitElement {
} }
private _customizeSidebar() { private _customizeSidebar() {
fireEvent(this, "hass-edit-sidebar"); fireEvent(this, "hass-edit-sidebar", { editMode: true });
} }
private async _refreshRefreshTokens() { private async _refreshRefreshTokens() {

View File

@ -18,8 +18,22 @@ export const sortableStyles = css`
animation-duration: 0.33s; animation-duration: 0.33s;
} }
#sortable a {
height: 48px;
display: flex;
}
#sortable { #sortable {
outline: none; outline: none;
display: block;
}
.hidden-panel {
display: flex;
}
.sortable-fallback {
display: none;
} }
.sortable-ghost { .sortable-ghost {
@ -54,13 +68,25 @@ export const sortableStyles = css`
} }
} }
.show-panel,
.hide-panel { .hide-panel {
display: none; display: none;
position: absolute; position: absolute;
top: 0;
right: 0; right: 0;
--mdc-icon-button-size: 40px;
}
.hide-panel {
top: 4px;
right: 8px;
} }
:host([expanded]) .hide-panel { :host([expanded]) .hide-panel {
display: block;
}
:host([expanded]) .show-panel {
display: inline-flex; display: inline-flex;
} }

View File

@ -16,13 +16,11 @@ declare global {
interface HASSDomEvents { interface HASSDomEvents {
"hass-dock-sidebar": DockSidebarParams; "hass-dock-sidebar": DockSidebarParams;
"hass-default-panel": DefaultPanelParams; "hass-default-panel": DefaultPanelParams;
"hass-edit-sidebar": undefined;
} }
// for add event listener // for add event listener
interface HTMLElementEventMap { interface HTMLElementEventMap {
"hass-dock-sidebar": HASSDomEvent<DockSidebarParams>; "hass-dock-sidebar": HASSDomEvent<DockSidebarParams>;
"hass-default-panel": HASSDomEvent<DefaultPanelParams>; "hass-default-panel": HASSDomEvent<DefaultPanelParams>;
"hass-edit-sidebar": undefined;
} }
} }