mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-11 03:51:07 +00:00
Compare commits
9 Commits
copilot/fi
...
wa-dialog-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6c6835de5 | ||
|
|
13346a21d7 | ||
|
|
fe364b0687 | ||
|
|
eb760d27b9 | ||
|
|
b62b7c6167 | ||
|
|
61238aad3a | ||
|
|
b4b7348646 | ||
|
|
f51d37f972 | ||
|
|
bca926f36c |
@@ -1,17 +1,16 @@
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state, query } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-bottom-sheet";
|
||||
import "../../../../components/ha-button";
|
||||
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-footer";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-icon-button-toggle";
|
||||
import "../../../../components/ha-wa-dialog";
|
||||
import type { EntityRegistryEntry } from "../../../../data/entity_registry";
|
||||
import type { LightColor, LightEntity } from "../../../../data/light";
|
||||
import {
|
||||
@@ -41,7 +40,11 @@ class DialogLightColorFavorite extends LitElement {
|
||||
|
||||
@state() private _modes: LightPickerMode[] = [];
|
||||
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
@state() private _open = false;
|
||||
|
||||
@state() private _narrow = false;
|
||||
|
||||
private _mediaQuery?: MediaQueryList;
|
||||
|
||||
public async showDialog(
|
||||
dialogParams: LightColorFavoriteDialogParams
|
||||
@@ -50,12 +53,22 @@ class DialogLightColorFavorite extends LitElement {
|
||||
this._dialogParams = dialogParams;
|
||||
this._color = dialogParams.initialColor ?? this._computeCurrentColor();
|
||||
this._updateModes();
|
||||
this._mediaQuery = matchMedia(
|
||||
"all and (max-width: 450px), all and (max-height: 500px)"
|
||||
);
|
||||
this._narrow = this._mediaQuery.matches;
|
||||
this._mediaQuery.addEventListener("change", this._handleMediaChange);
|
||||
this._open = true;
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._dialog?.close();
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
private _handleMediaChange = (ev: MediaQueryListEvent) => {
|
||||
this._narrow = ev.matches;
|
||||
};
|
||||
|
||||
private _updateModes() {
|
||||
const supportsTemp = lightSupportsColorMode(
|
||||
this.stateObj!,
|
||||
@@ -120,16 +133,16 @@ class DialogLightColorFavorite extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private async _cancel() {
|
||||
private _cancel() {
|
||||
this._dialogParams?.cancel?.();
|
||||
}
|
||||
|
||||
private _cancelDialog() {
|
||||
this._cancel();
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
private _dialogClosed(): void {
|
||||
if (this._mediaQuery) {
|
||||
this._mediaQuery.removeEventListener("change", this._handleMediaChange);
|
||||
this._mediaQuery = undefined;
|
||||
}
|
||||
this._dialogParams = undefined;
|
||||
this._entry = undefined;
|
||||
this._color = undefined;
|
||||
@@ -138,7 +151,6 @@ class DialogLightColorFavorite extends LitElement {
|
||||
|
||||
private async _save() {
|
||||
if (!this._color) {
|
||||
this._cancel();
|
||||
return;
|
||||
}
|
||||
this._dialogParams?.submit?.(this._color);
|
||||
@@ -153,89 +165,126 @@ class DialogLightColorFavorite extends LitElement {
|
||||
this._mode = newMode;
|
||||
}
|
||||
|
||||
private _renderModes() {
|
||||
if (this._modes.length <= 1) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
<div class="modes">
|
||||
${this._modes.map(
|
||||
(value) => html`
|
||||
<ha-icon-button-toggle
|
||||
border-only
|
||||
.selected=${value === this._mode}
|
||||
.label=${this.hass.localize(
|
||||
`ui.dialogs.more_info_control.light.color_picker.mode.${value}`
|
||||
)}
|
||||
.mode=${value}
|
||||
@click=${this._modeChanged}
|
||||
>
|
||||
<span class="wheel ${classMap({ [value]: true })}"></span>
|
||||
</ha-icon-button-toggle>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderColorPicker() {
|
||||
return html`
|
||||
${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}
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderButtons() {
|
||||
return html`
|
||||
<ha-button
|
||||
slot="secondaryAction"
|
||||
appearance="plain"
|
||||
@click=${this._cancel}
|
||||
>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
slot="primaryAction"
|
||||
appearance="accent"
|
||||
@click=${this._save}
|
||||
.disabled=${!this._color}
|
||||
>
|
||||
${this.hass.localize("ui.common.save")}
|
||||
</ha-button>
|
||||
`;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._entry || !this.stateObj) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
if (this._narrow) {
|
||||
return html`
|
||||
<ha-bottom-sheet .open=${this._open} @closed=${this._dialogClosed}>
|
||||
<div class="bottom-sheet-container">
|
||||
<ha-dialog-header>
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
@click=${this.closeDialog}
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<span slot="title">${this._dialogParams?.title}</span>
|
||||
</ha-dialog-header>
|
||||
<div class="header">${this._renderModes()}</div>
|
||||
<div class="content">${this._renderColorPicker()}</div>
|
||||
<div class="buttons">
|
||||
<ha-button appearance="plain" @click=${this._cancel}>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button
|
||||
appearance="accent"
|
||||
@click=${this._save}
|
||||
.disabled=${!this._color}
|
||||
>
|
||||
${this.hass.localize("ui.common.save")}
|
||||
</ha-button>
|
||||
</div>
|
||||
</div>
|
||||
</ha-bottom-sheet>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-md-dialog
|
||||
open
|
||||
@cancel=${this._cancel}
|
||||
<ha-wa-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
.headerTitle=${this._dialogParams?.title ?? ""}
|
||||
@closed=${this._dialogClosed}
|
||||
aria-labelledby="dialog-light-color-favorite-title"
|
||||
.getOpenAnimation=${getMobileOpenFromBottomAnimation}
|
||||
.getCloseAnimation=${getMobileCloseToBottomAnimation}
|
||||
>
|
||||
<ha-dialog-header slot="headline">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
@click=${this.closeDialog}
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<span slot="title" id="dialog-light-color-favorite-title"
|
||||
>${this._dialogParams?.title}</span
|
||||
>
|
||||
</ha-dialog-header>
|
||||
<div slot="content">
|
||||
<div class="header">
|
||||
${this._modes.length > 1
|
||||
? html`
|
||||
<div class="modes">
|
||||
${this._modes.map(
|
||||
(value) => html`
|
||||
<ha-icon-button-toggle
|
||||
border-only
|
||||
.selected=${value === this._mode}
|
||||
.label=${this.hass.localize(
|
||||
`ui.dialogs.more_info_control.light.color_picker.mode.${value}`
|
||||
)}
|
||||
.mode=${value}
|
||||
@click=${this._modeChanged}
|
||||
>
|
||||
<span
|
||||
class="wheel ${classMap({ [value]: true })}"
|
||||
></span>
|
||||
</ha-icon-button-toggle>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: 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 slot="actions">
|
||||
<ha-button appearance="plain" @click=${this._cancelDialog}>
|
||||
${this.hass.localize("ui.common.cancel")}
|
||||
</ha-button>
|
||||
<ha-button @click=${this._save} .disabled=${!this._color}
|
||||
>${this.hass.localize("ui.common.save")}</ha-button
|
||||
>
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
<div class="header">${this._renderModes()}</div>
|
||||
<div class="content">${this._renderColorPicker()}</div>
|
||||
<ha-dialog-footer slot="footer"
|
||||
>${this._renderButtons()}</ha-dialog-footer
|
||||
>
|
||||
</ha-wa-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -243,24 +292,39 @@ class DialogLightColorFavorite extends LitElement {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-md-dialog {
|
||||
min-width: 420px; /* prevent width jumps when switching modes */
|
||||
max-height: min(
|
||||
600px,
|
||||
100% - 48px
|
||||
); /* prevent scrolling on desktop */
|
||||
ha-wa-dialog {
|
||||
--ha-dialog-width-md: 420px;
|
||||
--dialog-content-padding: 0;
|
||||
--dialog-surface-position: fixed;
|
||||
}
|
||||
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
ha-md-dialog {
|
||||
min-width: 100%;
|
||||
min-height: auto;
|
||||
max-height: calc(100% - 100px);
|
||||
margin-bottom: 0;
|
||||
ha-bottom-sheet {
|
||||
--ha-bottom-sheet-max-width: 560px;
|
||||
--ha-bottom-sheet-padding: 0;
|
||||
--ha-bottom-sheet-surface-background: var(--card-background-color);
|
||||
}
|
||||
|
||||
--md-dialog-container-shape-start-start: 28px;
|
||||
--md-dialog-container-shape-start-end: 28px;
|
||||
}
|
||||
.bottom-sheet-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bottom-sheet-container .header {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.bottom-sheet-container .content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: var(--ha-space-2);
|
||||
padding: var(--ha-space-4) var(--ha-space-6);
|
||||
padding-bottom: max(var(--ha-space-4), env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -268,14 +332,14 @@ class DialogLightColorFavorite extends LitElement {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
padding: var(--ha-space-6);
|
||||
flex: 1;
|
||||
}
|
||||
.modes {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
padding: 0 24px;
|
||||
padding: 0 var(--ha-space-6);
|
||||
}
|
||||
.wheel {
|
||||
width: 30px;
|
||||
|
||||
Reference in New Issue
Block a user