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,
mdiRotateRight,
} 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 { stopPropagation } from "../../../common/dom/stop_propagation";
import {
@ -17,15 +17,16 @@ import { computeStateDisplay } from "../../../common/entity/compute_state_displa
import { stateActive } from "../../../common/entity/state_active";
import { supportsFeature } from "../../../common/entity/supports-feature";
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 { UNAVAILABLE } from "../../../data/entity";
import {
computeFanSpeedCount,
computeFanSpeedStateDisplay,
FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
FanEntity,
FanEntityFeature,
FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
computeFanSpeedCount,
computeFanSpeedStateDisplay,
} from "../../../data/fan";
import { forwardHaptic } from "../../../data/haptics";
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) {
ev.stopPropagation();
ev.preventDefault();
const index = ev.detail.index;
const newVal = this.stateObj!.attributes.preset_modes![index];
const newVal = ev.target.value;
const oldVal = this._presetMode;
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 {
if (changedProps.has("stateObj")) {
this._presetMode = this.stateObj?.attributes.preset_mode;
@ -170,162 +168,147 @@ class MoreInfoFan extends LitElement {
.stateOverride=${this._stateOverride}
></ha-more-info-state-header>
<div class="controls">
${
supportsSpeed
? html`
<ha-more-info-fan-speed
.stateObj=${this.stateObj}
.hass=${this.hass}
@slider-moved=${this._speedSliderMoved}
@value-changed=${this._speedValueChanged}
>
</ha-more-info-fan-speed>
`
: html`
<ha-more-info-toggle
.stateObj=${this.stateObj}
.hass=${this.hass}
.iconPathOn=${mdiFan}
.iconPathOff=${mdiFanOff}
></ha-more-info-toggle>
`
}
${
supportSpeedPercentage || supportsDirection || supportsOscillate
? html`<div class="buttons">
${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"
${supportsSpeed
? html`
<ha-more-info-fan-speed
.stateObj=${this.stateObj}
.hass=${this.hass}
@slider-moved=${this._speedSliderMoved}
@value-changed=${this._speedValueChanged}
>
</ha-more-info-fan-speed>
`
: html`
<ha-more-info-toggle
.stateObj=${this.stateObj}
.hass=${this.hass}
.iconPathOn=${mdiFan}
.iconPathOff=${mdiFanOff}
></ha-more-info-toggle>
`}
${supportSpeedPercentage || supportsDirection
? html`<div class="buttons">
${supportSpeedPercentage
? html`
<ha-outlined-icon-button
.disabled=${this.stateObj.state === UNAVAILABLE}
@click=${this._toggle}
>
${this._presetMode
? computeAttributeValueDisplay(
this.hass.localize,
this.stateObj!,
this.hass.locale,
this.hass.config,
this.hass.entities,
"preset_mode",
this._presetMode
)
: computeAttributeNameDisplay(
this.hass.localize,
this.stateObj,
this.hass.entities,
"preset_mode"
)}
<ha-svg-icon
slot="icon"
path=${mdiCreation}
></ha-svg-icon>
</ha-outlined-button>
${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-button-menu>
`
: nothing
}
<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}
</div> `
: nothing}
</div>
<div class="secondary-controls">
<div class="secondary-controls-scroll">
${supportsPresetMode && this.stateObj.attributes.preset_modes
? html`
<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>
<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>
`;
}