Use repeat for ha-form schemas

pull/22290/head
Paul Bottein 2024-10-08 17:30:33 +02:00
parent a35b4376ea
commit e2891f67a3
No known key found for this signature in database
1 changed files with 60 additions and 46 deletions

View File

@ -9,6 +9,7 @@ import {
TemplateResult, TemplateResult,
} from "lit"; } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { repeat } from "lit/directives/repeat";
import { dynamicElement } from "../../common/dom/dynamic-element-directive"; import { dynamicElement } from "../../common/dom/dynamic-element-directive";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { HomeAssistant } from "../../types"; import { HomeAssistant } from "../../types";
@ -110,6 +111,16 @@ export class HaForm extends LitElement implements HaFormElement {
} }
} }
private _schemaKeys = new WeakMap<HaFormSchema, string>();
private _getSchemaKey(schema: HaFormSchema) {
if (!this._schemaKeys.has(schema)) {
this._schemaKeys.set(schema, Math.random().toString());
}
return this._schemaKeys.get(schema)!;
}
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
<div class="root" part="root"> <div class="root" part="root">
@ -120,55 +131,58 @@ export class HaForm extends LitElement implements HaFormElement {
</ha-alert> </ha-alert>
` `
: ""} : ""}
${this.schema.map((item) => { ${repeat(
const error = getError(this.error, item); this.schema,
const warning = getWarning(this.warning, item); (item) => this._getSchemaKey(item),
(item) => {
return html` const error = getError(this.error, item);
${error const warning = getWarning(this.warning, item);
? html` return html`
<ha-alert own-margin alert-type="error"> ${error
${this._computeError(error, item)}
</ha-alert>
`
: warning
? html` ? html`
<ha-alert own-margin alert-type="warning"> <ha-alert own-margin alert-type="error">
${this._computeWarning(warning, item)} ${this._computeError(error, item)}
</ha-alert> </ha-alert>
` `
: ""} : warning
${"selector" in item ? html`
? html`<ha-selector <ha-alert own-margin alert-type="warning">
.schema=${item} ${this._computeWarning(warning, item)}
.hass=${this.hass} </ha-alert>
.name=${item.name} `
.selector=${item.selector} : ""}
.value=${getValue(this.data, item)} ${"selector" in item
.label=${this._computeLabel(item, this.data)} ? html`<ha-selector
.disabled=${item.disabled || this.disabled || false} .schema=${item}
.placeholder=${item.required ? "" : item.default} .hass=${this.hass}
.helper=${this._computeHelper(item)} .name=${item.name}
.localizeValue=${this.localizeValue} .selector=${item.selector}
.required=${item.required || false} .value=${getValue(this.data, item)}
.context=${this._generateContext(item)} .label=${this._computeLabel(item, this.data)}
></ha-selector>` .disabled=${item.disabled || this.disabled || false}
: dynamicElement(this.fieldElementName(item.type), { .placeholder=${item.required ? "" : item.default}
schema: item, .helper=${this._computeHelper(item)}
data: getValue(this.data, item), .localizeValue=${this.localizeValue}
label: this._computeLabel(item, this.data), .required=${item.required || false}
helper: this._computeHelper(item), .context=${this._generateContext(item)}
disabled: this.disabled || item.disabled || false, ></ha-selector>`
hass: this.hass, : dynamicElement(this.fieldElementName(item.type), {
localize: this.hass?.localize, schema: item,
computeLabel: this.computeLabel, data: getValue(this.data, item),
computeHelper: this.computeHelper, label: this._computeLabel(item, this.data),
localizeValue: this.localizeValue, helper: this._computeHelper(item),
context: this._generateContext(item), disabled: this.disabled || item.disabled || false,
...this.getFormProperties(), hass: this.hass,
})} localize: this.hass?.localize,
`; computeLabel: this.computeLabel,
})} computeHelper: this.computeHelper,
localizeValue: this.localizeValue,
context: this._generateContext(item),
...this.getFormProperties(),
})}
`;
}
)}
</div> </div>
`; `;
} }