mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 01:36:49 +00:00
Covert area picker to combo-box (#11562)
This commit is contained in:
parent
4092f7f75d
commit
d05f807b9d
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user