From b86c1db83d98af555f6fcc827604be23bac54b12 Mon Sep 17 00:00:00 2001 From: Wendelin <12148533+wendevlin@users.noreply.github.com> Date: Fri, 29 Aug 2025 08:39:06 +0200 Subject: [PATCH] Automation editor: fix focus handling (#26755) --- src/components/ha-automation-row.ts | 4 +- src/data/automation.ts | 6 +- .../action/ha-automation-action-row.ts | 5 +- .../condition/ha-automation-condition-row.ts | 5 +- .../automation/ha-automation-sidebar.ts | 2 +- .../option/ha-automation-option-row.ts | 5 +- .../trigger/ha-automation-trigger-row.ts | 5 +- .../config/script/ha-script-field-row.ts | 63 ++++++++----------- .../config/script/manual-script-editor.ts | 19 ++++-- 9 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/components/ha-automation-row.ts b/src/components/ha-automation-row.ts index e15a65bd50..6a0858682c 100644 --- a/src/components/ha-automation-row.ts +++ b/src/components/ha-automation-row.ts @@ -103,7 +103,9 @@ export class HaAutomationRow extends LitElement { } public focus() { - requestAnimationFrame(() => this._rowElement?.focus()); + requestAnimationFrame(() => { + this._rowElement?.focus(); + }); } static styles = css` diff --git a/src/data/automation.ts b/src/data/automation.ts index 00e69fadff..f629d73a44 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -558,11 +558,11 @@ export interface AutomationClipboard { export interface BaseSidebarConfig { toggleYamlMode: () => boolean; delete: () => void; + close: (focus?: boolean) => void; } export interface TriggerSidebarConfig extends BaseSidebarConfig { save: (value: Trigger) => void; - close: () => void; rename: () => void; disable: () => void; duplicate: () => void; @@ -575,7 +575,6 @@ export interface TriggerSidebarConfig extends BaseSidebarConfig { export interface ConditionSidebarConfig extends BaseSidebarConfig { save: (value: Condition) => void; - close: () => void; rename: () => void; disable: () => void; test: () => void; @@ -589,7 +588,6 @@ export interface ConditionSidebarConfig extends BaseSidebarConfig { export interface ActionSidebarConfig extends BaseSidebarConfig { save: (value: Action) => void; - close: () => void; rename: () => void; disable: () => void; duplicate: () => void; @@ -604,7 +602,6 @@ export interface ActionSidebarConfig extends BaseSidebarConfig { } export interface OptionSidebarConfig extends BaseSidebarConfig { - close: () => void; rename: () => void; duplicate: () => void; defaultOption?: boolean; @@ -612,7 +609,6 @@ export interface OptionSidebarConfig extends BaseSidebarConfig { export interface ScriptFieldSidebarConfig extends BaseSidebarConfig { save: (value: Field) => void; - close: () => void; config: { field: Field; selector: boolean; diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts index 034b55073a..d34bee9a05 100644 --- a/src/panels/config/automation/action/ha-automation-action-row.ts +++ b/src/panels/config/automation/action/ha-automation-action-row.ts @@ -676,9 +676,12 @@ export default class HaAutomationActionRow extends LitElement { save: (value) => { fireEvent(this, "value-changed", { value }); }, - close: () => { + close: (focus?: boolean) => { this._selected = false; fireEvent(this, "close-sidebar"); + if (focus) { + this.focus(); + } }, rename: () => { this._renameAction(); diff --git a/src/panels/config/automation/condition/ha-automation-condition-row.ts b/src/panels/config/automation/condition/ha-automation-condition-row.ts index 8b14e08f0a..bda6801e42 100644 --- a/src/panels/config/automation/condition/ha-automation-condition-row.ts +++ b/src/panels/config/automation/condition/ha-automation-condition-row.ts @@ -648,9 +648,12 @@ export default class HaAutomationConditionRow extends LitElement { save: (value) => { fireEvent(this, "value-changed", { value }); }, - close: () => { + close: (focus?: boolean) => { this._selected = false; fireEvent(this, "close-sidebar"); + if (focus) { + this.focus(); + } }, rename: () => { this._renameCondition(); diff --git a/src/panels/config/automation/ha-automation-sidebar.ts b/src/panels/config/automation/ha-automation-sidebar.ts index 14a60b0319..a62ee4d440 100644 --- a/src/panels/config/automation/ha-automation-sidebar.ts +++ b/src/panels/config/automation/ha-automation-sidebar.ts @@ -193,7 +193,7 @@ export default class HaAutomationSidebar extends LitElement { } private _closeSidebar() { - this.config?.close(); + this.config?.close(true); } private _toggleYamlMode = () => { diff --git a/src/panels/config/automation/option/ha-automation-option-row.ts b/src/panels/config/automation/option/ha-automation-option-row.ts index a03cce79f9..eee47b8cb4 100644 --- a/src/panels/config/automation/option/ha-automation-option-row.ts +++ b/src/panels/config/automation/option/ha-automation-option-row.ts @@ -385,9 +385,12 @@ export default class HaAutomationOptionRow extends LitElement { public openSidebar(): void { fireEvent(this, "open-sidebar", { - close: () => { + close: (focus?: boolean) => { this._selected = false; fireEvent(this, "close-sidebar"); + if (focus) { + this.focus(); + } }, rename: () => { this._renameOption(); diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index 1efd7bad89..926c25bb2f 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -482,9 +482,12 @@ export default class HaAutomationTriggerRow extends LitElement { save: (value) => { fireEvent(this, "value-changed", { value }); }, - close: () => { + close: (focus?: boolean) => { this._selected = false; fireEvent(this, "close-sidebar"); + if (focus) { + this.focus(); + } }, rename: () => { this._renameTrigger(); diff --git a/src/panels/config/script/ha-script-field-row.ts b/src/panels/config/script/ha-script-field-row.ts index c274255b6d..867ca2f958 100644 --- a/src/panels/config/script/ha-script-field-row.ts +++ b/src/panels/config/script/ha-script-field-row.ts @@ -1,17 +1,12 @@ -import { mdiDelete } from "@mdi/js"; import type { CSSResultGroup } from "lit"; import { LitElement, css, html, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../../common/dom/fire_event"; -import { preventDefaultStopPropagation } from "../../../common/dom/prevent_default_stop_propagation"; -import { stopPropagation } from "../../../common/dom/stop_propagation"; import type { LocalizeKeys } from "../../../common/translations/localize"; import "../../../components/ha-automation-row"; +import type { HaAutomationRow } from "../../../components/ha-automation-row"; import "../../../components/ha-card"; -import "../../../components/ha-icon-button"; -import "../../../components/ha-md-button-menu"; -import "../../../components/ha-md-menu-item"; import type { ScriptFieldSidebarConfig } from "../../../data/automation"; import type { Field } from "../../../data/script"; import { SELECTOR_SELECTOR_BUILDING_BLOCKS } from "../../../data/selector/selector_selector"; @@ -50,6 +45,12 @@ export default class HaScriptFieldRow extends LitElement { @query("ha-script-field-selector-editor") private _selectorEditor?: HaScriptFieldSelectorEditor; + @query("ha-automation-row:first-of-type") + private _fieldRowElement?: HaAutomationRow; + + @query(".selector-row ha-automation-row") + private _selectorRowElement?: HaAutomationRow; + protected render() { return html` @@ -64,29 +65,6 @@ export default class HaScriptFieldRow extends LitElement {

${this.key}

- - - - ${this.hass.localize( - "ui.panel.config.automation.editor.actions.delete" - )} - - -
{ fireEvent(this, "value-changed", { value }); }, - close: () => { + close: (focus?: boolean) => { if (selectorEditor) { this._selectorRowSelected = false; + if (focus) { + this.focusSelector(); + } } else { this._selected = false; + if (focus) { + this.focus(); + } } fireEvent(this, "close-sidebar"); }, @@ -280,15 +264,19 @@ export default class HaScriptFieldRow extends LitElement { }); }; + public focus() { + this._fieldRowElement?.focus(); + } + + public focusSelector() { + this._selectorRowElement?.focus(); + } + static get styles(): CSSResultGroup { return [ haStyle, indentStyle, css` - ha-button-menu, - ha-icon-button { - --mdc-theme-text-primary-on-background: var(--primary-text-color); - } .disabled { opacity: 0.5; pointer-events: none; @@ -334,9 +322,6 @@ export default class HaScriptFieldRow extends LitElement { ); } - ha-md-menu-item[disabled] { - --mdc-theme-text-primary-on-background: var(--disabled-text-color); - } .warning ul { margin: 4px 0; } @@ -352,6 +337,10 @@ export default class HaScriptFieldRow extends LitElement { border-color: var(--state-inactive-color); box-shadow: var(--shadow-default), var(--shadow-focus); } + + .selector-row { + padding: 12px 0 16px 16px; + } `, ]; } diff --git a/src/panels/config/script/manual-script-editor.ts b/src/panels/config/script/manual-script-editor.ts index 439bd6aad3..7d908830fa 100644 --- a/src/panels/config/script/manual-script-editor.ts +++ b/src/panels/config/script/manual-script-editor.ts @@ -38,6 +38,7 @@ import { showToast } from "../../../util/toast"; import "../automation/action/ha-automation-action"; import type HaAutomationAction from "../automation/action/ha-automation-action"; import "../automation/ha-automation-sidebar"; +import type HaAutomationSidebar from "../automation/ha-automation-sidebar"; import { showPasteReplaceDialog } from "../automation/paste-replace-dialog/show-dialog-paste-replace"; import { manualEditorStyles, saveFabStyles } from "../automation/styles"; import "./ha-script-fields"; @@ -69,17 +70,19 @@ export class HaManualScriptEditor extends LitElement { @property({ attribute: false }) public dirty = false; - @query("ha-script-fields") - private _scriptFields?: HaScriptFields; - - private _openFields = false; - @state() private _pastedConfig?: ScriptConfig; @state() private _sidebarConfig?: SidebarConfig; + @query("ha-script-fields") + private _scriptFields?: HaScriptFields; + + @query("ha-automation-sidebar") private _sidebarElement?: HaAutomationSidebar; + private _previousConfig?: ScriptConfig; + private _openFields = false; + public addFields() { this._openFields = true; fireEvent(this, "value-changed", { @@ -217,6 +220,7 @@ export class HaManualScriptEditor extends LitElement {
) { + private async _openSidebar(ev: CustomEvent) { // deselect previous selected row this._sidebarConfig?.close?.(); this._sidebarConfig = ev.detail; + + await this._sidebarElement?.updateComplete; + this._sidebarElement?.focus(); } private _sidebarConfigChanged(ev: CustomEvent<{ value: SidebarConfig }>) {