diff --git a/src/components/ha-form/ha-form-multi_select.ts b/src/components/ha-form/ha-form-multi_select.ts index 067840fc5c..f09bad520d 100644 --- a/src/components/ha-form/ha-form-multi_select.ts +++ b/src/components/ha-form/ha-form-multi_select.ts @@ -5,12 +5,14 @@ import { customElement, property, query, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import "../ha-button-menu"; import "../ha-check-list-item"; -import type { HaCheckListItem } from "../ha-check-list-item"; import "../ha-checkbox"; import type { HaCheckbox } from "../ha-checkbox"; import "../ha-formfield"; -import "../ha-svg-icon"; +import "../ha-icon-button"; import "../ha-textfield"; +import "../ha-md-button-menu"; +import "../ha-md-menu-item"; + import type { HaFormElement, HaFormMultiSelectData, @@ -73,13 +75,10 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { } return html` - - + > ${options.map((item: string | [string, string]) => { const value = optionValue(item); const selected = data.includes(value); - return html` + ${optionLabel(item)} - `; + `; })} - + `; } + protected _keydown(ev) { + if (ev.code === "Space" || ev.code === "Enter") { + ev.preventDefault(); + this._toggleItem(ev); + } + } + + protected _toggleItem(ev) { + const oldData = this.data || []; + let newData: string[]; + if (ev.currentTarget.action === "add") { + newData = [...oldData, ev.currentTarget.value]; + } else { + newData = oldData.filter((d) => d !== ev.currentTarget.value); + } + fireEvent(this, "value-changed", { + value: newData, + }); + } + protected firstUpdated() { this.updateComplete.then(() => { const { formElement, mdcRoot } = @@ -139,17 +166,6 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { } } - private _selectedChanged(ev: CustomEvent): void { - ev.stopPropagation(); - if (ev.detail.source === "property") { - return; - } - this._handleValueChanged( - (ev.target as HaCheckListItem).value, - ev.detail.selected - ); - } - private _valueChanged(ev: CustomEvent): void { const { value, checked } = ev.target as HaCheckbox; this._handleValueChanged(value, checked); @@ -195,7 +211,7 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { :host([own-margin]) { margin-bottom: 5px; } - ha-button-menu { + ha-md-button-menu { display: block; cursor: pointer; } @@ -208,22 +224,23 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { } ha-textfield { display: block; + width: 100%; pointer-events: none; } - ha-svg-icon { + ha-icon-button { color: var(--input-dropdown-icon-color); position: absolute; right: 1em; - top: 1em; + top: 4px; cursor: pointer; inset-inline-end: 1em; inset-inline-start: initial; direction: var(--direction); } - :host([opened]) ha-svg-icon { + :host([opened]) ha-icon-button { color: var(--primary-color); } - :host([opened]) ha-button-menu { + :host([opened]) ha-md-button-menu { --mdc-text-field-idle-line-color: var(--input-hover-line-color); --mdc-text-field-label-ink-color: var(--primary-color); } diff --git a/src/components/ha-md-button-menu.ts b/src/components/ha-md-button-menu.ts index 09a0a7fd9b..3d4012397f 100644 --- a/src/components/ha-md-button-menu.ts +++ b/src/components/ha-md-button-menu.ts @@ -3,6 +3,7 @@ import type { CSSResultGroup, TemplateResult } from "lit"; import { css, html, LitElement } from "lit"; import { customElement, property, query } from "lit/decorators"; import { FOCUS_TARGET } from "../dialogs/make-dialog-manager"; +import { fireEvent } from "../common/dom/fire_event"; import type { HaIconButton } from "./ha-icon-button"; import "./ha-menu"; import type { HaMenu } from "./ha-menu"; @@ -40,12 +41,22 @@ export class HaMdButtonMenu extends LitElement { `; } + private _handleOpening(): void { + fireEvent(this, "opening", undefined, { composed: false }); + } + + private _handleClosing(): void { + fireEvent(this, "closing", undefined, { composed: false }); + } + private _handleClick(): void { if (this.disabled) { return; @@ -88,3 +99,10 @@ declare global { "ha-md-button-menu": HaMdButtonMenu; } } + +declare global { + interface HASSDomEvents { + opening: undefined; + closing: undefined; + } +}