Redesign mode buttons for climate more-info (#17535)

This commit is contained in:
Paul Bottein 2023-08-10 09:57:03 +02:00 committed by GitHub
parent 416661f3d1
commit 023f13cd12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 294 additions and 148 deletions

View File

@ -1,18 +1,38 @@
import {
mdiAccountArrowRight,
mdiArrowAll,
mdiArrowLeftRight,
mdiArrowUpDown,
mdiBed,
mdiCircleMedium,
mdiClockOutline,
mdiFan,
mdiFanAuto,
mdiFanOff,
mdiFire,
mdiHeatWave,
mdiHome,
mdiLeaf,
mdiMotionSensor,
mdiPower,
mdiRocketLaunch,
mdiSnowflake,
mdiSofa,
mdiSpeedometer,
mdiSpeedometerMedium,
mdiSpeedometerSlow,
mdiSunSnowflakeVariant,
mdiTarget,
mdiThermostatAuto,
mdiWaterPercent,
mdiWeatherWindy,
} from "@mdi/js";
import {
HassEntityAttributeBase,
HassEntityBase,
} from "home-assistant-js-websocket";
import { haOscillatingOff } from "./icons/haOscillatingOff";
import { haOscillating } from "./icons/haOscillating";
export type HvacMode =
| "off"
@ -114,3 +134,82 @@ export const CLIMATE_HVAC_MODE_ICONS: Record<HvacMode, string> = {
off: mdiPower,
heat_cool: mdiSunSnowflakeVariant,
};
export const computeHvacModeIcon = (mode: HvacMode) =>
CLIMATE_HVAC_MODE_ICONS[mode];
type ClimateBuiltInPresetMode =
| "eco"
| "away"
| "boost"
| "comfort"
| "home"
| "sleep"
| "activity";
export const CLIMATE_PRESET_MODE_ICONS: Record<
ClimateBuiltInPresetMode,
string
> = {
away: mdiAccountArrowRight,
boost: mdiRocketLaunch,
comfort: mdiSofa,
eco: mdiLeaf,
home: mdiHome,
sleep: mdiBed,
activity: mdiMotionSensor,
};
export const computePresetModeIcon = (mode: string) =>
mode in CLIMATE_PRESET_MODE_ICONS
? CLIMATE_PRESET_MODE_ICONS[mode]
: mdiCircleMedium;
type ClimateBuiltInFanMode =
| "on"
| "off"
| "auto"
| "low"
| "medium"
| "high"
| "middle"
| "focus"
| "diffuse";
export const CLIMATE_FAN_MODE_ICONS: Record<ClimateBuiltInFanMode, string> = {
on: mdiFan,
off: mdiFanOff,
auto: mdiFanAuto,
low: mdiSpeedometerSlow,
medium: mdiSpeedometerMedium,
high: mdiSpeedometer,
middle: mdiSpeedometerMedium,
focus: mdiTarget,
diffuse: mdiWeatherWindy,
};
export const computeFanModeIcon = (mode: string) =>
mode in CLIMATE_FAN_MODE_ICONS
? CLIMATE_FAN_MODE_ICONS[mode]
: mdiCircleMedium;
type ClimateBuiltInSwingMode =
| "off"
| "on"
| "vertical"
| "horizontal"
| "both";
export const CLIMATE_SWING_MODE_ICONS: Record<ClimateBuiltInSwingMode, string> =
{
on: haOscillating,
off: haOscillatingOff,
vertical: mdiArrowUpDown,
horizontal: mdiArrowLeftRight,
both: mdiArrowAll,
};
export const computeSwingModeIcon = (mode: string) =>
mode in CLIMATE_SWING_MODE_ICONS
? CLIMATE_SWING_MODE_ICONS[mode]
: mdiCircleMedium;

View File

@ -1,9 +1,9 @@
import {
mdiAccountArrowRight,
mdiAirHumidifier,
mdiArrowDownBold,
mdiArrowUpBold,
mdiBabyCarriage,
mdiCircleMedium,
mdiClockOutline,
mdiHome,
mdiLeaf,
@ -68,7 +68,7 @@ export const HUMIDIFIER_MODE_ICONS: Record<HumidifierBuiltInMode, string> = {
};
export const computeHumidiferModeIcon = (mode?: string) =>
HUMIDIFIER_MODE_ICONS[mode as HumidifierBuiltInMode] ?? mdiAirHumidifier;
HUMIDIFIER_MODE_ICONS[mode as HumidifierBuiltInMode] ?? mdiCircleMedium;
export const HUMIDIFIER_ACTION_ICONS: Record<HumidifierAction, string> = {
drying: mdiArrowDownBold,

View File

@ -167,11 +167,12 @@ export class HaMoreInfoClimateTemperature extends LitElement {
const lowColor = stateColorCss(this.stateObj, "heat");
const highColor = stateColorCss(this.stateObj, "cool");
const color = colored
? target === "high"
? highColor
: lowColor
: undefined;
const color =
colored && stateActive(this.stateObj)
? target === "high"
? highColor
: lowColor
: undefined;
return html`
<div class="buttons">

View File

@ -1,5 +1,11 @@
import "@material/mwc-list/mwc-list-item";
import { mdiThermometer, mdiWaterPercent } from "@mdi/js";
import {
mdiFan,
mdiThermometer,
mdiThermostat,
mdiTuneVariant,
mdiWaterPercent,
} from "@mdi/js";
import {
CSSResultGroup,
LitElement,
@ -20,20 +26,28 @@ import { computeStateDisplay } from "../../../common/entity/compute_state_displa
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-icon-button-group";
import "../../../components/ha-icon-button-toggle";
import "../../../components/ha-list-item";
import "../../../components/ha-select";
import "../../../components/ha-switch";
import {
ClimateEntity,
ClimateEntityFeature,
HvacMode,
compareClimateHvacModes,
computeFanModeIcon,
computeHvacModeIcon,
computePresetModeIcon,
computeSwingModeIcon,
} from "../../../data/climate";
import { UNAVAILABLE } from "../../../data/entity";
import { HomeAssistant } from "../../../types";
import "../components/climate/ha-more-info-climate-humidity";
import "../components/climate/ha-more-info-climate-temperature";
import { moreInfoControlStyle } from "../components/ha-more-info-control-style";
import { haOscillating } from "../../../data/icons/haOscillating";
type MainControl = "temperature" | "humidity";
@ -173,6 +187,174 @@ class MoreInfoClimate extends LitElement {
`
: nothing}
</div>
<div class="secondary-controls">
<div class="secondary-controls-scroll">
<ha-control-select-menu
.label=${hass.localize("ui.card.climate.operation")}
.value=${stateObj.state}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleOperationmodeChanged}
@closed=${stopPropagation}
>
<ha-svg-icon
slot="icon"
.path=${computeHvacModeIcon(stateObj.state as HvacMode) ??
mdiThermostat}
></ha-svg-icon>
${stateObj.attributes.hvac_modes
.concat()
.sort(compareClimateHvacModes)
.map(
(mode) => html`
<ha-list-item .value=${mode} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${computeHvacModeIcon(mode)}
></ha-svg-icon>
${computeStateDisplay(
hass.localize,
stateObj,
hass.locale,
this.hass.config,
hass.entities,
mode
)}
</ha-list-item>
`
)}
</ha-control-select-menu>
${supportPresetMode && stateObj.attributes.preset_modes
? html`
<ha-control-select-menu
.label=${computeAttributeNameDisplay(
hass.localize,
stateObj,
hass.entities,
"preset_mode"
)}
.value=${stateObj.attributes.preset_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handlePresetmodeChanged}
@closed=${stopPropagation}
>
<ha-svg-icon
slot="icon"
.path=${stateObj.attributes.preset_mode
? computePresetModeIcon(stateObj.attributes.preset_mode)
: mdiTuneVariant}
></ha-svg-icon>
${stateObj.attributes.preset_modes!.map(
(mode) => html`
<ha-list-item .value=${mode} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${computePresetModeIcon(mode)}
></ha-svg-icon>
${computeAttributeValueDisplay(
hass.localize,
stateObj,
hass.locale,
hass.config,
hass.entities,
"preset_mode",
mode
)}
</ha-list-item>
`
)}
</ha-control-select-menu>
`
: nothing}
${supportFanMode && stateObj.attributes.fan_modes
? html`
<ha-control-select-menu
.label=${computeAttributeNameDisplay(
hass.localize,
stateObj,
hass.entities,
"fan_mode"
)}
.value=${stateObj.attributes.fan_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleFanmodeChanged}
@closed=${stopPropagation}
>
<ha-svg-icon
slot="icon"
.path=${stateObj.attributes.fan_mode
? computeFanModeIcon(stateObj.attributes.fan_mode)
: mdiFan}
></ha-svg-icon>
${stateObj.attributes.fan_modes!.map(
(mode) => html`
<ha-list-item .value=${mode} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${computeFanModeIcon(mode)}
></ha-svg-icon>
${computeAttributeValueDisplay(
hass.localize,
stateObj,
hass.locale,
this.hass.config,
hass.entities,
"fan_mode",
mode
)}
</ha-list-item>
`
)}
</ha-control-select-menu>
`
: nothing}
${supportSwingMode && stateObj.attributes.swing_modes
? html`
<ha-control-select-menu
.label=${computeAttributeNameDisplay(
hass.localize,
stateObj,
hass.entities,
"swing_mode"
)}
.value=${stateObj.attributes.swing_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleSwingmodeChanged}
@closed=${stopPropagation}
>
<ha-svg-icon
slot="icon"
.path=${stateObj.attributes.swing_mode
? computeSwingModeIcon(stateObj.attributes.swing_mode)
: haOscillating}
></ha-svg-icon>
${stateObj.attributes.swing_modes!.map(
(mode) => html`
<ha-list-item .value=${mode} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${computeSwingModeIcon(mode)}
></ha-svg-icon>
${computeAttributeValueDisplay(
hass.localize,
stateObj,
hass.locale,
this.hass.config,
hass.entities,
"swing_mode",
mode
)}
</ha-list-item>
`
)}
</ha-control-select-menu>
`
: nothing}
</div>
</div>
<div
class=${classMap({
"has-current_temperature":
@ -187,140 +369,6 @@ class MoreInfoClimate extends LitElement {
"has-preset_mode": supportPresetMode,
})}
>
<div class="container-hvac_modes">
<ha-select
.label=${hass.localize("ui.card.climate.operation")}
.value=${stateObj.state}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleOperationmodeChanged}
@closed=${stopPropagation}
>
${stateObj.attributes.hvac_modes
.concat()
.sort(compareClimateHvacModes)
.map(
(mode) => html`
<mwc-list-item .value=${mode}>
${computeStateDisplay(
hass.localize,
stateObj,
hass.locale,
this.hass.config,
hass.entities,
mode
)}
</mwc-list-item>
`
)}
</ha-select>
</div>
${supportPresetMode && stateObj.attributes.preset_modes
? html`
<div class="container-preset_modes">
<ha-select
.label=${computeAttributeNameDisplay(
hass.localize,
stateObj,
hass.entities,
"preset_mode"
)}
.value=${stateObj.attributes.preset_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handlePresetmodeChanged}
@closed=${stopPropagation}
>
${stateObj.attributes.preset_modes!.map(
(mode) => html`
<mwc-list-item .value=${mode}>
${computeAttributeValueDisplay(
hass.localize,
stateObj,
hass.locale,
hass.config,
hass.entities,
"preset_mode",
mode
)}
</mwc-list-item>
`
)}
</ha-select>
</div>
`
: ""}
${supportFanMode && stateObj.attributes.fan_modes
? html`
<div class="container-fan_list">
<ha-select
.label=${computeAttributeNameDisplay(
hass.localize,
stateObj,
hass.entities,
"fan_mode"
)}
.value=${stateObj.attributes.fan_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleFanmodeChanged}
@closed=${stopPropagation}
>
${stateObj.attributes.fan_modes!.map(
(mode) => html`
<mwc-list-item .value=${mode}>
${computeAttributeValueDisplay(
hass.localize,
stateObj,
hass.locale,
this.hass.config,
hass.entities,
"fan_mode",
mode
)}
</mwc-list-item>
`
)}
</ha-select>
</div>
`
: ""}
${supportSwingMode && stateObj.attributes.swing_modes
? html`
<div class="container-swing_list">
<ha-select
.label=${computeAttributeNameDisplay(
hass.localize,
stateObj,
hass.entities,
"swing_mode"
)}
.value=${stateObj.attributes.swing_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleSwingmodeChanged}
@closed=${stopPropagation}
>
${stateObj.attributes.swing_modes!.map(
(mode) => html`
<mwc-list-item .value=${mode}>
${computeAttributeValueDisplay(
hass.localize,
stateObj,
hass.locale,
this.hass.config,
hass.entities,
"swing_mode",
mode
)}
</mwc-list-item>
`
)}
</ha-select>
</div>
`
: ""}
${supportAuxHeat
? html`
<div class="container-aux_heat">

View File

@ -1,4 +1,4 @@
import { mdiCircleMedium, mdiPower, mdiTuneVariant } from "@mdi/js";
import { mdiPower, mdiTuneVariant } from "@mdi/js";
import {
CSSResultGroup,
LitElement,
@ -20,9 +20,9 @@ import { formatNumber } from "../../../common/number/format_number";
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
import "../../../components/ha-control-select-menu";
import {
HUMIDIFIER_MODE_ICONS,
HumidifierEntity,
HumidifierEntityFeature,
computeHumidiferModeIcon,
} from "../../../data/humidifier";
import { HomeAssistant } from "../../../types";
import { moreInfoControlStyle } from "../components/ha-more-info-control-style";
@ -137,8 +137,7 @@ class MoreInfoHumidifier extends LitElement {
<ha-svg-icon
slot="icon"
.path=${stateObj.attributes.mode
? HUMIDIFIER_MODE_ICONS[stateObj.attributes.mode] ||
mdiCircleMedium
? computeHumidiferModeIcon(stateObj.attributes.mode)
: mdiTuneVariant}
></ha-svg-icon>
${stateObj.attributes.available_modes!.map(
@ -146,8 +145,7 @@ class MoreInfoHumidifier extends LitElement {
<ha-list-item .value=${mode} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${HUMIDIFIER_MODE_ICONS[mode] ||
mdiCircleMedium}
.path=${computeHumidiferModeIcon(mode)}
></ha-svg-icon>
${computeAttributeValueDisplay(
hass.localize,