From 4a77359a06b0c172976bfded7f5b5ffa53dcd099 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 7 May 2024 15:30:45 +0200 Subject: [PATCH 1/2] Use Material 3 ripple (#20751) * Use material web ripple component * Improve button style * Use css animation instead of ripple for action * Use ha ripple in all components * Remove unused label --- package.json | 1 - src/components/ha-control-button.ts | 63 ++-------------- src/components/ha-control-select-menu.ts | 75 +++---------------- src/components/ha-label.ts | 3 - src/components/ha-ripple.ts | 63 ++++++++++++++++ src/components/ha-tab.ts | 66 +++------------- src/layouts/hass-tabs-subpage.ts | 1 - src/onboarding/onboarding-welcome-link.ts | 65 +++------------- .../integrations/ha-integration-card.ts | 68 ++++------------- src/panels/lovelace/cards/hui-area-card.ts | 1 - src/panels/lovelace/cards/hui-button-card.ts | 57 +++----------- src/panels/lovelace/cards/hui-tile-card.ts | 56 ++------------ .../directives/action-handler-directive.ts | 32 +++----- yarn.lock | 3 +- 14 files changed, 145 insertions(+), 409 deletions(-) create mode 100644 src/components/ha-ripple.ts diff --git a/package.json b/package.json index 6203e07435bf..38597f740ace 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "@material/mwc-list": "0.27.0", "@material/mwc-menu": "0.27.0", "@material/mwc-radio": "0.27.0", - "@material/mwc-ripple": "0.27.0", "@material/mwc-select": "0.27.0", "@material/mwc-snackbar": "0.27.0", "@material/mwc-switch": "0.27.0", diff --git a/src/components/ha-control-button.ts b/src/components/ha-control-button.ts index 6da398498461..862767c62df9 100644 --- a/src/components/ha-control-button.ts +++ b/src/components/ha-control-button.ts @@ -1,14 +1,7 @@ -import { Ripple } from "@material/mwc-ripple"; -import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { - customElement, - eventOptions, - property, - queryAsync, - state, -} from "lit/decorators"; +import { customElement, property } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; +import "./ha-ripple"; @customElement("ha-control-button") export class HaControlButton extends LitElement { @@ -16,10 +9,6 @@ export class HaControlButton extends LitElement { @property() public label?: string; - @queryAsync("mwc-ripple") private _ripple!: Promise; - - @state() private _shouldRenderRipple = false; - protected render(): TemplateResult { return html` `; } - 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(); - } - - private handleRippleFocus() { - this._rippleHandlers.startFocus(); - } - - private handleRippleBlur() { - this._rippleHandlers.endFocus(); - } - static get styles(): CSSResultGroup { return css` :host { @@ -86,6 +34,7 @@ export class HaControlButton extends LitElement { --control-button-border-radius: 10px; --control-button-padding: 8px; --mdc-icon-size: 20px; + --ha-ripple-color: var(--secondary-text-color); color: var(--primary-text-color); width: 40px; height: 40px; @@ -113,12 +62,14 @@ export class HaControlButton extends LitElement { outline: none; overflow: hidden; background: none; - --mdc-ripple-color: var(--control-button-background-color); /* For safari border-radius overflow */ z-index: 0; font-size: inherit; color: inherit; } + .button:focus-visible { + --control-button-background-opacity: 0.4; + } .button::before { content: ""; position: absolute; diff --git a/src/components/ha-control-select-menu.ts b/src/components/ha-control-select-menu.ts index c26d1cee5b2b..343b311127a8 100644 --- a/src/components/ha-control-select-menu.ts +++ b/src/components/ha-control-select-menu.ts @@ -1,22 +1,14 @@ -import { Ripple } from "@material/mwc-ripple"; -import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { SelectBase } from "@material/mwc-select/mwc-select-base"; import { mdiMenuDown } from "@mdi/js"; import { css, html, nothing } from "lit"; -import { - customElement, - eventOptions, - property, - query, - queryAsync, - state, -} from "lit/decorators"; +import { customElement, property, query } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { ifDefined } from "lit/directives/if-defined"; import { debounce } from "../common/util/debounce"; import { nextRender } from "../common/util/render-status"; import "./ha-icon"; import type { HaIcon } from "./ha-icon"; +import "./ha-ripple"; import "./ha-svg-icon"; import type { HaSvgIcon } from "./ha-svg-icon"; @@ -32,10 +24,6 @@ export class HaControlSelectMenu extends SelectBase { @property({ type: Boolean, attribute: "hide-label" }) public hideLabel = false; - @queryAsync("mwc-ripple") private _ripple!: Promise; - - @state() private _shouldRenderRipple = false; - public override render() { const classes = { "select-disabled": this.disabled, @@ -69,17 +57,10 @@ export class HaControlSelectMenu extends SelectBase { aria-labelledby=${ifDefined(labelledby)} aria-label=${ifDefined(labelAttribute)} aria-required=${this.required} - @click=${this.onClick} @focus=${this.onFocus} @blur=${this.onBlur} + @click=${this.onClick} @keydown=${this.onKeydown} - @mousedown=${this.handleRippleActivate} - @mouseup=${this.handleRippleDeactivate} - @mouseenter=${this.handleRippleMouseEnter} - @mouseleave=${this.handleRippleMouseLeave} - @touchstart=${this.handleRippleActivate} - @touchend=${this.handleRippleDeactivate} - @touchcancel=${this.handleRippleDeactivate} > ${this.renderIcon()}
@@ -91,9 +72,7 @@ export class HaControlSelectMenu extends SelectBase { : nothing}
${this.renderArrow()} - ${this._shouldRenderRipple && !this.disabled - ? html` ` - : nothing} + ${this.renderMenu()} @@ -135,46 +114,6 @@ export class HaControlSelectMenu extends SelectBase { `; } - protected onFocus() { - this.handleRippleFocus(); - super.onFocus(); - } - - protected onBlur() { - this.handleRippleBlur(); - super.onBlur(); - } - - 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(); - } - - private handleRippleFocus() { - this._rippleHandlers.startFocus(); - } - - private handleRippleBlur() { - this._rippleHandlers.endFocus(); - } - connectedCallback() { super.connectedCallback(); window.addEventListener("translations-updated", this._translationsUpdated); @@ -204,6 +143,7 @@ export class HaControlSelectMenu extends SelectBase { --control-select-menu-height: 48px; --control-select-menu-padding: 6px 10px; --mdc-icon-size: 20px; + --ha-ripple-color: var(--secondary-text-color); font-size: 14px; line-height: 1.4; width: auto; @@ -224,7 +164,6 @@ export class HaControlSelectMenu extends SelectBase { outline: none; overflow: hidden; background: none; - --mdc-ripple-color: var(--control-select-menu-background-color); /* For safari border-radius overflow */ z-index: 0; transition: color 180ms ease-in-out; @@ -264,6 +203,10 @@ export class HaControlSelectMenu extends SelectBase { letter-spacing: inherit; } + .select-anchor:focus-visible { + --control-select-menu-background-opacity: 0.4; + } + .select-anchor::before { content: ""; position: absolute; diff --git a/src/components/ha-label.ts b/src/components/ha-label.ts index d9d82052015b..53749dac82c7 100644 --- a/src/components/ha-label.ts +++ b/src/components/ha-label.ts @@ -1,6 +1,5 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import "@material/web/ripple/ripple"; @customElement("ha-label") class HaLabel extends LitElement { @@ -11,7 +10,6 @@ class HaLabel extends LitElement { - `; } @@ -27,7 +25,6 @@ class HaLabel extends LitElement { 0.15 ); --ha-label-background-opacity: 1; - position: relative; box-sizing: border-box; display: inline-flex; diff --git a/src/components/ha-ripple.ts b/src/components/ha-ripple.ts new file mode 100644 index 000000000000..0fadf1a375ad --- /dev/null +++ b/src/components/ha-ripple.ts @@ -0,0 +1,63 @@ +import { AttachableController } from "@material/web/internal/controller/attachable-controller"; +import { MdRipple } from "@material/web/ripple/ripple"; +import "element-internals-polyfill"; +import { css } from "lit"; +import { customElement } from "lit/decorators"; + +@customElement("ha-ripple") +export class HaRipple extends MdRipple { + private readonly attachableTouchController = new AttachableController( + this, + this.onTouchControlChange.bind(this) + ); + + attach(control: HTMLElement) { + super.attach(control); + this.attachableTouchController.attach(control); + } + + detach() { + super.detach(); + this.attachableTouchController.detach(); + } + + private _handleTouchEnd = () => { + if (!this.disabled) { + // @ts-ignore + super.endPressAnimation(); + } + }; + + private onTouchControlChange( + prev: HTMLElement | null, + next: HTMLElement | null + ) { + // Add touchend event to clean ripple on touch devices using action handler + prev?.removeEventListener("touchend", this._handleTouchEnd); + next?.addEventListener("touchend", this._handleTouchEnd); + } + + static override styles = [ + ...super.styles, + css` + :host { + --md-ripple-hover-opacity: var(--ha-ripple-hover-opacity, 0.08); + --md-ripple-pressed-opacity: var(--ha-ripple-pressed-opacity, 0.12); + --md-ripple-hover-color: var( + --ha-ripple-hover-color, + var(--ha-ripple-color, var(--secondary-text-color)) + ); + --md-ripple-pressed-color: var( + --ha-ripple-pressed-color, + var(--ha-ripple-color, var(--secondary-text-color)) + ); + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-ripple": HaRipple; + } +} diff --git a/src/components/ha-tab.ts b/src/components/ha-tab.ts index e9b01409ca1a..77a4b777d940 100644 --- a/src/components/ha-tab.ts +++ b/src/components/ha-tab.ts @@ -1,15 +1,7 @@ -import type { Ripple } from "@material/mwc-ripple"; -import "@material/mwc-ripple/mwc-ripple"; -import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { - customElement, - eventOptions, - property, - queryAsync, - state, -} from "lit/decorators"; +import { customElement, property } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; +import "./ha-ripple"; @customElement("ha-tab") export class HaTab extends LitElement { @@ -19,10 +11,6 @@ export class HaTab extends LitElement { @property() public name?: string; - @queryAsync("mwc-ripple") private _ripple!: Promise; - - @state() private _shouldRenderRipple = false; - protected render(): TemplateResult { return html`
${this.narrow ? html`` : ""} ${this.name} - ${this._shouldRenderRipple ? html`` : ""} +
`; } - private _rippleHandlers: RippleHandlers = new RippleHandlers(() => { - this._shouldRenderRipple = true; - return this._ripple; - }); - private _handleKeyDown(ev: KeyboardEvent): void { if (ev.key === "Enter") { (ev.target as HTMLElement).click(); } } - @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(); - } - - private handleRippleFocus() { - this._rippleHandlers.startFocus(); - } - - private handleRippleBlur() { - this._rippleHandlers.endFocus(); - } - static get styles(): CSSResultGroup { return css` div { @@ -126,6 +75,15 @@ export class HaTab extends LitElement { :host([narrow]) div { padding: 0 4px; } + + div:focus-visible:before { + position: absolute; + display: block; + content: ""; + inset: 0; + background-color: var(--secondary-text-color); + opacity: 0.08; + } `; } } diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index ee34ad75e2d3..1f40ab0ca916 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -1,4 +1,3 @@ -import "@material/mwc-ripple"; import { css, CSSResultGroup, diff --git a/src/onboarding/onboarding-welcome-link.ts b/src/onboarding/onboarding-welcome-link.ts index d1d7972f1502..6b9f243fa2da 100644 --- a/src/onboarding/onboarding-welcome-link.ts +++ b/src/onboarding/onboarding-welcome-link.ts @@ -1,15 +1,7 @@ -import "@material/mwc-ripple"; -import type { Ripple } from "@material/mwc-ripple"; -import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit"; -import { - customElement, - eventOptions, - property, - queryAsync, - state, -} from "lit/decorators"; +import { customElement, property } from "lit/decorators"; import "../components/ha-card"; +import "../components/ha-ripple"; import "../components/ha-svg-icon"; @customElement("onboarding-welcome-link") @@ -20,28 +12,15 @@ class OnboardingWelcomeLink extends LitElement { @property({ type: Boolean }) public noninteractive = false; - @queryAsync("mwc-ripple") private _ripple!: Promise; - - @state() private _shouldRenderRipple = false; - protected render(): TemplateResult { return html` ${this.label} - ${this._shouldRenderRipple ? html`` : ""} + `; } @@ -52,36 +31,6 @@ class OnboardingWelcomeLink extends LitElement { } } - private _rippleHandlers: RippleHandlers = new RippleHandlers(() => { - this._shouldRenderRipple = true; - return this._ripple; - }); - - private handleRippleMouseEnter() { - this._rippleHandlers.startHover(); - } - - private handleRippleMouseLeave() { - this._rippleHandlers.endHover(); - } - - @eventOptions({ passive: true }) - private handleRippleActivate(evt?: Event) { - this._rippleHandlers.startPress(evt); - } - - private handleRippleDeactivate() { - this._rippleHandlers.endPress(); - } - - private handleRippleFocus() { - this._rippleHandlers.startFocus(); - } - - private handleRippleBlur() { - this._rippleHandlers.endFocus(); - } - static get styles(): CSSResultGroup { return css` :host { @@ -104,6 +53,14 @@ class OnboardingWelcomeLink extends LitElement { padding: 8px; margin-bottom: 16px; } + ha-card:focus-visible:before { + position: absolute; + display: block; + content: ""; + inset: 0; + background-color: var(--secondary-text-color); + opacity: 0.08; + } `; } } diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 2625aa81a9a2..240e82ae2bb3 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -1,7 +1,4 @@ import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; -import "@material/mwc-ripple"; -import type { Ripple } from "@material/mwc-ripple"; -import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { mdiCloud, mdiPackageVariant } from "@mdi/js"; import { CSSResultGroup, @@ -11,18 +8,13 @@ import { html, nothing, } from "lit"; -import { - customElement, - eventOptions, - property, - queryAsync, - state, -} from "lit/decorators"; +import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; import { computeRTL } from "../../../common/util/compute_rtl"; -import "../../../components/ha-card"; import "../../../components/ha-button"; +import "../../../components/ha-card"; +import "../../../components/ha-ripple"; import "../../../components/ha-svg-icon"; import { ConfigEntry, ERROR_STATES } from "../../../data/config_entries"; import type { DeviceRegistryEntry } from "../../../data/device_registry"; @@ -54,10 +46,6 @@ export class HaIntegrationCard extends LitElement { @property({ attribute: false }) public logInfo?: IntegrationLogInfo; - @queryAsync("mwc-ripple") private _ripple!: Promise; - - @state() private _shouldRenderRipple = false; - protected render(): TemplateResult { const entryState = this._getState(this.items); @@ -79,17 +67,8 @@ export class HaIntegrationCard extends LitElement { - ${this._shouldRenderRipple ? html`` : ""} + { - this._shouldRenderRipple = true; - return this._ripple; - }); - - @eventOptions({ passive: true }) - private handleRippleActivate(evt?: Event) { - this._rippleHandlers.startPress(evt); - } - - private handleRippleDeactivate() { - this._rippleHandlers.endPress(); - } - - private handleRippleFocus() { - this._rippleHandlers.startFocus(); - } - - private handleRippleBlur() { - this._rippleHandlers.endFocus(); - } - - protected handleRippleMouseEnter() { - this._rippleHandlers.startHover(); - } - - protected handleRippleMouseLeave() { - this._rippleHandlers.endHover(); - } - static get styles(): CSSResultGroup { return [ haStyle, @@ -289,6 +238,15 @@ export class HaIntegrationCard extends LitElement { .ripple-anchor { flex-grow: 1; position: relative; + outline: none; + } + .ripple-anchor:focus-visible:before { + position: absolute; + display: block; + content: ""; + inset: 0; + background-color: var(--secondary-text-color); + opacity: 0.08; } ha-integration-header { height: 100%; diff --git a/src/panels/lovelace/cards/hui-area-card.ts b/src/panels/lovelace/cards/hui-area-card.ts index d11cab94756e..5bd7e44e317b 100644 --- a/src/panels/lovelace/cards/hui-area-card.ts +++ b/src/panels/lovelace/cards/hui-area-card.ts @@ -1,4 +1,3 @@ -import "@material/mwc-ripple"; import { mdiFan, mdiFanOff, diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index ddadb6d86fdc..c36a9fa6a27f 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -1,21 +1,18 @@ import { consume } from "@lit-labs/context"; -import "@material/mwc-ripple"; -import type { Ripple } from "@material/mwc-ripple"; -import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { HassConfig, HassEntities, HassEntity, } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, + css, + html, + nothing, } from "lit"; -import { customElement, eventOptions, queryAsync, state } from "lit/decorators"; +import { customElement, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; import { DOMAINS_TOGGLE } from "../../../common/const"; @@ -27,13 +24,14 @@ import { computeStateDisplaySingleEntity } from "../../../common/entity/compute_ import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { - stateColorCss, stateColorBrightness, + stateColorCss, } from "../../../common/entity/state_color"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; import { iconColorCSS } from "../../../common/style/icon_color_css"; import { LocalizeFunc } from "../../../common/translations/localize"; import "../../../components/ha-card"; +import "../../../components/ha-ripple"; import { CLIMATE_HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { configContext, @@ -132,10 +130,6 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { }) _entity?: EntityRegistryDisplayEntry; - @queryAsync("mwc-ripple") private _ripple!: Promise; - - @state() private _shouldRenderRipple = false; - private getStateColor(stateObj: HassEntity, config: ButtonCardConfig) { const domain = stateObj ? computeStateDomain(stateObj) : undefined; return config && (config.state_color ?? domain === "light"); @@ -197,13 +191,6 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { return html` + ${this._config.show_icon ? html` ` : ""} - ${this._shouldRenderRipple ? html`` : ""} `; } @@ -282,31 +269,6 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { } } - private _rippleHandlers: RippleHandlers = new RippleHandlers(() => { - this._shouldRenderRipple = true; - return this._ripple; - }); - - @eventOptions({ passive: true }) - private handleRippleActivate(evt?: Event) { - this._rippleHandlers.startPress(evt); - } - - @eventOptions({ passive: true }) - private handleRippleDeactivate() { - this._rippleHandlers.endPress(); - } - - @eventOptions({ passive: true }) - private handleRippleMouseEnter() { - this._rippleHandlers.startHover(); - } - - @eventOptions({ passive: true }) - private handleRippleMouseLeave() { - this._rippleHandlers.endHover(); - } - static get styles(): CSSResultGroup { return [ iconColorCSS, @@ -314,7 +276,9 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { ha-card { --state-inactive-color: var(--paper-item-icon-color, #44739e); --state-color: var(--paper-item-icon-color, #44739e); - --mdc-ripple-color: var(--state-color); + --ha-ripple-color: var(--state-color); + --ha-ripple-hover-opacity: 0.04; + --ha-ripple-pressed-opacity: 0.12; cursor: pointer; display: flex; flex-direction: column; @@ -340,6 +304,7 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { color: var(--state-color); --mdc-icon-size: 100%; transition: transform 180ms ease-in-out; + pointer-events: none; } ha-state-icon + span { diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 688363cb2323..634b52ca1478 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -1,5 +1,3 @@ -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 { @@ -10,13 +8,7 @@ import { html, nothing, } from "lit"; -import { - customElement, - eventOptions, - property, - queryAsync, - state, -} from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; @@ -29,6 +21,7 @@ import { computeDomain } from "../../../common/entity/compute_domain"; import { stateActive } from "../../../common/entity/state_active"; import { stateColorCss } from "../../../common/entity/state_color"; import "../../../components/ha-card"; +import "../../../components/ha-ripple"; import "../../../components/ha-state-icon"; import "../../../components/ha-svg-icon"; import "../../../components/tile/ha-tile-badge"; @@ -313,36 +306,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return this._renderStateContent(stateObj, "state"); } - @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) { - if (!this.hasCardAction) return; - this._rippleHandlers.startPress(evt); - } - - private handleRippleDeactivate() { - if (!this.hasCardAction) return; - this._rippleHandlers.endPress(); - } - - private handleRippleMouseEnter() { - if (!this.hasCardAction) return; - this._rippleHandlers.startHover(); - } - - private handleRippleMouseLeave() { - if (!this.hasCardAction) return; - this._rippleHandlers.endHover(); - } - get hasCardAction() { return ( !this._config?.tap_action || @@ -420,17 +383,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard { role=${ifDefined(this.hasCardAction ? "button" : undefined)} tabindex=${ifDefined(this.hasCardAction ? "0" : undefined)} aria-labelledby="info" - @mousedown=${this.handleRippleActivate} - @mouseup=${this.handleRippleDeactivate} - @mouseenter=${this.handleRippleMouseEnter} - @mouseleave=${this.handleRippleMouseLeave} - @touchstart=${this.handleRippleActivate} - @touchend=${this.handleRippleDeactivate} - @touchcancel=${this.handleRippleDeactivate} > - ${this._shouldRenderRipple - ? html`` - : nothing} +
Date: Tue, 7 May 2024 16:35:34 +0300 Subject: [PATCH 2/2] Logical property style fixes (#20752) logical prop fixes --- src/components/data-table/ha-data-table.ts | 1 + src/components/ha-filter-domains.ts | 4 ++-- src/panels/config/cloud/account/cloud-remote-pref.ts | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index 948bea729ea6..7c9f8aeda68e 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -984,6 +984,7 @@ export class HaDataTable extends LitElement { padding-top: 12px; padding-left: 12px; padding-inline-start: 12px; + padding-inline-end: initial; width: 100%; font-weight: 500; display: flex; diff --git a/src/components/ha-filter-domains.ts b/src/components/ha-filter-domains.ts index 867867ad1852..442cfd41be68 100644 --- a/src/components/ha-filter-domains.ts +++ b/src/components/ha-filter-domains.ts @@ -163,14 +163,14 @@ export class HaFilterDomains extends LitElement { align-items: center; } .header ha-icon-button { - margin-inline-start: auto; + margin-inline-start: initial; margin-inline-end: 8px; } .badge { display: inline-block; margin-left: 8px; margin-inline-start: 8px; - margin-inline-end: 0; + margin-inline-end: initial; min-width: 16px; box-sizing: border-box; border-radius: 50%; diff --git a/src/panels/config/cloud/account/cloud-remote-pref.ts b/src/panels/config/cloud/account/cloud-remote-pref.ts index 86cbfe5ce8d8..c33fb61d3122 100644 --- a/src/panels/config/cloud/account/cloud-remote-pref.ts +++ b/src/panels/config/cloud/account/cloud-remote-pref.ts @@ -541,6 +541,7 @@ export class CloudRemotePref extends LitElement { ha-formfield { margin-left: -12px; margin-inline-start: -12px; + margin-inline-end: initial; --ha-formfield-align-items: start; } .strict-connection-container {