mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add native color picker option (#16726)
This commit is contained in:
parent
efb0098eac
commit
b63a32109e
@ -1,6 +1,7 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import "@material/mwc-tab-bar/mwc-tab-bar";
|
import "@material/mwc-tab-bar/mwc-tab-bar";
|
||||||
import "@material/mwc-tab/mwc-tab";
|
import "@material/mwc-tab/mwc-tab";
|
||||||
|
import { mdiEyedropper } from "@mdi/js";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
@ -10,7 +11,14 @@ import {
|
|||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { hs2rgb, rgb2hs } from "../../../../common/color/convert-color";
|
import {
|
||||||
|
hex2rgb,
|
||||||
|
hs2rgb,
|
||||||
|
hsv2rgb,
|
||||||
|
rgb2hex,
|
||||||
|
rgb2hs,
|
||||||
|
rgb2hsv,
|
||||||
|
} from "../../../../common/color/convert-color";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { throttle } from "../../../../common/util/throttle";
|
import { throttle } from "../../../../common/util/throttle";
|
||||||
import "../../../../components/ha-button-toggle-group";
|
import "../../../../components/ha-button-toggle-group";
|
||||||
@ -27,6 +35,7 @@ import {
|
|||||||
lightSupportsColorMode,
|
lightSupportsColorMode,
|
||||||
} from "../../../../data/light";
|
} from "../../../../data/light";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
import "../../../../components/ha-icon";
|
||||||
|
|
||||||
export type LightPickerMode = "color_temp" | "color";
|
export type LightPickerMode = "color_temp" | "color";
|
||||||
|
|
||||||
@ -80,6 +89,16 @@ class LightColorPicker extends LitElement {
|
|||||||
!supportsRgbww &&
|
!supportsRgbww &&
|
||||||
lightSupportsColorMode(this.stateObj, LightColorMode.RGBW);
|
lightSupportsColorMode(this.stateObj, LightColorMode.RGBW);
|
||||||
|
|
||||||
|
const hexValue = this._hsPickerValue
|
||||||
|
? rgb2hex(
|
||||||
|
hsv2rgb([
|
||||||
|
this._hsPickerValue[0],
|
||||||
|
this._hsPickerValue[1],
|
||||||
|
((this._colorBrightnessSliderValue ?? 100) / 100) * 255,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
: "";
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this._modes.length > 1
|
${this._modes.length > 1
|
||||||
? html`
|
? html`
|
||||||
@ -116,27 +135,37 @@ class LightColorPicker extends LitElement {
|
|||||||
: nothing}
|
: nothing}
|
||||||
${this._mode === "color"
|
${this._mode === "color"
|
||||||
? html`
|
? html`
|
||||||
<ha-hs-color-picker
|
<div class="color-container">
|
||||||
@value-changed=${this._hsColorChanged}
|
<label class="native-color-picker">
|
||||||
@cursor-moved=${this._hsColorCursorMoved}
|
<input
|
||||||
.value=${this._hsPickerValue}
|
type="color"
|
||||||
.colorBrightness=${this._colorBrightnessSliderValue != null
|
.value=${hexValue ?? ""}
|
||||||
? (this._colorBrightnessSliderValue * 255) / 100
|
@input=${this._nativeColorChanged}
|
||||||
: undefined}
|
/>
|
||||||
.wv=${this._wvSliderValue != null
|
<ha-svg-icon .path=${mdiEyedropper}></ha-svg-icon>
|
||||||
? (this._wvSliderValue * 255) / 100
|
</label>
|
||||||
: undefined}
|
|
||||||
.ww=${this._wwSliderValue != null
|
|
||||||
? (this._wwSliderValue * 255) / 100
|
|
||||||
: undefined}
|
|
||||||
.cw=${this._cwSliderValue != null
|
|
||||||
? (this._cwSliderValue * 255) / 100
|
|
||||||
: undefined}
|
|
||||||
.minKelvin=${this.stateObj.attributes.min_color_temp_kelvin}
|
|
||||||
.maxKelvin=${this.stateObj.attributes.max_color_temp_kelvin}
|
|
||||||
>
|
|
||||||
</ha-hs-color-picker>
|
|
||||||
|
|
||||||
|
<ha-hs-color-picker
|
||||||
|
@value-changed=${this._hsColorChanged}
|
||||||
|
@cursor-moved=${this._hsColorCursorMoved}
|
||||||
|
.value=${this._hsPickerValue}
|
||||||
|
.colorBrightness=${this._colorBrightnessSliderValue != null
|
||||||
|
? (this._colorBrightnessSliderValue * 255) / 100
|
||||||
|
: undefined}
|
||||||
|
.wv=${this._wvSliderValue != null
|
||||||
|
? (this._wvSliderValue * 255) / 100
|
||||||
|
: undefined}
|
||||||
|
.ww=${this._wwSliderValue != null
|
||||||
|
? (this._wwSliderValue * 255) / 100
|
||||||
|
: undefined}
|
||||||
|
.cw=${this._cwSliderValue != null
|
||||||
|
? (this._cwSliderValue * 255) / 100
|
||||||
|
: undefined}
|
||||||
|
.minKelvin=${this.stateObj.attributes.min_color_temp_kelvin}
|
||||||
|
.maxKelvin=${this.stateObj.attributes.max_color_temp_kelvin}
|
||||||
|
>
|
||||||
|
</ha-hs-color-picker>
|
||||||
|
</div>
|
||||||
${supportsRgbw || supportsRgbww
|
${supportsRgbw || supportsRgbww
|
||||||
? html`<ha-labeled-slider
|
? html`<ha-labeled-slider
|
||||||
.caption=${this.hass.localize(
|
.caption=${this.hass.localize(
|
||||||
@ -349,6 +378,23 @@ class LightColorPicker extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _nativeColorChanged(ev) {
|
||||||
|
const rgb = hex2rgb(ev.currentTarget.value);
|
||||||
|
|
||||||
|
const hsv = rgb2hsv(rgb);
|
||||||
|
|
||||||
|
this._hsPickerValue = [hsv[0], hsv[1]];
|
||||||
|
|
||||||
|
if (
|
||||||
|
lightSupportsColorMode(this.stateObj!, LightColorMode.RGBW) ||
|
||||||
|
lightSupportsColorMode(this.stateObj!, LightColorMode.RGBWW)
|
||||||
|
) {
|
||||||
|
this._colorBrightnessSliderValue = hsv[2] / 2.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._throttleUpdateColor();
|
||||||
|
}
|
||||||
|
|
||||||
private _hsColorChanged(ev: CustomEvent) {
|
private _hsColorChanged(ev: CustomEvent) {
|
||||||
if (!ev.detail.value) {
|
if (!ev.detail.value) {
|
||||||
return;
|
return;
|
||||||
@ -537,10 +583,65 @@ class LightColorPicker extends LitElement {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-hs-color-picker {
|
.native-color-picker {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.native-color-picker ha-svg-icon {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="color"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
display: block;
|
||||||
|
width: var(--mdc-icon-button-size, 48px);
|
||||||
|
height: var(--mdc-icon-button-size, 48px);
|
||||||
|
padding: calc(
|
||||||
|
(var(--mdc-icon-button-size, 48px) - var(--mdc-icon-size, 24px)) / 2
|
||||||
|
);
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: calc(var(--mdc-icon-button-size, 48px) / 2);
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 180ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="color"]:focus-visible,
|
||||||
|
input[type="color"]:hover {
|
||||||
|
background-color: rgb(127, 127, 127, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="color"]::-webkit-color-swatch-wrapper {
|
||||||
|
display: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="color"]::-webkit-color-swatch {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-container {
|
||||||
|
position: relative;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
margin: 44px 0 44px 0;
|
margin: 0 0 44px 0;
|
||||||
|
padding-top: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-hs-color-picker {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-temp-color-picker {
|
ha-temp-color-picker {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user