diff --git a/src/common/datetime/format_date.ts b/src/common/datetime/format_date.ts index d8c46d4e8d79..a4441bf379a5 100644 --- a/src/common/datetime/format_date.ts +++ b/src/common/datetime/format_date.ts @@ -9,3 +9,12 @@ export const formatDate = toLocaleDateStringSupportsOptions day: "numeric", }) : (dateObj: Date) => format(dateObj, "longDate"); + +export const formatDateWeekday = toLocaleDateStringSupportsOptions + ? (dateObj: Date, locales: string) => + dateObj.toLocaleDateString(locales, { + weekday: "long", + month: "short", + day: "numeric", + }) + : (dateObj: Date) => format(dateObj, "dddd, D MMM"); diff --git a/src/common/datetime/format_time.ts b/src/common/datetime/format_time.ts index c27874f3a62d..6b79f0c173e4 100644 --- a/src/common/datetime/format_time.ts +++ b/src/common/datetime/format_time.ts @@ -17,3 +17,12 @@ export const formatTimeWithSeconds = toLocaleTimeStringSupportsOptions second: "2-digit", }) : (dateObj: Date) => format(dateObj, "mediumTime"); + +export const formatTimeWeekday = toLocaleTimeStringSupportsOptions + ? (dateObj: Date, locales: string) => + dateObj.toLocaleTimeString(locales, { + weekday: "long", + hour: "numeric", + minute: "2-digit", + }) + : (dateObj: Date) => format(dateObj, "dddd, HH:mm"); diff --git a/src/components/ha-markdown-element.ts b/src/components/ha-markdown-element.ts index cd07cf0a012e..503e77a39aa4 100644 --- a/src/components/ha-markdown-element.ts +++ b/src/components/ha-markdown-element.ts @@ -1,9 +1,13 @@ import { customElement, property, UpdatingElement } from "lit-element"; import { fireEvent } from "../common/dom/fire_event"; import { renderMarkdown } from "../resources/render-markdown"; +import type { HomeAssistant } from "../types"; +import { HuiTimestampDisplay } from "../panels/lovelace/components/hui-timestamp-display"; @customElement("ha-markdown-element") class HaMarkdownElement extends UpdatingElement { + @property({ attribute: false }) public hass?: HomeAssistant; + @property() public content?; @property({ type: Boolean }) public allowSvg = false; @@ -55,6 +59,8 @@ class HaMarkdownElement extends UpdatingElement { // Fire a resize event when images loaded to notify content resized } else if (node instanceof HTMLImageElement) { node.addEventListener("load", this._resize); + } else if (node instanceof HuiTimestampDisplay) { + node.hass = this.hass; } } } diff --git a/src/components/ha-markdown.ts b/src/components/ha-markdown.ts index c98f5d07a966..beb38d268e21 100644 --- a/src/components/ha-markdown.ts +++ b/src/components/ha-markdown.ts @@ -7,10 +7,13 @@ import { property, TemplateResult, } from "lit-element"; +import type { HomeAssistant } from "../types"; import "./ha-markdown-element"; @customElement("ha-markdown") class HaMarkdown extends LitElement { + @property({ attribute: false }) public hass?: HomeAssistant; + @property() public content?; @property({ type: Boolean }) public allowSvg = false; @@ -22,11 +25,13 @@ class HaMarkdown extends LitElement { return html``; } - return html``; + > + `; } static get styles(): CSSResult { diff --git a/src/panels/lovelace/cards/hui-markdown-card.ts b/src/panels/lovelace/cards/hui-markdown-card.ts index 8aaedc76a978..2b049ce4f2f7 100644 --- a/src/panels/lovelace/cards/hui-markdown-card.ts +++ b/src/panels/lovelace/cards/hui-markdown-card.ts @@ -82,6 +82,7 @@ export class HuiMarkdownCard extends LitElement implements LovelaceCard { return html` string } = { date: formatDate, + date_weekday: formatDateWeekday, datetime: formatDateTime, time: formatTime, + time_weekday: formatTimeWeekday, }; const INTERVAL_FORMAT = ["relative", "total"]; @customElement("hui-timestamp-display") -class HuiTimestampDisplay extends LitElement { +export class HuiTimestampDisplay extends LitElement { @property({ attribute: false }) public hass?: HomeAssistant; - @property() public ts?: Date; + @property() public ts?: string | Date; @property() public format?: TimestampRenderingFormats; @@ -52,7 +61,9 @@ class HuiTimestampDisplay extends LitElement { return html``; } - if (isNaN(this.ts.getTime())) { + const tsDate = this.ts instanceof Date ? this.ts : new Date(this.ts); + + if (!checkValidDate(tsDate)) { return html`${this.hass.localize( "ui.panel.lovelace.components.timestamp-display.invalid" )}`; @@ -64,7 +75,7 @@ class HuiTimestampDisplay extends LitElement { return html` ${this._relative} `; } if (format in FORMATS) { - return html` ${FORMATS[format](this.ts, this.hass.language)} `; + return html`${FORMATS[format](tsDate, this.hass.language)}`; } return html`${this.hass.localize( "ui.panel.lovelace.components.timestamp-display.invalid_format" @@ -105,11 +116,12 @@ class HuiTimestampDisplay extends LitElement { private _updateRelative(): void { if (this.ts && this.hass!.localize) { + const tsDate = this.ts instanceof Date ? this.ts : new Date(this.ts); this._relative = this._format === "relative" - ? relativeTime(this.ts, this.hass!.localize) + ? relativeTime(tsDate, this.hass!.localize) : (this._relative = relativeTime(new Date(), this.hass!.localize, { - compareTime: this.ts, + compareTime: tsDate, includeTense: false, })); } diff --git a/src/panels/lovelace/components/types.ts b/src/panels/lovelace/components/types.ts index 4e49ee3e4410..45907406066d 100644 --- a/src/panels/lovelace/components/types.ts +++ b/src/panels/lovelace/components/types.ts @@ -11,5 +11,7 @@ export type TimestampRenderingFormats = | "relative" | "total" | "date" + | "date_weekday" | "time" + | "time_weekday" | "datetime"; diff --git a/src/resources/markdown_worker.ts b/src/resources/markdown_worker.ts index 5545a87f358f..a41ba7d3a524 100644 --- a/src/resources/markdown_worker.ts +++ b/src/resources/markdown_worker.ts @@ -22,8 +22,10 @@ const renderMarkdown = ( if (!whiteListNormal) { whiteListNormal = { ...(getDefaultWhiteList() as WhiteList), + style: [], "ha-icon": ["icon"], "ha-svg-icon": ["path"], + "hui-timestamp-display": ["ts", "format"], }; }