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

View File

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

View File

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

View File

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

View File

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