1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00

Migrate button-menu to ha-dropdown in 9 files (#29089)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Wendelin
2026-01-20 15:20:29 +01:00
committed by GitHub
parent 1654a67d30
commit 681b60614f
9 changed files with 223 additions and 206 deletions

View File

@@ -6,9 +6,12 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { debounce } from "../../../../common/util/debounce"; import { debounce } from "../../../../common/util/debounce";
import "../../../../components/ha-alert"; import "../../../../components/ha-alert";
import "../../../../components/ha-button"; import "../../../../components/ha-button";
import "../../../../components/ha-button-menu";
import "../../../../components/ha-card"; import "../../../../components/ha-card";
import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../../components/ha-dropdown-item";
import "../../../../components/ha-list-item"; import "../../../../components/ha-list-item";
import "../../../../components/ha-svg-icon";
import "../../../../components/ha-tip"; import "../../../../components/ha-tip";
import type { import type {
CloudStatusLoggedIn, CloudStatusLoggedIn,
@@ -53,26 +56,26 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
.narrow=${this.narrow} .narrow=${this.narrow}
header="Home Assistant Cloud" header="Home Assistant Cloud"
> >
<ha-button-menu slot="toolbar-icon" @action=${this._handleMenuAction}> <ha-dropdown slot="toolbar-icon" @wa-select=${this._handleMenuAction}>
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass.localize("ui.common.menu")} .label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
<ha-list-item graphic="icon"> <ha-dropdown-item value="reset">
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.cloud.account.reset_cloud_data" "ui.panel.config.cloud.account.reset_cloud_data"
)} )}
<ha-svg-icon slot="graphic" .path=${mdiDeleteForever}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiDeleteForever}></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
<ha-list-item graphic="icon"> <ha-dropdown-item value="download">
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.cloud.account.download_support_package" "ui.panel.config.cloud.account.download_support_package"
)} )}
<ha-svg-icon slot="graphic" .path=${mdiDownload}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiDownload}></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
</ha-button-menu> </ha-dropdown>
<div class="content"> <div class="content">
<ha-config-section .isWide=${this.isWide}> <ha-config-section .isWide=${this.isWide}>
<span slot="header">Home Assistant Cloud</span> <span slot="header">Home Assistant Cloud</span>
@@ -297,13 +300,15 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
fireEvent(this, "ha-refresh-cloud-status"); fireEvent(this, "ha-refresh-cloud-status");
} }
private _handleMenuAction(ev) { private _handleMenuAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
switch (ev.detail.index) { const value = ev.detail.item.value;
case 0: switch (value) {
case "reset":
this._deleteCloudData(); this._deleteCloudData();
break; break;
case 1: case "download":
this._downloadSupportPackage(); this._downloadSupportPackage();
break;
} }
} }

View File

@@ -5,11 +5,14 @@ import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { navigate } from "../../../../common/navigate"; import { navigate } from "../../../../common/navigate";
import "../../../../components/ha-alert"; import "../../../../components/ha-alert";
import "../../../../components/ha-button-menu";
import "../../../../components/ha-card"; import "../../../../components/ha-card";
import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../../components/ha-dropdown-item";
import "../../../../components/ha-icon-next"; import "../../../../components/ha-icon-next";
import "../../../../components/ha-list"; import "../../../../components/ha-list";
import "../../../../components/ha-list-item"; import "../../../../components/ha-list-item";
import "../../../../components/ha-svg-icon";
import { removeCloudData } from "../../../../data/cloud"; import { removeCloudData } from "../../../../data/cloud";
import { import {
showAlertDialog, showAlertDialog,
@@ -44,26 +47,26 @@ export class CloudLoginPanel extends LitElement {
.narrow=${this.narrow} .narrow=${this.narrow}
header="Home Assistant Cloud" header="Home Assistant Cloud"
> >
<ha-button-menu slot="toolbar-icon" @action=${this._handleMenuAction}> <ha-dropdown slot="toolbar-icon" @wa-select=${this._handleMenuAction}>
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass.localize("ui.common.menu")} .label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
<ha-list-item graphic="icon"> <ha-dropdown-item value="reset">
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.cloud.account.reset_cloud_data" "ui.panel.config.cloud.account.reset_cloud_data"
)} )}
<ha-svg-icon slot="graphic" .path=${mdiDeleteForever}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiDeleteForever}></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
<ha-list-item graphic="icon"> <ha-dropdown-item value="download">
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.cloud.account.download_support_package" "ui.panel.config.cloud.account.download_support_package"
)} )}
<ha-svg-icon slot="graphic" .path=${mdiDownload}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiDownload}></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
</ha-button-menu> </ha-dropdown>
<div class="content"> <div class="content">
<ha-config-section .isWide=${this.isWide}> <ha-config-section .isWide=${this.isWide}>
<span slot="header">Home Assistant Cloud</span> <span slot="header">Home Assistant Cloud</span>
@@ -164,13 +167,15 @@ export class CloudLoginPanel extends LitElement {
fireEvent(this, "flash-message-changed", { value: "" }); fireEvent(this, "flash-message-changed", { value: "" });
} }
private _handleMenuAction(ev) { private _handleMenuAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
switch (ev.detail.index) { const value = ev.detail.item.value;
case 0: switch (value) {
case "reset":
this._deleteCloudData(); this._deleteCloudData();
break; break;
case 1: case "download":
this._downloadSupportPackage(); this._downloadSupportPackage();
break;
} }
} }

