Use ripple effect for tile card (#15007)

* Use ripple effect for tile card

* Use border for focus
This commit is contained in:
Paul Bottein 2023-01-18 11:35:54 +01:00 committed by GitHub
parent 789a69fea5
commit 9e5442db18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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<Ripple | null>;
@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`
<ha-card style=${styleMap(style)}>
${this._shouldRenderRipple ? html`<mwc-ripple></mwc-ripple>` : null}
<div class="tile">
<div
class="icon-container"
@ -313,10 +349,17 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
class="info"
.primary=${name}
.secondary=${stateDisplay}
role="button"
tabindex="0"
@action=${this._handleAction}
.actionHandler=${actionHandler()}
role="button"
tabindex="0"
@mousedown=${this.handleRippleActivate}
@mouseup=${this.handleRippleDeactivate}
@mouseenter=${this.handleRippleMouseEnter}
@mouseleave=${this.handleRippleMouseLeave}
@touchstart=${this.handleRippleActivate}
@touchend=${this.handleRippleDeactivate}
@touchcancel=${this.handleRippleDeactivate}
></ha-tile-info>
</div>
${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);
}
`;
}
}