diff --git a/src/components/ha-form/ha-form-expandable.ts b/src/components/ha-form/ha-form-expandable.ts index f8e88c43aa..1ffa6339b5 100644 --- a/src/components/ha-form/ha-form-expandable.ts +++ b/src/components/ha-form/ha-form-expandable.ts @@ -21,13 +21,45 @@ export class HaFormExpendable extends LitElement implements HaFormElement { @property({ attribute: false }) public computeLabel?: ( schema: HaFormSchema, - data?: HaFormDataContainer + data?: HaFormDataContainer, + options?: { path?: string[] } ) => string; @property({ attribute: false }) public computeHelper?: ( - schema: HaFormSchema + schema: HaFormSchema, + options?: { path?: string[] } ) => string; + private _renderDescription() { + const description = this.computeHelper?.(this.schema); + return description ? html`

${description}

` : nothing; + } + + private _computeLabel = ( + schema: HaFormSchema, + data?: HaFormDataContainer, + options?: { path?: string[] } + ) => { + if (!this.computeLabel) return this.computeLabel; + + return this.computeLabel(schema, data, { + ...options, + path: [...(options?.path || []), this.schema.name], + }); + }; + + private _computeHelper = ( + schema: HaFormSchema, + options?: { path?: string[] } + ) => { + if (!this.computeHelper) return this.computeHelper; + + return this.computeHelper(schema, { + ...options, + path: [...(options?.path || []), this.schema.name], + }); + }; + protected render() { return html` @@ -43,16 +75,17 @@ export class HaFormExpendable extends LitElement implements HaFormElement { ` : nothing} - ${this.schema.title} + ${this.schema.title || this.computeLabel?.(this.schema)}
+ ${this._renderDescription()}
@@ -71,6 +104,9 @@ export class HaFormExpendable extends LitElement implements HaFormElement { .content { padding: 12px; } + .content p { + margin: 0 0 24px; + } ha-expansion-panel { display: block; --expansion-panel-content-padding: 0; diff --git a/src/components/ha-form/ha-form.ts b/src/components/ha-form/ha-form.ts index 0d460098b0..0894ac38c4 100644 --- a/src/components/ha-form/ha-form.ts +++ b/src/components/ha-form/ha-form.ts @@ -31,7 +31,7 @@ const LOAD_ELEMENTS = { }; const getValue = (obj, item) => - obj ? (!item.name ? obj : obj[item.name]) : null; + obj ? (!item.name || item.flatten ? obj : obj[item.name]) : null; const getError = (obj, item) => (obj && item.name ? obj[item.name] : null); @@ -73,10 +73,6 @@ export class HaForm extends LitElement implements HaFormElement { schema: any ) => string | undefined; - @property({ attribute: false }) public localizeValue?: ( - key: string - ) => string; - protected getFormProperties(): Record { return {}; } @@ -149,7 +145,6 @@ export class HaForm extends LitElement implements HaFormElement { .disabled=${item.disabled || this.disabled || false} .placeholder=${item.required ? "" : item.default} .helper=${this._computeHelper(item)} - .localizeValue=${this.localizeValue} .required=${item.required || false} .context=${this._generateContext(item)} >` @@ -204,9 +199,10 @@ export class HaForm extends LitElement implements HaFormElement { if (ev.target === this) return; - const newValue = !schema.name - ? ev.detail.value - : { [schema.name]: ev.detail.value }; + const newValue = + !schema.name || ("flatten" in schema && schema.flatten) + ? ev.detail.value + : { [schema.name]: ev.detail.value }; this.data = { ...this.data, diff --git a/src/components/ha-form/types.ts b/src/components/ha-form/types.ts index e2e032312d..53a51313a1 100644 --- a/src/components/ha-form/types.ts +++ b/src/components/ha-form/types.ts @@ -31,15 +31,15 @@ export interface HaFormBaseSchema { export interface HaFormGridSchema extends HaFormBaseSchema { type: "grid"; - name: string; + flatten?: boolean; column_min_width?: string; schema: readonly HaFormSchema[]; } export interface HaFormExpandableSchema extends HaFormBaseSchema { type: "expandable"; - name: ""; - title: string; + flatten?: boolean; + title?: string; icon?: string; iconPath?: string; expanded?: boolean; @@ -100,7 +100,7 @@ export type SchemaUnion< SchemaArray extends readonly HaFormSchema[], Schema = SchemaArray[number], > = Schema extends HaFormGridSchema | HaFormExpandableSchema - ? SchemaUnion + ? SchemaUnion | Schema : Schema; export interface HaFormDataContainer { diff --git a/src/components/ha-selector/ha-selector-location.ts b/src/components/ha-selector/ha-selector-location.ts index 01fc052cb2..2ac0b8b82b 100644 --- a/src/components/ha-selector/ha-selector-location.ts +++ b/src/components/ha-selector/ha-selector-location.ts @@ -162,8 +162,14 @@ export class HaLocationSelector extends LitElement { private _computeLabel = ( entry: SchemaUnion> - ): string => - this.hass.localize(`ui.components.selectors.location.${entry.name}`); + ): string => { + if (entry.name) { + return this.hass.localize( + `ui.components.selectors.location.${entry.name}` + ); + } + return ""; + }; static styles = css` ha-locations-editor { diff --git a/src/dialogs/config-flow/show-dialog-config-flow.ts b/src/dialogs/config-flow/show-dialog-config-flow.ts index 1f930ea970..6682ce9a17 100644 --- a/src/dialogs/config-flow/show-dialog-config-flow.ts +++ b/src/dialogs/config-flow/show-dialog-config-flow.ts @@ -76,19 +76,36 @@ export const showConfigFlowDialog = ( : ""; }, - renderShowFormStepFieldLabel(hass, step, field) { + renderShowFormStepFieldLabel(hass, step, field, options) { + if (field.type === "expandable") { + return hass.localize( + `component.${step.handler}.config.step.${step.step_id}.sections.${field.name}.name` + ); + } + + const prefix = options?.path?.[0] ? `sections.${options.path[0]}` : ""; + return ( hass.localize( - `component.${step.handler}.config.step.${step.step_id}.data.${field.name}` + `component.${step.handler}.config.step.${step.step_id}.${prefix}data.${field.name}` ) || field.name ); }, - renderShowFormStepFieldHelper(hass, step, field) { + renderShowFormStepFieldHelper(hass, step, field, options) { + if (field.type === "expandable") { + return hass.localize( + `component.${step.translation_domain || step.handler}.config.step.${step.step_id}.sections.${field.name}.description` + ); + } + + const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : ""; + const description = hass.localize( - `component.${step.translation_domain || step.handler}.config.step.${step.step_id}.data_description.${field.name}`, + `component.${step.translation_domain || step.handler}.config.step.${step.step_id}.${prefix}data_description.${field.name}`, step.description_placeholders ); + return description ? html`` : ""; diff --git a/src/dialogs/config-flow/show-dialog-data-entry-flow.ts b/src/dialogs/config-flow/show-dialog-data-entry-flow.ts index 54caaecbc7..4ae9965e85 100644 --- a/src/dialogs/config-flow/show-dialog-data-entry-flow.ts +++ b/src/dialogs/config-flow/show-dialog-data-entry-flow.ts @@ -49,13 +49,15 @@ export interface FlowConfig { renderShowFormStepFieldLabel( hass: HomeAssistant, step: DataEntryFlowStepForm, - field: HaFormSchema + field: HaFormSchema, + options: { path?: string[]; [key: string]: any } ): string; renderShowFormStepFieldHelper( hass: HomeAssistant, step: DataEntryFlowStepForm, - field: HaFormSchema + field: HaFormSchema, + options: { path?: string[]; [key: string]: any } ): TemplateResult | string; renderShowFormStepFieldError( diff --git a/src/dialogs/config-flow/show-dialog-options-flow.ts b/src/dialogs/config-flow/show-dialog-options-flow.ts index 829f7b4718..089f0eee33 100644 --- a/src/dialogs/config-flow/show-dialog-options-flow.ts +++ b/src/dialogs/config-flow/show-dialog-options-flow.ts @@ -93,17 +93,33 @@ export const showOptionsFlowDialog = ( : ""; }, - renderShowFormStepFieldLabel(hass, step, field) { + renderShowFormStepFieldLabel(hass, step, field, options) { + if (field.type === "expandable") { + return hass.localize( + `component.${configEntry.domain}.options.step.${step.step_id}.sections.${field.name}.name` + ); + } + + const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : ""; + return ( hass.localize( - `component.${configEntry.domain}.options.step.${step.step_id}.data.${field.name}` + `component.${configEntry.domain}.options.step.${step.step_id}.${prefix}data.${field.name}` ) || field.name ); }, - renderShowFormStepFieldHelper(hass, step, field) { + renderShowFormStepFieldHelper(hass, step, field, options) { + if (field.type === "expandable") { + return hass.localize( + `component.${step.translation_domain || configEntry.domain}.options.step.${step.step_id}.sections.${field.name}.description` + ); + } + + const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : ""; + const description = hass.localize( - `component.${step.translation_domain || configEntry.domain}.options.step.${step.step_id}.data_description.${field.name}`, + `component.${step.translation_domain || configEntry.domain}.options.step.${step.step_id}.${prefix}data_description.${field.name}`, step.description_placeholders ); return description diff --git a/src/dialogs/config-flow/step-flow-form.ts b/src/dialogs/config-flow/step-flow-form.ts index 20c665df90..537c5731dd 100644 --- a/src/dialogs/config-flow/step-flow-form.ts +++ b/src/dialogs/config-flow/step-flow-form.ts @@ -225,11 +225,24 @@ class StepFlowForm extends LitElement { this._stepData = ev.detail.value; } - private _labelCallback = (field: HaFormSchema): string => - this.flowConfig.renderShowFormStepFieldLabel(this.hass, this.step, field); + private _labelCallback = (field: HaFormSchema, _data, options): string => + this.flowConfig.renderShowFormStepFieldLabel( + this.hass, + this.step, + field, + options + ); - private _helperCallback = (field: HaFormSchema): string | TemplateResult => - this.flowConfig.renderShowFormStepFieldHelper(this.hass, this.step, field); + private _helperCallback = ( + field: HaFormSchema, + options + ): string | TemplateResult => + this.flowConfig.renderShowFormStepFieldHelper( + this.hass, + this.step, + field, + options + ); private _errorCallback = (error: string) => this.flowConfig.renderShowFormStepFieldError(this.hass, this.step, error); diff --git a/src/panels/config/repairs/show-dialog-repair-flow.ts b/src/panels/config/repairs/show-dialog-repair-flow.ts index 015b60b2d3..8114d3ab75 100644 --- a/src/panels/config/repairs/show-dialog-repair-flow.ts +++ b/src/panels/config/repairs/show-dialog-repair-flow.ts @@ -96,20 +96,20 @@ export const showRepairsFlowDialog = ( : ""; }, - renderShowFormStepFieldLabel(hass, step, field) { + renderShowFormStepFieldLabel(hass, step, field, options) { return hass.localize( `component.${issue.domain}.issues.${ issue.translation_key || issue.issue_id - }.fix_flow.step.${step.step_id}.data.${field.name}`, + }.fix_flow.step.${step.step_id}.${options?.prefix ? `section.${options.prefix[0]}.` : ""}data.${field.name}`, step.description_placeholders ); }, - renderShowFormStepFieldHelper(hass, step, field) { + renderShowFormStepFieldHelper(hass, step, field, options) { const description = hass.localize( `component.${issue.domain}.issues.${ issue.translation_key || issue.issue_id - }.fix_flow.step.${step.step_id}.data_description.${field.name}`, + }.fix_flow.step.${step.step_id}.${options?.prefix ? `section.${options.prefix[0]}.` : ""}data_description.${field.name}`, step.description_placeholders ); return description diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts index d2a9d155d2..2458596fa4 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts @@ -74,10 +74,10 @@ export class HuiEntityBadgeEditor [ { name: "entity", selector: { entity: {} } }, { - name: "", + name: "appearance", type: "expandable", + flatten: true, iconPath: mdiPalette, - title: localize(`ui.panel.lovelace.editor.badge.entity.appearance`), schema: [ { name: "", @@ -153,9 +153,9 @@ export class HuiEntityBadgeEditor ], }, { - name: "", + name: "interactions", type: "expandable", - title: localize(`ui.panel.lovelace.editor.badge.entity.interactions`), + flatten: true, iconPath: mdiGestureTap, schema: [ { @@ -238,6 +238,8 @@ export class HuiEntityBadgeEditor case "state_content": case "show_entity_picture": case "displayed_elements": + case "appearance": + case "interactions": return this.hass!.localize( `ui.panel.lovelace.editor.badge.entity.${schema.name}` ); diff --git a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts index 587bb85fe4..cc8500eeb6 100644 --- a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts @@ -14,7 +14,6 @@ import { union, } from "superstruct"; import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event"; -import { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; import type { HaFormSchema, @@ -69,18 +68,14 @@ export class HuiTileCardEditor } private _schema = memoizeOne( - ( - localize: LocalizeFunc, - entityId: string | undefined, - hideState: boolean - ) => + (entityId: string | undefined, hideState: boolean) => [ { name: "entity", selector: { entity: {} } }, { - name: "", + name: "appearance", + flatten: true, type: "expandable", iconPath: mdiPalette, - title: localize(`ui.panel.lovelace.editor.card.tile.appearance`), schema: [ { name: "", @@ -136,9 +131,9 @@ export class HuiTileCardEditor ], }, { - name: "", + name: "interactions", type: "expandable", - title: localize(`ui.panel.lovelace.editor.card.tile.interactions`), + flatten: true, iconPath: mdiGestureTap, schema: [ { @@ -178,7 +173,6 @@ export class HuiTileCardEditor : undefined; const schema = this._schema( - this.hass!.localize, this._config.entity, this._config.hide_state ?? false ); @@ -306,6 +300,8 @@ export class HuiTileCardEditor case "vertical": case "hide_state": case "state_content": + case "appearance": + case "interactions": return this.hass!.localize( `ui.panel.lovelace.editor.card.tile.${schema.name}` );