From b9a3dc795b7468a75d9e69c5d11e2eb25376f095 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Fri, 9 Jan 2026 11:30:09 -0800 Subject: [PATCH] Duration selector: migrate legacy duration formats (#28880) --- .../ha-selector/ha-selector-duration.ts | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/components/ha-selector/ha-selector-duration.ts b/src/components/ha-selector/ha-selector-duration.ts index 7fa96adf3e..c38c7dcd56 100644 --- a/src/components/ha-selector/ha-selector-duration.ts +++ b/src/components/ha-selector/ha-selector-duration.ts @@ -1,3 +1,4 @@ +import memoizeOne from "memoize-one"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import type { DurationSelector } from "../../data/selector"; @@ -11,7 +12,10 @@ export class HaTimeDuration extends LitElement { @property({ attribute: false }) public selector!: DurationSelector; - @property({ attribute: false }) public value?: HaDurationData; + @property({ attribute: false }) public value?: + | HaDurationData + | string + | number; @property() public label?: string; @@ -21,12 +25,42 @@ export class HaTimeDuration extends LitElement { @property({ type: Boolean }) public required = true; + private _data = memoizeOne( + (value?: HaDurationData | string | number): HaDurationData | undefined => { + if (typeof value === "number") { + return { seconds: value }; + } + if (typeof value === "string") { + const negative = value.trim()[0] === "-"; + const parts = value + .split(":") + .map((p) => (negative && p ? -Math.abs(Number(p)) : Number(p))); + + if (parts.length === 1) { + return { seconds: parts[0] }; + } + if (parts.length === 2) { + return { hours: parts[0], minutes: parts[1] }; + } + if (parts.length === 3) { + return { + hours: parts[0], + minutes: parts[1], + seconds: parts[2], + }; + } + return undefined; + } + return value; + } + ); + protected render() { return html`