diff --git a/src/components/ha-help-tooltip.ts b/src/components/ha-help-tooltip.ts new file mode 100644 index 0000000000..73e60e5799 --- /dev/null +++ b/src/components/ha-help-tooltip.ts @@ -0,0 +1,45 @@ +import { mdiHelpCircle } from "@mdi/js"; +import "@polymer/paper-tooltip/paper-tooltip"; +import { + css, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import "./ha-svg-icon"; + +@customElement("ha-help-tooltip") +export class HaHelpTooltip extends LitElement { + @property() public label!: string; + + @property() public position = "top"; + + protected render(): TemplateResult { + return html` + + ${this.label} + `; + } + + static get styles() { + return css` + ha-svg-icon { + --mdc-icon-size: var(--ha-help-tooltip-size, 14px); + color: var(--ha-help-tooltip-color, var(--disabled-text-color)); + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-help-tooltip": HaHelpTooltip; + } +} diff --git a/src/panels/lovelace/components/hui-action-editor.ts b/src/panels/lovelace/components/hui-action-editor.ts index dea53bd0d3..7946138d6e 100644 --- a/src/panels/lovelace/components/hui-action-editor.ts +++ b/src/panels/lovelace/components/hui-action-editor.ts @@ -3,7 +3,10 @@ import "@polymer/paper-input/paper-input"; import "@polymer/paper-input/paper-textarea"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-listbox/paper-listbox"; +import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox"; import { + css, + CSSResult, customElement, html, LitElement, @@ -11,6 +14,7 @@ import { TemplateResult, } from "lit-element"; import { fireEvent } from "../../../common/dom/fire_event"; +import "../../../components/ha-help-tooltip"; import "../../../components/ha-service-picker"; import { ActionConfig, @@ -29,11 +33,9 @@ export class HuiActionEditor extends LitElement { @property() public actions?: string[]; - @property() protected hass?: HomeAssistant; + @property() public tooltipText?: string; - get _action(): string { - return this.config?.action || ""; - } + @property() protected hass?: HomeAssistant; get _navigation_path(): string { const config = this.config as NavigateActionConfig; @@ -54,72 +56,131 @@ export class HuiActionEditor extends LitElement { if (!this.hass || !this.actions) { return html``; } + return html` - - + - ${this.actions.map((action) => { - return html` ${action} `; - })} - - - ${this._action === "navigate" + + ${this.hass!.localize( + "ui.panel.lovelace.editor.action-editor.actions.default_action" + )} + ${this.actions.map((action) => { + return html` + ${this.hass!.localize( + `ui.panel.lovelace.editor.action-editor.actions.${action}` + )} + `; + })} + + + ${this.tooltipText + ? html` + + ` + : ""} + + ${this.config?.action === "navigate" ? html` ` : ""} - ${this._action === "url" + ${this.config?.action === "url" ? html` ` : ""} - ${this.config && this.config.action === "call-service" + ${this.config?.action === "call-service" ? html` - Service data can only be entered in the code editor + + ${this.hass!.localize( + "ui.panel.lovelace.editor.action-editor.editor_service_data" + )} + ` : ""} `; } - private _valueChanged(ev: Event): void { + private _actionPicked(ev: CustomEvent): void { + ev.stopPropagation(); + if (!this.hass) { + return; + } + const item = ev.detail.item; + const value = item.value; + if (this.config?.action === value) { + return; + } + if (value === "default") { + fireEvent(this, "value-changed", { value: undefined }); + if (this.config?.action) { + (this.shadowRoot!.querySelector( + "paper-listbox" + ) as PaperListboxElement).select(this.config.action); + } + return; + } + fireEvent(this, "value-changed", { + value: { action: value }, + }); + } + + private _valueChanged(ev: CustomEvent): void { ev.stopPropagation(); if (!this.hass) { return; } const target = ev.target! as EditorTarget; - if (this[`_${target.configValue}`] === target.value) { + const value = ev.detail.value; + if (this[`_${target.configValue}`] === value) { return; } if (target.configValue) { - const newConfig = - target.configValue === "action" - ? { action: target.value } - : { ...this.config!, [target.configValue!]: target.value }; - fireEvent(this, "value-changed", { value: newConfig }); + fireEvent(this, "value-changed", { + value: { ...this.config!, [target.configValue!]: value }, + }); } } + + static get styles(): CSSResult { + return css` + .dropdown { + display: flex; + } + `; + } } declare global { diff --git a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts index a2285c087d..b1930365d5 100644 --- a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts @@ -38,6 +38,15 @@ const cardConfigStruct = object({ show_state: optional(boolean()), }); +const actions = [ + "more-info", + "toggle", + "navigate", + "url", + "call-service", + "none", +]; + @customElement("hui-button-card-editor") export class HuiButtonCardEditor extends LitElement implements LovelaceCardEditor { @@ -80,8 +89,8 @@ export class HuiButtonCardEditor extends LitElement : ""; } - get _tap_action(): ActionConfig { - return this._config!.tap_action || { action: "toggle" }; + get _tap_action(): ActionConfig | undefined { + return this._config!.tap_action; } get _hold_action(): ActionConfig { @@ -97,14 +106,6 @@ export class HuiButtonCardEditor extends LitElement return html``; } - const actions = [ - "more-info", - "toggle", - "navigate", - "url", - "call-service", - "none", - ]; const dir = computeRTLDirection(this.hass!); return html` @@ -117,9 +118,9 @@ export class HuiButtonCardEditor extends LitElement "ui.panel.lovelace.editor.card.config.optional" )})" .hass=${this.hass} - .value="${this._entity}" + .value=${this._entity} .configValue=${"entity"} - @value-changed="${this._valueChanged}" + @value-changed=${this._valueChanged} allow-custom-entity >
@@ -129,9 +130,9 @@ export class HuiButtonCardEditor extends LitElement )} (${this.hass.localize( "ui.panel.lovelace.editor.card.config.optional" )})" - .value="${this._name}" - .configValue="${"name"}" - @value-changed="${this._valueChanged}" + .value=${this._name} + .configValue=${"name"} + @value-changed=${this._valueChanged} >
@@ -183,9 +184,9 @@ export class HuiButtonCardEditor extends LitElement .dir=${dir} > @@ -197,17 +198,17 @@ export class HuiButtonCardEditor extends LitElement )} (${this.hass.localize( "ui.panel.lovelace.editor.card.config.optional" )})" - .value="${this._icon_height}" - .configValue="${"icon_height"}" - @value-changed="${this._valueChanged}" + .value=${this._icon_height} + .configValue=${"icon_height"} + @value-changed=${this._valueChanged} type="number" >
px
@@ -218,10 +219,13 @@ export class HuiButtonCardEditor extends LitElement "ui.panel.lovelace.editor.card.config.optional" )})" .hass=${this.hass} - .config="${this._tap_action}" - .actions="${actions}" - .configValue="${"tap_action"}" - @value-changed="${this._valueChanged}" + .config=${this._tap_action} + .actions=${actions} + .configValue=${"tap_action"} + .tooltipText=${this.hass.localize( + "ui.panel.lovelace.editor.card.button.default_action_help" + )} + @value-changed=${this._valueChanged} >
@@ -251,11 +258,12 @@ export class HuiButtonCardEditor extends LitElement return; } - this._config = { - ...this._config, - [target.configValue!]: value, - }; - fireEvent(this, "config-changed", { config: this._config }); + fireEvent(this, "config-changed", { + config: { + ...this._config, + [target.configValue!]: value, + }, + }); } private _valueChanged(ev: CustomEvent): void { @@ -268,25 +276,22 @@ export class HuiButtonCardEditor extends LitElement if (this[`_${target.configValue}`] === value) { return; } + let newConfig; if (target.configValue) { if (value !== false && !value) { - this._config = { ...this._config }; - delete this._config[target.configValue!]; + newConfig = { ...this._config }; + delete newConfig[target.configValue!]; } else { - let newValue: string | undefined; - if ( - target.configValue === "icon_height" && - !isNaN(Number(target.value)) - ) { - newValue = `${String(value)}px`; - } - this._config = { + newConfig = { ...this._config, - [target.configValue!]: newValue !== undefined ? newValue : value, + [target.configValue!]: + target.configValue === "icon_height" && !isNaN(Number(target.value)) + ? `${String(value)}px` + : value, }; } } - fireEvent(this, "config-changed", { config: this._config }); + fireEvent(this, "config-changed", { config: newConfig }); } } diff --git a/src/translations/en.json b/src/translations/en.json index 5e6f032f48..f650ad9259 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2247,6 +2247,20 @@ "para_migrate": "Home Assistant can add ID's to all your cards and views automatically for you by pressing the 'Migrate configuration' button.", "migrate": "Migrate configuration" }, + "action-editor": { + "navigation_path": "Navigation Path", + "url_path": "Url Path", + "editor_service_data": "Service data can only be entered in the code editor", + "actions": { + "default_action": "Default Action", + "call-service": "Call Service", + "more-info": "More Info", + "toggle": "Toggle", + "navigate": "Navigate", + "url": "Url", + "none": "No Action" + } + }, "card": { "alarm-panel": { "name": "Alarm Panel", @@ -2304,7 +2318,8 @@ }, "button": { "name": "Button", - "description": "The Button card allows you to add buttons to perform tasks." + "description": "The Button card allows you to add buttons to perform tasks.", + "default_action_help": "The default action depends on the entity's capabilities, it will either be toggled or the more info will be shown." }, "entity-filter": { "name": "Entity Filter",