diff --git a/hassio/src/system/hassio-system.ts b/hassio/src/system/hassio-system.ts
index 1824c2be90..5db8cc409c 100644
--- a/hassio/src/system/hassio-system.ts
+++ b/hassio/src/system/hassio-system.ts
@@ -1,4 +1,3 @@
-import "@polymer/paper-menu-button/paper-menu-button";
import {
css,
CSSResult,
diff --git a/src/components/ha-button-menu.ts b/src/components/ha-button-menu.ts
index 3ba40df40c..31f9105d93 100644
--- a/src/components/ha-button-menu.ts
+++ b/src/components/ha-button-menu.ts
@@ -40,7 +40,7 @@ export class HaButtonMenu extends LitElement {
static get styles(): CSSResult {
return css`
:host {
- display: block;
+ display: inline-block;
position: relative;
}
`;
diff --git a/src/components/ha-icon-button-arrow-next.ts b/src/components/ha-icon-button-arrow-next.ts
index 269b7792a5..150f5b4b2d 100644
--- a/src/components/ha-icon-button-arrow-next.ts
+++ b/src/components/ha-icon-button-arrow-next.ts
@@ -1,17 +1,37 @@
-import { HaIconButton } from "./ha-icon-button";
+import {
+ LitElement,
+ property,
+ TemplateResult,
+ html,
+ customElement,
+} from "lit-element";
+import { mdiArrowLeft, mdiArrowRight } from "@mdi/js";
+import "@material/mwc-icon-button/mwc-icon-button";
+import "./ha-svg-icon";
+
+@customElement("ha-icon-button-arrow-next")
+export class HaIconButtonArrowNext extends LitElement {
+ @property({ type: Boolean }) public disabled = false;
+
+ @property() private _icon = mdiArrowRight;
-export class HaIconButtonArrowNext extends HaIconButton {
public connectedCallback() {
super.connectedCallback();
// wait to check for direction since otherwise direction is wrong even though top level is RTL
setTimeout(() => {
- this.icon =
+ this._icon =
window.getComputedStyle(this).direction === "ltr"
- ? "hass:arrow-right"
- : "hass:arrow-left";
+ ? mdiArrowRight
+ : mdiArrowLeft;
}, 100);
}
+
+ protected render(): TemplateResult {
+ return html`
+
+ `;
+ }
}
declare global {
@@ -19,5 +39,3 @@ declare global {
"ha-icon-button-arrow-next": HaIconButtonArrowNext;
}
}
-
-customElements.define("ha-icon-button-arrow-next", HaIconButtonArrowNext);
diff --git a/src/components/ha-icon-button-arrow-prev.ts b/src/components/ha-icon-button-arrow-prev.ts
index 59f5b7482f..06e97b290c 100644
--- a/src/components/ha-icon-button-arrow-prev.ts
+++ b/src/components/ha-icon-button-arrow-prev.ts
@@ -1,8 +1,15 @@
-import { LitElement, property, TemplateResult, html } from "lit-element";
+import {
+ LitElement,
+ property,
+ TemplateResult,
+ html,
+ customElement,
+} from "lit-element";
import { mdiArrowLeft, mdiArrowRight } from "@mdi/js";
import "@material/mwc-icon-button/mwc-icon-button";
import "./ha-svg-icon";
+@customElement("ha-icon-button-arrow-prev")
export class HaIconButtonArrowPrev extends LitElement {
@property({ type: Boolean }) public disabled = false;
@@ -32,5 +39,3 @@ declare global {
"ha-icon-button-arrow-prev": HaIconButtonArrowPrev;
}
}
-
-customElements.define("ha-icon-button-arrow-prev", HaIconButtonArrowPrev);
diff --git a/src/components/ha-icon-button-next.ts b/src/components/ha-icon-button-next.ts
index 68bfa5004c..6e37d1c764 100644
--- a/src/components/ha-icon-button-next.ts
+++ b/src/components/ha-icon-button-next.ts
@@ -1,17 +1,37 @@
-import { HaIconButton } from "./ha-icon-button";
+import {
+ LitElement,
+ property,
+ TemplateResult,
+ html,
+ customElement,
+} from "lit-element";
+import { mdiChevronRight, mdiChevronLeft } from "@mdi/js";
+import "@material/mwc-icon-button";
+import "./ha-svg-icon";
+
+@customElement("ha-icon-button-next")
+export class HaIconButtonNext extends LitElement {
+ @property({ type: Boolean }) public disabled = false;
+
+ @property() private _icon = mdiChevronRight;
-export class HaIconButtonNext extends HaIconButton {
public connectedCallback() {
super.connectedCallback();
// wait to check for direction since otherwise direction is wrong even though top level is RTL
setTimeout(() => {
- this.icon =
+ this._icon =
window.getComputedStyle(this).direction === "ltr"
- ? "hass:chevron-right"
- : "hass:chevron-left";
+ ? mdiChevronRight
+ : mdiChevronLeft;
}, 100);
}
+
+ protected render(): TemplateResult {
+ return html`
+
+ `;
+ }
}
declare global {
@@ -19,5 +39,3 @@ declare global {
"ha-icon-button-next": HaIconButtonNext;
}
}
-
-customElements.define("ha-icon-button-next", HaIconButtonNext);
diff --git a/src/components/ha-icon-button-prev.ts b/src/components/ha-icon-button-prev.ts
index 675719fc6e..7548004c02 100644
--- a/src/components/ha-icon-button-prev.ts
+++ b/src/components/ha-icon-button-prev.ts
@@ -1,17 +1,37 @@
-import { HaIconButton } from "./ha-icon-button";
+import {
+ LitElement,
+ property,
+ TemplateResult,
+ html,
+ customElement,
+} from "lit-element";
+import { mdiChevronRight, mdiChevronLeft } from "@mdi/js";
+import "@material/mwc-icon-button/mwc-icon-button";
+import "./ha-svg-icon";
+
+@customElement("ha-icon-button-prev")
+export class HaIconButtonPrev extends LitElement {
+ @property({ type: Boolean }) public disabled = false;
+
+ @property() private _icon = mdiChevronLeft;
-export class HaIconButtonPrev extends HaIconButton {
public connectedCallback() {
super.connectedCallback();
// wait to check for direction since otherwise direction is wrong even though top level is RTL
setTimeout(() => {
- this.icon =
+ this._icon =
window.getComputedStyle(this).direction === "ltr"
- ? "hass:chevron-left"
- : "hass:chevron-right";
+ ? mdiChevronLeft
+ : mdiChevronRight;
}, 100);
}
+
+ protected render(): TemplateResult {
+ return html`
+
+ `;
+ }
}
declare global {
@@ -19,5 +39,3 @@ declare global {
"ha-icon-button-prev": HaIconButtonPrev;
}
}
-
-customElements.define("ha-icon-button-prev", HaIconButtonPrev);
diff --git a/src/components/ha-menu-button.ts b/src/components/ha-menu-button.ts
index 4f65237636..985678b03b 100644
--- a/src/components/ha-menu-button.ts
+++ b/src/components/ha-menu-button.ts
@@ -1,3 +1,5 @@
+import "@material/mwc-icon-button";
+import { mdiMenu } from "@mdi/js";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import {
css,
@@ -12,8 +14,7 @@ import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain";
import { subscribeNotifications } from "../data/persistent_notification";
import { HomeAssistant } from "../types";
-import "./ha-icon-button";
-import { mdiMenu } from "@mdi/js";
+import "./ha-svg-icon";
@customElement("ha-menu-button")
class HaMenuButton extends LitElement {
diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts
index 5ceb4950f9..70c2806800 100644
--- a/src/components/ha-sidebar.ts
+++ b/src/components/ha-sidebar.ts
@@ -1,6 +1,12 @@
-import { mdiBell, mdiCellphoneSettingsVariant } from "@mdi/js";
+import "@material/mwc-icon-button";
+import {
+ mdiBell,
+ mdiCellphoneSettingsVariant,
+ mdiMenuOpen,
+ mdiMenu,
+ mdiViewDashboard,
+} from "@mdi/js";
import "@polymer/app-layout/app-toolbar/app-toolbar";
-import "./ha-icon-button";
import "@polymer/paper-item/paper-icon-item";
import type { PaperIconItemElement } from "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-item/paper-item";
@@ -29,9 +35,9 @@ import {
getExternalConfig,
} from "../external_app/external_config";
import type { HomeAssistant, PanelInfo } from "../types";
-import "./ha-svg-icon";
import "./ha-icon";
import "./ha-menu-button";
+import "./ha-svg-icon";
import "./user/ha-user-badge";
const SHOW_AFTER_SPACER = ["config", "developer-tools", "hassio"];
@@ -153,13 +159,16 @@ class HaSidebar extends LitElement {
-
-
+
+
+
+
+ ${this.hass.localize(
+ "ui.panel.config.integrations.config_entry.system_options"
)}
- >
-
-
- ${this.hass.localize(
- "ui.panel.config.integrations.config_entry.system_options"
- )}
-
- ${this.hass.localize(
- "ui.panel.config.integrations.config_entry.delete"
- )}
-
-
+
+
+ ${this.hass.localize(
+ "ui.panel.config.integrations.config_entry.delete"
+ )}
+
+
`;
@@ -379,9 +373,8 @@ export class HaIntegrationCard extends LitElement {
margin-top: 0;
min-height: 24px;
}
- paper-menu-button {
+ ha-button-menu {
color: var(--secondary-text-color);
- padding: 0;
}
@media (min-width: 563px) {
paper-listbox {
diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts
index e199c1b141..1d87c26803 100644
--- a/src/panels/lovelace/components/hui-card-options.ts
+++ b/src/panels/lovelace/components/hui-card-options.ts
@@ -1,7 +1,7 @@
import "@material/mwc-button";
-import "../../../components/ha-icon-button";
-import "@polymer/paper-listbox/paper-listbox";
-import "@polymer/paper-menu-button/paper-menu-button";
+import "@material/mwc-list/mwc-list-item";
+import "@material/mwc-icon-button";
+import "../../../components/ha-button-menu";
import {
css,
CSSResult,
@@ -19,6 +19,7 @@ import { swapCard } from "../editor/config-util";
import { confDeleteCard } from "../editor/delete-card";
import { Lovelace, LovelaceCard } from "../types";
import { computeCardSize } from "../common/compute-card-size";
+import { mdiDotsVertical, mdiArrowDown, mdiArrowUp } from "@mdi/js";
@customElement("hui-card-options")
export class HuiCardOptions extends LitElement {
@@ -47,53 +48,52 @@ export class HuiCardOptions extends LitElement {
>
-
-
+
+
+
-
-
+
+
-
-
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_card.move"
- )}
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_card.duplicate"
- )}
-
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.edit_card.delete"
- )}
-
-
+ title="${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_card.options"
+ )}"
+ >
+
+
+
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_card.move"
+ )}
+
${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_card.duplicate"
+ )}
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.edit_card.delete"
+ )}
+
@@ -103,7 +103,6 @@ export class HuiCardOptions extends LitElement {
static get styles(): CSSResult {
return css`
:host(:hover) {
- overflow: hidden;
outline: 2px solid var(--primary-color);
}
@@ -132,23 +131,14 @@ export class HuiCardOptions extends LitElement {
text-align: right;
}
- ha-icon-button {
+ mwc-icon-button {
color: var(--primary-text-color);
}
- ha-icon-button.move-arrow[disabled] {
+ mwc-icon-button.move-arrow[disabled] {
color: var(--disabled-text-color);
}
- paper-menu-button {
- color: var(--secondary-text-color);
- padding: 0;
- }
-
- paper-listbox {
- padding: 0;
- }
-
paper-item.header {
color: var(--primary-text-color);
text-transform: uppercase;
diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts
index 289100b08c..95843c2642 100644
--- a/src/panels/lovelace/hui-root.ts
+++ b/src/panels/lovelace/hui-root.ts
@@ -1,12 +1,17 @@
import "@material/mwc-button";
+import "@material/mwc-list/mwc-list-item";
+import {
+ mdiDotsVertical,
+ mdiMicrophone,
+ mdiPlus,
+ mdiClose,
+ mdiPencil,
+ mdiHelpCircle,
+} from "@mdi/js";
import "@polymer/app-layout/app-header-layout/app-header-layout";
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-scroll-effects/effects/waterfall";
import "@polymer/app-layout/app-toolbar/app-toolbar";
-import "../../components/ha-icon-button";
-import "@polymer/paper-item/paper-item";
-import "@polymer/paper-listbox/paper-listbox";
-import "@polymer/paper-menu-button/paper-menu-button";
import "@polymer/paper-tabs/paper-tab";
import "@polymer/paper-tabs/paper-tabs";
import {
@@ -27,10 +32,12 @@ import { navigate } from "../../common/navigate";
import { computeRTLDirection } from "../../common/util/compute_rtl";
import { debounce } from "../../common/util/debounce";
import { afterNextRender } from "../../common/util/render-status";
+import "../../components/ha-button-menu";
import "../../components/ha-icon";
-import "../../components/ha-menu-button";
+import "../../components/ha-svg-icon";
import "../../components/ha-icon-button-arrow-next";
import "../../components/ha-icon-button-arrow-prev";
+import "../../components/ha-menu-button";
import type {
LovelaceConfig,
LovelacePanelConfig,
@@ -99,78 +106,73 @@ class HUIRoot extends LitElement {
${this._editMode
? html`
-
+ >
+
+
${this.config.title ||
this.hass!.localize("ui.panel.lovelace.editor.header")}
-
+ >
+
+
-
-
-
+
-
- ${__DEMO__ /* No unused entities available in the demo */
- ? ""
- : html`
-
- ${this.hass!.localize(
- "ui.panel.lovelace.unused_entities.title"
- )}
-
- `}
-
- ${this.hass!.localize(
- "ui.panel.lovelace.editor.menu.raw_editor"
- )}
-
-
-
+
+
+ ${__DEMO__ /* No unused entities available in the demo */
+ ? ""
+ : html`
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.unused_entities.title"
+ )}
+
+ `}
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.editor.menu.raw_editor"
+ )}
+
+
`
: html`
@@ -182,96 +184,88 @@ class HUIRoot extends LitElement {
${this.config.title || "Home Assistant"}
${this._conversation(this.hass.config.components)
? html`
-
+ >
+
+
`
: ""}
-
-
+
-
- ${this._yamlMode
- ? html`
-
- ${this.hass!.localize(
- "ui.panel.lovelace.menu.refresh"
- )}
-
-
- ${this.hass!.localize(
- "ui.panel.lovelace.unused_entities.title"
- )}
-
- `
- : ""}
- ${(this.hass.panels.lovelace
- ?.config as LovelacePanelConfig)?.mode === "yaml"
- ? html`
-
- ${this.hass!.localize(
- "ui.panel.lovelace.menu.reload_resources"
- )}
-
- `
- : ""}
- ${this.hass!.user!.is_admin &&
- !this.hass!.config.safe_mode
- ? html`
-
- ${this.hass!.localize(
- "ui.panel.lovelace.menu.configure_ui"
- )}
-
- `
- : ""}
-
- ${this.hass!.localize("ui.panel.lovelace.menu.help")}
-
-
-
+
+
+ ${this._yamlMode
+ ? html`
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.menu.refresh"
+ )}
+
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.unused_entities.title"
+ )}
+
+ `
+ : ""}
+ ${(this.hass.panels.lovelace?.config as LovelacePanelConfig)
+ ?.mode === "yaml"
+ ? html`
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.menu.reload_resources"
+ )}
+
+ `
+ : ""}
+ ${this.hass!.user!.is_admin && !this.hass!.config.safe_mode
+ ? html`
+
+ ${this.hass!.localize(
+ "ui.panel.lovelace.menu.configure_ui"
+ )}
+
+ `
+ : ""}
+
+ ${this.hass!.localize("ui.panel.lovelace.menu.help")}
+
+
`}
${this.lovelace!.config.views.length > 1 || this._editMode
@@ -321,14 +315,14 @@ class HUIRoot extends LitElement {
: view.title || "Unnamed view"}
${this._editMode
? html`
-
+ >
+ >
+
+
`
: ""}
@@ -500,10 +495,6 @@ class HUIRoot extends LitElement {
navigate(this, `${this.route?.prefix}/hass-unused-entities`);
}
- private _deselect(ev): void {
- ev.target.selected = null;
- }
-
private _showVoiceCommandDialog(): void {
showVoiceCommandDialog(this);
}
@@ -671,9 +662,6 @@ class HUIRoot extends LitElement {
ha-app-layout {
min-height: 100%;
}
- paper-menu-button {
- padding: 0;
- }
paper-tabs {
margin-left: 12px;
--paper-tabs-selection-bar-color: var(--text-primary-color, #fff);
@@ -702,10 +690,9 @@ class HUIRoot extends LitElement {
position: absolute;
height: 44px;
}
- #add-view ha-icon {
+ #add-view ha-svg-icon {
background-color: var(--accent-color);
- border-radius: 5px;
- margin-top: 4px;
+ border-radius: 4px;
}
app-toolbar a {
color: var(--text-primary-color, white);
@@ -740,9 +727,6 @@ class HUIRoot extends LitElement {
#view.tabs-hidden {
min-height: calc(100vh - 64px);
}
- paper-item {
- cursor: pointer;
- }
.hide-tab {
display: none;
}
diff --git a/src/panels/lovelace/views/hui-view.ts b/src/panels/lovelace/views/hui-view.ts
index 0ff04793ab..ed5a68cc43 100644
--- a/src/panels/lovelace/views/hui-view.ts
+++ b/src/panels/lovelace/views/hui-view.ts
@@ -372,8 +372,6 @@ export class HUIView extends LitElement {
flex: 1 0 0;
max-width: 500px;
min-width: 0;
- /* on iOS devices the column can become wider when toggling a switch */
- overflow-x: hidden;
}
.column > * {
diff --git a/src/panels/shopping-list/ha-panel-shopping-list.js b/src/panels/shopping-list/ha-panel-shopping-list.js
index db11be6cc0..0f9e591367 100644
--- a/src/panels/shopping-list/ha-panel-shopping-list.js
+++ b/src/panels/shopping-list/ha-panel-shopping-list.js
@@ -8,7 +8,8 @@ import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
import "@polymer/paper-listbox/paper-listbox";
-import "@polymer/paper-menu-button/paper-menu-button";
+import "@material/mwc-list/mwc-list-item";
+import "../../components/ha-button-menu";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
@@ -18,6 +19,7 @@ import "../../components/ha-menu-button";
import { showVoiceCommandDialog } from "../../dialogs/voice-command-dialog/show-ha-voice-command-dialog";
import LocalizeMixin from "../../mixins/localize-mixin";
import "../../styles/polymer-ha-style";
+import { mdiDotsVertical } from "@mdi/js";
/*
* @appliesMixin LocalizeMixin
@@ -81,22 +83,17 @@ class HaPanelShoppingList extends LocalizeMixin(PolymerElement) {
icon="hass:microphone"
on-click="_showVoiceCommandDialog"
>
-
-
+
-
- [[localize('ui.panel.shopping-list.clear_completed')]]
-
-
+ label="Menu"
+ slot="trigger"
+ >
+
+
+ [[localize('ui.panel.shopping-list.clear_completed')]]
+
+
diff --git a/src/translations/en.json b/src/translations/en.json
index 2bb5d2bade..57e177903d 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -243,6 +243,8 @@
"save": "Save",
"yes": "Yes",
"no": "No",
+ "menu": "Menu",
+ "overflow_menu": "Overflow menu",
"successfully_saved": "Successfully saved",
"successfully_deleted": "Successfully deleted",
"back": "Back",
@@ -765,6 +767,8 @@
"save": "Save",
"unsaved_confirm": "You have unsaved changes. Are you sure you want to leave?",
"alias": "Name",
+ "move_up": "Move up",
+ "move_down": "Move down",
"description": {
"label": "Description",
"placeholder": "Optional description"