Bump dashboards: bar, icon, forecast and clock widget types

Plumbing only: the widget-type literal and its dtype table on both sides,
the regenerated client, a curated lucide map and four stubs the renderers
are wired to. Also a latching switch and a segmented dropdown, both a
`style` on the control that already publishes and reads back, plus the
option editor a dropdown never had.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTsT1isxUjw5gtkJk8WhuA
This commit is contained in:
2026-08-20 08:31:36 +02:00
co-authored by Claude Opus 5
parent 6be718f672
commit dbaa3518b9
11 changed files with 389 additions and 22 deletions
+11 -2
View File
@@ -42,6 +42,10 @@ WidgetType = Literal[
"markdown",
"agenda",
"notification",
"bar",
"icon",
"forecast",
"clock",
# Input
"button",
"switch",
@@ -66,6 +70,10 @@ WIDGET_DTYPES: dict[str, set[str]] = {
"switch": {"bool"},
"agenda": {"list"},
"notification": {"record"},
"bar": {"float", "int"},
"forecast": {"list"},
# An icon maps weather strings, bool hints and numbers alike, and a clock
# binds nothing at all, so neither has a row to be held to.
}
@@ -124,7 +132,8 @@ class WidgetDef(BaseModel):
if series.get("message")
]
name = self.config.get("message")
return [str(name)] if name else []
inner = self.config.get("inner") # only a bar nests a second reading
return [str(value) for value in (name, inner) if value]
@property
def target(self) -> str:
@@ -161,7 +170,7 @@ class WidgetDef(BaseModel):
str(series.get("dtype") or "")
for series in self.config.get("series") or []
]
return [str(self.config.get("dtype") or "")]
return [str(self.config.get(key) or "") for key in ("dtype", "inner_dtype")]
@model_validator(mode="after")
def _check_binding(self) -> WidgetDef: