mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Migrate dialog-light-color-favorite to ha-md-dialog (#22013)
* Migrate dialog-light-color-favorite to ha-md-dialog * Add aria-label to dialog-light-color-favorite * Add mobile dialog from bottom animation to dialog-light-color-favorite
This commit is contained in:
parent
f260c95add
commit
71dc26edab
@ -1,4 +1,9 @@
|
|||||||
import { MdDialog } from "@material/web/dialog/dialog";
|
import { MdDialog } from "@material/web/dialog/dialog";
|
||||||
|
import {
|
||||||
|
type DialogAnimation,
|
||||||
|
DIALOG_DEFAULT_CLOSE_ANIMATION,
|
||||||
|
DIALOG_DEFAULT_OPEN_ANIMATION,
|
||||||
|
} from "@material/web/dialog/internal/animations";
|
||||||
import { css } from "lit";
|
import { css } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
|
||||||
@ -131,7 +136,7 @@ export class HaMdDialog extends MdDialog {
|
|||||||
);
|
);
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
border-radius: 0;
|
--md-dialog-container-shape: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,6 +151,58 @@ export class HaMdDialog extends MdDialog {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// by default the dialog open/close animation will be from/to the top
|
||||||
|
// but if we have a special mobile dialog which is at the bottom of the screen, an from bottom animation can be used:
|
||||||
|
const OPEN_FROM_BOTTOM_ANIMATION: DialogAnimation = {
|
||||||
|
...DIALOG_DEFAULT_OPEN_ANIMATION,
|
||||||
|
dialog: [
|
||||||
|
[
|
||||||
|
// Dialog slide up
|
||||||
|
[{ transform: "translateY(50px)" }, { transform: "translateY(0)" }],
|
||||||
|
{ duration: 500, easing: "cubic-bezier(.3,0,0,1)" },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
container: [
|
||||||
|
[
|
||||||
|
// Container fade in
|
||||||
|
[{ opacity: 0 }, { opacity: 1 }],
|
||||||
|
{ duration: 50, easing: "linear", pseudoElement: "::before" },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const CLOSE_TO_BOTTOM_ANIMATION: DialogAnimation = {
|
||||||
|
...DIALOG_DEFAULT_CLOSE_ANIMATION,
|
||||||
|
dialog: [
|
||||||
|
[
|
||||||
|
// Dialog slide down
|
||||||
|
[{ transform: "translateY(0)" }, { transform: "translateY(50px)" }],
|
||||||
|
{ duration: 150, easing: "cubic-bezier(.3,0,0,1)" },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
container: [
|
||||||
|
[
|
||||||
|
// Container fade out
|
||||||
|
[{ opacity: "1" }, { opacity: "0" }],
|
||||||
|
{ delay: 100, duration: 50, easing: "linear", pseudoElement: "::before" },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMobileOpenFromBottomAnimation = () => {
|
||||||
|
const matches = window.matchMedia(
|
||||||
|
"all and (max-width: 450px), all and (max-height: 500px)"
|
||||||
|
).matches;
|
||||||
|
return matches ? OPEN_FROM_BOTTOM_ANIMATION : DIALOG_DEFAULT_OPEN_ANIMATION;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMobileCloseToBottomAnimation = () => {
|
||||||
|
const matches = window.matchMedia(
|
||||||
|
"all and (max-width: 450px), all and (max-height: 500px)"
|
||||||
|
).matches;
|
||||||
|
return matches ? CLOSE_TO_BOTTOM_ANIMATION : DIALOG_DEFAULT_CLOSE_ANIMATION;
|
||||||
|
};
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
"ha-md-dialog": HaMdDialog;
|
"ha-md-dialog": HaMdDialog;
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import { mdiClose } from "@mdi/js";
|
import { mdiClose } from "@mdi/js";
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state, query } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-dialog";
|
import {
|
||||||
|
getMobileOpenFromBottomAnimation,
|
||||||
|
getMobileCloseToBottomAnimation,
|
||||||
|
} from "../../../../components/ha-md-dialog";
|
||||||
|
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
||||||
import "../../../../components/ha-dialog-header";
|
import "../../../../components/ha-dialog-header";
|
||||||
import "../../../../components/ha-icon-button-toggle";
|
import "../../../../components/ha-icon-button-toggle";
|
||||||
import type { EntityRegistryEntry } from "../../../../data/entity_registry";
|
import type { EntityRegistryEntry } from "../../../../data/entity_registry";
|
||||||
import {
|
import {
|
||||||
formatTempColor,
|
|
||||||
LightColor,
|
LightColor,
|
||||||
LightColorMode,
|
LightColorMode,
|
||||||
LightEntity,
|
LightEntity,
|
||||||
@ -38,15 +41,7 @@ class DialogLightColorFavorite extends LitElement {
|
|||||||
|
|
||||||
@state() private _modes: LightPickerMode[] = [];
|
@state() private _modes: LightPickerMode[] = [];
|
||||||
|
|
||||||
@state() private _currentValue?: string;
|
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||||
|
|
||||||
private _colorHovered(ev: CustomEvent<HASSDomEvents["color-hovered"]>) {
|
|
||||||
if (ev.detail && "color_temp_kelvin" in ev.detail) {
|
|
||||||
this._currentValue = formatTempColor(ev.detail.color_temp_kelvin);
|
|
||||||
} else {
|
|
||||||
this._currentValue = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async showDialog(
|
public async showDialog(
|
||||||
dialogParams: LightColorFavoriteDialogParams
|
dialogParams: LightColorFavoriteDialogParams
|
||||||
@ -58,10 +53,7 @@ class DialogLightColorFavorite extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this._dialogParams = undefined;
|
this._dialog?.close();
|
||||||
this._entry = undefined;
|
|
||||||
this._color = undefined;
|
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _updateModes() {
|
private _updateModes() {
|
||||||
@ -130,9 +122,20 @@ class DialogLightColorFavorite extends LitElement {
|
|||||||
|
|
||||||
private async _cancel() {
|
private async _cancel() {
|
||||||
this._dialogParams?.cancel?.();
|
this._dialogParams?.cancel?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _cancelDialog() {
|
||||||
|
this._cancel();
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _dialogClosed(): void {
|
||||||
|
this._dialogParams = undefined;
|
||||||
|
this._entry = undefined;
|
||||||
|
this._color = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
private async _save() {
|
private async _save() {
|
||||||
if (!this._color) {
|
if (!this._color) {
|
||||||
this._cancel();
|
this._cancel();
|
||||||
@ -156,82 +159,83 @@ class DialogLightColorFavorite extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-md-dialog
|
||||||
open
|
open
|
||||||
@closed=${this._cancel}
|
@cancel=${this._cancel}
|
||||||
.heading=${this._dialogParams?.title ?? ""}
|
@closed=${this._dialogClosed}
|
||||||
flexContent
|
aria-labelledby="dialog-light-color-favorite-title"
|
||||||
|
.getOpenAnimation=${getMobileOpenFromBottomAnimation}
|
||||||
|
.getCloseAnimation=${getMobileCloseToBottomAnimation}
|
||||||
>
|
>
|
||||||
<ha-dialog-header slot="heading">
|
<ha-dialog-header slot="headline">
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="navigationIcon"
|
slot="navigationIcon"
|
||||||
dialogAction="cancel"
|
@click=${this.closeDialog}
|
||||||
.label=${this.hass.localize("ui.common.close")}
|
.label=${this.hass.localize("ui.common.close")}
|
||||||
.path=${mdiClose}
|
.path=${mdiClose}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<span slot="title">${this._dialogParams?.title}</span>
|
<span slot="title" id="dialog-light-color-favorite-title"
|
||||||
|
>${this._dialogParams?.title}</span
|
||||||
|
>
|
||||||
</ha-dialog-header>
|
</ha-dialog-header>
|
||||||
<div class="header">
|
<div slot="content">
|
||||||
<span class="value">${this._currentValue}</span>
|
<div class="header">
|
||||||
${this._modes.length > 1
|
${this._modes.length > 1
|
||||||
? html`
|
? html`
|
||||||
<div class="modes">
|
<div class="modes">
|
||||||
${this._modes.map(
|
${this._modes.map(
|
||||||
(value) => html`
|
(value) => html`
|
||||||
<ha-icon-button-toggle
|
<ha-icon-button-toggle
|
||||||
border-only
|
border-only
|
||||||
.selected=${value === this._mode}
|
.selected=${value === this._mode}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
`ui.dialogs.more_info_control.light.color_picker.mode.${value}`
|
`ui.dialogs.more_info_control.light.color_picker.mode.${value}`
|
||||||
)}
|
)}
|
||||||
.mode=${value}
|
.mode=${value}
|
||||||
@click=${this._modeChanged}
|
@click=${this._modeChanged}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="wheel ${classMap({ [value]: true })}"
|
class="wheel ${classMap({ [value]: true })}"
|
||||||
></span>
|
></span>
|
||||||
</ha-icon-button-toggle>
|
</ha-icon-button-toggle>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
${this._mode === "color_temp"
|
||||||
|
? html`
|
||||||
|
<light-color-temp-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
@color-changed=${this._colorChanged}
|
||||||
|
>
|
||||||
|
</light-color-temp-picker>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${this._mode === "color"
|
||||||
|
? html`
|
||||||
|
<light-color-rgb-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${this.stateObj}
|
||||||
|
@color-changed=${this._colorChanged}
|
||||||
|
>
|
||||||
|
</light-color-rgb-picker>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div slot="actions">
|
||||||
<div class="content">
|
<ha-button @click=${this._cancelDialog}>
|
||||||
${this._mode === "color_temp"
|
${this.hass.localize("ui.common.cancel")}
|
||||||
? html`
|
</ha-button>
|
||||||
<light-color-temp-picker
|
<ha-button @click=${this._save} .disabled=${!this._color}
|
||||||
.hass=${this.hass}
|
>${this.hass.localize("ui.common.save")}</ha-button
|
||||||
.stateObj=${this.stateObj}
|
>
|
||||||
@color-changed=${this._colorChanged}
|
|
||||||
@color-hovered=${this._colorHovered}
|
|
||||||
>
|
|
||||||
</light-color-temp-picker>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
${this._mode === "color"
|
|
||||||
? html`
|
|
||||||
<light-color-rgb-picker
|
|
||||||
.hass=${this.hass}
|
|
||||||
.stateObj=${this.stateObj}
|
|
||||||
@color-changed=${this._colorChanged}
|
|
||||||
@color-hovered=${this._colorHovered}
|
|
||||||
>
|
|
||||||
</light-color-rgb-picker>
|
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
</div>
|
</div>
|
||||||
<ha-button slot="secondaryAction" dialogAction="cancel">
|
</ha-md-dialog>
|
||||||
${this.hass.localize("ui.common.cancel")}
|
|
||||||
</ha-button>
|
|
||||||
<ha-button
|
|
||||||
slot="primaryAction"
|
|
||||||
@click=${this._save}
|
|
||||||
.disabled=${!this._color}
|
|
||||||
>${this.hass.localize("ui.common.save")}</ha-button
|
|
||||||
>
|
|
||||||
</ha-dialog>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,19 +243,23 @@ class DialogLightColorFavorite extends LitElement {
|
|||||||
return [
|
return [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
css`
|
css`
|
||||||
ha-dialog {
|
ha-md-dialog {
|
||||||
--dialog-content-padding: 0;
|
min-width: 420px; /* prevent width jumps when switching modes */
|
||||||
|
max-height: min(
|
||||||
|
600px,
|
||||||
|
100% - 48px
|
||||||
|
); /* prevent scrolling on desktop */
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||||
ha-dialog {
|
ha-md-dialog {
|
||||||
--dialog-surface-margin-top: 100px;
|
min-width: 100%;
|
||||||
--mdc-dialog-min-height: auto;
|
min-height: auto;
|
||||||
--mdc-dialog-max-height: calc(100% - 100px);
|
max-height: calc(100% - 100px);
|
||||||
--ha-dialog-border-radius: var(
|
margin-bottom: 0;
|
||||||
--ha-dialog-bottom-sheet-border-radius,
|
|
||||||
28px 28px 0 0
|
--md-dialog-container-shape-start-start: 28px;
|
||||||
);
|
--md-dialog-container-shape-start-end: 28px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,21 +295,6 @@ class DialogLightColorFavorite extends LitElement {
|
|||||||
rgb(255, 160, 0) 100%
|
rgb(255, 160, 0) 100%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
.value {
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: auto;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
height: 48px;
|
|
||||||
line-height: 48px;
|
|
||||||
letter-spacing: 0.1px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user