From d05f807b9df66d69a8a8b3829509459b9b26161f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sun, 6 Feb 2022 23:31:46 +0100 Subject: [PATCH] Covert area picker to combo-box (#11562) --- src/components/ha-area-picker.ts | 154 +++++++++++-------------------- src/components/ha-combo-box.ts | 4 +- src/translations/en.json | 1 + 3 files changed, 57 insertions(+), 102 deletions(-) diff --git a/src/components/ha-area-picker.ts b/src/components/ha-area-picker.ts index b6504f9dc1..bfb39ac3da 100644 --- a/src/components/ha-area-picker.ts +++ b/src/components/ha-area-picker.ts @@ -1,19 +1,6 @@ -import { mdiCheck, mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js"; -import "@polymer/paper-input/paper-input"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-item/paper-item-body"; -import "@polymer/paper-listbox/paper-listbox"; -import "@vaadin/combo-box/theme/material/vaadin-combo-box-light"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; -import { - css, - CSSResultGroup, - html, - LitElement, - PropertyValues, - TemplateResult, -} from "lit"; -import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers"; +import { html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { ComboBoxLitRenderer } from "lit-vaadin-helpers"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; @@ -41,38 +28,18 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin"; import { PolymerChangedEvent } from "../polymer-types"; import { HomeAssistant } from "../types"; import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker"; +import type { HaComboBox } from "./ha-combo-box"; +import "./ha-combo-box"; import "./ha-icon-button"; import "./ha-svg-icon"; const rowRenderer: ComboBoxLitRenderer = ( item - // eslint-disable-next-line lit/prefer-static-styles -) => html` - - - ${item.name} - `; +) => html` + ${item.name} +`; @customElement("ha-area-picker") export class HaAreaPicker extends SubscribeMixin(LitElement) { @@ -125,7 +92,9 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { @state() private _opened?: boolean; - @query("vaadin-combo-box-light", true) public comboBox!: HTMLElement; + @query("ha-combo-box", true) public comboBox!: HaComboBox; + + private _filter?: string; private _init = false; @@ -145,13 +114,13 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { public open() { this.updateComplete.then(() => { - (this.shadowRoot?.querySelector("vaadin-combo-box-light") as any)?.open(); + this.comboBox?.open(); }); } public focus() { this.updateComplete.then(() => { - this.shadowRoot?.querySelector("paper-input")?.focus(); + this.comboBox?.focus(); }); } @@ -339,52 +308,25 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { return html``; } return html` - - - ${this.value - ? html` - - ` - : ""} - - - - + `; } @@ -392,9 +334,29 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { this._areas?.find((area) => area.area_id === areaId) ); - private _clearValue(ev: Event) { - ev.stopPropagation(); - this._setValue(""); + private _filterChanged(ev: CustomEvent): void { + this._filter = ev.detail.value; + if (!this._filter) { + this.comboBox.filteredItems = this.comboBox.items; + return; + } + // @ts-ignore + if (!this.noAdd && this.comboBox._comboBox.filteredItems?.length === 0) { + this.comboBox.filteredItems = [ + { + area_id: "add_new_suggestion", + name: this.hass.localize( + "ui.components.area-picker.add_new_sugestion", + { name: this._filter } + ), + picture: null, + }, + ]; + } else { + this.comboBox.filteredItems = this.comboBox.items?.filter((item) => + item.name.toLowerCase().includes(this._filter!.toLowerCase()) + ); + } } private get _value() { @@ -406,9 +368,10 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { } private _areaChanged(ev: PolymerChangedEvent) { + ev.stopPropagation(); const newValue = ev.detail.value; - if (newValue !== "add_new") { + if (!["add_new_suggestion", "add_new"].includes(newValue)) { if (newValue !== this._value) { this._setValue(newValue); } @@ -425,6 +388,8 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { inputLabel: this.hass.localize( "ui.components.area-picker.add_dialog.name" ), + defaultValue: + newValue === "add_new_suggestion" ? this._filter : undefined, confirm: async (name) => { if (!name) { return; @@ -445,6 +410,8 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { this.entityFilter, this.noAdd ); + await this.updateComplete; + await this.comboBox.updateComplete; this._setValue(area.area_id); } catch (err: any) { showAlertDialog(this, { @@ -465,19 +432,6 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { fireEvent(this, "change"); }, 0); } - - static get styles(): CSSResultGroup { - return css` - paper-input > ha-icon-button { - --mdc-icon-button-size: 24px; - padding: 2px; - color: var(--secondary-text-color); - } - [hidden] { - display: none; - } - `; - } } declare global { diff --git a/src/components/ha-combo-box.ts b/src/components/ha-combo-box.ts index dd2b5d0e27..c4717b4d33 100644 --- a/src/components/ha-combo-box.ts +++ b/src/components/ha-combo-box.ts @@ -63,9 +63,9 @@ export class HaComboBox extends LitElement { @property() public value?: string; - @property() public items?: []; + @property() public items?: any[]; - @property() public filteredItems?: []; + @property() public filteredItems?: any[]; @property({ attribute: "allow-custom-value", type: Boolean }) public allowCustomValue?: boolean; diff --git a/src/translations/en.json b/src/translations/en.json index 034810a867..42eb7db2f6 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -401,6 +401,7 @@ "clear": "Clear", "show_areas": "Show areas", "area": "Area", + "add_new_sugestion": "Add new area ''{name}''", "add_new": "Add new area…", "no_areas": "You don't have any areas", "no_match": "No matching areas found",