mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-20 10:48:44 +00:00
Refactor generic pickers (#28570)
This commit is contained in:
@@ -277,13 +277,13 @@ export class HaEntityPicker extends LitElement {
|
|||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.allowCustomValue=${this.allowCustomEntity}
|
.allowCustomValue=${this.allowCustomEntity}
|
||||||
.label=${this.label}
|
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
|
.label=${this.label}
|
||||||
|
.placeholder=${placeholder}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
|
.value=${this.addButton ? undefined : this.value}
|
||||||
.searchLabel=${this.searchLabel}
|
.searchLabel=${this.searchLabel}
|
||||||
.notFoundLabel=${this._notFoundLabel}
|
.notFoundLabel=${this._notFoundLabel}
|
||||||
.placeholder=${placeholder}
|
|
||||||
.value=${this.addButton ? undefined : this.value}
|
|
||||||
.rowRenderer=${this._rowRenderer}
|
.rowRenderer=${this._rowRenderer}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
@@ -291,6 +291,7 @@ export class HaEntityPicker extends LitElement {
|
|||||||
.searchFn=${this._searchFn}
|
.searchFn=${this._searchFn}
|
||||||
.valueRenderer=${this._valueRenderer}
|
.valueRenderer=${this._valueRenderer}
|
||||||
.searchKeys=${entityComboBoxKeys}
|
.searchKeys=${entityComboBoxKeys}
|
||||||
|
use-top-label
|
||||||
.addButtonLabel=${this.addButton
|
.addButtonLabel=${this.addButton
|
||||||
? this.hass.localize("ui.components.entity.entity-picker.add")
|
? this.hass.localize("ui.components.entity.entity-picker.add")
|
||||||
: undefined}
|
: undefined}
|
||||||
|
|||||||
@@ -471,14 +471,14 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.allowCustomValue=${this.allowCustomEntity}
|
.allowCustomValue=${this.allowCustomEntity}
|
||||||
.label=${this.label}
|
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
|
.label=${this.label}
|
||||||
|
.placeholder=${placeholder}
|
||||||
|
.value=${this.value}
|
||||||
.notFoundLabel=${this._notFoundLabel}
|
.notFoundLabel=${this._notFoundLabel}
|
||||||
.emptyLabel=${this.hass.localize(
|
.emptyLabel=${this.hass.localize(
|
||||||
"ui.components.statistic-picker.no_statistics"
|
"ui.components.statistic-picker.no_statistics"
|
||||||
)}
|
)}
|
||||||
.placeholder=${placeholder}
|
|
||||||
.value=${this.value}
|
|
||||||
.rowRenderer=${this._rowRenderer}
|
.rowRenderer=${this._rowRenderer}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ class HaAddonPicker extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
|
const label =
|
||||||
|
this.label === undefined && this.hass
|
||||||
|
? this.hass.localize("ui.components.addon-picker.addon")
|
||||||
|
: this.label;
|
||||||
|
|
||||||
if (this._error) {
|
if (this._error) {
|
||||||
return html`<ha-alert alert-type="error">${this._error}</ha-alert>`;
|
return html`<ha-alert alert-type="error">${this._error}</ha-alert>`;
|
||||||
}
|
}
|
||||||
@@ -72,14 +77,11 @@ class HaAddonPicker extends LitElement {
|
|||||||
<ha-generic-picker
|
<ha-generic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.placeholder=${this.label === undefined && this.hass
|
.label=${label}
|
||||||
? this.hass.localize("ui.components.addon-picker.addon")
|
|
||||||
: this.label}
|
|
||||||
.valueRenderer=${this._valueRenderer}
|
.valueRenderer=${this._valueRenderer}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
show-label
|
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.searchKeys=${SEARCH_KEYS}
|
.searchKeys=${SEARCH_KEYS}
|
||||||
|
|||||||
@@ -51,9 +51,6 @@ export class HaAreaPicker extends LitElement {
|
|||||||
@property({ type: Boolean, attribute: "no-add" })
|
@property({ type: Boolean, attribute: "no-add" })
|
||||||
public noAdd = false;
|
public noAdd = false;
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "show-label" })
|
|
||||||
public showLabel = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show only areas with entities from specific domains.
|
* Show only areas with entities from specific domains.
|
||||||
* @type {Array}
|
* @type {Array}
|
||||||
@@ -366,16 +363,19 @@ export class HaAreaPicker extends LitElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const placeholder =
|
const baseLabel =
|
||||||
this.placeholder ?? this.hass.localize("ui.components.area-picker.area");
|
this.label ?? this.hass.localize("ui.components.area-picker.area");
|
||||||
const valueRenderer = this._computeValueRenderer(this.hass.areas);
|
const valueRenderer = this._computeValueRenderer(this.hass.areas);
|
||||||
|
|
||||||
let showLabel = this.showLabel;
|
// Only show label if there's no floor
|
||||||
if (this.value) {
|
let label: string | undefined = baseLabel;
|
||||||
|
if (this.value && baseLabel) {
|
||||||
const area = this.hass.areas[this.value];
|
const area = this.hass.areas[this.value];
|
||||||
if (area) {
|
if (area) {
|
||||||
const { floor } = getAreaContext(area, this.hass.floors);
|
const { floor } = getAreaContext(area, this.hass.floors);
|
||||||
showLabel = !floor && this.showLabel;
|
if (floor) {
|
||||||
|
label = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,14 +383,12 @@ export class HaAreaPicker extends LitElement {
|
|||||||
<ha-generic-picker
|
<ha-generic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.label=${this.label}
|
.label=${label}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.notFoundLabel=${this._notFoundLabel}
|
.notFoundLabel=${this._notFoundLabel}
|
||||||
.emptyLabel=${this.hass.localize("ui.components.area-picker.no_areas")}
|
.emptyLabel=${this.hass.localize("ui.components.area-picker.no_areas")}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
.placeholder=${placeholder}
|
|
||||||
.showLabel=${showLabel}
|
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
|
|||||||
@@ -389,14 +389,14 @@ export class HaFloorPicker extends LitElement {
|
|||||||
<ha-generic-picker
|
<ha-generic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
|
.disabled=${this.disabled}
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.disabled=${this.disabled}
|
.placeholder=${placeholder}
|
||||||
.notFoundLabel=${this._notFoundLabel}
|
.notFoundLabel=${this._notFoundLabel}
|
||||||
.emptyLabel=${this.hass.localize(
|
.emptyLabel=${this.hass.localize(
|
||||||
"ui.components.floor-picker.no_floors"
|
"ui.components.floor-picker.no_floors"
|
||||||
)}
|
)}
|
||||||
.placeholder=${placeholder}
|
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ifDefined } from "lit/directives/if-defined";
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { tinykeys } from "tinykeys";
|
import { tinykeys } from "tinykeys";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
|
import { PickerMixin } from "../mixins/picker-mixin";
|
||||||
import type { FuseWeightedKey } from "../resources/fuseMultiTerm";
|
import type { FuseWeightedKey } from "../resources/fuseMultiTerm";
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import { isIosApp } from "../util/is_ios";
|
import { isIosApp } from "../util/is_ios";
|
||||||
@@ -21,39 +22,18 @@ import type {
|
|||||||
PickerComboBoxSearchFn,
|
PickerComboBoxSearchFn,
|
||||||
} from "./ha-picker-combo-box";
|
} from "./ha-picker-combo-box";
|
||||||
import "./ha-picker-field";
|
import "./ha-picker-field";
|
||||||
import type { PickerValueRenderer } from "./ha-picker-field";
|
|
||||||
import "./ha-svg-icon";
|
import "./ha-svg-icon";
|
||||||
|
|
||||||
@customElement("ha-generic-picker")
|
@customElement("ha-generic-picker")
|
||||||
export class HaGenericPicker extends LitElement {
|
export class HaGenericPicker extends PickerMixin(LitElement) {
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public required = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "allow-custom-value" })
|
@property({ type: Boolean, attribute: "allow-custom-value" })
|
||||||
public allowCustomValue;
|
public allowCustomValue;
|
||||||
|
|
||||||
@property() public value?: string;
|
|
||||||
|
|
||||||
@property() public icon?: string;
|
|
||||||
|
|
||||||
@property() public label?: string;
|
|
||||||
|
|
||||||
@property() public helper?: string;
|
|
||||||
|
|
||||||
@property() public placeholder?: string;
|
|
||||||
|
|
||||||
@property({ type: String, attribute: "search-label" })
|
@property({ type: String, attribute: "search-label" })
|
||||||
public searchLabel?: string;
|
public searchLabel?: string;
|
||||||
|
|
||||||
@property({ attribute: "hide-clear-icon", type: Boolean })
|
|
||||||
public hideClearIcon = false;
|
|
||||||
|
|
||||||
@property({ attribute: "show-label", type: Boolean })
|
|
||||||
public showLabel = false;
|
|
||||||
|
|
||||||
/** To prevent lags, getItems needs to be memoized */
|
/** To prevent lags, getItems needs to be memoized */
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public getItems!: (
|
public getItems!: (
|
||||||
@@ -67,9 +47,6 @@ export class HaGenericPicker extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public rowRenderer?: RenderItemFunction<PickerComboBoxItem>;
|
public rowRenderer?: RenderItemFunction<PickerComboBoxItem>;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
public valueRenderer?: PickerValueRenderer;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public searchFn?: PickerComboBoxSearchFn<PickerComboBoxItem>;
|
public searchFn?: PickerComboBoxSearchFn<PickerComboBoxItem>;
|
||||||
|
|
||||||
@@ -119,7 +96,8 @@ export class HaGenericPicker extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: "selected-section" }) public selectedSection?: string;
|
@property({ attribute: "selected-section" }) public selectedSection?: string;
|
||||||
|
|
||||||
@property({ attribute: "unknown-item-text" }) public unknownItemText?: string;
|
@property({ type: Boolean, attribute: "use-top-label" })
|
||||||
|
public useTopLabel = false;
|
||||||
|
|
||||||
@query(".container") private _containerElement?: HTMLDivElement;
|
@query(".container") private _containerElement?: HTMLDivElement;
|
||||||
|
|
||||||
@@ -150,11 +128,13 @@ export class HaGenericPicker extends LitElement {
|
|||||||
private _unsubscribeTinyKeys?: () => void;
|
private _unsubscribeTinyKeys?: () => void;
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
// Only show label if it's not a top label and there is a value.
|
||||||
${this.label
|
const label = this.useTopLabel && this.value ? undefined : this.label;
|
||||||
|
|
||||||
|
return html`<div class="container">
|
||||||
|
${this.useTopLabel && this.label
|
||||||
? html`<label ?disabled=${this.disabled}>${this.label}</label>`
|
? html`<label ?disabled=${this.disabled}>${this.label}</label>`
|
||||||
: nothing}
|
: nothing}
|
||||||
<div class="container">
|
|
||||||
<div id="picker">
|
<div id="picker">
|
||||||
<slot name="field">
|
<slot name="field">
|
||||||
${this.addButtonLabel && !this.value
|
${this.addButtonLabel && !this.value
|
||||||
@@ -180,8 +160,10 @@ export class HaGenericPicker extends LitElement {
|
|||||||
@click=${this.open}
|
@click=${this.open}
|
||||||
@clear=${this._clear}
|
@clear=${this._clear}
|
||||||
.icon=${this.icon}
|
.icon=${this.icon}
|
||||||
.showLabel=${this.showLabel}
|
.image=${this.image}
|
||||||
|
.label=${label}
|
||||||
.placeholder=${this.placeholder}
|
.placeholder=${this.placeholder}
|
||||||
|
.helper=${this.helper}
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.valueRenderer=${this.valueRenderer}
|
.valueRenderer=${this.valueRenderer}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
@@ -189,6 +171,7 @@ export class HaGenericPicker extends LitElement {
|
|||||||
.invalid=${this.invalid}
|
.invalid=${this.invalid}
|
||||||
.hideClearIcon=${this.hideClearIcon}
|
.hideClearIcon=${this.hideClearIcon}
|
||||||
>
|
>
|
||||||
|
<slot name="start"></slot>
|
||||||
</ha-picker-field>`}
|
</ha-picker-field>`}
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
@@ -227,8 +210,7 @@ export class HaGenericPicker extends LitElement {
|
|||||||
</ha-bottom-sheet>`
|
</ha-bottom-sheet>`
|
||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
${this._renderHelper()}
|
${this._renderHelper()}`;
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderComboBox(dialogMode = false) {
|
private _renderComboBox(dialogMode = false) {
|
||||||
@@ -321,7 +303,7 @@ export class HaGenericPicker extends LitElement {
|
|||||||
this._newValue = value;
|
this._newValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _clear(e) {
|
private _clear(e: CustomEvent) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this._setValue(undefined);
|
this._setValue(undefined);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ export class HaIconPicker extends LitElement {
|
|||||||
<ha-generic-picker
|
<ha-generic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
allow-custom-value
|
allow-custom-value
|
||||||
show-label
|
|
||||||
.getItems=${this._getIconPickerItems}
|
.getItems=${this._getIconPickerItems}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
@@ -122,7 +121,7 @@ export class HaIconPicker extends LitElement {
|
|||||||
.invalid=${this.invalid}
|
.invalid=${this.invalid}
|
||||||
.rowRenderer=${rowRenderer}
|
.rowRenderer=${rowRenderer}
|
||||||
.icon=${this._icon}
|
.icon=${this._icon}
|
||||||
.placeholder=${this.label}
|
.label=${this.label}
|
||||||
.value=${this._value}
|
.value=${this._value}
|
||||||
.searchFn=${this._filterIcons}
|
.searchFn=${this._filterIcons}
|
||||||
.notFoundLabel=${this.hass?.localize(
|
.notFoundLabel=${this.hass?.localize(
|
||||||
@@ -131,6 +130,7 @@ export class HaIconPicker extends LitElement {
|
|||||||
popover-placement="bottom-start"
|
popover-placement="bottom-start"
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
>
|
>
|
||||||
|
<slot name="start"></slot>
|
||||||
</ha-generic-picker>
|
</ha-generic-picker>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ export class HaLanguagePicker extends LitElement {
|
|||||||
> `;
|
> `;
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
|
const label =
|
||||||
|
this.label ??
|
||||||
|
(this.hass?.localize("ui.components.language-picker.language") ||
|
||||||
|
"Language");
|
||||||
|
|
||||||
const value =
|
const value =
|
||||||
this.value ??
|
this.value ??
|
||||||
(this.required && !this.disabled ? this._getItems()[0].id : this.value);
|
(this.required && !this.disabled ? this._getItems()[0].id : this.value);
|
||||||
@@ -129,10 +134,7 @@ export class HaLanguagePicker extends LitElement {
|
|||||||
.emptyLabel=${this.hass?.localize(
|
.emptyLabel=${this.hass?.localize(
|
||||||
"ui.components.language-picker.no_languages"
|
"ui.components.language-picker.no_languages"
|
||||||
) || "No languages available"}
|
) || "No languages available"}
|
||||||
.placeholder=${this.label ??
|
.label=${label}
|
||||||
(this.hass?.localize("ui.components.language-picker.language") ||
|
|
||||||
"Language")}
|
|
||||||
show-label
|
|
||||||
.value=${value}
|
.value=${value}
|
||||||
.valueRenderer=${this._valueRenderer}
|
.valueRenderer=${this._valueRenderer}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import {
|
|||||||
type TemplateResult,
|
type TemplateResult,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { ifDefined } from "lit/directives/if-defined";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
|
import { PickerMixin } from "../mixins/picker-mixin";
|
||||||
import { localizeContext } from "../data/context";
|
import { localizeContext } from "../data/context";
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import "./ha-combo-box-item";
|
import "./ha-combo-box-item";
|
||||||
@@ -26,32 +28,7 @@ declare global {
|
|||||||
export type PickerValueRenderer = (value: string) => TemplateResult<1>;
|
export type PickerValueRenderer = (value: string) => TemplateResult<1>;
|
||||||
|
|
||||||
@customElement("ha-picker-field")
|
@customElement("ha-picker-field")
|
||||||
export class HaPickerField extends LitElement {
|
export class HaPickerField extends PickerMixin(LitElement) {
|
||||||
@property({ type: Boolean }) public disabled = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public required = false;
|
|
||||||
|
|
||||||
@property() public value?: string;
|
|
||||||
|
|
||||||
@property() public icon?: string;
|
|
||||||
|
|
||||||
@property() public helper?: string;
|
|
||||||
|
|
||||||
@property() public placeholder?: string;
|
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true }) public unknown = false;
|
|
||||||
|
|
||||||
@property({ attribute: "unknown-item-text" }) public unknownItemText?: string;
|
|
||||||
|
|
||||||
@property({ attribute: "hide-clear-icon", type: Boolean })
|
|
||||||
public hideClearIcon = false;
|
|
||||||
|
|
||||||
@property({ attribute: "show-label", type: Boolean })
|
|
||||||
public showLabel = false;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
public valueRenderer?: PickerValueRenderer;
|
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true }) public invalid = false;
|
@property({ type: Boolean, reflect: true }) public invalid = false;
|
||||||
|
|
||||||
@query("ha-combo-box-item", true) public item!: HaComboBoxItem;
|
@query("ha-combo-box-item", true) public item!: HaComboBoxItem;
|
||||||
@@ -66,15 +43,17 @@ export class HaPickerField extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const hasValue = !!this.value?.length;
|
const hasValue = !!this.value;
|
||||||
|
|
||||||
const showClearIcon =
|
const showClearIcon =
|
||||||
!!this.value && !this.required && !this.disabled && !this.hideClearIcon;
|
!!this.value && !this.required && !this.disabled && !this.hideClearIcon;
|
||||||
|
|
||||||
|
const placeholderText = this.placeholder ?? this.label;
|
||||||
|
|
||||||
const overlineLabel =
|
const overlineLabel =
|
||||||
this.showLabel && hasValue && this.placeholder
|
this.label && hasValue
|
||||||
? html`<span slot="overline"
|
? html`<span slot="overline"
|
||||||
>${this.placeholder}${this.required ? " *" : ""}</span
|
>${this.label}${this.required ? " *" : ""}</span
|
||||||
>`
|
>`
|
||||||
: nothing;
|
: nothing;
|
||||||
|
|
||||||
@@ -82,17 +61,30 @@ export class HaPickerField extends LitElement {
|
|||||||
? this.valueRenderer
|
? this.valueRenderer
|
||||||
? this.valueRenderer(this.value ?? "")
|
? this.valueRenderer(this.value ?? "")
|
||||||
: html`<span slot="headline">${this.value}</span>`
|
: html`<span slot="headline">${this.value}</span>`
|
||||||
: this.placeholder
|
: placeholderText
|
||||||
? html`<span slot="headline" class="placeholder">
|
? html`<span slot="headline" class="placeholder">
|
||||||
${this.placeholder}${this.required ? " *" : ""}
|
${placeholderText}${this.required ? " *" : ""}
|
||||||
</span>`
|
</span>`
|
||||||
: nothing;
|
: nothing;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-combo-box-item .disabled=${this.disabled} type="button" compact>
|
<ha-combo-box-item
|
||||||
${this.icon
|
aria-label=${ifDefined(this.label || this.placeholder)}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
type="button"
|
||||||
|
compact
|
||||||
|
>
|
||||||
|
${this.image
|
||||||
|
? html`<img
|
||||||
|
alt=${this.label ?? ""}
|
||||||
|
slot="start"
|
||||||
|
.src=${this.image}
|
||||||
|
crossorigin="anonymous"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
/>`
|
||||||
|
: this.icon
|
||||||
? html`<ha-icon slot="start" .icon=${this.icon}></ha-icon>`
|
? html`<ha-icon slot="start" .icon=${this.icon}></ha-icon>`
|
||||||
: nothing}
|
: html`<slot name="start"></slot>`}
|
||||||
${overlineLabel}${headlineContent}
|
${overlineLabel}${headlineContent}
|
||||||
${this.unknown
|
${this.unknown
|
||||||
? html`<div slot="supporting-text" class="unknown">
|
? html`<div slot="supporting-text" class="unknown">
|
||||||
@@ -119,7 +111,7 @@ export class HaPickerField extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _clear(e) {
|
private _clear(e: CustomEvent) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
fireEvent(this, "clear");
|
fireEvent(this, "clear");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ export class HaEntitySelector extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
|
.placeholder=${this.placeholder}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.includeEntities=${this.selector.entity?.include_entities}
|
.includeEntities=${this.selector.entity?.include_entities}
|
||||||
.excludeEntities=${this.selector.entity?.exclude_entities}
|
.excludeEntities=${this.selector.entity?.exclude_entities}
|
||||||
.entityFilter=${this._filterEntities}
|
.entityFilter=${this._filterEntities}
|
||||||
.createDomains=${this._createDomains}
|
.createDomains=${this._createDomains}
|
||||||
.placeholder=${this.placeholder}
|
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
@@ -83,13 +83,13 @@ export class HaEntitySelector extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
|
.placeholder=${this.placeholder}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.includeEntities=${this.selector.entity.include_entities}
|
.includeEntities=${this.selector.entity.include_entities}
|
||||||
.excludeEntities=${this.selector.entity.exclude_entities}
|
.excludeEntities=${this.selector.entity.exclude_entities}
|
||||||
.reorder=${this.selector.entity.reorder ?? false}
|
.reorder=${this.selector.entity.reorder ?? false}
|
||||||
.entityFilter=${this._filterEntities}
|
.entityFilter=${this._filterEntities}
|
||||||
.createDomains=${this._createDomains}
|
.createDomains=${this._createDomains}
|
||||||
.placeholder=${this.placeholder}
|
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
></ha-entities-picker>
|
></ha-entities-picker>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export class HaIconSelector extends LitElement {
|
|||||||
${!placeholder && stateObj
|
${!placeholder && stateObj
|
||||||
? html`
|
? html`
|
||||||
<ha-state-icon
|
<ha-state-icon
|
||||||
slot="fallback"
|
slot="start"
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.stateObj=${stateObj}
|
.stateObj=${stateObj}
|
||||||
></ha-state-icon>
|
></ha-state-icon>
|
||||||
|
|||||||
@@ -393,6 +393,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
.rowRenderer=${this._renderRow}
|
.rowRenderer=${this._renderRow}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
@value-changed=${this._targetPicked}
|
@value-changed=${this._targetPicked}
|
||||||
|
use-top-label
|
||||||
.addButtonLabel=${this.hass.localize(
|
.addButtonLabel=${this.hass.localize(
|
||||||
"ui.components.target-picker.add_target"
|
"ui.components.target-picker.add_target"
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -132,9 +132,9 @@ class HaUserPicker extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
.notFoundLabel=${this._notFoundLabel}
|
|
||||||
.placeholder=${placeholder}
|
.placeholder=${placeholder}
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
|
.notFoundLabel=${this._notFoundLabel}
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.valueRenderer=${this._valueRenderer}
|
.valueRenderer=${this._valueRenderer}
|
||||||
.rowRenderer=${this._rowRenderer}
|
.rowRenderer=${this._rowRenderer}
|
||||||
|
|||||||
38
src/mixins/picker-mixin.ts
Normal file
38
src/mixins/picker-mixin.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import type { ReactiveElement } from "lit";
|
||||||
|
import { property } from "lit/decorators";
|
||||||
|
import type { Constructor } from "../types";
|
||||||
|
import type { PickerValueRenderer } from "../components/ha-picker-field";
|
||||||
|
|
||||||
|
export const PickerMixin = <T extends Constructor<ReactiveElement>>(
|
||||||
|
superClass: T
|
||||||
|
) => {
|
||||||
|
class PickerFieldClass extends superClass {
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public required = false;
|
||||||
|
|
||||||
|
@property() public icon?: string;
|
||||||
|
|
||||||
|
@property() public image?: string;
|
||||||
|
|
||||||
|
@property() public label?: string;
|
||||||
|
|
||||||
|
@property() public placeholder?: string;
|
||||||
|
|
||||||
|
@property() public helper?: string;
|
||||||
|
|
||||||
|
@property() public value?: string;
|
||||||
|
|
||||||
|
@property({ type: Boolean, reflect: true }) public unknown = false;
|
||||||
|
|
||||||
|
@property({ attribute: "unknown-item-text" })
|
||||||
|
public unknownItemText?: string;
|
||||||
|
|
||||||
|
@property({ attribute: "hide-clear-icon", type: Boolean })
|
||||||
|
public hideClearIcon = false;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public valueRenderer?: PickerValueRenderer;
|
||||||
|
}
|
||||||
|
return PickerFieldClass;
|
||||||
|
};
|
||||||
@@ -160,7 +160,7 @@ class DialogFloorDetail extends LitElement {
|
|||||||
${!this._icon
|
${!this._icon
|
||||||
? html`
|
? html`
|
||||||
<ha-floor-icon
|
<ha-floor-icon
|
||||||
slot="fallback"
|
slot="start"
|
||||||
.floor=${{ level: this._level }}
|
.floor=${{ level: this._level }}
|
||||||
></ha-floor-icon>
|
></ha-floor-icon>
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
|||||||
@value-changed=${this._iconChanged}
|
@value-changed=${this._iconChanged}
|
||||||
>
|
>
|
||||||
<ha-domain-icon
|
<ha-domain-icon
|
||||||
slot="fallback"
|
slot="start"
|
||||||
domain=${this._params.domain}
|
domain=${this._params.domain}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
>
|
>
|
||||||
@@ -176,8 +176,10 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
|||||||
id="category"
|
id="category"
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.scope=${this._params.domain}
|
.scope=${this._params.domain}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.components.category-picker.category"
|
||||||
|
)}
|
||||||
.value=${this._entryUpdates.category}
|
.value=${this._entryUpdates.category}
|
||||||
show-label
|
|
||||||
@value-changed=${this._registryEntryChanged}
|
@value-changed=${this._registryEntryChanged}
|
||||||
></ha-category-picker>`
|
></ha-category-picker>`
|
||||||
: nothing}
|
: nothing}
|
||||||
@@ -194,7 +196,6 @@ class DialogAutomationSave extends LitElement implements HassDialog {
|
|||||||
id="area"
|
id="area"
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._entryUpdates.area}
|
.value=${this._entryUpdates.area}
|
||||||
show-label
|
|
||||||
@value-changed=${this._registryEntryChanged}
|
@value-changed=${this._registryEntryChanged}
|
||||||
></ha-area-picker>`
|
></ha-area-picker>`
|
||||||
: nothing}
|
: nothing}
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ class DialogAssignCategory extends LitElement {
|
|||||||
<ha-category-picker
|
<ha-category-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.scope=${this._scope}
|
.scope=${this._scope}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.components.category-picker.category"
|
||||||
|
)}
|
||||||
.value=${this._category}
|
.value=${this._category}
|
||||||
@value-changed=${this._categoryChanged}
|
@value-changed=${this._categoryChanged}
|
||||||
></ha-category-picker>
|
></ha-category-picker>
|
||||||
|
|||||||
@@ -39,9 +39,6 @@ export class HaCategoryPicker extends SubscribeMixin(LitElement) {
|
|||||||
@property({ type: Boolean, attribute: "no-add" })
|
@property({ type: Boolean, attribute: "no-add" })
|
||||||
public noAdd = false;
|
public noAdd = false;
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "show-label" })
|
|
||||||
public showLabel = false;
|
|
||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) public required = false;
|
@property({ type: Boolean }) public required = false;
|
||||||
@@ -183,10 +180,6 @@ export class HaCategoryPicker extends SubscribeMixin(LitElement) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const placeholder =
|
|
||||||
this.placeholder ??
|
|
||||||
this.hass.localize("ui.components.category-picker.category");
|
|
||||||
|
|
||||||
const valueRenderer = this._computeValueRenderer(this._categories);
|
const valueRenderer = this._computeValueRenderer(this._categories);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
@@ -194,13 +187,12 @@ export class HaCategoryPicker extends SubscribeMixin(LitElement) {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
|
.placeholder=${this.placeholder}
|
||||||
|
.value=${this.value}
|
||||||
.notFoundLabel=${this._notFoundLabel}
|
.notFoundLabel=${this._notFoundLabel}
|
||||||
.emptyLabel=${this.hass.localize(
|
.emptyLabel=${this.hass.localize(
|
||||||
"ui.components.category-picker.no_categories"
|
"ui.components.category-picker.no_categories"
|
||||||
)}
|
)}
|
||||||
.placeholder=${placeholder}
|
|
||||||
.showLabel=${this.showLabel}
|
|
||||||
.value=${this.value}
|
|
||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
.valueRenderer=${valueRenderer}
|
.valueRenderer=${valueRenderer}
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||||||
<ha-area-picker
|
<ha-area-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._areaId}
|
.value=${this._areaId}
|
||||||
show-label
|
|
||||||
@value-changed=${this._areaPicked}
|
@value-changed=${this._areaPicked}
|
||||||
></ha-area-picker>
|
></ha-area-picker>
|
||||||
<ha-labels-picker
|
<ha-labels-picker
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
|||||||
${!this._icon && !stateObj?.attributes.icon && stateObj
|
${!this._icon && !stateObj?.attributes.icon && stateObj
|
||||||
? html`
|
? html`
|
||||||
<ha-state-icon
|
<ha-state-icon
|
||||||
slot="fallback"
|
slot="start"
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.stateObj=${stateObj}
|
.stateObj=${stateObj}
|
||||||
></ha-state-icon>
|
></ha-state-icon>
|
||||||
@@ -778,7 +778,6 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._areaId}
|
.value=${this._areaId}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
show-label
|
|
||||||
@value-changed=${this._areaPicked}
|
@value-changed=${this._areaPicked}
|
||||||
></ha-area-picker>`
|
></ha-area-picker>`
|
||||||
: ""}
|
: ""}
|
||||||
@@ -1013,7 +1012,6 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
|||||||
? html`<ha-area-picker
|
? html`<ha-area-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._areaId}
|
.value=${this._areaId}
|
||||||
show-label
|
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
@value-changed=${this._areaPicked}
|
@value-changed=${this._areaPicked}
|
||||||
></ha-area-picker>`
|
></ha-area-picker>`
|
||||||
|
|||||||
Reference in New Issue
Block a user