mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-29 20:26:39 +00:00
Sidebar tweaks (#6994)
This commit is contained in:
parent
3030b8d476
commit
de95c92e2d
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user