diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index ae5c588a5a..981846ac5b 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -1,8 +1,16 @@ import { memoize } from "@fullcalendar/common"; +import { Ripple } from "@material/mwc-ripple"; +import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { mdiExclamationThick, mdiHelp } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { + customElement, + eventOptions, + property, + queryAsync, + state, +} from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import { computeCssColor } from "../../../common/color/compute-color"; import { hsv2rgb, rgb2hsv } from "../../../common/color/convert-color"; @@ -105,7 +113,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard { handleAction(this, this.hass!, this._config!, ev.detail.action!); } - private _handleIconAction() { + private _handleIconAction(ev: CustomEvent) { + ev.stopPropagation(); const config = { entity: this._config!.entity, tap_action: this._config!.icon_tap_action, @@ -219,6 +228,32 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return stateDisplay; } + @queryAsync("mwc-ripple") private _ripple!: Promise; + + @state() private _shouldRenderRipple = false; + + private _rippleHandlers: RippleHandlers = new RippleHandlers(() => { + this._shouldRenderRipple = true; + return this._ripple; + }); + + @eventOptions({ passive: true }) + private handleRippleActivate(evt?: Event) { + this._rippleHandlers.startPress(evt); + } + + private handleRippleDeactivate() { + this._rippleHandlers.endPress(); + } + + private handleRippleMouseEnter() { + this._rippleHandlers.startHover(); + } + + private handleRippleMouseLeave() { + this._rippleHandlers.endHover(); + } + protected render(): TemplateResult { if (!this._config || !this.hass) { return html``; @@ -274,6 +309,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return html` + ${this._shouldRenderRipple ? html`` : null}
${supportedFeatures?.length @@ -365,11 +408,18 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return css` :host { --tile-color: rgb(var(--rgb-state-inactive-color)); - --tile-tap-padding: 6px; -webkit-tap-highlight-color: transparent; } + ha-card:has(ha-tile-info:focus-visible) { + border-color: var(--tile-color); + box-shadow: 0 0 0 1px var(--tile-color); + } ha-card { + --mdc-ripple-color: var(--tile-color); height: 100%; + overflow: hidden; + // For safari overflow hidden + z-index: 0; } ha-card.disabled { --tile-color: rgb(var(--rgb-disabled-color)); @@ -381,18 +431,16 @@ export class HuiTileCard extends LitElement implements LovelaceCard { outline: none; } .tile { - padding: calc(12px - var(--tile-tap-padding)); display: flex; flex-direction: row; align-items: center; } .icon-container { position: relative; - padding: var(--tile-tap-padding); flex: none; - margin-right: calc(12px - 2 * var(--tile-tap-padding)); - margin-inline-end: calc(12px - 2 * var(--tile-tap-padding)); - margin-inline-start: initial; + margin-right: 12px; + margin-inline-start: 12px; + margin-inline-end: initial; direction: var(--direction); transition: transform 180ms ease-in-out; } @@ -401,8 +449,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } .icon-container .badge { position: absolute; - top: calc(-3px + var(--tile-tap-padding)); - right: calc(-3px + var(--tile-tap-padding)); + top: -3px; + right: -3px; } .icon-container[role="button"]:focus-visible, .icon-container[role="button"]:active { @@ -410,27 +458,12 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } .info { position: relative; - padding: var(--tile-tap-padding); + padding: 12px; flex: 1; min-width: 0; min-height: 40px; transition: background-color 180ms ease-in-out; } - .info::before { - content: ""; - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - border-radius: calc(var(--ha-card-border-radius, 10px) - 2px); - background-color: transparent; - opacity: 0.1; - transition: background-color ease-in-out 180ms; - } - .info:focus-visible::before { - background-color: var(--tile-color); - } `; } }