mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add tooltip to tile sliders and more info sliders (#18567)
This commit is contained in:
parent
f2505c0798
commit
bc21425981
@ -9,6 +9,7 @@ const sliders: {
|
|||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string;
|
||||||
mode?: "start" | "end" | "cursor";
|
mode?: "start" | "end" | "cursor";
|
||||||
|
unit?: string;
|
||||||
class?: string;
|
class?: string;
|
||||||
}[] = [
|
}[] = [
|
||||||
{
|
{
|
||||||
@ -31,18 +32,21 @@ const sliders: {
|
|||||||
label: "Slider (start mode) and custom style",
|
label: "Slider (start mode) and custom style",
|
||||||
mode: "start",
|
mode: "start",
|
||||||
class: "custom",
|
class: "custom",
|
||||||
|
unit: "mm",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "slider-end-custom",
|
id: "slider-end-custom",
|
||||||
label: "Slider (end mode) and custom style",
|
label: "Slider (end mode) and custom style",
|
||||||
mode: "end",
|
mode: "end",
|
||||||
class: "custom",
|
class: "custom",
|
||||||
|
unit: "mm",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "slider-cursor-custom",
|
id: "slider-cursor-custom",
|
||||||
label: "Slider (cursor mode) and custom style",
|
label: "Slider (cursor mode) and custom style",
|
||||||
mode: "cursor",
|
mode: "cursor",
|
||||||
class: "custom",
|
class: "custom",
|
||||||
|
unit: "mm",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -93,6 +97,7 @@ export class DemoHaBarSlider extends LitElement {
|
|||||||
@value-changed=${this.handleValueChanged}
|
@value-changed=${this.handleValueChanged}
|
||||||
@slider-moved=${this.handleSliderMoved}
|
@slider-moved=${this.handleSliderMoved}
|
||||||
aria-labelledby=${id}
|
aria-labelledby=${id}
|
||||||
|
.tooltipUnit=${config.unit}
|
||||||
>
|
>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
</div>
|
</div>
|
||||||
@ -114,6 +119,7 @@ export class DemoHaBarSlider extends LitElement {
|
|||||||
@value-changed=${this.handleValueChanged}
|
@value-changed=${this.handleValueChanged}
|
||||||
@slider-moved=${this.handleSliderMoved}
|
@slider-moved=${this.handleSliderMoved}
|
||||||
aria-label=${label}
|
aria-label=${label}
|
||||||
|
.tooltipUnit=${config.unit}
|
||||||
>
|
>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
`;
|
`;
|
||||||
|
15
src/common/translations/blank_before_unit.ts
Normal file
15
src/common/translations/blank_before_unit.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
|
import { blankBeforePercent } from "./blank_before_percent";
|
||||||
|
|
||||||
|
export const blankBeforeUnit = (
|
||||||
|
unit: string,
|
||||||
|
localeOptions?: FrontendLocaleData
|
||||||
|
): string => {
|
||||||
|
if (unit === "°") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (localeOptions && unit === "%") {
|
||||||
|
return blankBeforePercent(localeOptions);
|
||||||
|
}
|
||||||
|
return " ";
|
||||||
|
};
|
@ -4,13 +4,17 @@ import {
|
|||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
|
nothing,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, query } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
|
import { FrontendLocaleData } from "../data/translation";
|
||||||
|
import { formatNumber } from "../common/number/format_number";
|
||||||
|
import { blankBeforeUnit } from "../common/translations/blank_before_unit";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
@ -29,13 +33,21 @@ const A11Y_KEY_CODES = new Set([
|
|||||||
"End",
|
"End",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
type TooltipPosition = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
type TooltipMode = "never" | "always" | "interaction";
|
||||||
|
|
||||||
|
type SliderMode = "start" | "end" | "cursor";
|
||||||
|
|
||||||
@customElement("ha-control-slider")
|
@customElement("ha-control-slider")
|
||||||
export class HaControlSlider extends LitElement {
|
export class HaControlSlider extends LitElement {
|
||||||
|
@property({ attribute: false }) public locale?: FrontendLocaleData;
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true })
|
@property({ type: Boolean, reflect: true })
|
||||||
public disabled = false;
|
public disabled = false;
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
public mode?: "start" | "end" | "cursor" = "start";
|
public mode?: SliderMode = "start";
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true })
|
@property({ type: Boolean, reflect: true })
|
||||||
public vertical = false;
|
public vertical = false;
|
||||||
@ -46,6 +58,15 @@ export class HaControlSlider extends LitElement {
|
|||||||
@property({ type: Boolean, attribute: "inverted" })
|
@property({ type: Boolean, attribute: "inverted" })
|
||||||
public inverted = false;
|
public inverted = false;
|
||||||
|
|
||||||
|
@property({ attribute: "tooltip-position" })
|
||||||
|
public tooltipPosition?: TooltipPosition;
|
||||||
|
|
||||||
|
@property({ attribute: "tooltip-unit" })
|
||||||
|
public tooltipUnit?: string;
|
||||||
|
|
||||||
|
@property({ attribute: "tooltip-mode" })
|
||||||
|
public tooltipMode: TooltipMode = "interaction";
|
||||||
|
|
||||||
@property({ type: Number })
|
@property({ type: Number })
|
||||||
public value?: number;
|
public value?: number;
|
||||||
|
|
||||||
@ -58,11 +79,14 @@ export class HaControlSlider extends LitElement {
|
|||||||
@property({ type: Number })
|
@property({ type: Number })
|
||||||
public max = 100;
|
public max = 100;
|
||||||
|
|
||||||
private _mc?: HammerManager;
|
@state()
|
||||||
|
|
||||||
@property({ type: Boolean, reflect: true })
|
|
||||||
public pressed = false;
|
public pressed = false;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
public tooltipVisible = false;
|
||||||
|
|
||||||
|
private _mc?: HammerManager;
|
||||||
|
|
||||||
valueToPercentage(value: number) {
|
valueToPercentage(value: number) {
|
||||||
const percentage =
|
const percentage =
|
||||||
(this.boundedValue(value) - this.min) / (this.max - this.min);
|
(this.boundedValue(value) - this.min) / (this.max - this.min);
|
||||||
@ -98,6 +122,7 @@ export class HaControlSlider extends LitElement {
|
|||||||
if (changedProps.has("value")) {
|
if (changedProps.has("value")) {
|
||||||
const valuenow = this.steppedValue(this.value ?? 0);
|
const valuenow = this.steppedValue(this.value ?? 0);
|
||||||
this.setAttribute("aria-valuenow", valuenow.toString());
|
this.setAttribute("aria-valuenow", valuenow.toString());
|
||||||
|
this.setAttribute("aria-valuetext", this._formatValue(valuenow));
|
||||||
}
|
}
|
||||||
if (changedProps.has("min")) {
|
if (changedProps.has("min")) {
|
||||||
this.setAttribute("aria-valuemin", this.min.toString());
|
this.setAttribute("aria-valuemin", this.min.toString());
|
||||||
@ -143,11 +168,13 @@ export class HaControlSlider extends LitElement {
|
|||||||
this._mc.on("panstart", () => {
|
this._mc.on("panstart", () => {
|
||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
this.pressed = true;
|
this.pressed = true;
|
||||||
|
this._showTooltip();
|
||||||
savedValue = this.value;
|
savedValue = this.value;
|
||||||
});
|
});
|
||||||
this._mc.on("pancancel", () => {
|
this._mc.on("pancancel", () => {
|
||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
this.pressed = false;
|
this.pressed = false;
|
||||||
|
this._hideTooltip();
|
||||||
this.value = savedValue;
|
this.value = savedValue;
|
||||||
});
|
});
|
||||||
this._mc.on("panmove", (e) => {
|
this._mc.on("panmove", (e) => {
|
||||||
@ -160,6 +187,7 @@ export class HaControlSlider extends LitElement {
|
|||||||
this._mc.on("panend", (e) => {
|
this._mc.on("panend", (e) => {
|
||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
this.pressed = false;
|
this.pressed = false;
|
||||||
|
this._hideTooltip();
|
||||||
const percentage = this._getPercentageFromEvent(e);
|
const percentage = this._getPercentageFromEvent(e);
|
||||||
this.value = this.steppedValue(this.percentageToValue(percentage));
|
this.value = this.steppedValue(this.percentageToValue(percentage));
|
||||||
fireEvent(this, "slider-moved", { value: undefined });
|
fireEvent(this, "slider-moved", { value: undefined });
|
||||||
@ -191,6 +219,21 @@ export class HaControlSlider extends LitElement {
|
|||||||
return Math.max(this.step, (this.max - this.min) / 10);
|
return Math.max(this.step, (this.max - this.min) / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_showTooltip() {
|
||||||
|
if (this._tooltipTimeout != null) window.clearTimeout(this._tooltipTimeout);
|
||||||
|
this.tooltipVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hideTooltip(delay?: number) {
|
||||||
|
if (!delay) {
|
||||||
|
this.tooltipVisible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._tooltipTimeout = window.setTimeout(() => {
|
||||||
|
this.tooltipVisible = false;
|
||||||
|
}, delay);
|
||||||
|
}
|
||||||
|
|
||||||
_handleKeyDown(e: KeyboardEvent) {
|
_handleKeyDown(e: KeyboardEvent) {
|
||||||
if (!A11Y_KEY_CODES.has(e.code)) return;
|
if (!A11Y_KEY_CODES.has(e.code)) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -220,12 +263,16 @@ export class HaControlSlider extends LitElement {
|
|||||||
this.value = this.max;
|
this.value = this.max;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
this._showTooltip();
|
||||||
fireEvent(this, "slider-moved", { value: this.value });
|
fireEvent(this, "slider-moved", { value: this.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _tooltipTimeout?: number;
|
||||||
|
|
||||||
_handleKeyUp(e: KeyboardEvent) {
|
_handleKeyUp(e: KeyboardEvent) {
|
||||||
if (!A11Y_KEY_CODES.has(e.code)) return;
|
if (!A11Y_KEY_CODES.has(e.code)) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this._hideTooltip(500);
|
||||||
fireEvent(this, "value-changed", { value: this.value });
|
fireEvent(this, "value-changed", { value: this.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,36 +289,76 @@ export class HaControlSlider extends LitElement {
|
|||||||
return Math.max(Math.min(1, (x - offset) / total), 0);
|
return Math.max(Math.min(1, (x - offset) / total), 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private _formatValue(value: number) {
|
||||||
|
const formattedValue = formatNumber(value, this.locale);
|
||||||
|
|
||||||
|
const formattedUnit = this.tooltipUnit
|
||||||
|
? `${blankBeforeUnit(this.tooltipUnit, this.locale)}${this.tooltipUnit}`
|
||||||
|
: "";
|
||||||
|
|
||||||
|
return `${formattedValue}${formattedUnit}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderTooltip() {
|
||||||
|
if (this.tooltipMode === "never") return nothing;
|
||||||
|
|
||||||
|
const position = this.tooltipPosition ?? (this.vertical ? "left" : "top");
|
||||||
|
|
||||||
|
const visible =
|
||||||
|
this.tooltipMode === "always" ||
|
||||||
|
(this.tooltipVisible && this.tooltipMode === "interaction");
|
||||||
|
|
||||||
|
const value = this.steppedValue(this.value ?? 0);
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="tooltip ${classMap({
|
||||||
|
visible,
|
||||||
|
[position]: true,
|
||||||
|
[this.mode ?? "start"]: true,
|
||||||
|
"show-handle": this.showHandle,
|
||||||
|
})}"
|
||||||
|
>
|
||||||
|
${this._formatValue(value)}
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
id="slider"
|
class="container${classMap({
|
||||||
class="slider"
|
pressed: this.pressed,
|
||||||
|
})}"
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
"--value": `${this.valueToPercentage(this.value ?? 0)}`,
|
"--value": `${this.valueToPercentage(this.value ?? 0)}`,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div class="slider-track-background"></div>
|
<div id="slider" class="slider">
|
||||||
<slot name="background"></slot>
|
<div class="slider-track-background"></div>
|
||||||
${this.mode === "cursor"
|
<slot name="background"></slot>
|
||||||
? this.value != null
|
${this.mode === "cursor"
|
||||||
? html`
|
? this.value != null
|
||||||
|
? html`
|
||||||
|
<div
|
||||||
|
class=${classMap({
|
||||||
|
"slider-track-cursor": true,
|
||||||
|
})}
|
||||||
|
></div>
|
||||||
|
`
|
||||||
|
: null
|
||||||
|
: html`
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
"slider-track-cursor": true,
|
"slider-track-bar": true,
|
||||||
|
[this.mode ?? "start"]: true,
|
||||||
|
"show-handle": this.showHandle,
|
||||||
})}
|
})}
|
||||||
></div>
|
></div>
|
||||||
`
|
`}
|
||||||
: null
|
</div>
|
||||||
: html`
|
${this._renderTooltip()}
|
||||||
<div
|
|
||||||
class=${classMap({
|
|
||||||
"slider-track-bar": true,
|
|
||||||
[this.mode ?? "start"]: true,
|
|
||||||
"show-handle": this.showHandle,
|
|
||||||
})}
|
|
||||||
></div>
|
|
||||||
`}
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -285,6 +372,7 @@ export class HaControlSlider extends LitElement {
|
|||||||
--control-slider-background-opacity: 0.2;
|
--control-slider-background-opacity: 0.2;
|
||||||
--control-slider-thickness: 40px;
|
--control-slider-thickness: 40px;
|
||||||
--control-slider-border-radius: 10px;
|
--control-slider-border-radius: 10px;
|
||||||
|
--control-slider-tooltip-font-size: 14px;
|
||||||
height: var(--control-slider-thickness);
|
height: var(--control-slider-thickness);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: var(--control-slider-border-radius);
|
border-radius: var(--control-slider-border-radius);
|
||||||
@ -298,6 +386,88 @@ export class HaControlSlider extends LitElement {
|
|||||||
width: var(--control-slider-thickness);
|
width: var(--control-slider-thickness);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
--handle-size: 4px;
|
||||||
|
--handle-margin: calc(var(--control-slider-thickness) / 8);
|
||||||
|
}
|
||||||
|
.tooltip {
|
||||||
|
user-select: none;
|
||||||
|
position: absolute;
|
||||||
|
background-color: var(--clear-background-color);
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
font-size: var(--control-slider-tooltip-font-size);
|
||||||
|
border-radius: 0.8em;
|
||||||
|
padding: 0.2em 0.4em;
|
||||||
|
opacity: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
transition:
|
||||||
|
opacity 180ms ease-in-out,
|
||||||
|
left 180ms ease-in-out,
|
||||||
|
bottom 180ms ease-in-out;
|
||||||
|
--handle-spacing: calc(2 * var(--handle-margin) + var(--handle-size));
|
||||||
|
--slider-tooltip-margin: -4px;
|
||||||
|
--slider-tooltip-range: 100%;
|
||||||
|
--slider-tooltip-offset: 0px;
|
||||||
|
--slider-tooltip-position: calc(
|
||||||
|
min(
|
||||||
|
max(
|
||||||
|
var(--value) * var(--slider-tooltip-range) +
|
||||||
|
var(--slider-tooltip-offset),
|
||||||
|
0%
|
||||||
|
),
|
||||||
|
100%
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.tooltip.start {
|
||||||
|
--slider-tooltip-offset: calc(-0.5 * (var(--handle-spacing)));
|
||||||
|
}
|
||||||
|
.tooltip.end {
|
||||||
|
--slider-tooltip-offset: calc(0.5 * (var(--handle-spacing)));
|
||||||
|
}
|
||||||
|
.tooltip.cursor {
|
||||||
|
--slider-tooltip-range: calc(100% - var(--handle-spacing));
|
||||||
|
--slider-tooltip-offset: calc(0.5 * (var(--handle-spacing)));
|
||||||
|
}
|
||||||
|
.tooltip.show-handle {
|
||||||
|
--slider-tooltip-range: calc(100% - var(--handle-spacing));
|
||||||
|
--slider-tooltip-offset: calc(0.5 * (var(--handle-spacing)));
|
||||||
|
}
|
||||||
|
.tooltip.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.tooltip.top {
|
||||||
|
transform: translate3d(-50%, -100%, 0);
|
||||||
|
top: var(--slider-tooltip-margin);
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
.tooltip.bottom {
|
||||||
|
transform: translate3d(-50%, 100%, 0);
|
||||||
|
bottom: var(--slider-tooltip-margin);
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
.tooltip.left {
|
||||||
|
transform: translate3d(-100%, 50%, 0);
|
||||||
|
bottom: 50%;
|
||||||
|
left: var(--slider-tooltip-margin);
|
||||||
|
}
|
||||||
|
.tooltip.right {
|
||||||
|
transform: translate3d(100%, 50%, 0);
|
||||||
|
bottom: 50%;
|
||||||
|
right: var(--slider-tooltip-margin);
|
||||||
|
}
|
||||||
|
:host(:not([vertical])) .tooltip.top,
|
||||||
|
:host(:not([vertical])) .tooltip.bottom {
|
||||||
|
left: var(--slider-tooltip-position);
|
||||||
|
}
|
||||||
|
:host([vertical]) .tooltip.right,
|
||||||
|
:host([vertical]) .tooltip.left {
|
||||||
|
bottom: var(--slider-tooltip-position);
|
||||||
|
}
|
||||||
.slider {
|
.slider {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -328,8 +498,6 @@ export class HaControlSlider extends LitElement {
|
|||||||
}
|
}
|
||||||
.slider .slider-track-bar {
|
.slider .slider-track-bar {
|
||||||
--border-radius: var(--control-slider-border-radius);
|
--border-radius: var(--control-slider-border-radius);
|
||||||
--handle-size: 4px;
|
|
||||||
--handle-margin: calc(var(--control-slider-thickness) / 8);
|
|
||||||
--slider-size: 100%;
|
--slider-size: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -432,7 +600,6 @@ export class HaControlSlider extends LitElement {
|
|||||||
|
|
||||||
.slider .slider-track-cursor {
|
.slider .slider-track-cursor {
|
||||||
--cursor-size: calc(var(--control-slider-thickness) / 4);
|
--cursor-size: calc(var(--control-slider-thickness) / 4);
|
||||||
--handle-size: 4px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-radius: var(--handle-size);
|
border-radius: var(--handle-size);
|
||||||
@ -462,9 +629,11 @@ export class HaControlSlider extends LitElement {
|
|||||||
height: var(--handle-size);
|
height: var(--handle-size);
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
.pressed .tooltip {
|
||||||
:host([pressed]) .slider-track-bar,
|
transition: opacity 180ms ease-in-out;
|
||||||
:host([pressed]) .slider-track-cursor {
|
}
|
||||||
|
.pressed .slider-track-bar,
|
||||||
|
.pressed .slider-track-cursor {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
:host(:disabled) .slider {
|
:host(:disabled) .slider {
|
||||||
|
@ -34,7 +34,7 @@ export const TEMPERATURE_ATTRIBUTES = new Set([
|
|||||||
"max_temp",
|
"max_temp",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const DOMAIN_ATTRIBUTES_UNITS: Record<string, Record<string, string>> = {
|
export const DOMAIN_ATTRIBUTES_UNITS = {
|
||||||
climate: {
|
climate: {
|
||||||
humidity: "%",
|
humidity: "%",
|
||||||
current_humidity: "%",
|
current_humidity: "%",
|
||||||
@ -74,4 +74,4 @@ export const DOMAIN_ATTRIBUTES_UNITS: Record<string, Record<string, string>> = {
|
|||||||
sensor: {
|
sensor: {
|
||||||
battery_level: "%",
|
battery_level: "%",
|
||||||
},
|
},
|
||||||
};
|
} as const satisfies Record<string, Record<string, string>>;
|
||||||
|
@ -6,6 +6,7 @@ import { stateColorCss } from "../../../../common/entity/state_color";
|
|||||||
import "../../../../components/ha-control-slider";
|
import "../../../../components/ha-control-slider";
|
||||||
import { CoverEntity } from "../../../../data/cover";
|
import { CoverEntity } from "../../../../data/cover";
|
||||||
import { UNAVAILABLE } from "../../../../data/entity";
|
import { UNAVAILABLE } from "../../../../data/entity";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
@customElement("ha-more-info-cover-position")
|
@customElement("ha-more-info-cover-position")
|
||||||
@ -60,6 +61,8 @@ export class HaMoreInfoCoverPosition extends LitElement {
|
|||||||
"--control-slider-background": color,
|
"--control-slider-background": color,
|
||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_position}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
>
|
>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
`;
|
`;
|
||||||
@ -76,6 +79,7 @@ export class HaMoreInfoCoverPosition extends LitElement {
|
|||||||
--control-slider-color: var(--primary-color);
|
--control-slider-color: var(--primary-color);
|
||||||
--control-slider-background: var(--disabled-color);
|
--control-slider-background: var(--disabled-color);
|
||||||
--control-slider-background-opacity: 0.2;
|
--control-slider-background-opacity: 0.2;
|
||||||
|
--control-slider-tooltip-font-size: 20px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import { stateColorCss } from "../../../../common/entity/state_color";
|
|||||||
import "../../../../components/ha-control-slider";
|
import "../../../../components/ha-control-slider";
|
||||||
import { CoverEntity } from "../../../../data/cover";
|
import { CoverEntity } from "../../../../data/cover";
|
||||||
import { UNAVAILABLE } from "../../../../data/entity";
|
import { UNAVAILABLE } from "../../../../data/entity";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
export function generateTiltSliderTrackBackgroundGradient() {
|
export function generateTiltSliderTrackBackgroundGradient() {
|
||||||
@ -96,6 +97,8 @@ export class HaMoreInfoCoverTiltPosition extends LitElement {
|
|||||||
"--control-slider-background": color,
|
"--control-slider-background": color,
|
||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_tilt_position}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
>
|
>
|
||||||
<div slot="background" class="gradient"></div>
|
<div slot="background" class="gradient"></div>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
@ -113,6 +116,7 @@ export class HaMoreInfoCoverTiltPosition extends LitElement {
|
|||||||
--control-slider-color: var(--primary-color);
|
--control-slider-color: var(--primary-color);
|
||||||
--control-slider-background: var(--disabled-color);
|
--control-slider-background: var(--disabled-color);
|
||||||
--control-slider-background-opacity: 0.2;
|
--control-slider-background-opacity: 0.2;
|
||||||
|
--control-slider-tooltip-font-size: 20px;
|
||||||
}
|
}
|
||||||
.gradient {
|
.gradient {
|
||||||
background: -webkit-linear-gradient(top, ${GRADIENT});
|
background: -webkit-linear-gradient(top, ${GRADIENT});
|
||||||
|
@ -8,6 +8,7 @@ import "../../../../components/ha-control-select";
|
|||||||
import type { ControlSelectOption } from "../../../../components/ha-control-select";
|
import type { ControlSelectOption } from "../../../../components/ha-control-select";
|
||||||
import "../../../../components/ha-control-slider";
|
import "../../../../components/ha-control-slider";
|
||||||
import { UNAVAILABLE } from "../../../../data/entity";
|
import { UNAVAILABLE } from "../../../../data/entity";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes";
|
||||||
import {
|
import {
|
||||||
computeFanSpeedCount,
|
computeFanSpeedCount,
|
||||||
computeFanSpeedIcon,
|
computeFanSpeedIcon,
|
||||||
@ -130,6 +131,8 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
|||||||
"--control-slider-background": color,
|
"--control-slider-background": color,
|
||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.fan.percentage}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
>
|
>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
`;
|
`;
|
||||||
@ -146,6 +149,7 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
|||||||
--control-slider-color: var(--primary-color);
|
--control-slider-color: var(--primary-color);
|
||||||
--control-slider-background: var(--disabled-color);
|
--control-slider-background: var(--disabled-color);
|
||||||
--control-slider-background-opacity: 0.2;
|
--control-slider-background-opacity: 0.2;
|
||||||
|
--control-slider-tooltip-font-size: 20px;
|
||||||
}
|
}
|
||||||
ha-control-select {
|
ha-control-select {
|
||||||
height: 45vh;
|
height: 45vh;
|
||||||
|
@ -77,6 +77,8 @@ export class HaMoreInfoLightBrightness extends LitElement {
|
|||||||
"--control-slider-background": color,
|
"--control-slider-background": color,
|
||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${"%"}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
>
|
>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
`;
|
`;
|
||||||
@ -93,6 +95,7 @@ export class HaMoreInfoLightBrightness extends LitElement {
|
|||||||
--control-slider-color: var(--primary-color);
|
--control-slider-color: var(--primary-color);
|
||||||
--control-slider-background: var(--disabled-color);
|
--control-slider-background: var(--disabled-color);
|
||||||
--control-slider-background-opacity: 0.2;
|
--control-slider-background-opacity: 0.2;
|
||||||
|
--control-slider-tooltip-font-size: 20px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
LightEntity,
|
LightEntity,
|
||||||
} from "../../../../data/light";
|
} from "../../../../data/light";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
@ -93,6 +94,8 @@ class LightColorTempPicker extends LitElement {
|
|||||||
"--gradient": gradient,
|
"--gradient": gradient,
|
||||||
})}
|
})}
|
||||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.light.color_temp_kelvin}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
>
|
>
|
||||||
</ha-control-slider>
|
</ha-control-slider>
|
||||||
`;
|
`;
|
||||||
@ -193,6 +196,7 @@ class LightColorTempPicker extends LitElement {
|
|||||||
top,
|
top,
|
||||||
var(--gradient)
|
var(--gradient)
|
||||||
);
|
);
|
||||||
|
--control-slider-tooltip-font-size: 20px;
|
||||||
--control-slider-background-opacity: 1;
|
--control-slider-background-opacity: 1;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
@ -33,36 +33,12 @@ class MoreInfoCover extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public stateObj?: CoverEntity;
|
@property({ attribute: false }) public stateObj?: CoverEntity;
|
||||||
|
|
||||||
@state() private _livePosition?: number;
|
|
||||||
|
|
||||||
@state() private _liveTilt?: number;
|
|
||||||
|
|
||||||
@state() private _mode?: Mode;
|
@state() private _mode?: Mode;
|
||||||
|
|
||||||
private _setMode(ev) {
|
private _setMode(ev) {
|
||||||
this._mode = ev.currentTarget.mode;
|
this._mode = ev.currentTarget.mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _positionSliderMoved(ev) {
|
|
||||||
const value = (ev.detail as any).value;
|
|
||||||
if (isNaN(value)) return;
|
|
||||||
this._livePosition = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _positionValueChanged() {
|
|
||||||
this._livePosition = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _tiltSliderMoved(ev) {
|
|
||||||
const value = (ev.detail as any).value;
|
|
||||||
if (isNaN(value)) return;
|
|
||||||
this._liveTilt = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _tiltValueChanged() {
|
|
||||||
this._liveTilt = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected willUpdate(changedProps: PropertyValues): void {
|
protected willUpdate(changedProps: PropertyValues): void {
|
||||||
super.willUpdate(changedProps);
|
super.willUpdate(changedProps);
|
||||||
if (changedProps.has("stateObj") && this.stateObj) {
|
if (changedProps.has("stateObj") && this.stateObj) {
|
||||||
@ -77,20 +53,11 @@ class MoreInfoCover extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _stateOverride() {
|
private get _stateOverride() {
|
||||||
const liveValue = this._livePosition ?? this._liveTilt;
|
const stateDisplay = this.hass.formatEntityState(this.stateObj!);
|
||||||
|
|
||||||
const forcedState =
|
|
||||||
liveValue != null ? (liveValue ? "open" : "closed") : undefined;
|
|
||||||
|
|
||||||
const stateDisplay = this.hass.formatEntityState(
|
|
||||||
this.stateObj!,
|
|
||||||
forcedState
|
|
||||||
);
|
|
||||||
|
|
||||||
const positionStateDisplay = computeCoverPositionStateDisplay(
|
const positionStateDisplay = computeCoverPositionStateDisplay(
|
||||||
this.stateObj!,
|
this.stateObj!,
|
||||||
this.hass,
|
this.hass
|
||||||
liveValue
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (positionStateDisplay) {
|
if (positionStateDisplay) {
|
||||||
@ -147,8 +114,6 @@ class MoreInfoCover extends LitElement {
|
|||||||
<ha-more-info-cover-position
|
<ha-more-info-cover-position
|
||||||
.stateObj=${this.stateObj}
|
.stateObj=${this.stateObj}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@slider-moved=${this._positionSliderMoved}
|
|
||||||
@value-changed=${this._positionValueChanged}
|
|
||||||
></ha-more-info-cover-position>
|
></ha-more-info-cover-position>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
@ -157,8 +122,6 @@ class MoreInfoCover extends LitElement {
|
|||||||
<ha-more-info-cover-tilt-position
|
<ha-more-info-cover-tilt-position
|
||||||
.stateObj=${this.stateObj}
|
.stateObj=${this.stateObj}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@slider-moved=${this._tiltSliderMoved}
|
|
||||||
@value-changed=${this._tiltValueChanged}
|
|
||||||
></ha-more-info-cover-tilt-position>
|
></ha-more-info-cover-tilt-position>
|
||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
|
@ -40,18 +40,6 @@ class MoreInfoFan extends LitElement {
|
|||||||
|
|
||||||
@state() public _presetMode?: string;
|
@state() public _presetMode?: string;
|
||||||
|
|
||||||
@state() private _liveSpeed?: number;
|
|
||||||
|
|
||||||
private _speedSliderMoved(ev) {
|
|
||||||
const value = (ev.detail as any).value;
|
|
||||||
if (isNaN(value)) return;
|
|
||||||
this._liveSpeed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _speedValueChanged() {
|
|
||||||
this._liveSpeed = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _toggle = () => {
|
private _toggle = () => {
|
||||||
const service = this.stateObj?.state === "on" ? "turn_off" : "turn_on";
|
const service = this.stateObj?.state === "on" ? "turn_off" : "turn_on";
|
||||||
forwardHaptic("light");
|
forwardHaptic("light");
|
||||||
@ -104,23 +92,14 @@ class MoreInfoFan extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _stateOverride() {
|
private get _stateOverride() {
|
||||||
const liveValue = this._liveSpeed;
|
const stateDisplay = this.hass.formatEntityState(this.stateObj!);
|
||||||
|
|
||||||
const forcedState =
|
|
||||||
liveValue != null ? (liveValue ? "on" : "off") : undefined;
|
|
||||||
|
|
||||||
const stateDisplay = this.hass.formatEntityState(
|
|
||||||
this.stateObj!,
|
|
||||||
forcedState
|
|
||||||
);
|
|
||||||
|
|
||||||
const positionStateDisplay = computeFanSpeedStateDisplay(
|
const positionStateDisplay = computeFanSpeedStateDisplay(
|
||||||
this.stateObj!,
|
this.stateObj!,
|
||||||
this.hass,
|
this.hass
|
||||||
liveValue
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (positionStateDisplay && (stateActive(this.stateObj!) || liveValue)) {
|
if (positionStateDisplay && stateActive(this.stateObj!)) {
|
||||||
return positionStateDisplay;
|
return positionStateDisplay;
|
||||||
}
|
}
|
||||||
return stateDisplay;
|
return stateDisplay;
|
||||||
@ -165,8 +144,6 @@ class MoreInfoFan extends LitElement {
|
|||||||
<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}
|
|
||||||
@value-changed=${this._speedValueChanged}
|
|
||||||
>
|
>
|
||||||
</ha-more-info-fan-speed>
|
</ha-more-info-fan-speed>
|
||||||
`
|
`
|
||||||
|
@ -60,29 +60,10 @@ class MoreInfoLight extends LitElement {
|
|||||||
|
|
||||||
@state() private _effect?: string;
|
@state() private _effect?: string;
|
||||||
|
|
||||||
@state() private _selectedBrightness?: number;
|
|
||||||
|
|
||||||
@state() private _colorTempPreview?: number;
|
|
||||||
|
|
||||||
@state() private _mainControl: MainControl = "brightness";
|
@state() private _mainControl: MainControl = "brightness";
|
||||||
|
|
||||||
private _brightnessChanged(ev) {
|
|
||||||
const value = (ev.detail as any).value;
|
|
||||||
if (isNaN(value)) return;
|
|
||||||
this._selectedBrightness = (value * 255) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _tempColorHovered(ev: CustomEvent<HASSDomEvents["color-hovered"]>) {
|
|
||||||
if (ev.detail && "color_temp_kelvin" in ev.detail) {
|
|
||||||
this._colorTempPreview = ev.detail.color_temp_kelvin;
|
|
||||||
} else {
|
|
||||||
this._colorTempPreview = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues<typeof this>): void {
|
protected updated(changedProps: PropertyValues<typeof this>): void {
|
||||||
if (changedProps.has("stateObj")) {
|
if (changedProps.has("stateObj")) {
|
||||||
this._selectedBrightness = this.stateObj?.attributes.brightness;
|
|
||||||
this._effect = this.stateObj?.attributes.effect;
|
this._effect = this.stateObj?.attributes.effect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,19 +79,8 @@ class MoreInfoLight extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _stateOverride() {
|
private get _stateOverride() {
|
||||||
if (this._colorTempPreview) {
|
if (this.stateObj?.attributes.brightness) {
|
||||||
return this.hass.formatEntityAttributeValue(
|
return this.hass.formatEntityAttributeValue(this.stateObj!, "brightness");
|
||||||
this.stateObj!,
|
|
||||||
"color_temp_kelvin",
|
|
||||||
this._colorTempPreview
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this._selectedBrightness) {
|
|
||||||
return this.hass.formatEntityAttributeValue(
|
|
||||||
this.stateObj!,
|
|
||||||
"brightness",
|
|
||||||
this._selectedBrightness
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -168,7 +138,6 @@ class MoreInfoLight extends LitElement {
|
|||||||
<ha-more-info-light-brightness
|
<ha-more-info-light-brightness
|
||||||
.stateObj=${this.stateObj}
|
.stateObj=${this.stateObj}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@slider-moved=${this._brightnessChanged}
|
|
||||||
>
|
>
|
||||||
</ha-more-info-light-brightness>
|
</ha-more-info-light-brightness>
|
||||||
`
|
`
|
||||||
@ -187,7 +156,6 @@ class MoreInfoLight extends LitElement {
|
|||||||
<light-color-temp-picker
|
<light-color-temp-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.stateObj=${this.stateObj}
|
.stateObj=${this.stateObj}
|
||||||
@color-hovered=${this._tempColorHovered}
|
|
||||||
>
|
>
|
||||||
</light-color-temp-picker>
|
</light-color-temp-picker>
|
||||||
`
|
`
|
||||||
|
@ -350,7 +350,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card style=${styleMap(style)} class=${classMap({ active })}>
|
<ha-card style=${styleMap(style)} class=${classMap({ active })}>
|
||||||
${this._shouldRenderRipple ? html`<mwc-ripple></mwc-ripple>` : nothing}
|
|
||||||
<div class="tile">
|
<div class="tile">
|
||||||
<div
|
<div
|
||||||
class="background"
|
class="background"
|
||||||
@ -366,7 +365,11 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
@touchstart=${this.handleRippleActivate}
|
@touchstart=${this.handleRippleActivate}
|
||||||
@touchend=${this.handleRippleDeactivate}
|
@touchend=${this.handleRippleDeactivate}
|
||||||
@touchcancel=${this.handleRippleDeactivate}
|
@touchcancel=${this.handleRippleDeactivate}
|
||||||
></div>
|
>
|
||||||
|
${this._shouldRenderRipple
|
||||||
|
? html`<mwc-ripple></mwc-ripple>`
|
||||||
|
: nothing}
|
||||||
|
</div>
|
||||||
<div class="content ${classMap(contentClasses)}">
|
<div class="content ${classMap(contentClasses)}">
|
||||||
<div
|
<div
|
||||||
class="icon-container"
|
class="icon-container"
|
||||||
@ -437,7 +440,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
ha-card {
|
ha-card {
|
||||||
--mdc-ripple-color: var(--tile-color);
|
--mdc-ripple-color: var(--tile-color);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
|
||||||
transition:
|
transition:
|
||||||
box-shadow 180ms ease-in-out,
|
box-shadow 180ms ease-in-out,
|
||||||
border-color 180ms ease-in-out;
|
border-color 180ms ease-in-out;
|
||||||
@ -457,6 +459,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
border-radius: var(--ha-card-border-radius, 12px);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -13,6 +13,7 @@ import { UNAVAILABLE } from "../../../data/entity";
|
|||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceTileFeature } from "../types";
|
import { LovelaceTileFeature } from "../types";
|
||||||
import { CoverPositionTileFeatureConfig } from "./types";
|
import { CoverPositionTileFeatureConfig } from "./types";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes";
|
||||||
|
|
||||||
export const supportsCoverPositionTileFeature = (stateObj: HassEntity) => {
|
export const supportsCoverPositionTileFeature = (stateObj: HassEntity) => {
|
||||||
const domain = computeDomain(stateObj.entity_id);
|
const domain = computeDomain(stateObj.entity_id);
|
||||||
@ -93,6 +94,8 @@ class HuiCoverPositionTileFeature
|
|||||||
"current_position"
|
"current_position"
|
||||||
)}
|
)}
|
||||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_position}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
></ha-control-slider>
|
></ha-control-slider>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -13,6 +13,7 @@ import { generateTiltSliderTrackBackgroundGradient } from "../../../dialogs/more
|
|||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceTileFeature } from "../types";
|
import { LovelaceTileFeature } from "../types";
|
||||||
import { CoverTiltPositionTileFeatureConfig } from "./types";
|
import { CoverTiltPositionTileFeatureConfig } from "./types";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes";
|
||||||
|
|
||||||
const GRADIENT = generateTiltSliderTrackBackgroundGradient();
|
const GRADIENT = generateTiltSliderTrackBackgroundGradient();
|
||||||
|
|
||||||
@ -92,6 +93,8 @@ class HuiCoverTiltPositionTileFeature
|
|||||||
"current_tilt_position"
|
"current_tilt_position"
|
||||||
)}
|
)}
|
||||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_tilt_position}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
>
|
>
|
||||||
<div slot="background" class="gradient"></div
|
<div slot="background" class="gradient"></div
|
||||||
></ha-control-slider>
|
></ha-control-slider>
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceTileFeature } from "../types";
|
import { LovelaceTileFeature } from "../types";
|
||||||
import { FanSpeedTileFeatureConfig } from "./types";
|
import { FanSpeedTileFeatureConfig } from "./types";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes";
|
||||||
|
|
||||||
export const supportsFanSpeedTileFeature = (stateObj: HassEntity) => {
|
export const supportsFanSpeedTileFeature = (stateObj: HassEntity) => {
|
||||||
const domain = computeDomain(stateObj.entity_id);
|
const domain = computeDomain(stateObj.entity_id);
|
||||||
@ -126,6 +127,8 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
|||||||
"percentage"
|
"percentage"
|
||||||
)}
|
)}
|
||||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.fan.percentage}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
></ha-control-slider>
|
></ha-control-slider>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -67,6 +67,8 @@ class HuiLightBrightnessTileFeature
|
|||||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
.label=${this.hass.localize("ui.card.light.brightness")}
|
.label=${this.hass.localize("ui.card.light.brightness")}
|
||||||
|
.tooltipUnit=${"%"}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
></ha-control-slider>
|
></ha-control-slider>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -11,6 +11,7 @@ import { computeDomain } from "../../../common/entity/compute_domain";
|
|||||||
import { stateActive } from "../../../common/entity/state_active";
|
import { stateActive } from "../../../common/entity/state_active";
|
||||||
import "../../../components/ha-control-slider";
|
import "../../../components/ha-control-slider";
|
||||||
import { UNAVAILABLE } from "../../../data/entity";
|
import { UNAVAILABLE } from "../../../data/entity";
|
||||||
|
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes";
|
||||||
import { LightColorMode, lightSupportsColorMode } from "../../../data/light";
|
import { LightColorMode, lightSupportsColorMode } from "../../../data/light";
|
||||||
import { generateColorTemperatureGradient } from "../../../dialogs/more-info/components/lights/light-color-temp-picker";
|
import { generateColorTemperatureGradient } from "../../../dialogs/more-info/components/lights/light-color-temp-picker";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
@ -85,6 +86,8 @@ class HuiLightColorTempTileFeature
|
|||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
"--gradient": gradient,
|
"--gradient": gradient,
|
||||||
})}
|
})}
|
||||||
|
.tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.light.color_temp_kelvin}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
></ha-control-slider>
|
></ha-control-slider>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user