diff --git a/src/panels/lovelace/cards/hui-clock-card.ts b/src/panels/lovelace/cards/hui-clock-card.ts
index c99498614d..346ddb9adb 100644
--- a/src/panels/lovelace/cards/hui-clock-card.ts
+++ b/src/panels/lovelace/cards/hui-clock-card.ts
@@ -65,7 +65,9 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
minute: "2-digit",
second: "2-digit",
hourCycle: useAmPm(locale) ? "h12" : "h23",
- timeZone: resolveTimeZone(locale.time_zone, this.hass.config?.time_zone),
+ timeZone:
+ this._config?.time_zone ||
+ resolveTimeZone(locale.time_zone, this.hass.config?.time_zone),
});
this._tick();
@@ -79,7 +81,7 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
public getGridOptions(): LovelaceGridOptions {
if (this._config?.clock_size === "medium") {
return {
- min_rows: 1,
+ min_rows: this._config?.title ? 2 : 1,
rows: 2,
max_rows: 4,
min_columns: 4,
@@ -101,7 +103,7 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
min_rows: 1,
rows: 1,
max_rows: 4,
- min_columns: 4,
+ min_columns: 3,
columns: 6,
};
}
@@ -160,6 +162,9 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
? `size-${this._config.clock_size}`
: ""}"
>
+ ${this._config.title !== undefined
+ ? html`
${this._timeHour}
${this._timeMinute}
@@ -182,9 +187,41 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
.time-wrapper {
display: flex;
- height: 100%;
+ height: calc(100% - 12px);
align-items: center;
+ flex-direction: column;
justify-content: center;
+ padding: 6px 8px;
+ row-gap: 6px;
+ }
+
+ .time-wrapper.size-medium,
+ .time-wrapper.size-large {
+ height: calc(100% - 32px);
+ padding: 16px;
+ row-gap: 12px;
+ }
+
+ .time-title {
+ color: var(--primary-text-color);
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 18px;
+ overflow: hidden;
+ text-align: center;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ width: 100%;
+ }
+
+ .time-wrapper.size-medium .time-title {
+ font-size: 18px;
+ line-height: 21px;
+ }
+
+ .time-wrapper.size-large .time-title {
+ font-size: 24px;
+ line-height: 28px;
}
.time-parts {
@@ -197,7 +234,10 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
font-size: 2rem;
font-weight: 500;
line-height: 0.8;
- padding: 16px 0;
+ }
+
+ .time-title + .time-parts {
+ font-size: 1.5rem;
}
.time-wrapper.size-medium .time-parts {
@@ -242,8 +282,7 @@ export class HuiClockCard extends LitElement implements LovelaceCard {
.time-parts .time-part.second,
.time-parts .time-part.am-pm {
- font-size: 12px;
- font-weight: 500;
+ font-size: 10px;
margin-left: 4px;
}
diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts
index 5e7e25ed8d..30227b5fe3 100644
--- a/src/panels/lovelace/cards/types.ts
+++ b/src/panels/lovelace/cards/types.ts
@@ -349,9 +349,11 @@ export interface MarkdownCardConfig extends LovelaceCardConfig {
export interface ClockCardConfig extends LovelaceCardConfig {
type: "clock";
+ title?: string;
clock_size?: "small" | "medium" | "large";
show_seconds?: boolean | undefined;
time_format?: TimeFormat;
+ time_zone?: string;
}
export interface MediaControlCardConfig extends LovelaceCardConfig {
diff --git a/src/panels/lovelace/editor/config-elements/hui-clock-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-clock-card-editor.ts
index 83a140b553..cb73a2460d 100644
--- a/src/panels/lovelace/editor/config-elements/hui-clock-card-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-clock-card-editor.ts
@@ -1,3 +1,4 @@
+import timezones from "google-timezones-json";
import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
@@ -9,6 +10,7 @@ import {
literal,
object,
optional,
+ string,
union,
} from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
@@ -27,10 +29,12 @@ import { TimeFormat } from "../../../../data/translation";
const cardConfigStruct = assign(
baseLovelaceCardConfig,
object({
+ title: optional(string()),
clock_size: optional(
union([literal("small"), literal("medium"), literal("large")])
),
time_format: optional(enums(Object.values(TimeFormat))),
+ time_zone: optional(enums(Object.keys(timezones))),
show_seconds: optional(boolean()),
})
);
@@ -47,6 +51,7 @@ export class HuiClockCardEditor
private _schema = memoizeOne(
(localize: LocalizeFunc) =>
[
+ { name: "title", selector: { text: {} } },
{
name: "clock_size",
selector: {
@@ -61,12 +66,7 @@ export class HuiClockCardEditor
},
},
},
- {
- name: "show_seconds",
- selector: {
- boolean: {},
- },
- },
+ { name: "show_seconds", selector: { boolean: {} } },
{
name: "time_format",
selector: {
@@ -81,11 +81,32 @@ export class HuiClockCardEditor
},
},
},
+ {
+ name: "time_zone",
+ selector: {
+ select: {
+ mode: "dropdown",
+ options: [
+ [
+ "auto",
+ localize(
+ `ui.panel.lovelace.editor.card.clock.time_zones.auto`
+ ),
+ ],
+ ...Object.entries(timezones as Record
),
+ ].map(([key, value]) => ({
+ value: key,
+ label: value,
+ })),
+ },
+ },
+ },
] as const satisfies readonly HaFormSchema[]
);
private _data = memoizeOne((config) => ({
clock_size: "small",
+ time_zone: "auto",
time_format: "auto",
show_seconds: false,
...config,
@@ -113,6 +134,9 @@ export class HuiClockCardEditor
}
private _valueChanged(ev: CustomEvent): void {
+ if (ev.detail.value.time_zone === "auto") {
+ delete ev.detail.value.time_zone;
+ }
if (ev.detail.value.time_format === "auto") {
delete ev.detail.value.time_format;
}
@@ -124,6 +148,10 @@ export class HuiClockCardEditor
schema: SchemaUnion>
) => {
switch (schema.name) {
+ case "title":
+ return this.hass!.localize(
+ "ui.panel.lovelace.editor.card.generic.title"
+ );
case "clock_size":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.clock.clock_size`
@@ -132,6 +160,10 @@ export class HuiClockCardEditor
return this.hass!.localize(
`ui.panel.lovelace.editor.card.clock.time_format`
);
+ case "time_zone":
+ return this.hass!.localize(
+ `ui.panel.lovelace.editor.card.clock.time_zone`
+ );
case "show_seconds":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.clock.show_seconds`
diff --git a/src/translations/en.json b/src/translations/en.json
index ddb3c37d37..937aae1df3 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -7161,13 +7161,17 @@
"large": "Large"
},
"show_seconds": "Display seconds",
- "time_format": "Time format",
+ "time_format": "[%key:ui::panel::profile::time_format::dropdown_label%]",
"time_formats": {
"auto": "Use user settings",
"language": "[%key:ui::panel::profile::time_format::formats::language%]",
"system": "[%key:ui::panel::profile::time_format::formats::system%]",
"24": "[%key:ui::panel::profile::time_format::formats::24%]",
"12": "[%key:ui::panel::profile::time_format::formats::12%]"
+ },
+ "time_zone": "[%key:ui::panel::profile::time_zone::dropdown_label%]",
+ "time_zones": {
+ "auto": "Use user settings"
}
},
"media-control": {