Migrate ha-form to lit (#4000)

* Migrate ha-form to lit

* Fix import path

* Update

* add default, change suffix, fix import

* Fix select
This commit is contained in:
Bram Kragten 2019-10-18 16:08:34 +02:00 committed by GitHub
parent 035057b185
commit 00f2d36cb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 634 additions and 300 deletions

View File

@ -7,7 +7,7 @@ import {
css,
} from "lit-element";
import "@material/mwc-button";
import "../components/ha-form";
import "../components/ha-form/ha-form";
import "../components/ha-markdown";
import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin";
import { AuthProvider } from "../data/auth";

View File

@ -1,265 +0,0 @@
import "@polymer/paper-checkbox/paper-checkbox";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "./ha-paper-slider";
import { EventsMixin } from "../mixins/events-mixin";
/*
* @appliesMixin EventsMixin
*/
class HaForm extends EventsMixin(PolymerElement) {
static get template() {
return html`
<style>
.error {
color: red;
}
paper-checkbox {
display: inline-block;
padding: 22px 0;
}
</style>
<template is="dom-if" if="[[_isArray(schema)]]" restamp="">
<template is="dom-if" if="[[error.base]]">
<div class="error">[[computeError(error.base, schema)]]</div>
</template>
<template is="dom-repeat" items="[[schema]]">
<ha-form
data="[[_getValue(data, item)]]"
schema="[[item]]"
error="[[_getValue(error, item)]]"
on-data-changed="_valueChanged"
compute-error="[[computeError]]"
compute-label="[[computeLabel]]"
compute-suffix="[[computeSuffix]]"
></ha-form>
</template>
</template>
<template is="dom-if" if="[[!_isArray(schema)]]" restamp="">
<template is="dom-if" if="[[error]]">
<div class="error">[[computeError(error, schema)]]</div>
</template>
<template
is="dom-if"
if='[[_equals(schema.type, "string")]]'
restamp=""
>
<template
is="dom-if"
if='[[_includes(schema.name, "password")]]'
restamp=""
>
<paper-input
type="[[_passwordFieldType(unmaskedPassword)]]"
label="[[computeLabel(schema)]]"
value="{{data}}"
required="[[schema.required]]"
auto-validate="[[schema.required]]"
error-message="Required"
>
<paper-icon-button
toggles
active="{{unmaskedPassword}}"
slot="suffix"
icon="[[_passwordFieldIcon(unmaskedPassword)]]"
id="iconButton"
title="Click to toggle between masked and clear password"
>
</paper-icon-button>
</paper-input>
</template>
<template
is="dom-if"
if='[[!_includes(schema.name, "password")]]'
restamp=""
>
<paper-input
label="[[computeLabel(schema)]]"
value="{{data}}"
required="[[schema.required]]"
auto-validate="[[schema.required]]"
error-message="Required"
></paper-input>
</template>
</template>
<template
is="dom-if"
if='[[_equals(schema.type, "integer")]]'
restamp=""
>
<template is="dom-if" if="[[_isRange(schema)]]" restamp="">
<div>
[[computeLabel(schema)]]
<ha-paper-slider
pin=""
value="{{data}}"
min="[[schema.valueMin]]"
max="[[schema.valueMax]]"
></ha-paper-slider>
</div>
</template>
<template is="dom-if" if="[[!_isRange(schema)]]" restamp="">
<paper-input
label="[[computeLabel(schema)]]"
value="{{data}}"
type="number"
required="[[schema.required]]"
auto-validate="[[schema.required]]"
error-message="Required"
></paper-input>
</template>
</template>
<template is="dom-if" if='[[_equals(schema.type, "float")]]' restamp="">
<!-- TODO -->
<paper-input
label="[[computeLabel(schema)]]"
value="{{data}}"
required="[[schema.required]]"
auto-validate="[[schema.required]]"
error-message="Required"
>
<span suffix="" slot="suffix">[[computeSuffix(schema)]]</span>
</paper-input>
</template>
<template
is="dom-if"
if='[[_equals(schema.type, "boolean")]]'
restamp=""
>
<div>
<paper-checkbox checked="{{data}}"
>[[computeLabel(schema)]]</paper-checkbox
>
</div>
</template>
<template
is="dom-if"
if='[[_equals(schema.type, "select")]]'
restamp=""
>
<paper-dropdown-menu label="[[computeLabel(schema)]]">
<paper-listbox
slot="dropdown-content"
attr-for-selected="item-name"
selected="{{data}}"
>
<template is="dom-repeat" items="[[schema.options]]">
<paper-item item-name$="[[_optionValue(item)]]"
>[[_optionLabel(item)]]</paper-item
>
</template>
</paper-listbox>
</paper-dropdown-menu>
</template>
</template>
`;
}
static get properties() {
return {
data: {
type: Object,
notify: true,
},
schema: Object,
error: Object,
// A function that computes the label to be displayed for a given
// schema object.
computeLabel: {
type: Function,
value: () => (schema) => schema && schema.name,
},
// A function that computes the suffix to be displayed for a given
// schema object.
computeSuffix: {
type: Function,
value: () => (schema) =>
schema &&
schema.description &&
schema.description.unit_of_measurement,
},
// A function that computes an error message to be displayed for a
// given error ID, and relevant schema object
computeError: {
type: Function,
value: () => (error, schema) => error, // eslint-disable-line no-unused-vars
},
};
}
focus() {
const input = this.shadowRoot.querySelector(
"ha-form, paper-input, ha-paper-slider, paper-checkbox, paper-dropdown-menu"
);
if (!input) {
return;
}
input.focus();
}
_isArray(val) {
return Array.isArray(val);
}
_isRange(schema) {
return "valueMin" in schema && "valueMax" in schema;
}
_equals(a, b) {
return a === b;
}
_includes(a, b) {
return a.indexOf(b) >= 0;
}
_getValue(obj, item) {
if (obj) {
return obj[item.name];
}
return null;
}
_valueChanged(ev) {
let value = ev.detail.value;
if (ev.model.item.type === "integer") {
value = Number(ev.detail.value);
}
this.set(["data", ev.model.item.name], value);
}
_passwordFieldType(unmaskedPassword) {
return unmaskedPassword ? "text" : "password";
}
_passwordFieldIcon(unmaskedPassword) {
return unmaskedPassword ? "hass:eye-off" : "hass:eye";
}
_optionValue(item) {
return Array.isArray(item) ? item[0] : item;
}
_optionLabel(item) {
return Array.isArray(item) ? item[1] : item;
}
}
customElements.define("ha-form", HaForm);

View File

@ -0,0 +1,70 @@
import {
customElement,
LitElement,
html,
property,
TemplateResult,
CSSResult,
css,
query,
} from "lit-element";
import {
HaFormElement,
HaFormBooleanData,
HaFormBooleanSchema,
} from "./ha-form";
import { fireEvent } from "../../common/dom/fire_event";
import "@polymer/paper-checkbox/paper-checkbox";
// Not duplicate, is for typing
// tslint:disable-next-line
import { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox";
@customElement("ha-form-boolean")
export class HaFormBoolean extends LitElement implements HaFormElement {
@property() public schema!: HaFormBooleanSchema;
@property() public data!: HaFormBooleanData;
@property() public label!: string;
@property() public suffix!: string;
@query("paper-checkbox") private _input?: HTMLElement;
public focus() {
if (this._input) {
this._input.focus();
}
}
protected render(): TemplateResult {
return html`
<paper-checkbox .checked=${this.data} @change=${this._valueChanged}>
${this.label}
</paper-checkbox>
`;
}
private _valueChanged(ev: Event) {
fireEvent(
this,
"value-changed",
{
value: (ev.target as PaperCheckboxElement).checked,
},
{ bubbles: false }
);
}
static get styles(): CSSResult {
return css`
paper-checkbox {
display: inline-block;
padding: 22px 0;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-boolean": HaFormBoolean;
}
}

View File

@ -0,0 +1,65 @@
import {
customElement,
LitElement,
html,
property,
TemplateResult,
query,
} from "lit-element";
import { HaFormElement, HaFormFloatData, HaFormFloatSchema } from "./ha-form";
import { fireEvent } from "../../common/dom/fire_event";
import "@polymer/paper-input/paper-input";
// Not duplicate, is for typing
// tslint:disable-next-line
import { PaperInputElement } from "@polymer/paper-input/paper-input";
@customElement("ha-form-float")
export class HaFormFloat extends LitElement implements HaFormElement {
@property() public schema!: HaFormFloatSchema;
@property() public data!: HaFormFloatData;
@property() public label!: string;
@property() public suffix!: string;
@query("paper-input") private _input?: HTMLElement;
public focus() {
if (this._input) {
this._input.focus();
}
}
protected render(): TemplateResult {
return html`
<paper-input
.label=${this.label}
.value=${this.data}
.required=${this.schema.required}
.autoValidate=${this.schema.required}
@value-changed=${this._valueChanged}
>
<span suffix="" slot="suffix">${this.suffix}</span>
</paper-input>
`;
}
private _valueChanged(ev: Event) {
const value = Number((ev.target as PaperInputElement).value);
if (this.data === value) {
return;
}
fireEvent(
this,
"value-changed",
{
value,
},
{ bubbles: false }
);
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-float": HaFormFloat;
}
}

View File

@ -0,0 +1,85 @@
import {
customElement,
LitElement,
html,
property,
TemplateResult,
query,
} from "lit-element";
import {
HaFormElement,
HaFormIntegerData,
HaFormIntegerSchema,
} from "./ha-form";
import { fireEvent } from "../../common/dom/fire_event";
import "../ha-paper-slider";
import "@polymer/paper-input/paper-input";
// Not duplicate, is for typing
// tslint:disable-next-line
import { PaperInputElement } from "@polymer/paper-input/paper-input";
import { PaperSliderElement } from "@polymer/paper-slider/paper-slider";
@customElement("ha-form-integer")
export class HaFormInteger extends LitElement implements HaFormElement {
@property() public schema!: HaFormIntegerSchema;
@property() public data!: HaFormIntegerData;
@property() public label!: string;
@property() public suffix!: string;
@query("paper-input ha-paper-slider") private _input?: HTMLElement;
public focus() {
if (this._input) {
this._input.focus();
}
}
protected render(): TemplateResult {
return "valueMin" in this.schema && "valueMax" in this.schema
? html`
<div>
${this.label}
<ha-paper-slider
pin=""
.value=${this.data}
.min=${this.schema.valueMin}
.max=${this.schema.valueMax}
@value-changed=${this._valueChanged}
></ha-paper-slider>
</div>
`
: html`
<paper-input
type="number"
.label=${this.label}
.value=${this.data}
.required=${this.schema.required}
.autoValidate=${this.schema.required}
@value-changed=${this._valueChanged}
></paper-input>
`;
}
private _valueChanged(ev: Event) {
const value = Number(
(ev.target as PaperInputElement | PaperSliderElement).value
);
if (this.data === value) {
return;
}
fireEvent(
this,
"value-changed",
{
value,
},
{ bubbles: false }
);
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-integer": HaFormInteger;
}
}

View File

@ -0,0 +1,78 @@
import {
customElement,
LitElement,
html,
property,
TemplateResult,
query,
} from "lit-element";
import { HaFormElement, HaFormSelectData, HaFormSelectSchema } from "./ha-form";
import { fireEvent } from "../../common/dom/fire_event";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-listbox/paper-listbox";
import "@polymer/paper-item/paper-item";
@customElement("ha-form-select")
export class HaFormSelect extends LitElement implements HaFormElement {
@property() public schema!: HaFormSelectSchema;
@property() public data!: HaFormSelectData;
@property() public label!: string;
@property() public suffix!: string;
@query("paper-dropdown-menu") private _input?: HTMLElement;
public focus() {
if (this._input) {
this._input.focus();
}
}
protected render(): TemplateResult {
return html`
<paper-dropdown-menu .label=${this.label}>
<paper-listbox
slot="dropdown-content"
attr-for-selected="item-value"
.selected=${this.data}
@selected-item-changed=${this._valueChanged}
>
${this.schema.options!.map(
(item) => html`
<paper-item .itemValue=${this._optionValue(item)}>
${this._optionLabel(item)}
</paper-item>
`
)}
</paper-listbox>
</paper-dropdown-menu>
`;
}
private _optionValue(item) {
return Array.isArray(item) ? item[0] : item;
}
private _optionLabel(item) {
return Array.isArray(item) ? item[1] : item;
}
private _valueChanged(ev: CustomEvent) {
if (!ev.detail.value) {
return;
}
fireEvent(
this,
"value-changed",
{
value: ev.detail.value.itemValue,
},
{ bubbles: false }
);
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-select": HaFormSelect;
}
}

View File

@ -0,0 +1,93 @@
import {
customElement,
LitElement,
html,
property,
TemplateResult,
query,
} from "lit-element";
import { HaFormElement, HaFormStringData, HaFormStringSchema } from "./ha-form";
import { fireEvent } from "../../common/dom/fire_event";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-icon-button/paper-icon-button";
// Not duplicate, is for typing
// tslint:disable-next-line
import { PaperInputElement } from "@polymer/paper-input/paper-input";
@customElement("ha-form-string")
export class HaFormString extends LitElement implements HaFormElement {
@property() public schema!: HaFormStringSchema;
@property() public data!: HaFormStringData;
@property() public label!: string;
@property() public suffix!: string;
@property() private _unmaskedPassword = false;
@query("paper-input") private _input?: HTMLElement;
public focus() {
if (this._input) {
this._input.focus();
}
}
protected render(): TemplateResult {
return this.schema.name.includes("password")
? html`
<paper-input
.type=${this._unmaskedPassword ? "text" : "password"}
.label=${this.label}
.value=${this.data}
.required=${this.schema.required}
.autoValidate=${this.schema.required}
@value-changed=${this._valueChanged}
>
<paper-icon-button
toggles
.active=${this._unmaskedPassword}
slot="suffix"
.icon=${this._unmaskedPassword ? "hass:eye-off" : "hass:eye"}
id="iconButton"
title="Click to toggle between masked and clear password"
@click=${this._toggleUnmaskedPassword}
>
</paper-icon-button>
</paper-input>
`
: html`
<paper-input
.label=${this.label}
.value=${this.data}
.required=${this.schema.required}
.autoValidate=${this.schema.required}
error-message="Required"
@value-changed=${this._valueChanged}
></paper-input>
`;
}
private _toggleUnmaskedPassword(ev: Event) {
this._unmaskedPassword = (ev.target as any).active;
}
private _valueChanged(ev: Event) {
const value = (ev.target as PaperInputElement).value;
if (this.data === value) {
return;
}
fireEvent(
this,
"value-changed",
{
value,
},
{ bubbles: false }
);
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-string": HaFormString;
}
}

View File

@ -0,0 +1,225 @@
import {
customElement,
LitElement,
html,
property,
query,
CSSResult,
css,
PropertyValues,
} from "lit-element";
import "./ha-form-string";
import "./ha-form-integer";
import "./ha-form-float";
import "./ha-form-boolean";
import "./ha-form-select";
import { fireEvent } from "../../common/dom/fire_event";
export type HaFormSchema =
| HaFormStringSchema
| HaFormIntegerSchema
| HaFormFloatSchema
| HaFormBooleanSchema
| HaFormSelectSchema;
export interface HaFormBaseSchema {
name: string;
default?: HaFormData;
required?: boolean;
optional?: boolean;
description?: { suffix?: string };
}
export interface HaFormIntegerSchema extends HaFormBaseSchema {
type: "integer";
default?: HaFormIntegerData;
valueMin?: number;
valueMax?: number;
}
export interface HaFormSelectSchema extends HaFormBaseSchema {
type: "select";
options?: string[];
}
export interface HaFormFloatSchema extends HaFormBaseSchema {
type: "float";
}
export interface HaFormStringSchema extends HaFormBaseSchema {
type: "string";
}
export interface HaFormBooleanSchema extends HaFormBaseSchema {
type: "boolean";
}
export interface HaFormDataContainer {
[key: string]: HaFormData;
}
export type HaFormData =
| HaFormStringData
| HaFormIntegerData
| HaFormFloatData
| HaFormBooleanData
| HaFormSelectData;
export type HaFormStringData = string;
export type HaFormIntegerData = number;
export type HaFormFloatData = number;
export type HaFormBooleanData = boolean;
export type HaFormSelectData = string;
export interface HaFormElement extends LitElement {
schema: HaFormSchema;
data: HaFormDataContainer | HaFormData;
label?: string;
suffix?: string;
}
@customElement("ha-form")
export class HaForm extends LitElement implements HaFormElement {
@property() public data!: HaFormDataContainer | HaFormData;
@property() public schema!: HaFormSchema;
@property() public error;
@property() public computeError?: (schema: HaFormSchema, error) => string;
@property() public computeLabel?: (schema: HaFormSchema) => string;
@property() public computeSuffix?: (schema: HaFormSchema) => string;
@query("ha-form") private _childForm?: HaForm;
@query("#element") private _elementContainer?: HTMLDivElement;
public focus() {
const input = this._childForm
? this._childForm
: this._elementContainer
? this._elementContainer.lastChild
: undefined;
if (!input) {
return;
}
(input as HTMLElement).focus();
}
protected render() {
if (Array.isArray(this.schema)) {
return html`
${this.error && this.error.base
? html`
<div class="error">
${this._computeError(this.error.base, this.schema)}
</div>
`
: ""}
${this.schema.map(
(item) => html`
<ha-form
.data=${this._getValue(this.data, item)}
.schema=${item}
.error=${this._getValue(this.error, item)}
@value-changed=${this._valueChanged}
.computeError=${this.computeError}
.computeLabel=${this.computeLabel}
.computeSuffix=${this.computeSuffix}
></ha-form>
`
)}
`;
}
return html`
${this.error
? html`
<div class="error">
${this._computeError(this.error, this.schema)}
</div>
`
: ""}
<div id="element" @value-changed=${this._valueChanged}></div>
`;
}
protected updated(changedProperties: PropertyValues) {
const schemaChanged = changedProperties.has("schema");
const oldSchema = schemaChanged
? changedProperties.get("schema")
: undefined;
if (
!Array.isArray(this.schema) &&
schemaChanged &&
(!oldSchema || (oldSchema as HaFormSchema).type !== this.schema.type)
) {
const element = document.createElement(
`ha-form-${this.schema.type}`
) as HaFormElement;
element.schema = this.schema;
element.data = this.data;
element.label = this._computeLabel(this.schema);
element.suffix = this._computeSuffix(this.schema);
if (this._elementContainer!.lastChild) {
this._elementContainer!.removeChild(this._elementContainer!.lastChild);
}
this._elementContainer!.append(element);
} else if (this._elementContainer && this._elementContainer.lastChild) {
const element = this._elementContainer!.lastChild as HaFormElement;
element.schema = this.schema;
element.data = this.data;
element.label = this._computeLabel(this.schema);
element.suffix = this._computeSuffix(this.schema);
}
}
private _computeLabel(schema: HaFormSchema) {
return this.computeLabel
? this.computeLabel(schema)
: schema
? schema.name
: "";
}
private _computeSuffix(schema: HaFormSchema) {
return this.computeSuffix
? this.computeSuffix(schema)
: schema && schema.description
? schema.description.suffix
: "";
}
private _computeError(error, schema: HaFormSchema) {
return this.computeError ? this.computeError(error, schema) : error;
}
private _getValue(obj, item) {
if (obj) {
return obj[item.name];
}
return null;
}
private _valueChanged(ev: CustomEvent) {
ev.stopPropagation();
const schema = (ev.target as HaFormElement).schema;
const data = this.data as HaFormDataContainer;
data[schema.name] = ev.detail.value;
fireEvent(this, "value-changed", {
value: { ...data },
});
}
static get styles(): CSSResult {
return css`
.error {
color: var(--error-color);
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form": HaForm;
}
}

View File

@ -14,7 +14,7 @@ import "@polymer/paper-tooltip/paper-tooltip";
import "@polymer/paper-spinner/paper-spinner";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import "../../components/ha-form";
import "../../components/ha-form/ha-form";
import "../../components/ha-markdown";
import "../../resources/ha-style";
import "../../components/dialog/ha-paper-dialog";

View File

@ -12,10 +12,9 @@ import "@material/mwc-button";
import "@polymer/paper-tooltip/paper-tooltip";
import "@polymer/paper-spinner/paper-spinner";
import "../../components/ha-form";
import "../../components/ha-form/ha-form";
import "../../components/ha-markdown";
import "../../resources/ha-style";
import { PolymerChangedEvent, applyPolymerEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types";
import { fireEvent } from "../../common/dom/fire_event";
import { configFlowContentStyles } from "./styles";
@ -69,7 +68,7 @@ class StepFlowForm extends LitElement {
${this.flowConfig.renderShowFormStepDescription(this.hass, this.step)}
<ha-form
.data=${stepData}
@data-changed=${this._stepDataChanged}
@value-changed=${this._stepDataChanged}
.schema=${step.data_schema}
.error=${step.errors}
.computeLabel=${this._labelCallback}
@ -169,8 +168,8 @@ class StepFlowForm extends LitElement {
}
}
private _stepDataChanged(ev: PolymerChangedEvent<any>): void {
this._stepData = applyPolymerEvent(ev, this._stepData);
private _stepDataChanged(ev: CustomEvent): void {
this._stepData = ev.detail.value;
}
private _labelCallback = (field: FieldSchema): string =>

View File

@ -2,7 +2,7 @@ import { h, Component } from "preact";
import "../../../../components/device/ha-device-picker";
import "../../../../components/device/ha-device-condition-picker";
import "../../../../components/ha-form";
import "../../../../components/ha-form/ha-form";
import {
fetchDeviceConditionCapabilities,
@ -64,9 +64,9 @@ export default class DeviceCondition extends Component<any, any> {
{extraFieldsData && (
<ha-form
data={Object.assign({}, ...extraFieldsData)}
onData-changed={this._extraFieldsChanged}
schema={this.state.capabilities.extra_fields}
computeLabel={this._extraFieldsComputeLabelCallback(hass.localize)}
onvalue-changed={this._extraFieldsChanged}
/>
)}
</div>
@ -98,15 +98,9 @@ export default class DeviceCondition extends Component<any, any> {
}
private _extraFieldsChanged(ev) {
if (!ev.detail.path) {
return;
}
const item = ev.detail.path.replace("data.", "");
const value = ev.detail.value || undefined;
this.props.onChange(this.props.index, {
...this.props.condition,
[item]: value,
...ev.detail.value,
});
}

View File

@ -2,7 +2,7 @@ import { h, Component } from "preact";
import "../../../../components/device/ha-device-picker";
import "../../../../components/device/ha-device-action-picker";
import "../../../../components/ha-form";
import "../../../../components/ha-form/ha-form";
import {
fetchDeviceActionCapabilities,
@ -117,15 +117,9 @@ export default class DeviceActionEditor extends Component<
}
private _extraFieldsChanged(ev) {
if (!ev.detail.path) {
return;
}
const item = ev.detail.path.replace("data.", "");
const value = ev.detail.value || undefined;
this.props.onChange(this.props.index, {
...this.props.action,
[item]: value,
...ev.detail.value,
});
}

View File

@ -2,7 +2,7 @@ import { h, Component } from "preact";
import "../../../../components/device/ha-device-picker";
import "../../../../components/device/ha-device-trigger-picker";
import "../../../../components/ha-form";
import "../../../../components/ha-form/ha-form";
import {
fetchDeviceTriggerCapabilities,
@ -65,9 +65,9 @@ export default class DeviceTrigger extends Component<any, any> {
{extraFieldsData && (
<ha-form
data={Object.assign({}, ...extraFieldsData)}
onData-changed={this._extraFieldsChanged}
schema={this.state.capabilities.extra_fields}
computeLabel={this._extraFieldsComputeLabelCallback(hass.localize)}
onvalue-changed={this._extraFieldsChanged}
/>
)}
</div>
@ -99,15 +99,9 @@ export default class DeviceTrigger extends Component<any, any> {
}
private _extraFieldsChanged(ev) {
if (!ev.detail.path) {
return;
}
const item = ev.detail.path.replace("data.", "");
const value = ev.detail.value || undefined;
this.props.onChange(this.props.index, {
...this.props.trigger,
[item]: value,
...ev.detail.value,
});
}

View File

@ -5,7 +5,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../components/dialog/ha-paper-dialog";
import "../../components/ha-form";
import "../../components/ha-form/ha-form";
import "../../components/ha-markdown";
import "../../resources/ha-style";

View File

@ -33,7 +33,9 @@ documentContainer.innerHTML = `<custom-style>
--scrollbar-thumb-color: rgb(194, 194, 194);
--error-state-color: #db4437;
--error-color: #db4437;
--error-state-color: var(--error-color);
/* states and badges */
--state-icon-color: #44739e;