Covert area picker to combo-box (#11562)

This commit is contained in:
Bram Kragten 2022-02-06 23:31:46 +01:00 committed by GitHub
parent 4092f7f75d
commit d05f807b9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 102 deletions

View File

@ -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<AreaRegistryEntry> = (
item
// eslint-disable-next-line lit/prefer-static-styles
) => html`<style>
paper-item {
padding: 0;
margin: -10px;
margin-left: 0;
}
#content {
display: flex;
align-items: center;
}
ha-svg-icon {
padding-left: 2px;
margin-right: -2px;
color: var(--secondary-text-color);
}
:host(:not([selected])) ha-svg-icon {
display: none;
}
:host([selected]) paper-item {
margin-left: 10px;
}
</style>
<ha-svg-icon .path=${mdiCheck}></ha-svg-icon>
<paper-item class=${classMap({ "add-new": item.area_id === "add_new" })}>
<paper-item-body two-line>${item.name}</paper-item-body>
</paper-item>`;
) => html`<mwc-list-item
class=${classMap({ "add-new": item.area_id === "add_new" })}
>
${item.name}
</mwc-list-item>`;
@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`
<vaadin-combo-box-light
<ha-combo-box
.hass=${this.hass}
item-value-path="area_id"
item-id-path="area_id"
item-label-path="name"
.value=${this.value}
.disabled=${this.disabled}
${comboBoxRenderer(rowRenderer)}
.label=${this.label === undefined && this.hass
? this.hass.localize("ui.components.area-picker.area")
: this.label}
.placeholder=${this.placeholder
? this._area(this.placeholder)?.name
: undefined}
.renderer=${rowRenderer}
@filter-changed=${this._filterChanged}
@opened-changed=${this._openedChanged}
@value-changed=${this._areaChanged}
>
<paper-input
.label=${this.label === undefined && this.hass
? this.hass.localize("ui.components.area-picker.area")
: this.label}
.placeholder=${this.placeholder
? this._area(this.placeholder)?.name
: undefined}
.disabled=${this.disabled}
class="input"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
spellcheck="false"
>
${this.value
? html`
<ha-icon-button
.label=${this.hass.localize(
"ui.components.area-picker.clear"
)}
.path=${mdiClose}
slot="suffix"
class="clear-button"
@click=${this._clearValue}
></ha-icon-button>
`
: ""}
<ha-icon-button
.label=${this.hass.localize("ui.components.area-picker.toggle")}
.path=${this._opened ? mdiMenuUp : mdiMenuDown}
slot="suffix"
class="toggle-button"
></ha-icon-button>
</paper-input>
</vaadin-combo-box-light>
</ha-combo-box>
`;
}
@ -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<string>) {
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 {

View File

@ -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;

View File

@ -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",