diff --git a/src/components/ha-control-circular-slider.ts b/src/components/ha-control-circular-slider.ts index b8bbffb336..3f6344647d 100644 --- a/src/components/ha-control-circular-slider.ts +++ b/src/components/ha-control-circular-slider.ts @@ -59,6 +59,8 @@ const A11Y_KEY_CODES = new Set([ "End", ]); +export type ControlCircularSliderMode = "start" | "end" | "full"; + @customElement("ha-control-circular-slider") export class HaControlCircularSlider extends LitElement { @property({ type: Boolean, reflect: true }) @@ -67,8 +69,11 @@ export class HaControlCircularSlider extends LitElement { @property({ type: Boolean }) public dual?: boolean; - @property({ type: Boolean, reflect: true }) - public inverted?: boolean; + @property({ type: String }) + public mode?: ControlCircularSliderMode; + + @property({ type: Boolean }) + public inactive?: boolean; @property({ type: String }) public label?: string; @@ -407,12 +412,10 @@ export class HaControlCircularSlider extends LitElement { protected renderArc( id: string, value: number | undefined, - inverted: boolean | undefined + mode: ControlCircularSliderMode ) { if (this.disabled) return nothing; - const limit = inverted ? this.max : this.min; - const path = svgArc({ x: 0, y: 0, @@ -421,82 +424,100 @@ export class HaControlCircularSlider extends LitElement { r: RADIUS, }); + const limit = mode === "end" ? this.max : this.min; + const current = this.current ?? limit; const target = value ?? limit; - const showActive = inverted ? target <= current : current <= target; + const showActive = + mode === "end" + ? target <= current + : mode === "start" + ? current <= target + : false; - const activeArcDashArray = showActive - ? inverted + const activeArc = showActive + ? mode === "end" ? this._strokeDashArc(target, current) : this._strokeDashArc(current, target) : this._strokeCircleDashArc(target); - const arcDashArray = inverted - ? this._strokeDashArc(target, limit) - : this._strokeDashArc(limit, target); + const coloredArc = + mode === "full" + ? this._strokeDashArc(this.min, this.max) + : mode === "end" + ? this._strokeDashArc(target, limit) + : this._strokeDashArc(limit, target); - const targetCircleDashArray = this._strokeCircleDashArc(target); + const targetCircle = this._strokeCircleDashArc(target); - const currentCircleDashArray = + const currentCircle = this.current != null && - showActive && - current <= this.max && - current >= this.min + this.current <= this.max && + this.current >= this.min && + (showActive || this.mode === "full") ? this._strokeCircleDashArc(this.current) : undefined; return svg` - - - + + + + ${ + currentCircle + ? svg` + + ` + : nothing } - aria-disabled=${this.disabled} - aria-label=${ifDefined(this.lowLabel ?? this.label)} - @keydown=${this._handleKeyDown} - @keyup=${this._handleKeyUp} - /> - ${ - currentCircleDashArray - ? svg` - - ` - : nothing - } - + + + `; } @@ -551,11 +572,11 @@ export class HaControlCircularSlider extends LitElement { ? this.renderArc( this.dual ? "low" : "value", lowValue, - this.inverted + (!this.dual && this.mode) || "start" ) : nothing} ${this.dual && highValue != null - ? this.renderArc("high", highValue, true) + ? this.renderArc("high", highValue, "end") : nothing} @@ -634,6 +655,19 @@ export class HaControlCircularSlider extends LitElement { opacity 180ms ease-in-out; } + .target-border { + fill: none; + stroke-linecap: round; + stroke-width: 24px; + stroke: white; + transition: + stroke-width 300ms ease-in-out, + stroke-dasharray 300ms ease-in-out, + stroke-dashoffset 300ms ease-in-out, + stroke 180ms ease-in-out, + opacity 180ms ease-in-out; + } + .current { fill: none; stroke-linecap: round; @@ -655,7 +689,7 @@ export class HaControlCircularSlider extends LitElement { .arc-clear { stroke: var(--clear-background-color); } - .arc-background { + .arc-colored { opacity: 0.5; } .arc-active { @@ -667,6 +701,7 @@ export class HaControlCircularSlider extends LitElement { .pressed .arc, .pressed .target, + .pressed .target-border, .pressed .current { transition: stroke-width 300ms ease-in-out, @@ -674,6 +709,11 @@ export class HaControlCircularSlider extends LitElement { opacity 180ms ease-in-out; } + .inactive .arc, + .inactive .arc-current { + opacity: 0; + } + .value { stroke: var(--control-circular-slider-color); } diff --git a/src/dialogs/more-info/components/climate/ha-more-info-climate-humidity.ts b/src/dialogs/more-info/components/climate/ha-more-info-climate-humidity.ts index 5225d51045..57344a4219 100644 --- a/src/dialogs/more-info/components/climate/ha-more-info-climate-humidity.ts +++ b/src/dialogs/more-info/components/climate/ha-more-info-climate-humidity.ts @@ -163,6 +163,7 @@ export class HaMoreInfoClimateHumidity extends LitElement { })} > = { + auto: "full", + cool: "end", + dry: "full", + fan_only: "full", + heat: "start", + heat_cool: "full", + off: "full", +}; + @customElement("ha-more-info-climate-temperature") export class HaMoreInfoClimateTemperature extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -267,17 +279,15 @@ export class HaMoreInfoClimateTemperature extends LitElement { ); } - const hvacModes = this.stateObj.attributes.hvac_modes; + const activeModes = this.stateObj.attributes.hvac_modes.filter( + (m) => m !== "off" + ); if ( supportsTargetTemperature && this._targetTemperature.value != null && this.stateObj.state !== UNAVAILABLE ) { - const hasOnlyCoolMode = - hvacModes.length === 2 && - hvacModes.includes("cool") && - hvacModes.includes("off"); return html`