Use comboBoxRenderer from lit-vaadin-helpers (#9201)

This commit is contained in:
Bram Kragten 2021-05-25 13:27:49 +02:00 committed by GitHub
parent 7f75ca81f1
commit 0eca602e61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 126 additions and 211 deletions

View File

@ -117,6 +117,7 @@
"leaflet": "^1.7.1", "leaflet": "^1.7.1",
"leaflet-draw": "^1.0.4", "leaflet-draw": "^1.0.4",
"lit": "^2.0.0-rc.2", "lit": "^2.0.0-rc.2",
"lit-vaadin-helpers": "^0.1.3",
"marked": "2.0.0", "marked": "2.0.0",
"mdn-polyfills": "^5.16.0", "mdn-polyfills": "^5.16.0",
"memoize-one": "^5.0.2", "memoize-one": "^5.0.2",

View File

@ -38,6 +38,7 @@ import { PolymerChangedEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
import "../ha-svg-icon"; import "../ha-svg-icon";
import "./ha-devices-picker"; import "./ha-devices-picker";
import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers";
interface DevicesByArea { interface DevicesByArea {
[areaId: string]: AreaDevices; [areaId: string]: AreaDevices;
@ -49,14 +50,7 @@ interface AreaDevices {
devices: string[]; devices: string[];
} }
const rowRenderer = ( const rowRenderer: ComboBoxLitRenderer<AreaDevices> = (item) => html`<style>
root: HTMLElement,
_owner,
model: { item: AreaDevices }
) => {
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
width: 100%; width: 100%;
margin: -10px 0; margin: -10px 0;
@ -74,17 +68,10 @@ const rowRenderer = (
</style> </style>
<paper-item> <paper-item>
<paper-item-body two-line=""> <paper-item-body two-line="">
<div class='name'>[[item.name]]</div> <div class="name">${item.name}</div>
<div secondary>[[item.devices.length]] devices</div> <div secondary>${item.devices.length} devices</div>
</paper-item-body> </paper-item-body>
</paper-item> </paper-item>`;
`;
}
root.querySelector(".name")!.textContent = model.item.name!;
root.querySelector(
"[secondary]"
)!.textContent = `${model.item.devices.length.toString()} devices`;
};
@customElement("ha-area-devices-picker") @customElement("ha-area-devices-picker")
export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) { export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
@ -310,7 +297,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
item-label-path="name" item-label-path="name"
.items=${areas} .items=${areas}
.value=${this._value} .value=${this._value}
.renderer=${rowRenderer} ${comboBoxRenderer(rowRenderer)}
@opened-changed=${this._openedChanged} @opened-changed=${this._openedChanged}
@value-changed=${this._areaPicked} @value-changed=${this._areaPicked}
> >

View File

@ -33,6 +33,7 @@ import { PolymerChangedEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
import "../ha-combo-box"; import "../ha-combo-box";
import type { HaComboBox } from "../ha-combo-box"; import type { HaComboBox } from "../ha-combo-box";
import { ComboBoxLitRenderer } from "lit-vaadin-helpers";
interface Device { interface Device {
name: string; name: string;
@ -44,27 +45,18 @@ export type HaDevicePickerDeviceFilterFunc = (
device: DeviceRegistryEntry device: DeviceRegistryEntry
) => boolean; ) => boolean;
const rowRenderer = (root: HTMLElement, _owner, model: { item: Device }) => { const rowRenderer: ComboBoxLitRenderer<Device> = (item) => html`<style>
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
margin: -10px 0; margin: -10px 0;
padding: 0; padding: 0;
} }
</style> </style>
<paper-item> <paper-item>
<paper-item-body two-line=""> <paper-item-body two-line>
<div class='name'>[[item.name]]</div> ${item.name}
<div secondary>[[item.area]]</div> <span secondary>${item.area}</span>
</paper-item-body> </paper-item-body>
</paper-item> </paper-item>`;
`;
}
root.querySelector(".name")!.textContent = model.item.name!;
root.querySelector("[secondary]")!.textContent = model.item.area!;
};
@customElement("ha-device-picker") @customElement("ha-device-picker")
export class HaDevicePicker extends SubscribeMixin(LitElement) { export class HaDevicePicker extends SubscribeMixin(LitElement) {

View File

@ -12,6 +12,7 @@ import {
PropertyValues, PropertyValues,
TemplateResult, TemplateResult,
} from "lit"; } from "lit";
import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { PolymerChangedEvent } from "../../polymer-types"; import { PolymerChangedEvent } from "../../polymer-types";
@ -22,22 +23,13 @@ import "./state-badge";
export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean; export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean;
const rowRenderer = (root: HTMLElement, _owner, model: { item: string }) => { const rowRenderer: ComboBoxLitRenderer<string> = (item) => html`<style>
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
margin: -10px; margin: -5px -10px;
padding: 0; padding: 0;
} }
</style> </style>
<paper-item></paper-item> <paper-item>${formatAttributeName(item)}</paper-item>`;
`;
}
root.querySelector("paper-item")!.textContent = formatAttributeName(
model.item
);
};
@customElement("ha-entity-attribute-picker") @customElement("ha-entity-attribute-picker")
class HaEntityAttributePicker extends LitElement { class HaEntityAttributePicker extends LitElement {
@ -82,8 +74,8 @@ class HaEntityAttributePicker extends LitElement {
<vaadin-combo-box-light <vaadin-combo-box-light
.value=${this._value} .value=${this._value}
.allowCustomValue=${this.allowCustomValue} .allowCustomValue=${this.allowCustomValue}
.renderer=${rowRenderer}
attr-for-value="bind-value" attr-for-value="bind-value"
${comboBoxRenderer(rowRenderer)}
@opened-changed=${this._openedChanged} @opened-changed=${this._openedChanged}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
> >

View File

@ -13,6 +13,7 @@ import {
PropertyValues, PropertyValues,
TemplateResult, TemplateResult,
} from "lit"; } from "lit";
import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, query } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
@ -25,32 +26,19 @@ import "./state-badge";
export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean; export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean;
const rowRenderer = ( const rowRenderer: ComboBoxLitRenderer<HassEntity> = (item) => html`<style>
root: HTMLElement,
_owner,
model: { item: HassEntity }
) => {
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-icon-item { paper-icon-item {
margin: -10px; margin: -10px;
padding: 0; padding: 0;
} }
</style> </style>
<paper-icon-item> <paper-icon-item>
<state-badge slot="item-icon"></state-badge> <state-badge slot="item-icon" .stateObj=${item}></state-badge>
<paper-item-body two-line=""> <paper-item-body two-line="">
<div class='name'></div> ${computeStateName(item)}
<div secondary></div> <span secondary>${item.entity_id}</span>
</paper-item-body> </paper-item-body>
</paper-icon-item> </paper-icon-item>`;
`;
}
root.querySelector("state-badge")!.stateObj = model.item;
root.querySelector(".name")!.textContent = computeStateName(model.item);
root.querySelector("[secondary]")!.textContent = model.item.entity_id;
};
@customElement("ha-entity-picker") @customElement("ha-entity-picker")
export class HaEntityPicker extends LitElement { export class HaEntityPicker extends LitElement {
@ -221,7 +209,7 @@ export class HaEntityPicker extends LitElement {
item-label-path="entity_id" item-label-path="entity_id"
.value=${this._value} .value=${this._value}
.allowCustomValue=${this.allowCustomEntity} .allowCustomValue=${this.allowCustomEntity}
.renderer=${rowRenderer} ${comboBoxRenderer(rowRenderer)}
@opened-changed=${this._openedChanged} @opened-changed=${this._openedChanged}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
@filter-changed=${this._filterChanged} @filter-changed=${this._filterChanged}

View File

@ -9,32 +9,20 @@ import { showAlertDialog } from "../dialogs/generic/show-dialog-box";
import { PolymerChangedEvent } from "../polymer-types"; import { PolymerChangedEvent } from "../polymer-types";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { HaComboBox } from "./ha-combo-box"; import { HaComboBox } from "./ha-combo-box";
import { ComboBoxLitRenderer } from "lit-vaadin-helpers";
const rowRenderer = ( const rowRenderer: ComboBoxLitRenderer<HassioAddonInfo> = (item) => html`<style>
root: HTMLElement,
_owner,
model: { item: HassioAddonInfo }
) => {
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
margin: -10px 0; margin: -10px 0;
padding: 0; padding: 0;
} }
</style> </style>
<paper-item> <paper-item>
<paper-item-body two-line=""> <paper-item-body two-line>
<div class='name'>[[item.name]]</div> ${item.name}
<div secondary>[[item.slug]]</div> <span secondary>${item.slug}</span>
</paper-item-body> </paper-item-body>
</paper-item> </paper-item>`;
`;
}
root.querySelector(".name")!.textContent = model.item.name;
root.querySelector("[secondary]")!.textContent = model.item.slug;
};
@customElement("ha-addon-picker") @customElement("ha-addon-picker")
class HaAddonPicker extends LitElement { class HaAddonPicker extends LitElement {

View File

@ -14,7 +14,9 @@ import {
PropertyValues, PropertyValues,
TemplateResult, TemplateResult,
} from "lit"; } from "lit";
import { customElement, property, state, query } from "lit/decorators"; import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain"; import { computeDomain } from "../common/entity/compute_domain";
@ -42,14 +44,9 @@ import { HomeAssistant } from "../types";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker"; import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./ha-svg-icon"; import "./ha-svg-icon";
const rowRenderer = ( const rowRenderer: ComboBoxLitRenderer<AreaRegistryEntry> = (
root: HTMLElement, item
_owner, ) => html`<style>
model: { item: AreaRegistryEntry }
) => {
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
margin: -10px 0; margin: -10px 0;
padding: 0; padding: 0;
@ -58,20 +55,9 @@ const rowRenderer = (
font-weight: 500; font-weight: 500;
} }
</style> </style>
<paper-item> <paper-item class=${classMap({ "add-new": item.area_id === "add_new" })}>
<paper-item-body two-line> <paper-item-body two-line>${item.name}</paper-item-body>
<div class='name'>[[item.name]]</div> </paper-item>`;
</paper-item-body>
</paper-item>
`;
}
root.querySelector(".name")!.textContent = model.item.name!;
if (model.item.area_id === "add_new") {
root.querySelector("paper-item")!.className = "add-new";
} else {
root.querySelector("paper-item")!.classList.remove("add-new");
}
};
@customElement("ha-area-picker") @customElement("ha-area-picker")
export class HaAreaPicker extends SubscribeMixin(LitElement) { export class HaAreaPicker extends SubscribeMixin(LitElement) {
@ -340,8 +326,8 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
item-id-path="area_id" item-id-path="area_id"
item-label-path="name" item-label-path="name"
.value=${this._value} .value=${this._value}
.renderer=${rowRenderer}
.disabled=${this.disabled} .disabled=${this.disabled}
${comboBoxRenderer(rowRenderer)}
@opened-changed=${this._openedChanged} @opened-changed=${this._openedChanged}
@value-changed=${this._areaChanged} @value-changed=${this._areaChanged}
> >

View File

@ -6,31 +6,20 @@ import "@polymer/paper-item/paper-item-body";
import "@polymer/paper-listbox/paper-listbox"; import "@polymer/paper-listbox/paper-listbox";
import "@vaadin/vaadin-combo-box/theme/material/vaadin-combo-box-light"; import "@vaadin/vaadin-combo-box/theme/material/vaadin-combo-box-light";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state, query } from "lit/decorators"; import { ComboBoxLitRenderer, comboBoxRenderer } from "lit-vaadin-helpers";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { PolymerChangedEvent } from "../polymer-types"; import { PolymerChangedEvent } from "../polymer-types";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import "./ha-svg-icon"; import "./ha-svg-icon";
const defaultRowRenderer = ( const defaultRowRenderer: ComboBoxLitRenderer<string> = (item) => html`<style>
root: HTMLElement,
_owner,
model: { item: any }
) => {
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
margin: -5px -10px; margin: -5px -10px;
padding: 0; padding: 0;
} }
</style> </style>
<paper-item></paper-item> <paper-item>${item}</paper-item>`;
`;
}
root.querySelector("paper-item")!.textContent = model.item;
};
@customElement("ha-combo-box") @customElement("ha-combo-box")
export class HaComboBox extends LitElement { export class HaComboBox extends LitElement {
@ -53,11 +42,7 @@ export class HaComboBox extends LitElement {
@property({ attribute: "item-id-path" }) public itemIdPath?: string; @property({ attribute: "item-id-path" }) public itemIdPath?: string;
@property() public renderer?: ( @property() public renderer?: ComboBoxLitRenderer<any>;
root: HTMLElement,
owner: HTMLElement,
model: { item: any }
) => void;
@property({ type: Boolean }) public disabled?: boolean; @property({ type: Boolean }) public disabled?: boolean;
@ -90,9 +75,9 @@ export class HaComboBox extends LitElement {
.value=${this.value} .value=${this.value}
.items=${this.items} .items=${this.items}
.filteredItems=${this.filteredItems} .filteredItems=${this.filteredItems}
.renderer=${this.renderer || defaultRowRenderer}
.allowCustomValue=${this.allowCustomValue} .allowCustomValue=${this.allowCustomValue}
.disabled=${this.disabled} .disabled=${this.disabled}
${comboBoxRenderer(this.renderer || defaultRowRenderer)}
@opened-changed=${this._openedChanged} @opened-changed=${this._openedChanged}
@filter-changed=${this._filterChanged} @filter-changed=${this._filterChanged}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}

View File

@ -6,33 +6,22 @@ import { LocalizeFunc } from "../common/translations/localize";
import { domainToName } from "../data/integration"; import { domainToName } from "../data/integration";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import "./ha-combo-box"; import "./ha-combo-box";
import { ComboBoxLitRenderer } from "lit-vaadin-helpers";
const rowRenderer = ( const rowRenderer: ComboBoxLitRenderer<{ service: string; name: string }> = (
root: HTMLElement, item
_owner, ) => html`<style>
model: { item: { service: string; name: string } }
) => {
if (!root.firstElementChild) {
root.innerHTML = `
<style>
paper-item { paper-item {
margin: -10px 0; margin: -10px 0;
padding: 0; padding: 0;
} }
</style> </style>
<paper-item> <paper-item>
<paper-item-body two-line=""> <paper-item-body two-line>
<div class='name'>[[item.name]]</div> ${item.name}
<div secondary>[[item.service]]</div> <span secondary>${item.name === item.service ? "" : item.service}</span>
</paper-item-body> </paper-item-body>
</paper-item> </paper-item>`;
`;
}
root.querySelector(".name")!.textContent = model.item.name;
root.querySelector("[secondary]")!.textContent =
model.item.name === model.item.service ? "" : model.item.service;
};
class HaServicePicker extends LitElement { class HaServicePicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;

View File

@ -8721,6 +8721,13 @@ lit-html@2.0.0-rc.3, lit-html@^1.4.0, lit-html@^2.0.0-rc.3:
dependencies: dependencies:
"@types/trusted-types" "^1.0.1" "@types/trusted-types" "^1.0.1"
lit-vaadin-helpers@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/lit-vaadin-helpers/-/lit-vaadin-helpers-0.1.3.tgz#6230ffdb90f7808d087107f18e83f14d64f0f5d5"
integrity sha512-fEUJEVzC1IluUbOOExBYuwal/DyhZqheIvtDV/Tlnmbq1NFtIjgybFQuFNXAyHDaaVwuKDijTGP1c3wwf9rg8w==
dependencies:
lit "^2.0.0-rc.1"
lit@^2.0.0-rc.1, lit@^2.0.0-rc.2: lit@^2.0.0-rc.1, lit@^2.0.0-rc.2:
version "2.0.0-rc.2" version "2.0.0-rc.2"
resolved "https://registry.yarnpkg.com/lit/-/lit-2.0.0-rc.2.tgz#724a2d621aa098001d73bf7106f3a72b7b5948ef" resolved "https://registry.yarnpkg.com/lit/-/lit-2.0.0-rc.2.tgz#724a2d621aa098001d73bf7106f3a72b7b5948ef"