View File

@@ -14,7 +14,6 @@ import { navigate } from "../../../common/navigate";
import { blankBeforePercent } from "../../../common/translations/blank_before_percent"; import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
import "../../../components/ha-alert"; import "../../../components/ha-alert";
import "../../../components/ha-button"; import "../../../components/ha-button";
import "../../../components/ha-button-menu";
import "../../../components/ha-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-icon-next"; import "../../../components/ha-icon-next";
import "../../../components/ha-list"; import "../../../components/ha-list";

View File

@@ -1,3 +1,4 @@
import "@home-assistant/webawesome/dist/components/divider/divider";
import { import {
mdiBug, mdiBug,
mdiCommentProcessingOutline, mdiCommentProcessingOutline,
@@ -18,14 +19,17 @@ import { formatLanguageCode } from "../../../common/language/format_language";
import { navigate } from "../../../common/navigate"; import { navigate } from "../../../common/navigate";
import "../../../components/ha-alert"; import "../../../components/ha-alert";
import "../../../components/ha-button"; import "../../../components/ha-button";
import "../../../components/ha-button-menu";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import "../../../components/ha-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-list"; import "../../../components/ha-list";
import "../../../components/ha-list-item"; import "../../../components/ha-list-item";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import "../../../components/ha-switch"; import "../../../components/ha-switch";
import type { HaSwitch } from "../../../components/ha-switch"; import type { HaSwitch } from "../../../components/ha-switch";
import "../../../components/voice-assistant-brand-icon";
import type { AssistPipeline } from "../../../data/assist_pipeline"; import type { AssistPipeline } from "../../../data/assist_pipeline";
import { import {
createAssistPipeline, createAssistPipeline,
@@ -48,7 +52,6 @@ import { showVoiceCommandDialog } from "../../../dialogs/voice-command-dialog/sh
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { documentationUrl } from "../../../util/documentation-url"; import { documentationUrl } from "../../../util/documentation-url";
import { showVoiceAssistantPipelineDetailDialog } from "./show-dialog-voice-assistant-pipeline-detail"; import { showVoiceAssistantPipelineDetailDialog } from "./show-dialog-voice-assistant-pipeline-detail";
import "../../../components/voice-assistant-brand-icon";
@customElement("assist-pref") @customElement("assist-pref")
export class AssistPref extends LitElement { export class AssistPref extends LitElement {
@@ -144,7 +147,12 @@ export class AssistPref extends LitElement {
<span slot="secondary"> <span slot="secondary">
${formatLanguageCode(pipeline.language, this.hass.locale)} ${formatLanguageCode(pipeline.language, this.hass.locale)}
</span> </span>
<ha-button-menu fixed slot="meta" @click=${stopPropagation}> <ha-dropdown
slot="meta"
placement="bottom-end"
@click=${stopPropagation}
@wa-select=${this._handlePipelineMenuAction}
>
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass!.localize( .label=${this.hass!.localize(
@@ -152,64 +160,48 @@ export class AssistPref extends LitElement {
)} )}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
<ha-list-item <ha-dropdown-item value="talk" .data=${pipeline.id}>
graphic="icon"
.id=${pipeline.id}
@request-selected=${this._talkWithPipeline}
>
${this.hass!.localize( ${this.hass!.localize(
"ui.panel.config.voice_assistants.assistants.pipeline.start_conversation" "ui.panel.config.voice_assistants.assistants.pipeline.start_conversation"
)} )}
<ha-svg-icon <ha-svg-icon
slot="graphic" slot="icon"
.path=${mdiCommentProcessingOutline} .path=${mdiCommentProcessingOutline}
></ha-svg-icon> ></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
<ha-list-item <ha-dropdown-item
graphic="icon" value="set-preferred"
.data=${pipeline.id}
.disabled=${this._preferred === pipeline.id} .disabled=${this._preferred === pipeline.id}
.id=${pipeline.id}
@request-selected=${this._setPreferredPipeline}
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.voice_assistants.assistants.pipeline.detail.set_as_preferred" "ui.panel.config.voice_assistants.assistants.pipeline.detail.set_as_preferred"
)} )}
<ha-svg-icon slot="graphic" .path=${mdiStar}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiStar}></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
<ha-list-item <ha-dropdown-item value="debug" .data=${pipeline.id}>
graphic="icon"
.id=${pipeline.id}
@request-selected=${this._debugPipeline}
>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.voice_assistants.assistants.pipeline.detail.debug" "ui.panel.config.voice_assistants.assistants.pipeline.detail.debug"
)} )}
<ha-svg-icon slot="graphic" .path=${mdiBug}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiBug}></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
<ha-list-item <ha-dropdown-item value="duplicate" .data=${pipeline.id}>
graphic="icon"
.id=${pipeline.id}
@request-selected=${this._duplicatePipeline}
>
${this.hass.localize("ui.common.duplicate")} ${this.hass.localize("ui.common.duplicate")}
<ha-svg-icon <ha-svg-icon
slot="graphic" slot="icon"
.path=${mdiContentDuplicate} .path=${mdiContentDuplicate}
></ha-svg-icon> ></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
<ha-list-item <wa-divider></wa-divider>
class="danger" <ha-dropdown-item
graphic="icon" variant="danger"
.id=${pipeline.id} value="delete"
@request-selected=${this._deletePipeline} .data=${pipeline.id}
> >
${this.hass.localize("ui.common.delete")} ${this.hass.localize("ui.common.delete")}
<ha-svg-icon <ha-svg-icon slot="icon" .path=${mdiTrashCan}></ha-svg-icon>
slot="graphic" </ha-dropdown-item>
.path=${mdiTrashCan} </ha-dropdown>
></ha-svg-icon>
</ha-list-item>
</ha-button-menu>
</ha-list-item> </ha-list-item>
` `
)} )}
@@ -286,24 +278,42 @@ export class AssistPref extends LitElement {
} }
} }
private _talkWithPipeline(ev) { private _handlePipelineMenuAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
const id = ev.currentTarget.id as string; const value = ev.detail.item.value;
const id = (ev.detail.item as any).data as string;
switch (value) {
case "talk":
this._talkWithPipeline(id);
break;
case "set-preferred":
this._setPreferredPipeline(id);
break;
case "debug":
this._debugPipeline(id);
break;
case "duplicate":
this._duplicatePipeline(id);
break;
case "delete":
this._deletePipeline(id);
break;
}
}
private _talkWithPipeline(id: string) {
showVoiceCommandDialog(this, this.hass, { pipeline_id: id }); showVoiceCommandDialog(this, this.hass, { pipeline_id: id });
} }
private async _setPreferredPipeline(ev) { private async _setPreferredPipeline(id: string) {
const id = ev.currentTarget.id as string;
await setAssistPipelinePreferred(this.hass!, id); await setAssistPipelinePreferred(this.hass!, id);
this._preferred = id; this._preferred = id;
} }
private async _debugPipeline(ev) { private async _debugPipeline(id: string) {
const id = ev.currentTarget.id as string;
navigate(`/config/voice-assistants/debug/${id}`); navigate(`/config/voice-assistants/debug/${id}`);
} }
private async _duplicatePipeline(ev: Event) { private async _duplicatePipeline(id: string) {
const id = (ev.currentTarget as HTMLElement).id as string;
const pipeline = this._pipelines.find((res) => res.id === id); const pipeline = this._pipelines.find((res) => res.id === id);
if (!pipeline) { if (!pipeline) {
showAlertDialog(this, { showAlertDialog(this, {
@@ -326,8 +336,7 @@ export class AssistPref extends LitElement {
this._openDialog(newPipeline); this._openDialog(newPipeline);
} }
private async _deletePipeline(ev) { private async _deletePipeline(id: string) {
const id = ev.currentTarget.id as string;
if (this._preferred === id) { if (this._preferred === id) {
showAlertDialog(this, { showAlertDialog(this, {
text: this.hass!.localize( text: this.hass!.localize(
@@ -426,16 +435,11 @@ export class AssistPref extends LitElement {
--mdc-list-side-padding-left: 16px; --mdc-list-side-padding-left: 16px;
} }
ha-list-item.danger {
color: var(--error-color);
border-top: 1px solid var(--divider-color);
}
ha-button-menu a { ha-button-menu a {
text-decoration: none; text-decoration: none;
} }
ha-svg-icon { ha-list-item span ha-svg-icon {
color: currentColor; color: currentColor;
width: 16px; width: 16px;
} }
@@ -460,6 +464,12 @@ export class AssistPref extends LitElement {
margin-inline-end: 16px; margin-inline-end: 16px;
margin-inline-start: initial; margin-inline-start: initial;
} }
ha-dropdown {
font-size: var(--ha-font-size-m);
font-family: var(--ha-font-family-body);
letter-spacing: normal;
}
`; `;
} }

View File

@@ -1,4 +1,4 @@
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@home-assistant/webawesome/dist/components/divider/divider";
import { import {
mdiContentCopy, mdiContentCopy,
mdiContentCut, mdiContentCut,
@@ -14,9 +14,10 @@ import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { storage } from "../../../common/decorators/storage"; import { storage } from "../../../common/decorators/storage";
import { fireEvent } from "../../../common/dom/fire_event"; import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-button-menu"; import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import "../../../components/ha-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-list-item";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import { ensureBadgeConfig } from "../../../data/lovelace/config/badge"; import { ensureBadgeConfig } from "../../../data/lovelace/config/badge";
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
@@ -120,48 +121,46 @@ export class HuiBadgeEditMode extends LitElement {
<div class="edit-overlay"></div> <div class="edit-overlay"></div>
<ha-svg-icon class="edit" .path=${mdiPencil}> </ha-svg-icon> <ha-svg-icon class="edit" .path=${mdiPencil}> </ha-svg-icon>
</div> </div>
<ha-button-menu <ha-dropdown
class="more" class="more"
corner="BOTTOM_END" placement="bottom-end"
menu-corner="END" @wa-select=${this._handleAction}
.path=${[this.path!]}
@action=${this._handleAction}
@opened=${this._handleOpened} @opened=${this._handleOpened}
@closed=${this._handleClosed} @closed=${this._handleClosed}
> >
<ha-icon-button slot="trigger" .path=${mdiDotsVertical}> <ha-icon-button slot="trigger" .path=${mdiDotsVertical}>
</ha-icon-button> </ha-icon-button>
<ha-list-item graphic="icon"> <ha-dropdown-item value="edit">
<ha-svg-icon slot="graphic" .path=${mdiPencil}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiPencil}></ha-svg-icon>
${this.hass.localize("ui.panel.lovelace.editor.edit_card.edit")} ${this.hass.localize("ui.panel.lovelace.editor.edit_card.edit")}
</ha-list-item> </ha-dropdown-item>
<ha-list-item graphic="icon"> <ha-dropdown-item value="duplicate">
<ha-svg-icon <ha-svg-icon
slot="graphic" slot="icon"
.path=${mdiPlusCircleMultipleOutline} .path=${mdiPlusCircleMultipleOutline}
></ha-svg-icon> ></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.lovelace.editor.edit_card.duplicate" "ui.panel.lovelace.editor.edit_card.duplicate"
)} )}
</ha-list-item> </ha-dropdown-item>
<ha-list-item graphic="icon"> <ha-dropdown-item value="copy">
<ha-svg-icon slot="graphic" .path=${mdiContentCopy}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiContentCopy}></ha-svg-icon>
${this.hass.localize("ui.panel.lovelace.editor.edit_card.copy")} ${this.hass.localize("ui.panel.lovelace.editor.edit_card.copy")}
</ha-list-item> </ha-dropdown-item>
<ha-list-item graphic="icon"> <ha-dropdown-item value="cut">
<ha-svg-icon slot="graphic" .path=${mdiContentCut}></ha-svg-icon> <ha-svg-icon slot="icon" .path=${mdiContentCut}></ha-svg-icon>
${this.hass.localize("ui.panel.lovelace.editor.edit_card.cut")} ${this.hass.localize("ui.panel.lovelace.editor.edit_card.cut")}
</ha-list-item> </ha-dropdown-item>
<li divider role="separator"></li> <wa-divider></wa-divider>
<ha-list-item graphic="icon" class="warning"> <ha-dropdown-item value="delete" class="warning">
${this.hass.localize("ui.panel.lovelace.editor.edit_card.delete")} ${this.hass.localize("ui.panel.lovelace.editor.edit_card.delete")}
<ha-svg-icon <ha-svg-icon
class="warning" class="warning"
slot="graphic" slot="icon"
.path=${mdiDelete} .path=${mdiDelete}
></ha-svg-icon> ></ha-svg-icon>
</ha-list-item> </ha-dropdown-item>
</ha-button-menu> </ha-dropdown>
</div> </div>
`; `;
} }
@@ -186,21 +185,22 @@ export class HuiBadgeEditMode extends LitElement {
this._editBadge(); this._editBadge();
} }
private _handleAction(ev: CustomEvent<ActionDetail>) { private _handleAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
switch (ev.detail.index) { const value = ev.detail.item.value;
case 0: switch (value) {
case "edit":
this._editBadge(); this._editBadge();
break; break;
case 1: case "duplicate":
this._duplicateBadge(); this._duplicateBadge();
break; break;
case 2: case "copy":
this._copyBadge(); this._copyBadge();
break; break;
case 3: case "cut":
this._cutBadge(); this._cutBadge();
break; break;
case 4: case "delete":
this._deleteBadge(); this._deleteBadge();
break; break;
} }
@@ -297,7 +297,7 @@ export class HuiBadgeEditMode extends LitElement {
background: var(--secondary-background-color); background: var(--secondary-background-color);
--mdc-icon-size: 16px; --mdc-icon-size: 16px;
} }
.more { .more ha-icon-button {
position: absolute; position: absolute;
right: -8px; right: -8px;
top: -8px; top: -8px;

View File

@@ -1,5 +1,4 @@
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item"; import { mdiCheck, mdiDotsVertical } from "@mdi/js";
import { mdiDotsVertical } from "@mdi/js";
import { import {
differenceInDays, differenceInDays,
differenceInMonths, differenceInMonths,
@@ -16,14 +15,16 @@ import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { PropertyValues } from "lit"; import type { PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit"; import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one";
import { import {
calcDate, calcDate,
calcDateProperty,
calcDateDifferenceProperty, calcDateDifferenceProperty,
calcDateProperty,
shiftDateRange, shiftDateRange,
} from "../../../common/datetime/calc_date"; } from "../../../common/datetime/calc_date";
import type { DateRange } from "../../../common/datetime/calc_date_range";
import { calcDateRange } from "../../../common/datetime/calc_date_range";
import { firstWeekdayIndex } from "../../../common/datetime/first_weekday"; import { firstWeekdayIndex } from "../../../common/datetime/first_weekday";
import { import {
formatDate, formatDate,
@@ -33,19 +34,19 @@ import {
formatDateYear, formatDateYear,
} from "../../../common/datetime/format_date"; } from "../../../common/datetime/format_date";
import { debounce } from "../../../common/util/debounce"; import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-button-menu";
import "../../../components/ha-button"; import "../../../components/ha-button";
import "../../../components/ha-check-list-item";
import "../../../components/ha-date-range-picker"; import "../../../components/ha-date-range-picker";
import type { DateRangePickerRanges } from "../../../components/ha-date-range-picker"; import type { DateRangePickerRanges } from "../../../components/ha-date-range-picker";
import "../../../components/ha-dropdown";
import "../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
import "../../../components/ha-icon-button-next"; import "../../../components/ha-icon-button-next";
import "../../../components/ha-icon-button-prev"; import "../../../components/ha-icon-button-prev";
import "../../../components/ha-svg-icon";
import type { EnergyData } from "../../../data/energy"; import type { EnergyData } from "../../../data/energy";
import { CompareMode, getEnergyDataCollection } from "../../../data/energy"; import { CompareMode, getEnergyDataCollection } from "../../../data/energy";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { calcDateRange } from "../../../common/datetime/calc_date_range";
import type { DateRange } from "../../../common/datetime/calc_date_range";
const RANGE_KEYS: DateRange[] = [ const RANGE_KEYS: DateRange[] = [
"today", "today",
@@ -233,25 +234,30 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
</ha-button>` </ha-button>`
: nothing} : nothing}
<ha-button-menu> <ha-dropdown
placement="bottom-end"
@wa-select=${this._handleMenuAction}
>
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass.localize("ui.common.menu")} .label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
${this.allowCompare ${this.allowCompare
? html`<ha-check-list-item ? html`<ha-dropdown-item value="toggle-compare">
left ${this._compare
@request-selected=${this._toggleCompare} ? html`<ha-svg-icon
.selected=${this._compare} slot="icon"
> .path=${mdiCheck}
></ha-svg-icon>`
: nothing}
${this.hass.localize( ${this.hass.localize(
"ui.panel.lovelace.components.energy_period_selector.compare" "ui.panel.lovelace.components.energy_period_selector.compare"
)} )}
</ha-check-list-item>` </ha-dropdown-item>`
: nothing} : nothing}
<slot name="overflow-menu"></slot> <slot name="overflow-menu"></slot>
</ha-button-menu> </ha-dropdown>
</div> </div>
`; `;
} }
@@ -464,11 +470,15 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
this._datepickerOpen = ev.detail.open; this._datepickerOpen = ev.detail.open;
} }
private _toggleCompare(ev: CustomEvent<RequestSelectedDetail>) { private _handleMenuAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
if (ev.detail.source !== "interaction") { const value = ev.detail.item.value;
return; if (value === "toggle-compare") {
this._toggleCompare();
} }
this._compare = ev.detail.selected; }
private _toggleCompare() {
this._compare = !this._compare;
const energyCollection = getEnergyDataCollection(this.hass, { const energyCollection = getEnergyDataCollection(this.hass, {
key: this.collectionKey, key: this.collectionKey,
}); });

View File

@@ -2,9 +2,7 @@ import { mdiDelete, mdiDragHorizontalVariant, mdiPencil } from "@mdi/js";
import type { CSSResultGroup, TemplateResult } from "lit"; import type { CSSResultGroup, TemplateResult } from "lit";
import { LitElement, css, html } from "lit"; import { LitElement, css, html } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import "../../../components/ha-button-menu";
import "../../../components/ha-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-list-item";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";

View File

@@ -1,4 +1,3 @@
import type { ActionDetail } from "@material/mwc-list";
import { import {
mdiClose, mdiClose,
mdiDotsVertical, mdiDotsVertical,
@@ -12,11 +11,12 @@ import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import { stopPropagation } from "../../../../common/dom/stop_propagation"; import { stopPropagation } from "../../../../common/dom/stop_propagation";
import "../../../../components/ha-button"; import "../../../../components/ha-button";
import "../../../../components/ha-button-menu";
import "../../../../components/ha-dialog"; import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header"; import "../../../../components/ha-dialog-header";
import "../../../../components/ha-dropdown";
import "../../../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../../../components/ha-dropdown-item";
import "../../../../components/ha-icon-button"; import "../../../../components/ha-icon-button";
import "../../../../components/ha-list-item";
import "../../../../components/ha-tab-group"; import "../../../../components/ha-tab-group";
import "../../../../components/ha-tab-group-tab"; import "../../../../components/ha-tab-group-tab";
import "../../../../components/ha-yaml-editor"; import "../../../../components/ha-yaml-editor";
@@ -165,38 +165,33 @@ export class HuiDialogEditSection
.path=${mdiClose} .path=${mdiClose}
></ha-icon-button> ></ha-icon-button>
<span slot="title">${heading}</span> <span slot="title">${heading}</span>
<ha-button-menu <ha-dropdown
slot="actionItems" slot="actionItems"
fixed placement="bottom-end"
corner="BOTTOM_END"
menu-corner="END"
@closed=${stopPropagation} @closed=${stopPropagation}
@action=${this._handleAction} @wa-select=${this._handleAction}
> >
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass!.localize("ui.common.menu")} .label=${this.hass!.localize("ui.common.menu")}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
<ha-list-item graphic="icon"> <ha-dropdown-item value="toggle-yaml">
<ha-svg-icon slot="icon" .path=${mdiPlaylistEdit}></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
`ui.panel.lovelace.editor.edit_view.edit_${!this._yamlMode ? "yaml" : "ui"}` `ui.panel.lovelace.editor.edit_view.edit_${!this._yamlMode ? "yaml" : "ui"}`
)} )}
</ha-dropdown-item>
<ha-dropdown-item value="move-to-view">
<ha-svg-icon <ha-svg-icon
slot="graphic" slot="icon"
.path=${mdiPlaylistEdit} .path=${mdiFileMoveOutline}
></ha-svg-icon> ></ha-svg-icon>
</ha-list-item>
<ha-list-item graphic="icon">
${this.hass!.localize( ${this.hass!.localize(
"ui.panel.lovelace.editor.edit_view.move_to_view" "ui.panel.lovelace.editor.edit_view.move_to_view"
)} )}
<ha-svg-icon </ha-dropdown-item>
slot="graphic" </ha-dropdown>
.path=${mdiFileMoveOutline}
></ha-svg-icon>
</ha-list-item>
</ha-button-menu>
${!this._yamlMode ${!this._yamlMode
? html` ? html`
<ha-tab-group @wa-tab-show=${this._handleTabChanged}> <ha-tab-group @wa-tab-show=${this._handleTabChanged}>
@@ -246,14 +241,13 @@ export class HuiDialogEditSection
this._currTab = newTab; this._currTab = newTab;
} }
private async _handleAction(ev: CustomEvent<ActionDetail>) { private async _handleAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
ev.stopPropagation(); const value = ev.detail.item.value;
ev.preventDefault(); switch (value) {
switch (ev.detail.index) { case "toggle-yaml":
case 0:
this._yamlMode = !this._yamlMode; this._yamlMode = !this._yamlMode;
break; break;
case 1: case "move-to-view":
this._openSelectView(); this._openSelectView();
break; break;
} }

View File

@@ -1,4 +1,3 @@
import type { ActionDetail } from "@material/mwc-list";
import { import {
mdiAlphaABoxOutline, mdiAlphaABoxOutline,
mdiDotsVertical, mdiDotsVertical,
@@ -12,9 +11,11 @@ import { storage } from "../../common/decorators/storage";
import type { HASSDomEvent } from "../../common/dom/fire_event"; import type { HASSDomEvent } from "../../common/dom/fire_event";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { navigate } from "../../common/navigate"; import { navigate } from "../../common/navigate";
import "../../components/ha-dropdown";
import "../../components/ha-dropdown-item";
import type { HaDropdownItem } from "../../components/ha-dropdown-item";
import "../../components/ha-icon-button"; import "../../components/ha-icon-button";
import "../../components/ha-icon-button-arrow-prev"; import "../../components/ha-icon-button-arrow-prev";
import "../../components/ha-list-item";
import "../../components/ha-menu-button"; import "../../components/ha-menu-button";
import "../../components/ha-top-app-bar-fixed"; import "../../components/ha-top-app-bar-fixed";
import "../../components/media-player/ha-media-manage-button"; import "../../components/media-player/ha-media-manage-button";
@@ -119,43 +120,40 @@ class PanelMediaBrowser extends LitElement {
.currentItem=${this._currentItem} .currentItem=${this._currentItem}
@media-refresh=${this._refreshMedia} @media-refresh=${this._refreshMedia}
></ha-media-manage-button> ></ha-media-manage-button>
<ha-button-menu slot="actionItems" @action=${this._handleMenuAction}> <ha-dropdown slot="actionItems" @wa-select=${this._handleMenuAction}>
<ha-icon-button <ha-icon-button
slot="trigger" slot="trigger"
.label=${this.hass.localize("ui.common.menu")} .label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical} .path=${mdiDotsVertical}
></ha-icon-button> ></ha-icon-button>
<ha-list-item graphic="icon"> <ha-dropdown-item
value="auto"
class=${this._preferredLayout === "auto"
? "selected_menu_item"
: ""}
>
${this.hass.localize("ui.components.media-browser.auto")} ${this.hass.localize("ui.components.media-browser.auto")}
<ha-svg-icon <ha-svg-icon slot="icon" .path=${mdiAlphaABoxOutline}></ha-svg-icon>
class=${this._preferredLayout === "auto" </ha-dropdown-item>
? "selected_menu_item" <ha-dropdown-item
: ""} value="grid"
slot="graphic" class=${this._preferredLayout === "grid"
.path=${mdiAlphaABoxOutline} ? "selected_menu_item"
></ha-svg-icon> : ""}
</ha-list-item> >
<ha-list-item graphic="icon">
${this.hass.localize("ui.components.media-browser.grid")} ${this.hass.localize("ui.components.media-browser.grid")}
<ha-svg-icon <ha-svg-icon slot="icon" .path=${mdiGrid}></ha-svg-icon>
class=${this._preferredLayout === "grid" </ha-dropdown-item>
? "selected_menu_item" <ha-dropdown-item
: ""} value="list"
slot="graphic" class=${this._preferredLayout === "list"
.path=${mdiGrid} ? "selected_menu_item"
></ha-svg-icon> : ""}
</ha-list-item> >
<ha-list-item graphic="icon">
${this.hass.localize("ui.components.media-browser.list")} ${this.hass.localize("ui.components.media-browser.list")}
<ha-svg-icon <ha-svg-icon slot="icon" .path=${mdiListBoxOutline}></ha-svg-icon>
slot="graphic" </ha-dropdown-item>
class=${this._preferredLayout === "list" </ha-dropdown>
? "selected_menu_item"
: ""}
.path=${mdiListBoxOutline}
></ha-svg-icon>
</ha-list-item>
</ha-button-menu>
<ha-media-player-browse <ha-media-player-browse
.hass=${this.hass} .hass=${this.hass}
.entityId=${this._entityId} .entityId=${this._entityId}
@@ -174,17 +172,11 @@ class PanelMediaBrowser extends LitElement {
`; `;
} }
private async _handleMenuAction(ev: CustomEvent<ActionDetail>) { private _handleMenuAction(ev: CustomEvent<{ item: HaDropdownItem }>) {
switch (ev.detail.index) { const value = ev.detail.item.value;
case 0:
this._preferredLayout = "auto"; if (["auto", "grid", "list"].includes(value)) {
break; this._preferredLayout = value as MediaPlayerLayoutType;
case 1:
this._preferredLayout = "grid";
break;
case 2:
this._preferredLayout = "list";
break;
} }
} }
@@ -372,6 +364,10 @@ class PanelMediaBrowser extends LitElement {
color: var(--primary-color); color: var(--primary-color);
} }
.selected_menu_item ha-svg-icon {
color: currentColor;
}
ha-bar-media-player { ha-bar-media-player {
position: fixed; position: fixed;
bottom: var(--safe-area-inset-bottom, 0px); bottom: var(--safe-area-inset-bottom, 0px);