Improve disabled state in more info (#17570)

This commit is contained in:
Paul Bottein 2023-08-15 13:50:44 +02:00 committed by GitHub
parent f6087f3805
commit baba02f563
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 358 additions and 550 deletions

View File

@ -238,6 +238,11 @@ export class HaControlSelectMenu extends SelectBase {
opacity: var(--control-select-menu-background-opacity);
}
.select-disabled .select-anchor {
cursor: not-allowed;
color: var(--disabled-color);
}
mwc-menu {
--mdc-shape-medium: 8px;
}

View File

@ -38,7 +38,7 @@ export class HaIconButtonToggle extends HaIconButton {
:host([selected]) mwc-icon-button {
color: var(--primary-background-color);
}
:host([selected]) mwc-icon-button::before {
:host([selected]:not([disabled])) mwc-icon-button::before {
opacity: 1;
}
`;

View File

@ -16,6 +16,7 @@ import { ClimateEntity, ClimateEntityFeature } from "../../../../data/climate";
import { UNAVAILABLE } from "../../../../data/entity";
import { computeCssVariable } from "../../../../resources/css-variables";
import { HomeAssistant } from "../../../../types";
import { moreInfoControlCircularSliderStyle } from "../ha-more-info-control-circular-slider-style";
@customElement("ha-more-info-climate-humidity")
export class HaMoreInfoClimateHumidity extends LitElement {
@ -78,8 +79,16 @@ export class HaMoreInfoClimateHumidity extends LitElement {
}
private _renderLabel() {
if (this.stateObj.state === UNAVAILABLE) {
return html`
<p class="label disabled">
${this.hass.formatEntityState(this.stateObj, UNAVAILABLE)}
</p>
`;
}
return html`
<p class="action">
<p class="label">
${this.hass.localize(
"ui.dialogs.more_info_control.climate.humidity_target"
)}
@ -131,7 +140,7 @@ export class HaMoreInfoClimateHumidity extends LitElement {
const active = stateActive(this.stateObj);
// Use humidifier state color
const mainColor = computeCssVariable(
const stateColor = computeCssVariable(
domainStateColorProperties(
"humidifier",
this.stateObj,
@ -142,12 +151,16 @@ export class HaMoreInfoClimateHumidity extends LitElement {
const targetHumidity = this._targetHumidity;
const currentHumidity = this.stateObj.attributes.current_humidity;
if (supportsTargetHumidity && targetHumidity != null) {
if (
supportsTargetHumidity &&
targetHumidity != null &&
this.stateObj.state !== UNAVAILABLE
) {
return html`
<div
class="container"
style=${styleMap({
"--main-color": mainColor,
"--state-color": stateColor,
})}
>
<ha-control-circular-slider
@ -156,13 +169,12 @@ export class HaMoreInfoClimateHumidity extends LitElement {
.max=${this._max}
.step=${this._step}
.current=${currentHumidity}
.disabled=${this.stateObj!.state === UNAVAILABLE}
@value-changed=${this._valueChanged}
@value-changing=${this._valueChanging}
>
</ha-control-circular-slider>
<div class="info">
<div class="action-container">${this._renderLabel()}</div>
<div class="label-container">${this._renderLabel()}</div>
<div class="target-container">
${this._renderTarget(targetHumidity)}
</div>
@ -175,152 +187,40 @@ export class HaMoreInfoClimateHumidity extends LitElement {
return html`
<div class="container">
<ha-control-circular-slider
.current=${this.stateObj.attributes.current_temperature}
.current=${this.stateObj.attributes.current_humidity}
.min=${this._min}
.max=${this._max}
.step=${this._step}
disabled
>
</ha-control-circular-slider>
<div class="info">
<div class="label-container">${this._renderLabel()}</div>
</div>
</div>
`;
}
static get styles(): CSSResultGroup {
return css`
/* Layout */
.container {
position: relative;
}
.info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
font-size: 16px;
line-height: 24px;
letter-spacing: 0.1px;
}
.info * {
margin: 0;
pointer-events: auto;
}
/* Elements */
.target-container {
margin-bottom: 30px;
}
.target .value {
font-size: 56px;
line-height: 1;
letter-spacing: -0.25px;
}
.target .value .unit {
font-size: 0.4em;
line-height: 1;
margin-left: 2px;
}
.action-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 48px;
margin-bottom: 6px;
}
.action {
font-weight: 500;
text-align: center;
color: var(--action-color, inherit);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.dual {
display: flex;
flex-direction: row;
gap: 24px;
margin-bottom: 40px;
}
.dual button {
outline: none;
background: none;
color: inherit;
font-family: inherit;
-webkit-tap-highlight-color: transparent;
border: none;
opacity: 0.5;
padding: 0;
transition:
opacity 180ms ease-in-out,
transform 180ms ease-in-out;
cursor: pointer;
}
.dual button:focus-visible {
transform: scale(1.1);
}
.dual button.selected {
opacity: 1;
}
.buttons {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
margin: 0 auto;
width: 120px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-size: 48px;
--md-outlined-icon-button-icon-size: 24px;
}
/* Accessibility */
.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
/* Slider */
ha-control-circular-slider {
--control-circular-slider-color: var(
--main-color,
var(--disabled-color)
);
}
ha-control-circular-slider::after {
display: block;
content: "";
position: absolute;
top: -10%;
left: -10%;
right: -10%;
bottom: -10%;
background: radial-gradient(
50% 50% at 50% 50%,
var(--action-color, transparent) 0%,
transparent 100%
);
opacity: 0.15;
pointer-events: none;
}
`;
return [
moreInfoControlCircularSliderStyle,
css`
/* Elements */
.target-container {
margin-bottom: 30px;
}
.target .value {
font-size: 58px;
line-height: 1;
letter-spacing: -0.25px;
}
.target .value .unit {
font-size: 0.4em;
line-height: 1;
margin-left: 2px;
}
`,
];
}
}

View File

@ -27,6 +27,7 @@ import {
} from "../../../../data/climate";
import { UNAVAILABLE } from "../../../../data/entity";
import { HomeAssistant } from "../../../../types";
import { moreInfoControlCircularSliderStyle } from "../ha-more-info-control-circular-slider-style";
type Target = "value" | "low" | "high";
@ -137,7 +138,15 @@ export class HaMoreInfoClimateTemperature extends LitElement {
this._selectTargetTemperature = target;
}
private _renderHvacAction() {
private _renderLabel() {
if (this.stateObj.state === UNAVAILABLE) {
return html`
<p class="label disabled">
${this.hass.formatEntityState(this.stateObj, UNAVAILABLE)}
</p>
`;
}
const action = this.stateObj.attributes.hvac_action;
const actionLabel = computeAttributeValueDisplay(
@ -150,7 +159,7 @@ export class HaMoreInfoClimateTemperature extends LitElement {
) as string;
return html`
<p class="action">
<p class="label">
${action && ["preheating", "heating", "cooling"].includes(action)
? this.hass.localize(
"ui.dialogs.more_info_control.climate.target_label",
@ -246,7 +255,7 @@ export class HaMoreInfoClimateTemperature extends LitElement {
const action = this.stateObj.attributes.hvac_action;
const active = stateActive(this.stateObj);
const mainColor = stateColorCss(this.stateObj);
const stateColor = stateColorCss(this.stateObj);
const lowColor = stateColorCss(this.stateObj, active ? "heat" : "off");
const highColor = stateColorCss(this.stateObj, active ? "cool" : "off");
@ -260,7 +269,11 @@ export class HaMoreInfoClimateTemperature extends LitElement {
const hvacModes = this.stateObj.attributes.hvac_modes;
if (supportsTargetTemperature && this._targetTemperature.value != null) {
if (
supportsTargetTemperature &&
this._targetTemperature.value != null &&
this.stateObj.state !== UNAVAILABLE
) {
const hasOnlyCoolMode =
hvacModes.length === 2 &&
hvacModes.includes("cool") &&
@ -269,7 +282,7 @@ export class HaMoreInfoClimateTemperature extends LitElement {
<div
class="container"
style=${styleMap({
"--main-color": mainColor,
"--state-color": stateColor,
"--action-color": actionColor,
})}
>
@ -280,13 +293,12 @@ export class HaMoreInfoClimateTemperature extends LitElement {
.max=${this._max}
.step=${this._step}
.current=${this.stateObj.attributes.current_temperature}
.disabled=${this.stateObj!.state === UNAVAILABLE}
@value-changed=${this._valueChanged}
@value-changing=${this._valueChanging}
>
</ha-control-circular-slider>
<div class="info">
<div class="action-container">${this._renderHvacAction()}</div>
<div class="label-container">${this._renderLabel()}</div>
<div class="temperature-container">
${this._renderTargetTemperature(this._targetTemperature.value)}
</div>
@ -299,7 +311,8 @@ export class HaMoreInfoClimateTemperature extends LitElement {
if (
supportsTargetTemperatureRange &&
this._targetTemperature.low != null &&
this._targetTemperature.high != null
this._targetTemperature.high != null &&
this.stateObj.state !== UNAVAILABLE
) {
return html`
<div
@ -312,7 +325,6 @@ export class HaMoreInfoClimateTemperature extends LitElement {
>
<ha-control-circular-slider
dual
.disabled=${this.stateObj!.state === UNAVAILABLE}
.low=${this._targetTemperature.low}
.high=${this._targetTemperature.high}
.min=${this._min}
@ -326,7 +338,7 @@ export class HaMoreInfoClimateTemperature extends LitElement {
>
</ha-control-circular-slider>
<div class="info">
<div class="action-container">${this._renderHvacAction()}</div>
<div class="label-container">${this._renderLabel()}</div>
<div class="temperature-container dual">
<button
@click=${this._handleSelectTemp}
@ -368,163 +380,87 @@ export class HaMoreInfoClimateTemperature extends LitElement {
disabled
>
</ha-control-circular-slider>
<div class="info">
<div class="label-container">${this._renderLabel()}</div>
</div>
</div>
`;
}
static get styles(): CSSResultGroup {
return css`
/* Layout */
.container {
position: relative;
}
.info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
font-size: 16px;
line-height: 24px;
letter-spacing: 0.1px;
}
.info * {
margin: 0;
pointer-events: auto;
}
/* Elements */
.temperature-container {
margin-bottom: 30px;
}
.temperature {
display: inline-flex;
font-size: 58px;
line-height: 64px;
letter-spacing: -0.25px;
margin: 0;
}
.temperature span {
display: inline-flex;
}
.temperature .unit {
font-size: 24px;
line-height: 40px;
}
.temperature .decimal {
font-size: 24px;
line-height: 40px;
align-self: flex-end;
margin-right: -18px;
}
.action-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 48px;
margin-bottom: 6px;
}
.action {
font-weight: 500;
text-align: center;
color: var(--action-color, inherit);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.dual {
display: flex;
flex-direction: row;
gap: 24px;
margin-bottom: 40px;
}
return [
moreInfoControlCircularSliderStyle,
css`
/* Elements */
.temperature-container {
margin-bottom: 30px;
}
.temperature {
display: inline-flex;
font-size: 58px;
line-height: 64px;
letter-spacing: -0.25px;
margin: 0;
}
.temperature span {
display: inline-flex;
}
.temperature .decimal {
font-size: 24px;
line-height: 32px;
align-self: flex-end;
width: 20px;
margin-bottom: 4px;
}
.temperature .unit {
font-size: 20px;
line-height: 24px;
align-self: flex-start;
margin-left: -20px;
width: 20px;
margin-top: 4px;
}
.dual button {
outline: none;
background: none;
color: inherit;
font-family: inherit;
-webkit-tap-highlight-color: transparent;
border: none;
opacity: 0.5;
padding: 0;
transition:
opacity 180ms ease-in-out,
transform 180ms ease-in-out;
cursor: pointer;
}
.dual button:focus-visible {
transform: scale(1.1);
}
.dual button.selected {
opacity: 1;
}
.buttons {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
margin: 0 auto;
width: 120px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-size: 48px;
--md-outlined-icon-button-icon-size: 24px;
}
/* Accessibility */
.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
/* Slider */
ha-control-circular-slider {
--control-circular-slider-color: var(
--main-color,
var(--disabled-color)
);
--control-circular-slider-low-color: var(
--low-color,
var(--disabled-color)
);
--control-circular-slider-high-color: var(
--high-color,
var(--disabled-color)
);
}
ha-control-circular-slider::after {
display: block;
content: "";
position: absolute;
top: -10%;
left: -10%;
right: -10%;
bottom: -10%;
background: radial-gradient(
50% 50% at 50% 50%,
var(--action-color, transparent) 0%,
transparent 100%
);
opacity: 0.15;
pointer-events: none;
}
`;
.dual {
display: flex;
flex-direction: row;
gap: 24px;
margin-bottom: 40px;
}
.dual button {
outline: none;
background: none;
color: inherit;
font-family: inherit;
-webkit-tap-highlight-color: transparent;
border: none;
opacity: 0.5;
padding: 0;
transition:
opacity 180ms ease-in-out,
transform 180ms ease-in-out;
cursor: pointer;
}
.dual button:focus-visible {
transform: scale(1.1);
}
.dual button.selected {
opacity: 1;
}
/* Slider */
ha-control-circular-slider {
--control-circular-slider-low-color: var(
--low-color,
var(--disabled-color)
);
--control-circular-slider-high-color: var(
--high-color,
var(--disabled-color)
);
}
`,
];
}
}

View File

@ -0,0 +1,97 @@
import { css } from "lit";
export const moreInfoControlCircularSliderStyle = css`
/* Layout elements */
.container {
position: relative;
}
.info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
font-size: 16px;
line-height: 24px;
letter-spacing: 0.1px;
}
.info * {
margin: 0;
pointer-events: auto;
}
/* Info elements */
.label-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 48px;
margin-bottom: 6px;
}
.label {
font-weight: 500;
text-align: center;
color: var(--action-color, inherit);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.label.disabled {
color: var(--secondary-text-color);
}
.buttons {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
margin: 0 auto;
width: 120px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-size: 48px;
--md-outlined-icon-button-icon-size: 24px;
}
/* Accessibility */
.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
/* Slider */
ha-control-circular-slider {
--control-circular-slider-color: var(--state-color, var(--disabled-color));
}
ha-control-circular-slider::after {
display: block;
content: "";
position: absolute;
top: -10%;
left: -10%;
right: -10%;
bottom: -10%;
background: radial-gradient(
50% 50% at 50% 50%,
var(--action-color, transparent) 0%,
transparent 100%
);
opacity: 0.15;
pointer-events: none;
}
`;

View File

@ -19,6 +19,7 @@ import {
HumidifierEntityDeviceClass,
} from "../../../../data/humidifier";
import { HomeAssistant } from "../../../../types";
import { moreInfoControlCircularSliderStyle } from "../ha-more-info-control-circular-slider-style";
@customElement("ha-more-info-humidifier-humidity")
export class HaMoreInfoHumidifierHumidity extends LitElement {
@ -80,7 +81,15 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
this._debouncedCallService();
}
private _renderAction() {
private _renderLabel() {
if (this.stateObj.state === UNAVAILABLE) {
return html`
<p class="label disabled">
${this.hass.formatEntityState(this.stateObj, UNAVAILABLE)}
</p>
`;
}
const action = this.stateObj.attributes.action;
const actionLabel = computeAttributeValueDisplay(
@ -93,7 +102,7 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
) as string;
return html`
<p class="action">
<p class="label">
${action && ["drying", "humidifying"].includes(action)
? this.hass.localize(
"ui.dialogs.more_info_control.humidifier.target_label",
@ -145,7 +154,7 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
}
protected render() {
const mainColor = stateColorCss(this.stateObj);
const stateColor = stateColorCss(this.stateObj);
const active = stateActive(this.stateObj);
const action = this.stateObj.attributes.action;
@ -161,7 +170,7 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
const targetHumidity = this._targetHumidity;
const currentHumidity = this.stateObj.attributes.current_humidity;
if (targetHumidity != null) {
if (targetHumidity != null && this.stateObj.state !== UNAVAILABLE) {
const inverted =
this.stateObj.attributes.device_class ===
HumidifierEntityDeviceClass.DEHUMIDIFIER;
@ -170,7 +179,7 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
<div
class="container"
style=${styleMap({
"--main-color": mainColor,
"--state-color": stateColor,
"--action-color": actionColor,
})}
>
@ -181,13 +190,12 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
.max=${this._max}
.step=${this._step}
.current=${currentHumidity}
.disabled=${this.stateObj.state === UNAVAILABLE}
@value-changed=${this._valueChanged}
@value-changing=${this._valueChanging}
>
</ha-control-circular-slider>
<div class="info">
<div class="action-container">${this._renderAction()}</div>
<div class="label-container">${this._renderLabel()}</div>
<div class="target-container">
${this._renderTarget(targetHumidity)}
</div>
@ -212,118 +220,33 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
disabled
>
</ha-control-circular-slider>
<div class="info">
<div class="label-container">${this._renderLabel()}</div>
</div>
</div>
`;
}
static get styles(): CSSResultGroup {
return css`
/* Layout */
.container {
position: relative;
}
.info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
font-size: 16px;
line-height: 24px;
letter-spacing: 0.1px;
}
.info * {
margin: 0;
pointer-events: auto;
}
/* Elements */
.target-container {
margin-bottom: 30px;
}
.target .value {
font-size: 56px;
line-height: 1;
letter-spacing: -0.25px;
}
.target .value .unit {
font-size: 0.4em;
line-height: 1;
margin-left: 2px;
}
.action-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 48px;
margin-bottom: 6px;
}
.action {
font-weight: 500;
text-align: center;
color: var(--action-color, inherit);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.buttons {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
margin: 0 auto;
width: 120px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-size: 48px;
--md-outlined-icon-button-icon-size: 24px;
}
/* Accessibility */
.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
/* Slider */
ha-control-circular-slider {
--control-circular-slider-color: var(
--main-color,
var(--disabled-color)
);
}
ha-control-circular-slider::after {
display: block;
content: "";
position: absolute;
top: -10%;
left: -10%;
right: -10%;
bottom: -10%;
background: radial-gradient(
50% 50% at 50% 50%,
var(--action-color, transparent) 0%,
transparent 100%
);
opacity: 0.15;
pointer-events: none;
}
`;
return [
moreInfoControlCircularSliderStyle,
css`
/* Elements */
.target-container {
margin-bottom: 30px;
}
.target .value {
font-size: 58px;
line-height: 1;
letter-spacing: -0.25px;
}
.target .value .unit {
font-size: 0.4em;
line-height: 1;
margin-left: 2px;
}
`,
];
}
}

View File

@ -23,6 +23,7 @@ import {
WaterHeaterEntityFeature,
} from "../../../../data/water_heater";
import { HomeAssistant } from "../../../../types";
import { moreInfoControlCircularSliderStyle } from "../ha-more-info-control-circular-slider-style";
@customElement("ha-more-info-water_heater-temperature")
export class HaMoreInfoWaterHeaterTemperature extends LitElement {
@ -88,8 +89,16 @@ export class HaMoreInfoWaterHeaterTemperature extends LitElement {
}
private _renderLabel() {
if (this.stateObj.state === UNAVAILABLE) {
return html`
<p class="label disabled">
${this.hass.formatEntityState(this.stateObj, UNAVAILABLE)}
</p>
`;
}
return html`
<p class="action">
<p class="label">
${this.hass.localize(
"ui.dialogs.more_info_control.water_heater.target"
)}
@ -153,14 +162,18 @@ export class HaMoreInfoWaterHeaterTemperature extends LitElement {
WaterHeaterEntityFeature.TARGET_TEMPERATURE
);
const mainColor = stateColorCss(this.stateObj);
const stateColor = stateColorCss(this.stateObj);
if (supportsTargetTemperature && this._targetTemperature != null) {
if (
supportsTargetTemperature &&
this._targetTemperature != null &&
this.stateObj.state !== UNAVAILABLE
) {
return html`
<div
class="container"
style=${styleMap({
"--main-color": mainColor,
"--state-color": stateColor,
})}
>
<ha-control-circular-slider
@ -169,13 +182,12 @@ export class HaMoreInfoWaterHeaterTemperature extends LitElement {
.max=${this._max}
.step=${this._step}
.current=${this.stateObj.attributes.current_temperature}
.disabled=${this.stateObj!.state === UNAVAILABLE}
@value-changed=${this._valueChanged}
@value-changing=${this._valueChanging}
>
</ha-control-circular-slider>
<div class="info">
<div class="action-container">${this._renderLabel()}</div>
<div class="label-container">${this._renderLabel()}</div>
<div class="temperature-container">
${this._renderTargetTemperature(this._targetTemperature)}
</div>
@ -195,128 +207,48 @@ export class HaMoreInfoWaterHeaterTemperature extends LitElement {
disabled
>
</ha-control-circular-slider>
<div class="info">
<div class="label-container">${this._renderLabel()}</div>
</div>
</div>
`;
}
static get styles(): CSSResultGroup {
return css`
/* Layout */
.container {
position: relative;
}
.info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
pointer-events: none;
font-size: 16px;
line-height: 24px;
letter-spacing: 0.1px;
}
.info * {
margin: 0;
pointer-events: auto;
}
/* Elements */
.temperature-container {
margin-bottom: 30px;
}
.temperature {
display: inline-flex;
font-size: 58px;
line-height: 64px;
letter-spacing: -0.25px;
margin: 0;
}
.temperature span {
display: inline-flex;
}
.temperature .unit {
font-size: 24px;
line-height: 40px;
}
.temperature .decimal {
font-size: 24px;
line-height: 40px;
align-self: flex-end;
margin-right: -18px;
}
.action-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200px;
height: 48px;
margin-bottom: 6px;
}
.action {
font-weight: 500;
text-align: center;
color: var(--action-color, inherit);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.buttons {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
margin: 0 auto;
width: 120px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-size: 48px;
--md-outlined-icon-button-icon-size: 24px;
}
/* Accessibility */
.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
/* Slider */
ha-control-circular-slider {
--control-circular-slider-color: var(
--main-color,
var(--disabled-color)
);
}
ha-control-circular-slider::after {
display: block;
content: "";
position: absolute;
top: -10%;
left: -10%;
right: -10%;
bottom: -10%;
background: radial-gradient(
50% 50% at 50% 50%,
var(--action-color, transparent) 0%,
transparent 100%
);
opacity: 0.15;
pointer-events: none;
}
`;
return [
moreInfoControlCircularSliderStyle,
css`
/* Elements */
.temperature-container {
margin-bottom: 30px;
}
.temperature {
display: inline-flex;
font-size: 58px;
line-height: 64px;
letter-spacing: -0.25px;
margin: 0;
}
.temperature span {
display: inline-flex;
}
.temperature .decimal {
font-size: 24px;
line-height: 32px;
align-self: flex-end;
width: 20px;
margin-bottom: 4px;
}
.temperature .unit {
font-size: 20px;
line-height: 24px;
align-self: flex-start;
margin-left: -20px;
width: 20px;
margin-top: 4px;
}
`,
];
}
}

View File

@ -170,6 +170,7 @@ class MoreInfoClimate extends LitElement {
<ha-control-select-menu
.label=${hass.localize("ui.card.climate.operation")}
.value=${stateObj.state}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleOperationModeChanged}
@ -203,6 +204,7 @@ class MoreInfoClimate extends LitElement {
"preset_mode"
)}
.value=${stateObj.attributes.preset_mode}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handlePresetmodeChanged}
@ -240,6 +242,7 @@ class MoreInfoClimate extends LitElement {
"fan_mode"
)}
.value=${stateObj.attributes.fan_mode}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleFanModeChanged}
@ -277,6 +280,7 @@ class MoreInfoClimate extends LitElement {
"swing_mode"
)}
.value=${stateObj.attributes.swing_mode}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleSwingmodeChanged}

View File

@ -201,6 +201,7 @@ class MoreInfoFan extends LitElement {
"preset_mode"
)}
.value=${this.stateObj.attributes.preset_mode}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handlePresetMode}
@ -232,6 +233,7 @@ class MoreInfoFan extends LitElement {
"direction"
)}
.value=${this.stateObj.attributes.direction}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleDirection}
@ -243,7 +245,7 @@ class MoreInfoFan extends LitElement {
? mdiRotateLeft
: mdiRotateRight}
></ha-svg-icon>
<ha-list-item .value=${"forward"} graphic="icon">
<ha-list-item value="forward" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${mdiRotateRight}
@ -254,7 +256,7 @@ class MoreInfoFan extends LitElement {
"forward"
)}
</ha-list-item>
<ha-list-item .value=${"reverse"} graphic="icon">
<ha-list-item value="reverse" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${mdiRotateLeft}
@ -276,6 +278,7 @@ class MoreInfoFan extends LitElement {
"oscillating"
)}
.value=${this.stateObj.attributes.oscillating ? "on" : "off"}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleOscillating}
@ -287,14 +290,14 @@ class MoreInfoFan extends LitElement {
? haOscillating
: haOscillatingOff}
></ha-svg-icon>
<ha-list-item .value=${"on"} graphic="icon">
<ha-list-item value="on" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${haOscillating}
></ha-svg-icon>
${this.hass.localize("state.default.on")}
</ha-list-item>
<ha-list-item .value=${"off"} graphic="icon">
<ha-list-item value="off" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${haOscillatingOff}

View File

@ -19,6 +19,8 @@ import { supportsFeature } from "../../../common/entity/supports-feature";
import { formatNumber } from "../../../common/number/format_number";
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
import "../../../components/ha-control-select-menu";
import "../../../components/ha-list-item";
import { UNAVAILABLE } from "../../../data/entity";
import {
HumidifierEntity,
HumidifierEntityFeature,
@ -95,13 +97,14 @@ class MoreInfoHumidifier extends LitElement {
<ha-control-select-menu
.label=${this.hass.localize("ui.card.humidifier.state")}
.value=${this.stateObj.state}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleStateChanged}
@closed=${stopPropagation}
>
<ha-svg-icon slot="icon" .path=${mdiPower}></ha-svg-icon>
<mwc-list-item value="off">
<ha-list-item value="off">
${computeStateDisplay(
this.hass.localize,
this.stateObj,
@ -110,8 +113,8 @@ class MoreInfoHumidifier extends LitElement {
this.hass.entities,
"off"
)}
</mwc-list-item>
<mwc-list-item value="on">
</ha-list-item>
<ha-list-item value="on">
${computeStateDisplay(
this.hass.localize,
this.stateObj,
@ -120,7 +123,7 @@ class MoreInfoHumidifier extends LitElement {
this.hass.entities,
"on"
)}
</mwc-list-item>
</ha-list-item>
</ha-control-select-menu>
${supportModes
@ -128,6 +131,7 @@ class MoreInfoHumidifier extends LitElement {
<ha-control-select-menu
.label=${hass.localize("ui.card.humidifier.mode")}
.value=${stateObj.attributes.mode}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleModeChanged}

View File

@ -294,6 +294,7 @@ class MoreInfoLight extends LitElement {
"effect"
)}
.value=${this.stateObj.attributes.effect}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleEffect}

View File

@ -16,6 +16,7 @@ import {
import { HomeAssistant } from "../../../types";
import { moreInfoControlStyle } from "../components/ha-more-info-control-style";
import "../components/water_heater/ha-more-info-water_heater-temperature";
import { UNAVAILABLE } from "../../../data/entity";
@customElement("more-info-water_heater")
class MoreInfoWaterHeater extends LitElement {
@ -77,6 +78,7 @@ class MoreInfoWaterHeater extends LitElement {
"operation"
)}
.value=${stateObj.state}
.disabled=${stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleOperationModeChanged}
@ -113,6 +115,7 @@ class MoreInfoWaterHeater extends LitElement {
"away_mode"
)}
.value=${stateObj.attributes.away_mode}
.disabled=${stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleAwayModeChanged}
@ -124,14 +127,14 @@ class MoreInfoWaterHeater extends LitElement {
? mdiAccountArrowRight
: mdiAccount}
></ha-svg-icon>
<ha-list-item .value=${"on"} graphic="icon">
<ha-list-item value="on" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${mdiAccountArrowRight}
></ha-svg-icon>
${this.hass.localize("state.default.on")}
</ha-list-item>
<ha-list-item .value=${"off"} graphic="icon">
<ha-list-item value="off" graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${mdiAccount}