@@ -161,7 +169,9 @@ class HuiMapCard extends LitElement implements LovelaceCard {
.paths=${this._getHistoryPaths(this._config, this._stateHistory)}
.autoFit=${this._config.auto_fit || false}
.fitZones=${this._config.fit_zones}
- ?darkMode=${this._config.dark_mode}
+ ?forceDarkMode=${this._config.theme_mode === "dark" ||
+ this._config.dark_mode}
+ ?forceLightMode=${this._config.theme_mode === "light"}
interactiveZones
renderPassive
>
@@ -170,6 +180,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
"ui.panel.lovelace.cards.map.reset_focus"
)}
.path=${mdiImageFilterCenterFocus}
+ style=${isDarkMode ? "color:#ffffff" : "color:#000000"}
@click=${this._fitMap}
tabindex="0"
>
diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts
index 0ae62e6aea78..a32d345c2aee 100644
--- a/src/panels/lovelace/cards/types.ts
+++ b/src/panels/lovelace/cards/types.ts
@@ -3,7 +3,7 @@ import { ActionConfig } from "../../../data/lovelace/config/action";
import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
import { Statistic, StatisticType } from "../../../data/recorder";
import { ForecastType } from "../../../data/weather";
-import { FullCalendarView, TranslationDict } from "../../../types";
+import { FullCalendarView, ThemeMode, TranslationDict } from "../../../types";
import { LovelaceCardFeatureConfig } from "../card-features/types";
import { LegacyStateFilter } from "../common/evaluate-filter";
import { Condition, LegacyCondition } from "../common/validate-condition";
@@ -314,6 +314,7 @@ export interface MapCardConfig extends LovelaceCardConfig {
hours_to_show?: number;
geo_location_sources?: string[];
dark_mode?: boolean;
+ theme_mode?: ThemeMode;
}
export interface MarkdownCardConfig extends LovelaceCardConfig {
diff --git a/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts
index 7fb605e3f885..636ed4b85b5a 100644
--- a/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts
@@ -1,3 +1,4 @@
+import { mdiPalette } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import {
@@ -11,6 +12,7 @@ import {
string,
union,
} from "superstruct";
+import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../common/dom/fire_event";
import { hasLocation } from "../../../../common/entity/has_location";
import "../../../../components/ha-form/ha-form";
@@ -28,6 +30,7 @@ import { processEditorEntities } from "../process-editor-entities";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
+import { LocalizeFunc } from "../../../../common/translations/localize";
export const mapEntitiesConfigStruct = union([
object({
@@ -50,30 +53,11 @@ const cardConfigStruct = assign(
hours_to_show: optional(number()),
geo_location_sources: optional(array(string())),
auto_fit: optional(boolean()),
+ theme_mode: optional(string()),
})
);
-const SCHEMA = [
- { name: "title", selector: { text: {} } },
- {
- name: "",
- type: "grid",
- schema: [
- { name: "aspect_ratio", selector: { text: {} } },
- {
- name: "default_zoom",
- default: DEFAULT_ZOOM,
- selector: { number: { mode: "box", min: 0 } },
- },
- { name: "dark_mode", selector: { boolean: {} } },
- {
- name: "hours_to_show",
- default: DEFAULT_HOURS_TO_SHOW,
- selector: { number: { mode: "box", min: 0 } },
- },
- ],
- },
-] as const;
+const themeModes = ["auto", "light", "dark"] as const;
@customElement("hui-map-card-editor")
export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
@@ -83,8 +67,68 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
@state() private _configEntities?: EntityConfig[];
+ private _schema = memoizeOne(
+ (localize: LocalizeFunc) =>
+ [
+ { name: "title", selector: { text: {} } },
+ {
+ name: "",
+ type: "expandable",
+ iconPath: mdiPalette,
+ title: localize(`ui.panel.lovelace.editor.card.map.appearance`),
+ schema: [
+ {
+ name: "",
+ type: "grid",
+ schema: [
+ { name: "aspect_ratio", selector: { text: {} } },
+ {
+ name: "default_zoom",
+ default: DEFAULT_ZOOM,
+ selector: { number: { mode: "box", min: 0 } },
+ },
+ {
+ name: "theme_mode",
+ default: "auto",
+ selector: {
+ select: {
+ mode: "dropdown",
+ options: themeModes.map((themeMode) => ({
+ value: themeMode,
+ label: localize(
+ `ui.panel.lovelace.editor.card.map.theme_modes.${themeMode}`
+ ),
+ })),
+ },
+ },
+ },
+ {
+ name: "hours_to_show",
+ default: DEFAULT_HOURS_TO_SHOW,
+ selector: { number: { mode: "box", min: 0 } },
+ },
+ ],
+ },
+ ],
+ },
+ ] as const
+ );
+
public setConfig(config: MapCardConfig): void {
assert(config, cardConfigStruct);
+
+ // Migrate legacy dark_mode to theme_mode
+ if (!this._config && !("theme_mode" in config)) {
+ config = { ...config };
+ if (config.dark_mode) {
+ config.theme_mode = "dark";
+ } else {
+ config.theme_mode = "auto";
+ }
+ delete config.dark_mode;
+ fireEvent(this, "config-changed", { config: config });
+ }
+
this._config = config;
this._configEntities = config.entities
? processEditorEntities(config.entities)
@@ -104,33 +148,32 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
-
-
-
- ${this.hass.localize(
- "ui.panel.lovelace.editor.card.map.geo_location_sources"
- )}
-
-
-
-
-
+
+
+
+
+ ${this.hass.localize(
+ "ui.panel.lovelace.editor.card.map.geo_location_sources"
+ )}
+
+
+
`;
}
@@ -170,9 +213,14 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
fireEvent(this, "config-changed", { config: ev.detail.value });
}
- private _computeLabelCallback = (schema: SchemaUnion
) => {
+ private _computeLabelCallback = (
+ schema: SchemaUnion>
+ ) => {
switch (schema.name) {
- case "dark_mode":
+ case "theme_mode":
+ return this.hass!.localize(
+ `ui.panel.lovelace.editor.card.map.${schema.name}`
+ );
case "default_zoom":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.map.${schema.name}`
@@ -185,16 +233,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
};
static get styles(): CSSResultGroup {
- return [
- configElementStyle,
- css`
- .geo_location_sources {
- padding-left: 20px;
- padding-inline-start: 20px;
- direction: var(--direction);
- }
- `,
- ];
+ return [configElementStyle, css``];
}
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 65b153f5221d..8be6f084acee 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -5835,7 +5835,14 @@
"name": "Map",
"geo_location_sources": "Geolocation sources",
"dark_mode": "Dark mode?",
- "default_zoom": "Default zoom",
+ "appearance": "Appearance",
+ "theme_mode": "Theme Mode",
+ "theme_modes": {
+ "auto": "Auto",
+ "light": "Light",
+ "dark": "Dark"
+ },
+ "default_zoom": "Default Zoom",
"source": "Source",
"description": "The Map card that allows you to display entities on a map."
},
diff --git a/src/types.ts b/src/types.ts
index c6b32be85d06..31a412364034 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -139,6 +139,8 @@ export type FullCalendarView =
| "dayGridDay"
| "listWeek";
+export type ThemeMode = "auto" | "light" | "dark";
+
export interface ToggleButton {
label: string;
iconPath?: string;