diff --git a/src/components/ha-selector/ha-selector-ui-color.ts b/src/components/ha-selector/ha-selector-ui-color.ts
new file mode 100644
index 0000000000..98dbf3c1fb
--- /dev/null
+++ b/src/components/ha-selector/ha-selector-ui-color.ts
@@ -0,0 +1,42 @@
+import { html, LitElement } from "lit";
+import { customElement, property } from "lit/decorators";
+import { fireEvent } from "../../common/dom/fire_event";
+import { ActionConfig } from "../../data/lovelace";
+import { UiColorSelector } from "../../data/selector";
+import "../../panels/lovelace/components/hui-color-picker";
+import { HomeAssistant } from "../../types";
+
+@customElement("ha-selector-ui-color")
+export class HaSelectorUiColor extends LitElement {
+ @property() public hass!: HomeAssistant;
+
+ @property() public selector!: UiColorSelector;
+
+ @property() public value?: ActionConfig;
+
+ @property() public label?: string;
+
+ @property() public helper?: string;
+
+ protected render() {
+ return html`
+
+ `;
+ }
+
+ private _valueChanged(ev: CustomEvent) {
+ fireEvent(this, "value-changed", { value: ev.detail.value });
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-selector-ui-color": HaSelectorUiColor;
+ }
+}
diff --git a/src/components/ha-selector/ha-selector.ts b/src/components/ha-selector/ha-selector.ts
index 2b3dbb8f79..e76253f057 100644
--- a/src/components/ha-selector/ha-selector.ts
+++ b/src/components/ha-selector/ha-selector.ts
@@ -34,6 +34,7 @@ const LOAD_ELEMENTS = {
location: () => import("./ha-selector-location"),
color_temp: () => import("./ha-selector-color-temp"),
"ui-action": () => import("./ha-selector-ui-action"),
+ "ui-color": () => import("./ha-selector-ui-color"),
};
@customElement("ha-selector")
diff --git a/src/data/selector.ts b/src/data/selector.ts
index a50128c979..b55c97a6b5 100644
--- a/src/data/selector.ts
+++ b/src/data/selector.ts
@@ -33,7 +33,8 @@ export type Selector =
| TemplateSelector
| ThemeSelector
| TimeSelector
- | UiActionSelector;
+ | UiActionSelector
+ | UiColorSelector;
export interface ActionSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
@@ -273,6 +274,11 @@ export interface UiActionSelector {
} | null;
}
+export interface UiColorSelector {
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ "ui-color": {} | null;
+}
+
export const filterSelectorDevices = (
filterDevice: SelectorDevice,
device: DeviceRegistryEntry,
diff --git a/src/panels/lovelace/components/hui-color-picker.ts b/src/panels/lovelace/components/hui-color-picker.ts
new file mode 100644
index 0000000000..3bcff432f4
--- /dev/null
+++ b/src/panels/lovelace/components/hui-color-picker.ts
@@ -0,0 +1,105 @@
+import "@material/mwc-list/mwc-list-item";
+import { css, html, LitElement } from "lit";
+import { customElement, property } from "lit/decorators";
+import { styleMap } from "lit/directives/style-map";
+import {
+ computeRgbColor,
+ THEME_COLORS,
+} from "../../../common/color/compute-color";
+import { fireEvent } from "../../../common/dom/fire_event";
+import { stopPropagation } from "../../../common/dom/stop_propagation";
+import "../../../components/ha-select";
+import { HomeAssistant } from "../../../types";
+
+@customElement("hui-color-picker")
+export class HuiColorPicker extends LitElement {
+ @property() public label?: string;
+
+ @property() public helper?: string;
+
+ @property() public hass!: HomeAssistant;
+
+ @property() public value?: string;
+
+ @property({ type: Boolean }) public disabled = false;
+
+ _valueSelected(ev) {
+ const value = ev.target.value;
+ if (value) {
+ fireEvent(this, "value-changed", {
+ value: value !== "default" ? value : undefined,
+ });
+ }
+ }
+
+ render() {
+ return html`
+
+ ${this.value
+ ? html`
+
+ ${this.renderColorCircle(this.value || "grey")}
+
+ `
+ : null}
+
+ ${this.hass.localize(
+ `ui.panel.lovelace.editor.color-picker.default_color`
+ )}
+
+ ${Array.from(THEME_COLORS).map(
+ (color) => html`
+
+ ${this.hass.localize(
+ `ui.panel.lovelace.editor.color-picker.colors.${color}`
+ ) || color}
+ ${this.renderColorCircle(color)}
+
+ `
+ )}
+
+ `;
+ }
+
+ private renderColorCircle(color: string) {
+ return html`
+
+ `;
+ }
+
+ static get styles() {
+ return css`
+ .circle-color {
+ display: block;
+ background-color: rgb(var(--circle-color));
+ border-radius: 10px;
+ width: 20px;
+ height: 20px;
+ }
+ ha-select {
+ width: 100%;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "hui-color-picker": HuiColorPicker;
+ }
+}
diff --git a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts
index c86b264e69..e03e130296 100644
--- a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts
@@ -13,11 +13,9 @@ import {
optional,
string,
} from "superstruct";
-import { THEME_COLORS } from "../../../../common/color/compute-color";
import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
import { computeDomain } from "../../../../common/entity/compute_domain";
import { domainIcon } from "../../../../common/entity/domain_icon";
-import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
import "../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types";
@@ -93,20 +91,7 @@ export class HuiTileCardEditor
{
name: "color",
selector: {
- select: {
- options: [
- {
- label: this.hass!.localize(
- `ui.panel.lovelace.editor.card.tile.default_color`
- ),
- value: "default",
- },
- ...Array.from(THEME_COLORS).map((color) => ({
- label: capitalizeFirstLetter(color),
- value: color,
- })),
- ],
- },
+ "ui-color": {},
},
},
{
@@ -159,11 +144,6 @@ export class HuiTileCardEditor
stateObj
);
- const data = {
- color: "default",
- ...this._config,
- };
-
if (this._subElementEditorConfig) {
return html`