Redesign mode buttons for fan more-info (#17537)

This commit is contained in:
Paul Bottein 2023-08-10 09:59:06 +02:00 committed by GitHub
parent ebee8f670e
commit 5dee92b214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,7 +6,7 @@ import {
mdiRotateLeft, mdiRotateLeft,
mdiRotateRight, mdiRotateRight,
} from "@mdi/js"; } from "@mdi/js";
import { CSSResultGroup, html, LitElement, nothing, PropertyValues } from "lit"; import { CSSResultGroup, LitElement, PropertyValues, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { stopPropagation } from "../../../common/dom/stop_propagation"; import { stopPropagation } from "../../../common/dom/stop_propagation";
import { import {
@ -17,15 +17,16 @@ import { computeStateDisplay } from "../../../common/entity/compute_state_displa
import { stateActive } from "../../../common/entity/state_active"; import { stateActive } from "../../../common/entity/state_active";
import { supportsFeature } from "../../../common/entity/supports-feature"; import { supportsFeature } from "../../../common/entity/supports-feature";
import "../../../components/ha-attributes"; import "../../../components/ha-attributes";
import "../../../components/ha-outlined-button"; import "../../../components/ha-control-select-menu";
import "../../../components/ha-list-item";
import "../../../components/ha-outlined-icon-button"; import "../../../components/ha-outlined-icon-button";
import { UNAVAILABLE } from "../../../data/entity"; import { UNAVAILABLE } from "../../../data/entity";
import { import {
computeFanSpeedCount, FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
computeFanSpeedStateDisplay,
FanEntity, FanEntity,
FanEntityFeature, FanEntityFeature,
FAN_SPEED_COUNT_MAX_FOR_BUTTONS, computeFanSpeedCount,
computeFanSpeedStateDisplay,
} from "../../../data/fan"; } from "../../../data/fan";
import { forwardHaptic } from "../../../data/haptics"; import { forwardHaptic } from "../../../data/haptics";
import { haOscillating } from "../../../data/icons/haOscillating"; import { haOscillating } from "../../../data/icons/haOscillating";
@ -78,20 +79,8 @@ class MoreInfoFan extends LitElement {
}); });
} }
_toggleOscillate() {
const oscillating = this.stateObj!.attributes.oscillating;
this.hass.callService("fan", "oscillate", {
entity_id: this.stateObj!.entity_id,
oscillating: !oscillating,
});
}
_handlePresetMode(ev) { _handlePresetMode(ev) {
ev.stopPropagation(); const newVal = ev.target.value;
ev.preventDefault();
const index = ev.detail.index;
const newVal = this.stateObj!.attributes.preset_modes![index];
const oldVal = this._presetMode; const oldVal = this._presetMode;
if (!newVal || oldVal === newVal) return; if (!newVal || oldVal === newVal) return;
@ -103,6 +92,15 @@ class MoreInfoFan extends LitElement {
}); });
} }
_handleOscillating(ev) {
const newVal = ev.target.value === "yes";
this.hass.callService("fan", "oscillate", {
entity_id: this.stateObj!.entity_id,
oscillating: newVal,
});
}
protected updated(changedProps: PropertyValues): void { protected updated(changedProps: PropertyValues): void {
if (changedProps.has("stateObj")) { if (changedProps.has("stateObj")) {
this._presetMode = this.stateObj?.attributes.preset_mode; this._presetMode = this.stateObj?.attributes.preset_mode;
@ -170,162 +168,147 @@ class MoreInfoFan extends LitElement {
.stateOverride=${this._stateOverride} .stateOverride=${this._stateOverride}
></ha-more-info-state-header> ></ha-more-info-state-header>
<div class="controls"> <div class="controls">
${ ${supportsSpeed
supportsSpeed ? html`
? html` <ha-more-info-fan-speed
<ha-more-info-fan-speed .stateObj=${this.stateObj}
.stateObj=${this.stateObj} .hass=${this.hass}
.hass=${this.hass} @slider-moved=${this._speedSliderMoved}
@slider-moved=${this._speedSliderMoved} @value-changed=${this._speedValueChanged}
@value-changed=${this._speedValueChanged} >
> </ha-more-info-fan-speed>
</ha-more-info-fan-speed> `
` : html`
: html` <ha-more-info-toggle
<ha-more-info-toggle .stateObj=${this.stateObj}
.stateObj=${this.stateObj} .hass=${this.hass}
.hass=${this.hass} .iconPathOn=${mdiFan}
.iconPathOn=${mdiFan} .iconPathOff=${mdiFanOff}
.iconPathOff=${mdiFanOff} ></ha-more-info-toggle>
></ha-more-info-toggle> `}
` ${supportSpeedPercentage || supportsDirection
} ? html`<div class="buttons">
${ ${supportSpeedPercentage
supportSpeedPercentage || supportsDirection || supportsOscillate ? html`
? html`<div class="buttons"> <ha-outlined-icon-button
${supportSpeedPercentage
? html`
<ha-outlined-icon-button
.disabled=${this.stateObj.state === UNAVAILABLE}
@click=${this._toggle}
>
<ha-svg-icon .path=${mdiPower}></ha-svg-icon>
</ha-outlined-icon-button>
`
: nothing}
${supportsDirection
? html`
<ha-outlined-icon-button
.disabled=${this.stateObj.state === UNAVAILABLE ||
this.stateObj.attributes.direction === "reverse"}
.title=${this.hass.localize(
"ui.dialogs.more_info_control.fan.set_reverse_direction"
)}
.ariaLabel=${this.hass.localize(
"ui.dialogs.more_info_control.fan.set_reverse_direction"
)}
@click=${this._setReverseDirection}
>
<ha-svg-icon .path=${mdiRotateLeft}></ha-svg-icon>
</ha-outlined-icon-button>
<ha-outlined-icon-button
.disabled=${this.stateObj.state === UNAVAILABLE ||
this.stateObj.attributes.direction === "forward"}
.title=${this.hass.localize(
"ui.dialogs.more_info_control.fan.set_forward_direction"
)}
.ariaLabel=${this.hass.localize(
"ui.dialogs.more_info_control.fan.set_forward_direction"
)}
@click=${this._setForwardDirection}
>
<ha-svg-icon .path=${mdiRotateRight}></ha-svg-icon>
</ha-outlined-icon-button>
`
: nothing}
${supportsOscillate
? html`
<ha-outlined-icon-button
.disabled=${this.stateObj.state === UNAVAILABLE}
.title=${this.hass.localize(
`ui.dialogs.more_info_control.fan.${
this.stateObj.attributes.oscillating
? "turn_off_oscillating"
: "turn_on_oscillating"
}`
)}
.ariaLabel=${this.hass.localize(
`ui.dialogs.more_info_control.fan.${
this.stateObj.attributes.oscillating
? "turn_off_oscillating"
: "turn_on_oscillating"
}`
)}
@click=${this._toggleOscillate}
>
<ha-svg-icon
.path=${this.stateObj.attributes.oscillating
? haOscillating
: haOscillatingOff}
></ha-svg-icon>
</ha-outlined-icon-button>
`
: nothing}
</div> `
: nothing
}
${
supportsPresetMode && this.stateObj.attributes.preset_modes
? html`
<ha-button-menu
@action=${this._handlePresetMode}
@closed=${stopPropagation}
fixed
.disabled=${this.stateObj.state === UNAVAILABLE}
>
<ha-outlined-button
slot="trigger"
.disabled=${this.stateObj.state === UNAVAILABLE} .disabled=${this.stateObj.state === UNAVAILABLE}
@click=${this._toggle}
> >
${this._presetMode <ha-svg-icon .path=${mdiPower}></ha-svg-icon>
? computeAttributeValueDisplay( </ha-outlined-icon-button>
this.hass.localize, `
this.stateObj!, : nothing}
this.hass.locale, ${supportsDirection
this.hass.config, ? html`
this.hass.entities, <ha-outlined-icon-button
"preset_mode", .disabled=${this.stateObj.state === UNAVAILABLE ||
this._presetMode this.stateObj.attributes.direction === "reverse"}
) .title=${this.hass.localize(
: computeAttributeNameDisplay( "ui.dialogs.more_info_control.fan.set_reverse_direction"
this.hass.localize, )}
this.stateObj, .ariaLabel=${this.hass.localize(
this.hass.entities, "ui.dialogs.more_info_control.fan.set_reverse_direction"
"preset_mode" )}
)} @click=${this._setReverseDirection}
<ha-svg-icon >
slot="icon" <ha-svg-icon .path=${mdiRotateLeft}></ha-svg-icon>
path=${mdiCreation} </ha-outlined-icon-button>
></ha-svg-icon> <ha-outlined-icon-button
</ha-outlined-button> .disabled=${this.stateObj.state === UNAVAILABLE ||
${this.stateObj.attributes.preset_modes?.map( this.stateObj.attributes.direction === "forward"}
(mode) => html` .title=${this.hass.localize(
<ha-list-item "ui.dialogs.more_info_control.fan.set_forward_direction"
.value=${mode} )}
.activated=${this._presetMode === mode} .ariaLabel=${this.hass.localize(
> "ui.dialogs.more_info_control.fan.set_forward_direction"
${computeAttributeValueDisplay( )}
this.hass.localize, @click=${this._setForwardDirection}
this.stateObj!, >
this.hass.locale, <ha-svg-icon .path=${mdiRotateRight}></ha-svg-icon>
this.hass.config, </ha-outlined-icon-button>
this.hass.entities, `
"preset_mode", : nothing}
mode </div> `
)} : nothing}
</ha-list-item> </div>
` <div class="secondary-controls">
)} <div class="secondary-controls-scroll">
</ha-button-menu> ${supportsPresetMode && this.stateObj.attributes.preset_modes
` ? html`
: nothing <ha-control-select-menu
} .label=${computeAttributeNameDisplay(
this.hass.localize,
this.stateObj,
this.hass.entities,
"preset_mode"
)}
.value=${this.stateObj.attributes.preset_mode}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handlePresetMode}
@closed=${stopPropagation}
>
<ha-svg-icon slot="icon" .path=${mdiCreation}></ha-svg-icon>
${this.stateObj.attributes.preset_modes?.map(
(mode) => html`
<ha-list-item
.value=${mode}
.activated=${this._presetMode === mode}
>
${computeAttributeValueDisplay(
this.hass.localize,
this.stateObj!,
this.hass.locale,
this.hass.config,
this.hass.entities,
"preset_mode",
mode
)}
</ha-list-item>
`
)}
</ha-control-select-menu>
`
: nothing}
${supportsOscillate
? html`
<ha-control-select-menu
.label=${computeAttributeNameDisplay(
this.hass.localize,
this.stateObj,
this.hass.entities,
"oscillating"
)}
.value=${this.stateObj.attributes.oscillating ? "yes" : "no"}
fixedMenuPosition
naturalMenuWidth
@selected=${this._handleOscillating}
@closed=${stopPropagation}
>
<ha-svg-icon
slot="icon"
.path=${this.stateObj.attributes.oscillating
? haOscillating
: haOscillatingOff}
></ha-svg-icon>
<ha-list-item .value=${"yes"} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${haOscillating}
></ha-svg-icon>
${this.hass.localize("ui.common.yes")}
</ha-list-item>
<ha-list-item .value=${"no"} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${haOscillatingOff}
></ha-svg-icon>
${this.hass.localize("ui.common.no")}
</ha-list-item>
</ha-control-select-menu>
`
: nothing}
</div> </div>
<ha-attributes
.hass=${this.hass}
.stateObj=${this.stateObj}
extra-filters="percentage_step,speed,preset_mode,preset_modes,speed_list,percentage,oscillating,direction"
></ha-attributes>
</div> </div>
`; `;
} }