Make the full generic entity row clickable (#24968)

* Make the full generic entity row clickable

* Apply suggestions from code review

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>

---------

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
Paul Bottein 2025-04-08 15:17:05 +02:00 committed by GitHub
parent 4a1cf250c4
commit 9c3f77532c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -61,15 +61,8 @@ export class HuiGenericEntityRow extends LitElement {
const name = this.config.name ?? computeStateName(stateObj); const name = this.config.name ?? computeStateName(stateObj);
return html` return html`
<state-badge <div
class=${classMap({ class="row ${classMap({ pointer })}"
pointer,
})}
.hass=${this.hass}
.stateObj=${stateObj}
.overrideIcon=${this.config.icon}
.overrideImage=${this.config.image}
.stateColor=${this.config.state_color}
@action=${this._handleAction} @action=${this._handleAction}
.actionHandler=${actionHandler({ .actionHandler=${actionHandler({
hasHold: hasAction(this.config!.hold_action), hasHold: hasAction(this.config!.hold_action),
@ -80,98 +73,99 @@ export class HuiGenericEntityRow extends LitElement {
? "0" ? "0"
: undefined : undefined
)} )}
></state-badge> >
${!this.hideName <state-badge
? html`<div .hass=${this.hass}
class="info ${classMap({ .stateObj=${stateObj}
pointer, .overrideIcon=${this.config.icon}
"text-content": !hasSecondary, .overrideImage=${this.config.image}
})}" .stateColor=${this.config.state_color}
@action=${this._handleAction} ></state-badge>
.actionHandler=${actionHandler({ ${!this.hideName
hasHold: hasAction(this.config!.hold_action), ? html`<div
hasDoubleClick: hasAction(this.config!.double_tap_action), class="info ${classMap({ "text-content": !hasSecondary })}"
})} .title=${name}
.title=${name} >
> ${this.config.name || computeStateName(stateObj)}
${this.config.name || computeStateName(stateObj)} ${hasSecondary
${hasSecondary ? html`
? html` <div class="secondary">
<div class="secondary"> ${this.secondaryText ||
${this.secondaryText || (this.config.secondary_info === "entity-id"
(this.config.secondary_info === "entity-id" ? stateObj.entity_id
? stateObj.entity_id : this.config.secondary_info === "last-changed"
: this.config.secondary_info === "last-changed"
? html`
<ha-relative-time
.hass=${this.hass}
.datetime=${stateObj.last_changed}
capitalize
></ha-relative-time>
`
: this.config.secondary_info === "last-updated"
? html` ? html`
<ha-relative-time <ha-relative-time
.hass=${this.hass} .hass=${this.hass}
.datetime=${stateObj.last_updated} .datetime=${stateObj.last_changed}
capitalize capitalize
></ha-relative-time> ></ha-relative-time>
` `
: this.config.secondary_info === "last-triggered" : this.config.secondary_info === "last-updated"
? stateObj.attributes.last_triggered ? html`
? html` <ha-relative-time
<ha-relative-time .hass=${this.hass}
.hass=${this.hass} .datetime=${stateObj.last_updated}
.datetime=${stateObj.attributes capitalize
.last_triggered} ></ha-relative-time>
capitalize `
></ha-relative-time> : this.config.secondary_info === "last-triggered"
` ? stateObj.attributes.last_triggered
: this.hass.localize( ? html`
"ui.panel.lovelace.cards.entities.never_triggered" <ha-relative-time
) .hass=${this.hass}
: this.config.secondary_info === "position" && .datetime=${stateObj.attributes
stateObj.attributes.current_position !== .last_triggered}
undefined capitalize
? `${this.hass.localize( ></ha-relative-time>
"ui.card.cover.position" `
)}: ${stateObj.attributes.current_position}` : this.hass.localize(
: this.config.secondary_info === "ui.panel.lovelace.cards.entities.never_triggered"
"tilt-position" && )
stateObj.attributes.current_tilt_position !== : this.config.secondary_info === "position" &&
stateObj.attributes.current_position !==
undefined undefined
? `${this.hass.localize( ? `${this.hass.localize(
"ui.card.cover.tilt_position" "ui.card.cover.position"
)}: ${ )}: ${stateObj.attributes.current_position}`
stateObj.attributes.current_tilt_position : this.config.secondary_info ===
}` "tilt-position" &&
: this.config.secondary_info === "brightness" && stateObj.attributes
stateObj.attributes.brightness .current_tilt_position !== undefined
? html`${Math.round( ? `${this.hass.localize(
(stateObj.attributes.brightness / 255) * "ui.card.cover.tilt_position"
100 )}: ${
)} stateObj.attributes.current_tilt_position
%` }`
: "")} : this.config.secondary_info ===
</div> "brightness" &&
` stateObj.attributes.brightness
: ""} ? html`${Math.round(
</div>` (stateObj.attributes.brightness / 255) *
: nothing} 100
${(this.catchInteraction ?? !DOMAINS_INPUT_ROW.includes(domain)) )}
? html`<div %`
class="text-content value ${classMap({ : nothing)}
pointer, </div>
})}" `
@action=${this._handleAction} : nothing}
.actionHandler=${actionHandler({ </div>`
hasHold: hasAction(this.config!.hold_action), : nothing}
hasDoubleClick: hasAction(this.config!.double_tap_action), ${(this.catchInteraction ?? !DOMAINS_INPUT_ROW.includes(domain))
})} ? html`<div
> class="text-content value ${classMap({
<div class="state"><slot></slot></div> pointer,
</div>` })}"
: html`<slot></slot>`} @action=${this._handleAction}
.actionHandler=${actionHandler({
hasHold: hasAction(this.config!.hold_action),
hasDoubleClick: hasAction(this.config!.double_tap_action),
})}
>
<div class="state"><slot></slot></div>
</div>`
: html`<slot></slot>`}
</div>
`; `;
} }
@ -194,6 +188,17 @@ export class HuiGenericEntityRow extends LitElement {
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
} }
.row {
display: flex;
align-items: center;
flex-direction: row;
width: 100%;
outline: none;
transition: background-color 180ms ease-in-out;
}
.row:focus-visible {
background-color: var(--primary-background-color);
}
.info { .info {
padding-left: 16px; padding-left: 16px;
padding-right: 8px; padding-right: 8px;