@glasshome/widget-sdk 1.11.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -84,6 +84,19 @@ declare function icon(o: {
84
84
  declare function icon(o?: {
85
85
  title?: string;
86
86
  }): z.ZodOptional<z.ZodString>;
87
+ /**
88
+ * Image id (an opaque handle, not a URL). The host renders its picker and
89
+ * resolves the id with `imageUrl()`.
90
+ */
91
+ declare function image(o: {
92
+ title?: string;
93
+ description?: string;
94
+ default: string;
95
+ }): z.ZodDefault<z.ZodString>;
96
+ declare function image(o?: {
97
+ title?: string;
98
+ description?: string;
99
+ }): z.ZodOptional<z.ZodString>;
87
100
  declare function stringList(o: {
88
101
  title: string;
89
102
  description?: string;
@@ -132,6 +145,7 @@ export declare const field: {
132
145
  entity: typeof entity;
133
146
  area: typeof area;
134
147
  icon: typeof icon;
148
+ image: typeof image;
135
149
  stringList: typeof stringList;
136
150
  group: typeof group;
137
151
  list: typeof list;
package/dist/index.js CHANGED
@@ -7,9 +7,9 @@ import { Show as C, createContext as pe, createEffect as w, createMemo as T, cre
7
7
  import { addEventListener as k, className as A, createComponent as j, delegateEvents as _e, effect as M, insert as N, memo as P, setStyleProperty as F, style as ve, template as I, use as ye } from "solid-js/web";
8
8
  import { clsx as be } from "clsx";
9
9
  import { twMerge as xe } from "tailwind-merge";
10
- import { Badge as Se, Button as Ce, ColorSlider as we, ColorWheel as Te, Input as Ee, Label as De, ResponsiveDialog as Oe, ResponsiveDialogContent as ke, ResponsiveDialogDescription as Ae, ResponsiveDialogHeader as je, ResponsiveDialogTitle as Me, SchemaForm as Ne, Select as Pe, SelectContent as Fe, SelectItem as Ie, SelectTrigger as Le, SelectValue as Re, Slider as ze, Switch as Be, parseColor as Ve } from "@glasshome/ui/solid";
10
+ import { Badge as Se, Button as Ce, Carousel as we, CarouselContent as Te, CarouselDots as Ee, CarouselItem as De, CarouselNext as Oe, CarouselPrevious as ke, ColorSlider as Ae, ColorWheel as je, Input as Me, Label as Ne, ResponsiveDialog as Pe, ResponsiveDialogContent as Fe, ResponsiveDialogDescription as Ie, ResponsiveDialogHeader as Le, ResponsiveDialogTitle as Re, SchemaForm as ze, Select as Be, SelectContent as Ve, SelectItem as He, SelectTrigger as Ue, SelectValue as We, Slider as Ge, Switch as Ke, imageUrl as qe, mediaUrl as Je, parseColor as Ye } from "@glasshome/ui/solid";
11
11
  //#region src/framework/to-form-schema.ts
12
- function He(e) {
12
+ function Xe(e) {
13
13
  return o.toJSONSchema(e, { override: (e) => {
14
14
  let t = o.globalRegistry.get(e.zodSchema);
15
15
  return t && typeof t == "object" && Object.keys(t).length > 0 ? {
@@ -18,7 +18,7 @@ function He(e) {
18
18
  } : e.jsonSchema;
19
19
  } });
20
20
  }
21
- function Ue(e) {
21
+ function Ze(e) {
22
22
  try {
23
23
  return e.parse({});
24
24
  } catch {
@@ -27,30 +27,30 @@ function Ue(e) {
27
27
  }
28
28
  //#endregion
29
29
  //#region src/define-widget.ts
30
- function We(e) {
31
- return e.configSchema && (e.manifest.schema || (e.manifest.schema = He(e.configSchema)), e.manifest.defaultConfig || (e.manifest.defaultConfig = Ue(e.configSchema))), e;
30
+ function Qe(e) {
31
+ return e.configSchema && (e.manifest.schema || (e.manifest.schema = Xe(e.configSchema)), e.manifest.defaultConfig || (e.manifest.defaultConfig = Ze(e.configSchema))), e;
32
32
  }
33
33
  //#endregion
34
34
  //#region src/framework/hooks/use-widget-context.ts
35
35
  var L = pe();
36
- function Ge() {
36
+ function $e() {
37
37
  let e = O(L);
38
38
  if (!e) throw Error("useWidgetContext must be used within a Widget component");
39
39
  return e;
40
40
  }
41
41
  //#endregion
42
42
  //#region src/framework/hooks/use-service.ts
43
- function Ke(e) {
43
+ function et(e) {
44
44
  let t = Array.isArray(e) ? e[0] : e, n = t?.split(".")[0];
45
45
  if (!n) throw Error(`Invalid entity ID: ${String(t)}`);
46
46
  return n;
47
47
  }
48
48
  function R(e, t) {
49
49
  return async (n, r = {}) => {
50
- await e(Ke(n), t, r, { entity_id: n });
50
+ await e(et(n), t, r, { entity_id: n });
51
51
  };
52
52
  }
53
- function qe() {
53
+ function tt() {
54
54
  let e = O(L)?.callService;
55
55
  return e ? {
56
56
  callService: e,
@@ -59,15 +59,15 @@ function qe() {
59
59
  toggle: R(e, "toggle")
60
60
  } : S();
61
61
  }
62
- function Je() {
62
+ function nt() {
63
63
  let e = O(L)?.callService;
64
64
  return e ? R(e, "turn_on") : de();
65
65
  }
66
- function Ye() {
66
+ function rt() {
67
67
  let e = O(L)?.callService;
68
68
  return e ? R(e, "turn_off") : ue();
69
69
  }
70
- function Xe() {
70
+ function it() {
71
71
  let e = O(L)?.callService;
72
72
  return e ? R(e, "toggle") : le();
73
73
  }
@@ -78,41 +78,41 @@ var z = {
78
78
  CONTENT: 10,
79
79
  OVERLAY: 20,
80
80
  ACTIONS: 30
81
- }, Ze = pe();
82
- function Qe() {
83
- let e = O(Ze);
81
+ }, at = pe();
82
+ function ot() {
83
+ let e = O(at);
84
84
  if (!e) throw Error("useWidgetDimensions must be called inside <Widget>: move the call into a component rendered within <Widget> (the top-level widget scope only sees the host stub).");
85
85
  return e;
86
86
  }
87
87
  //#endregion
88
88
  //#region src/framework/theming/tokens.css?raw
89
- var $e = "/* Authoritative SDK CSS contract. Injected once on first Widget mount\n * via framework/theming/tokens.ts.\n *\n * All widget-internal visual scale is driven from CSS custom properties +\n * container queries on the `.glasshome-widget` shell (`container-type: size`).\n * No JS classifier, no size tier enum.\n */\n\n:root {\n --tone-success: oklch(0.70 0.18 145);\n --tone-warning: oklch(0.80 0.17 75);\n --tone-danger: oklch(0.64 0.22 27);\n --tone-info: oklch(0.66 0.20 245);\n --tone-neutral: oklch(0.65 0.02 250);\n --tone-accent: oklch(0.74 0.18 60);\n\n --widget-grad-strength: 1;\n --widget-glow-default: 0.4;\n --widget-border-highlight: oklch(0.98 0 0 / 0.4);\n}\n\n.dark {\n --tone-success: oklch(0.74 0.18 145);\n --tone-warning: oklch(0.82 0.17 75);\n --tone-danger: oklch(0.68 0.22 27);\n --tone-info: oklch(0.70 0.20 245);\n --tone-neutral: oklch(0.69 0.02 250);\n --tone-accent: oklch(0.78 0.18 60);\n\n --widget-grad-strength: 1.1;\n --widget-glow-default: 0.5;\n --widget-border-highlight: oklch(1 0 0 / 0.08);\n}\n\n@property --widget-color {\n syntax: \"<color>\";\n inherits: true;\n initial-value: oklch(0.65 0.02 250);\n}\n\n/* === Widget shell ===\n * Fluid scale tokens — tied to the shell's own container box (cqb=height, cqi=width).\n * Icon/pad/gap track HEIGHT (cqb) not the shortest side: two widgets of equal\n * height match regardless of width (a 2×2 and a 4×2 get the same icon). cqmin\n * starved portrait tiles by pinning the icon to the narrow width. Tune\n * multipliers / clamps to adjust density. */\n.glasshome-widget {\n --widget-color: var(--tone-neutral);\n --widget-glow-strength: var(--widget-glow-default);\n\n --widget-icon-box: clamp(44px, 25cqb, 58px);\n --widget-icon-glyph: clamp(24px, 14cqb, 33px);\n --widget-pad: clamp(8px, 3.5cqb, 22px);\n --widget-gap: clamp(6px, 2cqb, 14px);\n --widget-title-size: clamp(12px, 2cqi, 18px);\n --widget-subtitle: clamp(12px, 2.5cqi, 20px);\n --widget-status-size: clamp(14px, 5cqi, 36px);\n --widget-value-size: clamp(18px, 7cqi, 48px);\n --widget-badge-size: clamp(11px, 1.6cqi, 14px);\n}\n\n/* Shell material. Two channels, both host/variant-driven:\n * - `--widget-backdrop`: the live backdrop filter (the shared glass recipe is\n * blur + saturate, matching ui's CARD_BLUR). Default none — a variant opts\n * in (classic-glass), and a performant-blur host disables it via override\n * sheet when it paints a precomputed frost instead.\n * - `--glass-frost`: one full background layer (image + position / size +\n * repeat) composited at the BOTTOM, under the accent gradient — the same\n * frost slot ui's `.glass` formula ends its background list with. Unset →\n * none. A performant-blur host sets it per shell with the viewport-aligned\n * slice of its pre-blurred bitmap. */\n.glasshome-widget {\n background:\n var(--widget-gradient,\n linear-gradient(135deg,\n color-mix(in oklch, var(--widget-color) calc(22% * var(--widget-grad-strength)), transparent),\n color-mix(in oklch, var(--widget-color-to, var(--widget-color)) calc(11% * var(--widget-grad-strength)), transparent)\n )\n ),\n var(--glass-frost, none);\n backdrop-filter: var(--widget-backdrop, none);\n -webkit-backdrop-filter: var(--widget-backdrop, none);\n box-shadow: inset 0 1px 0 var(--widget-border-highlight);\n}\n\n/* === Slot: content layout === */\n/* Default: column. Flip to row only on wide-and-short widgets (matches the\n * old contentLayout heuristic: aspect > 1 AND height < 150px). */\n.glasshome-widget-content {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: var(--widget-pad);\n gap: var(--widget-gap);\n overflow: hidden;\n}\n@container widget (min-aspect-ratio: 1) and (max-height: 149px) {\n .glasshome-widget-content {\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n }\n}\n\n/* === Compact 1×1 ===\n * Small in BOTH axes → stack the tile: icon on top, label + status centered\n * under it. Icon stays moderate (not a hero) so the text keeps room. Wide\n * tiles (2×1) fail the width test and keep the row layout above. Placed after\n * the row-flip so it wins. */\n@container widget (max-width: 189px) and (max-height: 189px) {\n .glasshome-widget-content {\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n gap: clamp(4px, 2.5cqmin, 8px);\n }\n .glasshome-widget-content > * { align-items: center; text-align: center; }\n .glasshome-widget-icon {\n --widget-icon-box: clamp(36px, 30cqmin, 56px);\n --widget-icon-glyph: clamp(20px, 17cqmin, 32px);\n }\n .glasshome-widget-title { font-size: clamp(11px, 6cqmin, 14px); max-width: 100%; }\n .glasshome-widget-status,\n .glasshome-widget-value { font-size: clamp(13px, 7cqmin, 17px); }\n .glasshome-widget-content [class*=\"ml-auto\"] { margin-left: 0 !important; }\n}\n.glasshome-widget-content [class*=\"ml-auto\"] {\n position: relative;\n z-index: 30;\n}\n\n/* === Slot: icon === */\n.glasshome-widget-icon {\n width: var(--widget-icon-box);\n height: var(--widget-icon-box);\n border-radius: var(--radius-sm, 12px);\n background: var(--widget-icon-color, var(--widget-color));\n box-shadow: 0 0 calc(var(--widget-glow-strength) * 30px)\n color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 50%, transparent);\n color: oklch(from var(--widget-icon-color, var(--widget-color)) calc(0.52 + sign(0.5 - l) * 0.43) calc(c * 0.2) h);\n}\n.glasshome-widget-icon-glyph {\n font-size: var(--widget-icon-glyph);\n line-height: 1;\n}\n.glasshome-widget-icon-stack {\n position: absolute;\n width: 102%;\n height: 102%;\n border-radius: var(--radius-sm, 12px);\n}\n.glasshome-widget-icon-stack-2 { bottom: -14%; right: -10%; opacity: 0.45; z-index: -2; }\n.glasshome-widget-icon-stack-3 { bottom: -28%; right: -20%; opacity: 0.20; z-index: -3; }\n\n/* === Slot: text === */\n.glasshome-widget-title {\n font-size: var(--widget-title-size);\n line-height: 1.2;\n color: color-mix(in oklch, var(--color-foreground, currentColor) 60%, transparent);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.glasshome-widget-subtitle {\n font-size: var(--widget-subtitle);\n color: color-mix(in oklch, var(--color-foreground, currentColor) 60%, transparent);\n}\n.glasshome-widget-status {\n font-size: var(--widget-status-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.1;\n}\n.glasshome-widget-value {\n font-size: var(--widget-value-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.05;\n}\n.glasshome-widget-badge {\n font-size: var(--widget-badge-size);\n font-weight: 500;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--color-foreground, currentColor) 20%, transparent);\n color: var(--color-foreground, currentColor);\n}\n\n.glasshome-widget-loading {\n background: color-mix(in oklch, var(--widget-color) 20%, transparent);\n}\n\n/* === Slider fill ===\n * Value flows in via --widget-fill-value (0-100). Vertical orientation auto-\n * detected via container query. */\n.glasshome-widget-slider-fill {\n --widget-fill-value: 0;\n background: color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 30%, transparent);\n box-shadow: 0 0 calc(var(--widget-glow-strength) * 40px)\n color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 40%, transparent);\n clip-path: inset(0 calc((100 - var(--widget-fill-value)) * 1%) 0 0);\n}\n@container widget (max-aspect-ratio: 1) {\n .glasshome-widget-slider-fill {\n clip-path: inset(calc((100 - var(--widget-fill-value)) * 1%) 0 0 0);\n }\n}\n", et = !1, B, tt = /* @__PURE__ */ new WeakSet();
90
- function nt() {
91
- return B || (B = new CSSStyleSheet(), B.replaceSync($e.replace(/:root\b/g, ":host").replace(/^\.dark\b/gm, ":host(.dark)"))), B;
89
+ var st = "/* Authoritative SDK CSS contract. Injected once on first Widget mount\n * via framework/theming/tokens.ts.\n *\n * All widget-internal visual scale is driven from CSS custom properties +\n * container queries on the `.glasshome-widget` shell (`container-type: size`).\n * No JS classifier, no size tier enum.\n */\n\n:root {\n --tone-success: oklch(0.70 0.18 145);\n --tone-warning: oklch(0.80 0.17 75);\n --tone-danger: oklch(0.64 0.22 27);\n --tone-info: oklch(0.66 0.20 245);\n --tone-neutral: oklch(0.65 0.02 250);\n --tone-accent: oklch(0.74 0.18 60);\n\n --widget-grad-strength: 1;\n --widget-glow-default: 0.4;\n --widget-border-highlight: oklch(0.98 0 0 / 0.4);\n}\n\n.dark {\n --tone-success: oklch(0.74 0.18 145);\n --tone-warning: oklch(0.82 0.17 75);\n --tone-danger: oklch(0.68 0.22 27);\n --tone-info: oklch(0.70 0.20 245);\n --tone-neutral: oklch(0.69 0.02 250);\n --tone-accent: oklch(0.78 0.18 60);\n\n --widget-grad-strength: 1.1;\n --widget-glow-default: 0.5;\n --widget-border-highlight: oklch(1 0 0 / 0.08);\n}\n\n@property --widget-color {\n syntax: \"<color>\";\n inherits: true;\n initial-value: oklch(0.65 0.02 250);\n}\n\n/* === Widget shell ===\n * Fluid scale tokens — tied to the shell's own container box (cqb=height, cqi=width).\n * Icon/pad/gap track HEIGHT (cqb) not the shortest side: two widgets of equal\n * height match regardless of width (a 2×2 and a 4×2 get the same icon). cqmin\n * starved portrait tiles by pinning the icon to the narrow width. Tune\n * multipliers / clamps to adjust density. */\n.glasshome-widget {\n --widget-color: var(--tone-neutral);\n --widget-glow-strength: var(--widget-glow-default);\n\n --widget-icon-box: clamp(44px, 25cqb, 58px);\n --widget-icon-glyph: clamp(24px, 14cqb, 33px);\n --widget-pad: clamp(8px, 3.5cqb, 22px);\n --widget-gap: clamp(6px, 2cqb, 14px);\n --widget-title-size: clamp(12px, 2cqi, 18px);\n --widget-subtitle: clamp(12px, 2.5cqi, 20px);\n --widget-status-size: clamp(14px, 5cqi, 36px);\n --widget-value-size: clamp(18px, 7cqi, 48px);\n --widget-badge-size: clamp(11px, 1.6cqi, 14px);\n}\n\n/* Shell material. Two channels, both host/variant-driven:\n * - `--widget-backdrop`: the live backdrop filter (the shared glass recipe is\n * blur + saturate, matching ui's CARD_BLUR). Default none — a variant opts\n * in (classic-glass), and a performant-blur host disables it via override\n * sheet when it paints a precomputed frost instead.\n * - `--glass-frost`: one full background layer (image + position / size +\n * repeat) composited at the BOTTOM, under the accent gradient — the same\n * frost slot ui's `.glass` formula ends its background list with. Unset →\n * none. A performant-blur host sets it per shell with the viewport-aligned\n * slice of its pre-blurred bitmap. */\n.glasshome-widget {\n background:\n var(--widget-gradient,\n linear-gradient(135deg,\n color-mix(in oklch, var(--widget-color) calc(22% * var(--widget-grad-strength)), transparent),\n color-mix(in oklch, var(--widget-color-to, var(--widget-color)) calc(11% * var(--widget-grad-strength)), transparent)\n )\n ),\n var(--glass-frost, none);\n backdrop-filter: var(--widget-backdrop, none);\n -webkit-backdrop-filter: var(--widget-backdrop, none);\n box-shadow: inset 0 1px 0 var(--widget-border-highlight);\n}\n\n/* === Slot: content layout === */\n/* Default: column. Flip to row only on wide-and-short widgets (matches the\n * old contentLayout heuristic: aspect > 1 AND height < 150px). */\n.glasshome-widget-content {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: var(--widget-pad);\n gap: var(--widget-gap);\n overflow: hidden;\n}\n@container widget (min-aspect-ratio: 1) and (max-height: 149px) {\n .glasshome-widget-content {\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n }\n}\n\n/* === Compact 1×1 ===\n * Small in BOTH axes → stack the tile: icon on top, label + status centered\n * under it. Icon stays moderate (not a hero) so the text keeps room. Wide\n * tiles (2×1) fail the width test and keep the row layout above. Placed after\n * the row-flip so it wins. */\n@container widget (max-width: 189px) and (max-height: 189px) {\n .glasshome-widget-content {\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n gap: clamp(4px, 2.5cqmin, 8px);\n }\n .glasshome-widget-content > * { align-items: center; text-align: center; }\n .glasshome-widget-icon {\n --widget-icon-box: clamp(36px, 30cqmin, 56px);\n --widget-icon-glyph: clamp(20px, 17cqmin, 32px);\n }\n .glasshome-widget-title { font-size: clamp(11px, 6cqmin, 14px); max-width: 100%; }\n .glasshome-widget-status,\n .glasshome-widget-value { font-size: clamp(13px, 7cqmin, 17px); }\n .glasshome-widget-content [class*=\"ml-auto\"] { margin-left: 0 !important; }\n}\n.glasshome-widget-content [class*=\"ml-auto\"] {\n position: relative;\n z-index: 30;\n}\n\n/* === Slot: icon === */\n.glasshome-widget-icon {\n width: var(--widget-icon-box);\n height: var(--widget-icon-box);\n border-radius: var(--radius-sm, 12px);\n background: var(--widget-icon-color, var(--widget-color));\n box-shadow: 0 0 calc(var(--widget-glow-strength) * 30px)\n color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 50%, transparent);\n color: oklch(from var(--widget-icon-color, var(--widget-color)) calc(0.52 + sign(0.5 - l) * 0.43) calc(c * 0.2) h);\n}\n.glasshome-widget-icon-glyph {\n font-size: var(--widget-icon-glyph);\n line-height: 1;\n}\n.glasshome-widget-icon-stack {\n position: absolute;\n width: 102%;\n height: 102%;\n border-radius: var(--radius-sm, 12px);\n}\n.glasshome-widget-icon-stack-2 { bottom: -14%; right: -10%; opacity: 0.45; z-index: -2; }\n.glasshome-widget-icon-stack-3 { bottom: -28%; right: -20%; opacity: 0.20; z-index: -3; }\n\n/* === Slot: text === */\n.glasshome-widget-title {\n font-size: var(--widget-title-size);\n line-height: 1.2;\n color: color-mix(in oklch, var(--color-foreground, currentColor) 60%, transparent);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.glasshome-widget-subtitle {\n font-size: var(--widget-subtitle);\n color: color-mix(in oklch, var(--color-foreground, currentColor) 60%, transparent);\n}\n.glasshome-widget-status {\n font-size: var(--widget-status-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.1;\n}\n.glasshome-widget-value {\n font-size: var(--widget-value-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.05;\n}\n.glasshome-widget-badge {\n font-size: var(--widget-badge-size);\n font-weight: 500;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--color-foreground, currentColor) 20%, transparent);\n color: var(--color-foreground, currentColor);\n}\n\n.glasshome-widget-loading {\n background: color-mix(in oklch, var(--widget-color) 20%, transparent);\n}\n\n/* === Slider fill ===\n * Value flows in via --widget-fill-value (0-100). Vertical orientation auto-\n * detected via container query. */\n.glasshome-widget-slider-fill {\n --widget-fill-value: 0;\n background: color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 30%, transparent);\n box-shadow: 0 0 calc(var(--widget-glow-strength) * 40px)\n color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 40%, transparent);\n clip-path: inset(0 calc((100 - var(--widget-fill-value)) * 1%) 0 0);\n}\n@container widget (max-aspect-ratio: 1) {\n .glasshome-widget-slider-fill {\n clip-path: inset(calc((100 - var(--widget-fill-value)) * 1%) 0 0 0);\n }\n}\n", ct = !1, B, lt = /* @__PURE__ */ new WeakSet();
90
+ function ut() {
91
+ return B || (B = new CSSStyleSheet(), B.replaceSync(st.replace(/:root\b/g, ":host").replace(/^\.dark\b/gm, ":host(.dark)"))), B;
92
92
  }
93
- function rt(e) {
93
+ function dt(e) {
94
94
  if (typeof ShadowRoot < "u" && e instanceof ShadowRoot) {
95
- if (tt.has(e)) return;
96
- let t = nt();
97
- e.adoptedStyleSheets.includes(t) || (e.adoptedStyleSheets = [...e.adoptedStyleSheets, t]), tt.add(e);
95
+ if (lt.has(e)) return;
96
+ let t = ut();
97
+ e.adoptedStyleSheets.includes(t) || (e.adoptedStyleSheets = [...e.adoptedStyleSheets, t]), lt.add(e);
98
98
  return;
99
99
  }
100
- if (et) return;
100
+ if (ct) return;
101
101
  let t = e ?? (typeof document > "u" ? void 0 : document);
102
102
  if (!t) return;
103
103
  if (t.head.querySelector?.("style[data-glasshome-tokens]")) {
104
- et = !0;
104
+ ct = !0;
105
105
  return;
106
106
  }
107
107
  let n = t.createElement("style");
108
- n.setAttribute("data-glasshome-tokens", ""), n.textContent = $e, t.head.appendChild(n), et = !0;
108
+ n.setAttribute("data-glasshome-tokens", ""), n.textContent = st, t.head.appendChild(n), ct = !0;
109
109
  }
110
110
  //#endregion
111
111
  //#region src/framework/utils/cn.ts
112
112
  function V(...e) {
113
113
  return xe(be(e));
114
114
  }
115
- var it = {
115
+ var ft = {
116
116
  "classic-glass": {
117
117
  id: "classic-glass",
118
118
  name: "Classic Glass",
@@ -194,15 +194,15 @@ var it = {
194
194
  }
195
195
  }
196
196
  };
197
- function at(e) {
198
- return it[e];
197
+ function pt(e) {
198
+ return ft[e];
199
199
  }
200
200
  //#endregion
201
201
  //#region src/framework/backgrounds/WidgetSliderFill.tsx
202
- var ot = /*#__PURE__*/ I("<div>");
203
- function st(e) {
202
+ var mt = /*#__PURE__*/ I("<div>");
203
+ function ht(e) {
204
204
  return (() => {
205
- var t = ot();
205
+ var t = mt();
206
206
  return M((n) => {
207
207
  var r = V("glasshome-widget-slider-fill pointer-events-none absolute inset-0", e.isDragging ? "duration-0" : "transition-all duration-300 ease-out", e.class), i = {
208
208
  "--widget-fill-value": e.value,
@@ -218,33 +218,33 @@ function st(e) {
218
218
  }
219
219
  //#endregion
220
220
  //#region src/framework/components/WidgetContent.tsx
221
- var ct = /*#__PURE__*/ I("<div>");
222
- function lt(e) {
221
+ var gt = /*#__PURE__*/ I("<div>");
222
+ function _t(e) {
223
223
  return (() => {
224
- var t = ct();
224
+ var t = gt();
225
225
  return N(t, () => e.children), M(() => A(t, V("glasshome-widget-content", e.class))), t;
226
226
  })();
227
227
  }
228
228
  //#endregion
229
229
  //#region src/framework/components/WidgetIcon.tsx
230
- var ut = /*#__PURE__*/ I("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-2\">"), dt = /*#__PURE__*/ I("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-3\">"), ft = /*#__PURE__*/ I("<div><div class=\"glasshome-widget-icon-glyph flex items-center justify-center\">");
231
- function pt(e) {
230
+ var vt = /*#__PURE__*/ I("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-2\">"), yt = /*#__PURE__*/ I("<div class=\"glasshome-widget-icon glasshome-widget-icon-stack glasshome-widget-icon-stack-3\">"), bt = /*#__PURE__*/ I("<div><div class=\"glasshome-widget-icon-glyph flex items-center justify-center\">");
231
+ function xt(e) {
232
232
  let t = () => e.entityCount ?? 1;
233
233
  return (() => {
234
- var n = ft(), r = n.firstChild;
234
+ var n = bt(), r = n.firstChild;
235
235
  return N(n, j(C, {
236
236
  get when() {
237
237
  return t() >= 2;
238
238
  },
239
239
  get children() {
240
- return ut();
240
+ return vt();
241
241
  }
242
242
  }), r), N(n, j(C, {
243
243
  get when() {
244
244
  return t() >= 3;
245
245
  },
246
246
  get children() {
247
- return dt();
247
+ return yt();
248
248
  }
249
249
  }), r), N(r, () => e.icon), M((t) => {
250
250
  var r = V("glasshome-widget-icon", "relative flex shrink-0 items-center justify-center pointer-events-none transition-all", e.dimmed && "opacity-50", e.class), i = e.color ? { "--widget-icon-color": e.color } : void 0;
@@ -257,10 +257,10 @@ function pt(e) {
257
257
  }
258
258
  //#endregion
259
259
  //#region src/framework/components/WidgetStatus.tsx
260
- var mt = /*#__PURE__*/ I("<p>");
261
- function ht(e) {
260
+ var St = /*#__PURE__*/ I("<p>");
261
+ function Ct(e) {
262
262
  return (() => {
263
- var t = mt();
263
+ var t = St();
264
264
  return N(t, (() => {
265
265
  var t = P(() => !!e.isUnavailable);
266
266
  return () => t() ? "Unavailable" : e.children;
@@ -275,16 +275,16 @@ function ht(e) {
275
275
  }
276
276
  //#endregion
277
277
  //#region src/framework/components/WidgetTitle.tsx
278
- var gt = /*#__PURE__*/ I("<span class=\"glasshome-widget-badge shrink-0\">"), _t = /*#__PURE__*/ I("<div><h3 class=glasshome-widget-title>");
279
- function vt(e) {
278
+ var wt = /*#__PURE__*/ I("<span class=\"glasshome-widget-badge shrink-0\">"), Tt = /*#__PURE__*/ I("<div><h3 class=glasshome-widget-title>");
279
+ function Et(e) {
280
280
  return (() => {
281
- var t = _t(), n = t.firstChild;
281
+ var t = Tt(), n = t.firstChild;
282
282
  return N(n, () => e.children), N(t, j(C, {
283
283
  get when() {
284
284
  return P(() => e.badge !== void 0)() && e.badge > 0;
285
285
  },
286
286
  get children() {
287
- var t = gt();
287
+ var t = wt();
288
288
  return N(t, () => e.badge), t;
289
289
  }
290
290
  }), null), M((n) => {
@@ -298,7 +298,7 @@ function vt(e) {
298
298
  }
299
299
  //#endregion
300
300
  //#region src/framework/utils/entity-aggregation.ts
301
- function yt(e, t = !1) {
301
+ function Dt(e, t = !1) {
302
302
  if (e.length === 0) return {
303
303
  isGroup: !1,
304
304
  state: "unknown",
@@ -321,7 +321,7 @@ function yt(e, t = !1) {
321
321
  isUnavailable: t.state === "unavailable",
322
322
  brightness: r,
323
323
  brightnessPercent: i,
324
- color: St(t),
324
+ color: At(t),
325
325
  onCount: +!!n,
326
326
  totalCount: 1,
327
327
  description: n ? "On" : "Off"
@@ -333,7 +333,7 @@ function yt(e, t = !1) {
333
333
  if (r++, t.attributes?.brightness !== void 0 && (s += t.attributes.brightness, c++), t.attributes?.rgb_color) l.push(t.attributes.rgb_color);
334
334
  else if (t.attributes?.hs_color) {
335
335
  let [e, n] = t.attributes.hs_color;
336
- l.push(xt(e, n));
336
+ l.push(kt(e, n));
337
337
  }
338
338
  break;
339
339
  case "off":
@@ -350,7 +350,7 @@ function yt(e, t = !1) {
350
350
  if (l.length > 0) {
351
351
  let e = Math.round(l.reduce((e, t) => e + t[0], 0) / l.length), t = Math.round(l.reduce((e, t) => e + t[1], 0) / l.length), n = Math.round(l.reduce((e, t) => e + t[2], 0) / l.length), r = v / 255;
352
352
  y = `rgb(${Math.round(e * r)}, ${Math.round(t * r)}, ${Math.round(n * r)})`;
353
- } else y = St(e[0]);
353
+ } else y = At(e[0]);
354
354
  let b;
355
355
  return b = m ? "All on" : h ? "All off" : r > 0 ? `${r} of ${u} on` : "Off", {
356
356
  isGroup: n,
@@ -365,7 +365,7 @@ function yt(e, t = !1) {
365
365
  description: b
366
366
  };
367
367
  }
368
- function bt(e, t = "mean", n = !0) {
368
+ function Ot(e, t = "mean", n = !0) {
369
369
  if (e.length === 0) return {
370
370
  isGroup: !1,
371
371
  state: "unknown",
@@ -461,7 +461,7 @@ function bt(e, t = "mean", n = !0) {
461
461
  memberValues: a
462
462
  };
463
463
  }
464
- function xt(e, t) {
464
+ function kt(e, t) {
465
465
  let n = t / 100, r = n * (1 - Math.abs(e / 60 % 2 - 1)), i = 1 - n, a = 0, o = 0, s = 0;
466
466
  return e < 60 ? [a, o] = [n, r] : e < 120 ? [a, o] = [r, n] : e < 180 ? [o, s] = [n, r] : e < 240 ? [o, s] = [r, n] : e < 300 ? [a, s] = [r, n] : [a, s] = [n, r], [
467
467
  (a + i) * 255,
@@ -469,7 +469,7 @@ function xt(e, t) {
469
469
  (s + i) * 255
470
470
  ];
471
471
  }
472
- function St(e) {
472
+ function At(e) {
473
473
  if (e.state !== "on") return "rgb(100, 100, 100)";
474
474
  let t = (e.attributes?.brightness ?? 255) / 255;
475
475
  if (e.attributes?.rgb_color) {
@@ -477,7 +477,7 @@ function St(e) {
477
477
  return `rgb(${Math.round(n * t)}, ${Math.round(r * t)}, ${Math.round(i * t)})`;
478
478
  }
479
479
  if (e.attributes?.hs_color) {
480
- let [n, r] = e.attributes.hs_color, [i, a, o] = xt(n, r);
480
+ let [n, r] = e.attributes.hs_color, [i, a, o] = kt(n, r);
481
481
  return `rgb(${Math.round(i * t)}, ${Math.round(a * t)}, ${Math.round(o * t)})`;
482
482
  }
483
483
  if (e.attributes?.color_temp) {
@@ -488,7 +488,7 @@ function St(e) {
488
488
  }
489
489
  //#endregion
490
490
  //#region src/framework/utils/entity-state.ts
491
- function Ct(e) {
491
+ function jt(e) {
492
492
  if (!e) return !1;
493
493
  if ([
494
494
  "on",
@@ -504,15 +504,15 @@ function Ct(e) {
504
504
  }
505
505
  return !1;
506
506
  }
507
- function wt(e, t, n) {
507
+ function Mt(e, t, n) {
508
508
  return e?.attributes ? e.attributes[t] ?? n : n;
509
509
  }
510
- function Tt(e) {
511
- return e.filter(Ct).length;
510
+ function Nt(e) {
511
+ return e.filter(jt).length;
512
512
  }
513
513
  //#endregion
514
514
  //#region src/framework/utils/format-value.ts
515
- function Et(e, t, n) {
515
+ function Pt(e, t, n) {
516
516
  let { decimals: r, scale: i = !0 } = n || {};
517
517
  if (typeof e == "string") return t ? `${e}${t}` : e;
518
518
  if (e == null || Number.isNaN(e)) return t ? `--${t}` : "--";
@@ -523,30 +523,30 @@ function Et(e, t, n) {
523
523
  }
524
524
  //#endregion
525
525
  //#region src/framework/utils/interpret-value.ts
526
- function Dt(e, t) {
526
+ function Ft(e, t) {
527
527
  return e == null || isNaN(e) ? null : t === "°C" ? e < 10 ? "Cold" : e < 18 ? "Cool" : e < 24 ? "Comfortable" : e < 28 ? "Warm" : "Hot" : t === "°F" ? e < 50 ? "Cold" : e < 64 ? "Cool" : e < 75 ? "Comfortable" : e < 82 ? "Warm" : "Hot" : t === "%" ? e < 20 ? "Very Low" : e < 40 ? "Low" : e < 60 ? "Medium" : e < 80 ? "High" : "Very High" : t === "ppm" ? e < 400 ? "Excellent" : e < 600 ? "Good" : e < 1e3 ? "Acceptable" : e < 1500 ? "Mediocre" : "Poor" : t === "lx" ? e < 50 ? "Dark" : e < 200 ? "Dim" : e < 500 ? "Moderate" : e < 1e3 ? "Bright" : "Very Bright" : t === "AQI" ? e <= 50 ? "Good" : e <= 100 ? "Moderate" : e <= 150 ? "Unhealthy for Sensitive" : e <= 200 ? "Unhealthy" : e <= 300 ? "Very Unhealthy" : "Hazardous" : t === "dB" ? e < 30 ? "Very Quiet" : e < 50 ? "Quiet" : e < 70 ? "Moderate" : e < 85 ? "Loud" : "Very Loud" : null;
528
528
  }
529
529
  //#endregion
530
530
  //#region src/framework/components/WidgetValue.tsx
531
- var Ot = /*#__PURE__*/ I("<div class=glasshome-widget-subtitle>"), kt = /*#__PURE__*/ I("<div><div class=glasshome-widget-value>");
532
- function At(e) {
531
+ var It = /*#__PURE__*/ I("<div class=glasshome-widget-subtitle>"), Lt = /*#__PURE__*/ I("<div><div class=glasshome-widget-value>");
532
+ function Rt(e) {
533
533
  return (() => {
534
- var t = kt(), n = t.firstChild;
535
- return N(n, () => Et(e.value, e.unit)), N(t, j(C, {
534
+ var t = Lt(), n = t.firstChild;
535
+ return N(n, () => Pt(e.value, e.unit)), N(t, j(C, {
536
536
  get when() {
537
537
  return P(() => !!e.interpret)() && typeof e.value == "number";
538
538
  },
539
539
  get children() {
540
- var t = Ot();
541
- return N(t, () => Dt(e.value, e.unit)), t;
540
+ var t = It();
541
+ return N(t, () => Ft(e.value, e.unit)), t;
542
542
  }
543
543
  }), null), M(() => A(t, V("flex flex-col", e.class))), t;
544
544
  })();
545
545
  }
546
546
  //#endregion
547
547
  //#region src/framework/core/Widget.tsx
548
- var jt = /*#__PURE__*/ I("<div><div class=\"relative h-full w-full\">"), Mt = /*#__PURE__*/ I("<div class=\"glasshome-widget-loading pointer-events-none absolute inset-0 animate-pulse\">"), Nt = /*#__PURE__*/ I("<div class=\"flex h-full w-full flex-col items-center justify-center gap-2 text-center\">"), Pt = /*#__PURE__*/ I("<div class=\"flex items-center justify-center text-white/30\">"), Ft = /*#__PURE__*/ I("<h3 class=\"font-semibold text-sm text-white/60\">"), It = /*#__PURE__*/ I("<p class=\"text-white/50 text-xs\">");
549
- function Lt(t) {
548
+ var zt = /*#__PURE__*/ I("<div><div class=\"relative h-full w-full\">"), Bt = /*#__PURE__*/ I("<div class=\"glasshome-widget-loading pointer-events-none absolute inset-0 animate-pulse\">"), Vt = /*#__PURE__*/ I("<div class=\"flex h-full w-full flex-col items-center justify-center gap-2 text-center\">"), Ht = /*#__PURE__*/ I("<div class=\"flex items-center justify-center text-white/30\">"), Ut = /*#__PURE__*/ I("<h3 class=\"font-semibold text-sm text-white/60\">"), Wt = /*#__PURE__*/ I("<p class=\"text-white/50 text-xs\">");
549
+ function Gt(t) {
550
550
  let n = O(L), [r, i] = E(), [a, o] = E({
551
551
  width: 0,
552
552
  height: 0
@@ -568,7 +568,7 @@ function Lt(t) {
568
568
  t.observe(e), D(() => t.disconnect());
569
569
  }), he(() => {
570
570
  let e = r()?.getRootNode();
571
- rt(typeof ShadowRoot < "u" && e instanceof ShadowRoot || typeof Document < "u" && e instanceof Document ? e : void 0);
571
+ dt(typeof ShadowRoot < "u" && e instanceof ShadowRoot || typeof Document < "u" && e instanceof Document ? e : void 0);
572
572
  });
573
573
  let s = {
574
574
  updateConfig: n?.updateConfig ?? (() => {}),
@@ -576,7 +576,7 @@ function Lt(t) {
576
576
  callService: n?.callService,
577
577
  dimensions: e(() => a(), "ctx.dimensions")
578
578
  }, c = T(() => {
579
- if (t.variant) return typeof t.variant == "string" ? at(t.variant) : t.variant;
579
+ if (t.variant) return typeof t.variant == "string" ? pt(t.variant) : t.variant;
580
580
  }), l = T(() => ({
581
581
  "container-type": "size",
582
582
  "container-name": "widget",
@@ -601,15 +601,15 @@ function Lt(t) {
601
601
  return j(L.Provider, {
602
602
  value: s,
603
603
  get children() {
604
- return j(Ze.Provider, {
604
+ return j(at.Provider, {
605
605
  value: a,
606
606
  get children() {
607
- var e = jt(), n = e.firstChild;
607
+ var e = zt(), n = e.firstChild;
608
608
  return k(e, "pointercancel", h), k(e, "pointerup", m), k(e, "pointermove", p), k(e, "pointerdown", f), k(e, "pointerenter", d), ye((e) => {
609
609
  i(e), t.gestures?.bindElement(e);
610
610
  }, e), N(n, (() => {
611
611
  var e = P(() => !!t.emptyState);
612
- return () => e() ? j(Rt, {
612
+ return () => e() ? j(Kt, {
613
613
  get icon() {
614
614
  return t.emptyState.icon;
615
615
  },
@@ -623,7 +623,7 @@ function Lt(t) {
623
623
  })()), N(e, (() => {
624
624
  var e = P(() => !!t.loading);
625
625
  return () => e() && (() => {
626
- var e = Mt();
626
+ var e = Bt();
627
627
  return M((t) => F(e, "z-index", z.OVERLAY)), e;
628
628
  })();
629
629
  })(), null), M((r) => {
@@ -639,76 +639,76 @@ function Lt(t) {
639
639
  }
640
640
  });
641
641
  }
642
- function Rt(e) {
642
+ function Kt(e) {
643
643
  return (() => {
644
- var t = Nt();
644
+ var t = Vt();
645
645
  return N(t, (() => {
646
646
  var t = P(() => !!e.icon);
647
647
  return () => t() && (() => {
648
- var t = Pt();
648
+ var t = Ht();
649
649
  return N(t, () => e.icon), t;
650
650
  })();
651
651
  })(), null), N(t, (() => {
652
652
  var t = P(() => !!e.title);
653
653
  return () => t() && (() => {
654
- var t = Ft();
654
+ var t = Ut();
655
655
  return N(t, () => e.title), t;
656
656
  })();
657
657
  })(), null), N(t, (() => {
658
658
  var t = P(() => !!e.message);
659
659
  return () => t() && (() => {
660
- var t = It();
660
+ var t = Wt();
661
661
  return N(t, () => e.message), t;
662
662
  })();
663
663
  })(), null), t;
664
664
  })();
665
665
  }
666
- var H = Lt;
667
- H.Content = lt, H.Icon = pt, H.Title = vt, H.Status = ht, H.Value = At, H.SliderFill = st;
666
+ var H = Gt;
667
+ H.Content = _t, H.Icon = xt, H.Title = Et, H.Status = Ct, H.Value = Rt, H.SliderFill = ht;
668
668
  //#endregion
669
669
  //#region src/framework/dialogs/validate-config.ts
670
- function zt(e) {
670
+ function qt(e) {
671
671
  let t = "";
672
672
  for (let n of e) t += typeof n == "number" ? `[${n}]` : t ? `.${String(n)}` : String(n);
673
673
  return t;
674
674
  }
675
- function Bt(e, t) {
675
+ function Jt(e, t) {
676
676
  let n = e.safeParse(t);
677
677
  return n.success ? null : n.error.issues.map((e) => {
678
- let t = zt(e.path);
678
+ let t = qt(e.path);
679
679
  return t ? `${t}: ${e.message}` : e.message;
680
680
  });
681
681
  }
682
682
  //#endregion
683
683
  //#region src/framework/dialogs/WidgetDialog.tsx
684
- var Vt = /*#__PURE__*/ I("<span class=\"inline-flex size-3.5 shrink-0 items-center\">"), Ht = /*#__PURE__*/ I("<button type=button>"), Ut = /*#__PURE__*/ I("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\">"), Wt = /*#__PURE__*/ I("<div class=\"rounded-lg bg-muted/30 p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No edit options available"), Gt = /*#__PURE__*/ I("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><line x1=4 y1=21 x2=4 y2=14></line><line x1=4 y1=10 x2=4 y2=3></line><line x1=12 y1=21 x2=12 y2=12></line><line x1=12 y1=8 x2=12 y2=3></line><line x1=20 y1=21 x2=20 y2=16></line><line x1=20 y1=12 x2=20 y2=3></line><line x1=1 y1=14 x2=7 y2=14></line><line x1=9 y1=8 x2=15 y2=8></line><line x1=17 y1=16 x2=23 y2=16>"), Kt = /*#__PURE__*/ I("<div class=\"rounded-lg bg-muted/30 p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No additional controls"), qt = /*#__PURE__*/ I("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"m8 2 1.88 1.88\"></path><path d=\"M14.12 3.88 16 2\"></path><path d=\"M9 7.13v-1a3.003 3.003 0 1 1 6 0v1\"></path><path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6\"></path><path d=\"M12 20v-9\"></path><path d=\"M6.53 9C4.6 8.8 3 7.1 3 5\"></path><path d=\"M6 13H2\"></path><path d=\"M3 21c0-2.1 1.7-3.9 3.8-4\"></path><path d=\"M20.97 5c0 2.1-1.6 3.8-3.5 4\"></path><path d=\"M22 13h-4\"></path><path d=\"M17.2 17c2.1.1 3.8 1.9 3.8 4\">"), Jt = /*#__PURE__*/ I("<div class=\"rounded-lg bg-muted/30 p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No debug information available"), Yt = /*#__PURE__*/ I("<div class=\"min-w-0 shrink-0\">"), Xt = /*#__PURE__*/ I("<div class=\"flex items-center gap-2\"><div class=\"flex h-8 items-center rounded-lg border border-border/50 bg-muted/30 p-0.5\">"), Zt = /*#__PURE__*/ I("<div class=\"gh-scroll min-h-0 flex-1 overflow-y-auto px-6\">"), Qt = /*#__PURE__*/ I("<div class=\"flex shrink-0 items-center justify-end gap-2 border-border/50 border-t px-6 pt-3\">"), $t = (e) => He(e);
685
- function en(e) {
684
+ var Yt = /*#__PURE__*/ I("<span class=\"inline-flex size-3.5 shrink-0 items-center\">"), Xt = /*#__PURE__*/ I("<button type=button>"), Zt = /*#__PURE__*/ I("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\">"), Qt = /*#__PURE__*/ I("<div class=\"rounded-lg bg-muted/30 p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No edit options available"), $t = /*#__PURE__*/ I("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><line x1=4 y1=21 x2=4 y2=14></line><line x1=4 y1=10 x2=4 y2=3></line><line x1=12 y1=21 x2=12 y2=12></line><line x1=12 y1=8 x2=12 y2=3></line><line x1=20 y1=21 x2=20 y2=16></line><line x1=20 y1=12 x2=20 y2=3></line><line x1=1 y1=14 x2=7 y2=14></line><line x1=9 y1=8 x2=15 y2=8></line><line x1=17 y1=16 x2=23 y2=16>"), en = /*#__PURE__*/ I("<div class=\"rounded-lg bg-muted/30 p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No additional controls"), tn = /*#__PURE__*/ I("<svg xmlns=http://www.w3.org/2000/svg class=size-3.5 fill=none viewBox=\"0 0 24 24\"stroke=currentColor stroke-width=2><path d=\"m8 2 1.88 1.88\"></path><path d=\"M14.12 3.88 16 2\"></path><path d=\"M9 7.13v-1a3.003 3.003 0 1 1 6 0v1\"></path><path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6\"></path><path d=\"M12 20v-9\"></path><path d=\"M6.53 9C4.6 8.8 3 7.1 3 5\"></path><path d=\"M6 13H2\"></path><path d=\"M3 21c0-2.1 1.7-3.9 3.8-4\"></path><path d=\"M20.97 5c0 2.1-1.6 3.8-3.5 4\"></path><path d=\"M22 13h-4\"></path><path d=\"M17.2 17c2.1.1 3.8 1.9 3.8 4\">"), nn = /*#__PURE__*/ I("<div class=\"rounded-lg bg-muted/30 p-2 text-center md:p-6\"><p class=\"text-muted-foreground text-sm\">No debug information available"), rn = /*#__PURE__*/ I("<div class=\"min-w-0 shrink-0\">"), an = /*#__PURE__*/ I("<div class=\"flex items-center gap-2\"><div class=\"flex h-8 items-center rounded-lg border border-border/50 bg-muted/30 p-0.5\">"), on = /*#__PURE__*/ I("<div class=\"gh-scroll min-h-0 flex-1 overflow-y-auto px-6\">"), sn = /*#__PURE__*/ I("<div class=\"flex shrink-0 items-center justify-end gap-2 border-border/50 border-t px-6 pt-3\">"), cn = (e) => Xe(e);
685
+ function ln(e) {
686
686
  return (() => {
687
- var t = Ht();
687
+ var t = Xt();
688
688
  return t.$$click = () => e.onClick(), N(t, j(C, {
689
689
  get when() {
690
690
  return e.isActive;
691
691
  },
692
692
  get children() {
693
- var t = Vt();
693
+ var t = Yt();
694
694
  return N(t, () => e.icon), t;
695
695
  }
696
696
  }), null), N(t, () => e.label, null), M(() => A(t, V("flex cursor-pointer items-center justify-center rounded-md px-3 py-1.5 text-xs transition-all duration-300 ease-in-out", e.isActive ? "gap-1.5 bg-foreground/10 font-semibold text-foreground shadow-sm" : "gap-0 text-muted-foreground hover:bg-foreground/5 hover:text-foreground"))), t;
697
697
  })();
698
698
  }
699
- function tn(e) {
699
+ function un(e) {
700
700
  let [t] = ge(e, /* @__PURE__ */ "open.onOpenChange.title.onSave.hasUnsavedChanges.onDelete.editContent.controlsContent.debugContent.debugData.tabs.class.maxWidth.defaultTab.activeTab.onActiveTabChange.headerActions.configSchema.config.onConfigSave.ResponsiveDialog.ResponsiveDialogContent.ResponsiveDialogHeader.ResponsiveDialogTitle.ResponsiveDialogDescription.Button.SchemaForm".split(".")), n = () => !!t.configSchema && !!t.config && !!t.onConfigSave && !!t.SchemaForm, [r, i] = E({}), [a, o] = E(null), [s, c] = E([]);
701
701
  w(me(() => t.config, (e) => {
702
702
  e && i({ ...e });
703
703
  })), w(me(() => t.configSchema, (e) => {
704
- e && o($t(e));
704
+ e && o(cn(e));
705
705
  }));
706
706
  let l = () => n() && JSON.stringify(r()) !== JSON.stringify(t.config), u = (e) => {
707
707
  !e && t.config && (i({ ...t.config }), c([])), t.onOpenChange(e);
708
708
  }, d = () => {
709
709
  let e = t.configSchema;
710
710
  if (e) {
711
- let t = Bt(e, r());
711
+ let t = Jt(e, r());
712
712
  if (t) {
713
713
  c(t);
714
714
  return;
@@ -731,10 +731,10 @@ function tn(e) {
731
731
  return e.push({
732
732
  id: "edit",
733
733
  label: "Edit",
734
- icon: Ut(),
734
+ icon: Zt(),
735
735
  content: t.editContent ?? (() => {
736
736
  let e = t.SchemaForm, o = n() ? a() : void 0;
737
- return !o || !e ? Wt() : j(e, {
737
+ return !o || !e ? Qt() : j(e, {
738
738
  schema: o,
739
739
  get data() {
740
740
  return r();
@@ -748,13 +748,13 @@ function tn(e) {
748
748
  }), e.push({
749
749
  id: "controls",
750
750
  label: "Controls",
751
- icon: Gt(),
752
- content: t.controlsContent ?? Kt()
751
+ icon: $t(),
752
+ content: t.controlsContent ?? en()
753
753
  }), e.push({
754
754
  id: "debug",
755
755
  label: "Debug",
756
- icon: qt(),
757
- content: t.debugContent ?? Jt()
756
+ icon: tn(),
757
+ content: t.debugContent ?? nn()
758
758
  }), e;
759
759
  }, v = async () => {
760
760
  if (t.debugData !== void 0) try {
@@ -786,7 +786,7 @@ function tn(e) {
786
786
  class: "flex flex-row items-center justify-between gap-3 px-6",
787
787
  get children() {
788
788
  return [(() => {
789
- var e = Yt();
789
+ var e = rn();
790
790
  return N(e, j(ne, {
791
791
  class: "truncate leading-tight",
792
792
  get children() {
@@ -797,8 +797,8 @@ function tn(e) {
797
797
  children: "Widget configuration dialog"
798
798
  }), null), e;
799
799
  })(), (() => {
800
- var e = Xt(), n = e.firstChild;
801
- return N(n, () => ie().map((e) => j(en, {
800
+ var e = an(), n = e.firstChild;
801
+ return N(n, () => ie().map((e) => j(ln, {
802
802
  get icon() {
803
803
  return e.icon;
804
804
  },
@@ -821,7 +821,7 @@ function tn(e) {
821
821
  }
822
822
  }),
823
823
  (() => {
824
- var e = Zt();
824
+ var e = on();
825
825
  return N(e, ee), e;
826
826
  })(),
827
827
  j(C, {
@@ -829,7 +829,7 @@ function tn(e) {
829
829
  return P(() => m() === "edit")() && (S() || t.onDelete) || m() === "debug" && t.debugData !== void 0;
830
830
  },
831
831
  get children() {
832
- var e = Qt();
832
+ var e = sn();
833
833
  return N(e, j(C, {
834
834
  get when() {
835
835
  return P(() => m() === "edit")() && t.onDelete;
@@ -880,7 +880,7 @@ function tn(e) {
880
880
  _e(["click"]);
881
881
  //#endregion
882
882
  //#region src/framework/hooks/use-intersection-pause.ts
883
- function nn(e) {
883
+ function dn(e) {
884
884
  if (typeof IntersectionObserver > "u") return () => !1;
885
885
  let [t, n] = E(!1), r = new IntersectionObserver((e) => {
886
886
  let t = e[0];
@@ -893,14 +893,14 @@ function nn(e) {
893
893
  }
894
894
  //#endregion
895
895
  //#region src/framework/hooks/use-reduced-motion.ts
896
- function rn() {
896
+ function fn() {
897
897
  if (typeof window > "u" || typeof window.matchMedia != "function") return () => !1;
898
898
  let e = window.matchMedia("(prefers-reduced-motion: reduce)"), [t, n] = E(e.matches), r = (e) => n(e.matches);
899
899
  return e.addEventListener("change", r), D(() => e.removeEventListener("change", r)), t;
900
900
  }
901
901
  //#endregion
902
902
  //#region src/framework/hooks/use-widget-dialog.ts
903
- function an(e = "controls") {
903
+ function pn(e = "controls") {
904
904
  let [t, n] = E(!1), [r, i] = E(e), a = (t) => {
905
905
  i(t ?? e), n(!0);
906
906
  }, o = O(L);
@@ -925,14 +925,14 @@ function an(e = "controls") {
925
925
  }
926
926
  //#endregion
927
927
  //#region src/framework/hooks/use-widget-entity-group.ts
928
- function on(e) {
928
+ function mn(e) {
929
929
  let t = e.minEntities ?? 1, n = T(() => e.entities().length), r = T(() => n() >= t), i = T(() => !r() || !e.calculateGroupData ? null : e.calculateGroupData(e.entities())), a = T(() => {
930
930
  if (!r()) return;
931
931
  let t = e.aggregationMode?.();
932
932
  if (!t || t === "none") return;
933
933
  let n = e.entities();
934
- if (t === "light" || t === "binary-sensor" || t === "switch") return yt(n, e.allEntitiesMode);
935
- if (t === "sensor") return bt(n, e.sensorGroupType?.() ?? "mean", !0);
934
+ if (t === "light" || t === "binary-sensor" || t === "switch") return Dt(n, e.allEntitiesMode);
935
+ if (t === "sensor") return Ot(n, e.sensorGroupType?.() ?? "mean", !0);
936
936
  }), o = T(() => r() ? void 0 : e.emptyStateConfig);
937
937
  return {
938
938
  entities: e.entities,
@@ -946,13 +946,13 @@ function on(e) {
946
946
  //#endregion
947
947
  //#region src/framework/gestures/cursors.ts
948
948
  var U = 32, W = U / 2, G = "white", K = "rgba(0,0,0,0.4)", q = 2, J = 3;
949
- function sn(e) {
949
+ function hn(e) {
950
950
  return `url("data:image/svg+xml,${encodeURIComponent(e)}")`;
951
951
  }
952
952
  function Y(e) {
953
953
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${U}" height="${U}" viewBox="0 0 ${U} ${U}">${e}</svg>`;
954
954
  }
955
- var cn = Y(`
955
+ var gn = Y(`
956
956
  <g transform="translate(6, 2)">
957
957
  <!-- shadow -->
958
958
  <g stroke="${K}" stroke-width="${J}" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -963,13 +963,13 @@ var cn = Y(`
963
963
  <path d="M10 8V3a2 2 0 0 1 4 0v10l4.5-4.5a2 2 0 0 1 2.83 2.83L14 18.5c-2 2-4 3.5-8 3.5-3 0-5-2-5-5v-6a2 2 0 0 1 4 0v2"/>
964
964
  </g>
965
965
  </g>
966
- `), ln = Y(`
966
+ `), _n = Y(`
967
967
  <g>
968
968
  <circle cx="${W}" cy="${W}" r="8" stroke="${K}" stroke-width="${J}" fill="none"/>
969
969
  <circle cx="${W}" cy="${W}" r="8" stroke="${G}" stroke-width="1.5" fill="none"/>
970
970
  <circle cx="${W}" cy="${W}" r="1.5" fill="${G}"/>
971
971
  </g>
972
- `), un = Y(`
972
+ `), vn = Y(`
973
973
  <g>
974
974
  <!-- shadow -->
975
975
  <g stroke="${K}" stroke-width="${J}" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -988,7 +988,7 @@ var cn = Y(`
988
988
  <circle cx="11" cy="${W}" r="1" fill="${G}" opacity="0.6"/>
989
989
  <circle cx="21" cy="${W}" r="1" fill="${G}" opacity="0.6"/>
990
990
  </g>
991
- `), dn = Y(`
991
+ `), yn = Y(`
992
992
  <g>
993
993
  <!-- shadow -->
994
994
  <g stroke="${K}" stroke-width="${J}" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -1007,7 +1007,7 @@ var cn = Y(`
1007
1007
  <circle cx="${W}" cy="11" r="1" fill="${G}" opacity="0.6"/>
1008
1008
  <circle cx="${W}" cy="21" r="1" fill="${G}" opacity="0.6"/>
1009
1009
  </g>
1010
- `), fn = Y(`
1010
+ `), bn = Y(`
1011
1011
  <g>
1012
1012
  <!-- shadow -->
1013
1013
  <g stroke="${K}" stroke-width="${J}" fill="none" stroke-linecap="round" stroke-linejoin="round">
@@ -1033,54 +1033,54 @@ var cn = Y(`
1033
1033
  `);
1034
1034
  function X(e, t, n) {
1035
1035
  return {
1036
- css: `${sn(e)} ${t} ${n}, auto`,
1036
+ css: `${hn(e)} ${t} ${n}, auto`,
1037
1037
  hotspotX: t,
1038
1038
  hotspotY: n
1039
1039
  };
1040
1040
  }
1041
1041
  var Z = {
1042
- tap: X(cn, 12, 4),
1043
- hold: X(ln, 16, 16),
1044
- slideHorizontal: X(un, W, W),
1045
- slideVertical: X(dn, W, W),
1046
- slideAuto: X(fn, W, W)
1042
+ tap: X(gn, 12, 4),
1043
+ hold: X(_n, 16, 16),
1044
+ slideHorizontal: X(vn, W, W),
1045
+ slideVertical: X(yn, W, W),
1046
+ slideAuto: X(bn, W, W)
1047
1047
  };
1048
1048
  //#endregion
1049
1049
  //#region src/framework/gestures/haptics.ts
1050
- function pn() {
1050
+ function xn() {
1051
1051
  if (typeof window > "u") return null;
1052
1052
  let e = window;
1053
1053
  return e.Capacitor?.isNativePlatform?.() ? e.Capacitor.Plugins?.Haptics ?? null : null;
1054
1054
  }
1055
- function mn(e) {
1055
+ function Sn(e) {
1056
1056
  if (!(typeof navigator > "u" || typeof navigator.vibrate != "function")) try {
1057
1057
  navigator.vibrate(e);
1058
1058
  } catch {}
1059
1059
  }
1060
- var hn = {
1060
+ var Cn = {
1061
1061
  tick() {
1062
- let e = pn();
1062
+ let e = xn();
1063
1063
  if (e) {
1064
1064
  e.impact({ style: "Light" }).catch(() => {});
1065
1065
  return;
1066
1066
  }
1067
- mn(8);
1067
+ Sn(8);
1068
1068
  },
1069
1069
  bump() {
1070
- let e = pn();
1070
+ let e = xn();
1071
1071
  if (e) {
1072
1072
  e.impact({ style: "Medium" }).catch(() => {});
1073
1073
  return;
1074
1074
  }
1075
- mn(20);
1075
+ Sn(20);
1076
1076
  },
1077
1077
  pulse() {
1078
- let e = pn();
1078
+ let e = xn();
1079
1079
  if (e) {
1080
1080
  e.impact({ style: "Heavy" }).catch(() => {});
1081
1081
  return;
1082
1082
  }
1083
- mn([
1083
+ Sn([
1084
1084
  0,
1085
1085
  15,
1086
1086
  40,
@@ -1090,7 +1090,7 @@ var hn = {
1090
1090
  };
1091
1091
  //#endregion
1092
1092
  //#region src/framework/gestures/use-widget-gestures.ts
1093
- function gn(e, t) {
1093
+ function wn(e, t) {
1094
1094
  let n = {
1095
1095
  isDown: !1,
1096
1096
  isTouch: !1,
@@ -1133,7 +1133,7 @@ function gn(e, t) {
1133
1133
  if (n.isDown = !0, n.isTouch = t.pointerType === "touch", n.element = t.currentTarget, c(n.element), n.startX = t.clientX, n.startY = t.clientY, n.startTime = Date.now(), n.hasMoved = !1, n.sliding = !1, r.hold) {
1134
1134
  let e = r.hold.delay ?? 300;
1135
1135
  n.holdTimer = setTimeout(() => {
1136
- n.holdTimer = null, !(!n.isDown || n.hasMoved) && (hn.bump(), r.hold?.action(), n.isDown = !1);
1136
+ n.holdTimer = null, !(!n.isDown || n.hasMoved) && (Cn.bump(), r.hold?.action(), n.isDown = !1);
1137
1137
  }, e);
1138
1138
  }
1139
1139
  if (!n.isTouch && r.slide) try {
@@ -1201,7 +1201,7 @@ function gn(e, t) {
1201
1201
  }
1202
1202
  //#endregion
1203
1203
  //#region src/framework/theming/svg-colors.ts
1204
- var _n = {
1204
+ var Tn = {
1205
1205
  solar: "oklch(0.74 0.18 60)",
1206
1206
  grid: "oklch(0.62 0.12 245)",
1207
1207
  battery: "oklch(0.70 0.18 145)",
@@ -1210,21 +1210,21 @@ var _n = {
1210
1210
  positive: "oklch(0.70 0.14 160)",
1211
1211
  negative: "oklch(0.64 0.22 27)"
1212
1212
  };
1213
- function vn(e) {
1213
+ function En(e) {
1214
1214
  return {
1215
1215
  fill: `color-mix(in oklch, ${e} 20%, transparent)`,
1216
1216
  stroke: e,
1217
1217
  solid: e
1218
1218
  };
1219
1219
  }
1220
- var yn = Object.fromEntries(Object.entries(_n).map(([e, t]) => [e, vn(t)])), bn = o.enum([
1220
+ var Dn = Object.fromEntries(Object.entries(Tn).map(([e, t]) => [e, En(t)])), On = o.enum([
1221
1221
  "success",
1222
1222
  "warning",
1223
1223
  "danger",
1224
1224
  "info",
1225
1225
  "neutral",
1226
1226
  "accent"
1227
- ]), xn = {
1227
+ ]), kn = {
1228
1228
  title: e(() => o.string().optional().meta({
1229
1229
  title: "Title",
1230
1230
  description: "Optional display name override"
@@ -1244,45 +1244,45 @@ var yn = Object.fromEntries(Object.entries(_n).map(([e, t]) => [e, vn(t)])), bn
1244
1244
  formType: "area-picker",
1245
1245
  title: "Area"
1246
1246
  }), "widgetFields.areaId")
1247
- }, Sn = 24;
1247
+ }, An = 24;
1248
1248
  function Q(e) {
1249
1249
  let t = {};
1250
1250
  for (let [n, r] of Object.entries(e)) r !== void 0 && (t[n] = r);
1251
1251
  return t;
1252
1252
  }
1253
- function Cn() {
1253
+ function jn() {
1254
1254
  return o.string().optional().meta({
1255
1255
  title: "Title",
1256
1256
  description: "Optional display name override"
1257
1257
  });
1258
1258
  }
1259
- function wn(e) {
1259
+ function Mn(e) {
1260
1260
  return (e.default === void 0 ? o.string().optional() : o.string().default(e.default)).meta(Q({
1261
1261
  title: e.title,
1262
1262
  description: e.description
1263
1263
  }));
1264
1264
  }
1265
- function Tn(e) {
1265
+ function Nn(e) {
1266
1266
  let t = o.number();
1267
1267
  return e.min !== void 0 && (t = t.min(e.min)), e.max !== void 0 && (t = t.max(e.max)), (e.default === void 0 ? t.optional() : t.default(e.default)).meta(Q({
1268
1268
  title: e.title,
1269
1269
  description: e.description
1270
1270
  }));
1271
1271
  }
1272
- function En(e) {
1272
+ function Pn(e) {
1273
1273
  return o.boolean().default(e.default ?? !1).meta(Q({
1274
1274
  title: e.title,
1275
1275
  description: e.description
1276
1276
  }));
1277
1277
  }
1278
- function Dn(e, t) {
1278
+ function Fn(e, t) {
1279
1279
  let n = o.enum(e);
1280
1280
  return (t.default === void 0 ? n.optional() : n.default(t.default)).meta(Q({
1281
1281
  title: t.title,
1282
1282
  description: t.description
1283
1283
  }));
1284
1284
  }
1285
- function On(e, t) {
1285
+ function In(e, t) {
1286
1286
  return o.array(o.string()).default([]).meta(Q({
1287
1287
  domain: e,
1288
1288
  title: t?.title ?? "Entities",
@@ -1290,7 +1290,7 @@ function On(e, t) {
1290
1290
  deviceClass: t?.deviceClass
1291
1291
  }));
1292
1292
  }
1293
- function kn(e, t) {
1293
+ function Ln(e, t) {
1294
1294
  return o.array(o.string()).default([]).meta(Q({
1295
1295
  domain: e,
1296
1296
  title: t?.title ?? "Entity",
@@ -1299,49 +1299,57 @@ function kn(e, t) {
1299
1299
  singleSelect: !0
1300
1300
  }));
1301
1301
  }
1302
- function An(e) {
1302
+ function Rn(e) {
1303
1303
  return o.string().optional().meta({
1304
1304
  formType: "area-picker",
1305
1305
  title: e?.title ?? "Area"
1306
1306
  });
1307
1307
  }
1308
- function jn(e) {
1308
+ function zn(e) {
1309
1309
  let t = o.string().meta({
1310
1310
  formType: "icon-picker",
1311
1311
  title: e?.title ?? "Icon"
1312
1312
  });
1313
1313
  return e?.default === void 0 ? t.optional() : t.default(e.default);
1314
1314
  }
1315
- function Mn(e) {
1315
+ function Bn(e) {
1316
+ let t = o.string().meta(Q({
1317
+ formType: "image-picker",
1318
+ title: e?.title ?? "Image",
1319
+ description: e?.description
1320
+ }));
1321
+ return e?.default === void 0 ? t.optional() : t.default(e.default);
1322
+ }
1323
+ function Vn(e) {
1316
1324
  return o.array(o.string()).default([]).meta(Q({
1317
1325
  title: e.title,
1318
1326
  description: e.description
1319
1327
  }));
1320
1328
  }
1321
- function Nn(e, t) {
1329
+ function Hn(e, t) {
1322
1330
  let n = o.object(e);
1323
- return n.default(Ue(n)).meta({ title: t.title });
1331
+ return n.default(Ze(n)).meta({ title: t.title });
1324
1332
  }
1325
- function Pn(e) {
1333
+ function Un(e) {
1326
1334
  return e.def;
1327
1335
  }
1328
1336
  function $(e) {
1329
1337
  if (o.globalRegistry.get(e)?.formType === "list") return !0;
1330
- let t = Pn(e);
1338
+ let t = Un(e);
1331
1339
  return t.shape ? Object.values(t.shape).some($) : t.options ? t.options.some($) : t.element ? $(t.element) : t.innerType ? $(t.innerType) : !1;
1332
1340
  }
1333
- function Fn(e) {
1334
- let t = e, n = Pn(t).innerType;
1335
- for (; n;) t = n, n = Pn(t).innerType;
1341
+ function Wn(e) {
1342
+ let t = e, n = Un(t).innerType;
1343
+ for (; n;) t = n, n = Un(t).innerType;
1336
1344
  return t;
1337
1345
  }
1338
- function In(e) {
1339
- let t = Pn(Fn(e));
1346
+ function Gn(e) {
1347
+ let t = Un(Wn(e));
1340
1348
  if (t.shape) return new Set(Object.keys(t.shape));
1341
1349
  if (t.options) {
1342
1350
  let e = [];
1343
1351
  for (let n of t.options) {
1344
- let t = In(n);
1352
+ let t = Gn(n);
1345
1353
  if (!t) return null;
1346
1354
  e.push(t);
1347
1355
  }
@@ -1353,7 +1361,7 @@ function In(e) {
1353
1361
  }
1354
1362
  return null;
1355
1363
  }
1356
- function Ln(e, t, n) {
1364
+ function Kn(e, t, n) {
1357
1365
  let r = { [t]: n };
1358
1366
  try {
1359
1367
  return e.parse(r);
@@ -1361,12 +1369,12 @@ function Ln(e, t, n) {
1361
1369
  return r;
1362
1370
  }
1363
1371
  }
1364
- function Rn(e, t) {
1372
+ function qn(e, t) {
1365
1373
  if (!Number.isInteger(t.max) || t.max < 1) throw Error(`field.list: max must be a positive integer, got ${t.max}`);
1366
- if (t.max > Sn) throw Error(`field.list: max ${t.max} exceeds the ceiling of ${Sn}`);
1374
+ if (t.max > An) throw Error(`field.list: max ${t.max} exceeds the ceiling of ${An}`);
1367
1375
  if (t.min !== void 0 && (!Number.isInteger(t.min) || t.min < 0 || t.min > t.max)) throw Error(`field.list: min must be an integer between 0 and max, got ${t.min}`);
1368
1376
  if ($(e)) throw Error("field.list: a list item cannot contain another field.list (depth 1 only)");
1369
- if (t.labelField !== void 0 && !In(e)?.has(t.labelField)) throw Error(`field.list: labelField "${t.labelField}" must name a field present in every item`);
1377
+ if (t.labelField !== void 0 && !Gn(e)?.has(t.labelField)) throw Error(`field.list: labelField "${t.labelField}" must name a field present in every item`);
1370
1378
  let n = o.array(e);
1371
1379
  return t.min !== void 0 && (n = n.min(t.min)), n = n.max(t.max), n.default([]).meta(Q({
1372
1380
  formType: "list",
@@ -1376,7 +1384,7 @@ function Rn(e, t) {
1376
1384
  labelField: t.labelField
1377
1385
  }));
1378
1386
  }
1379
- function zn(e, t, n) {
1387
+ function Jn(e, t, n) {
1380
1388
  let r = Object.keys(t)[0];
1381
1389
  if (r === void 0) throw Error("field.variants: at least one variant is required");
1382
1390
  if (n.shared && e in n.shared) throw Error(`field.variants: shared fields cannot redefine the discriminator "${e}"`);
@@ -1389,7 +1397,7 @@ function zn(e, t, n) {
1389
1397
  ...r,
1390
1398
  [e]: o.literal(t)
1391
1399
  })), a = o.discriminatedUnion(e, i), s = i[0];
1392
- return a.default(s ? Ln(s, e, r) : {}).meta(Q({
1400
+ return a.default(s ? Kn(s, e, r) : {}).meta(Q({
1393
1401
  formType: "variants",
1394
1402
  discriminator: e,
1395
1403
  title: n.title,
@@ -1397,27 +1405,28 @@ function zn(e, t, n) {
1397
1405
  labels: n.labels
1398
1406
  }));
1399
1407
  }
1400
- var Bn = {
1401
- title: Cn,
1402
- text: wn,
1403
- number: Tn,
1404
- toggle: En,
1405
- choice: Dn,
1406
- entities: On,
1407
- entity: kn,
1408
- area: An,
1409
- icon: jn,
1410
- stringList: Mn,
1411
- group: Nn,
1412
- list: Rn,
1413
- variants: zn
1408
+ var Yn = {
1409
+ title: jn,
1410
+ text: Mn,
1411
+ number: Nn,
1412
+ toggle: Pn,
1413
+ choice: Fn,
1414
+ entities: In,
1415
+ entity: Ln,
1416
+ area: Rn,
1417
+ icon: zn,
1418
+ image: Bn,
1419
+ stringList: Vn,
1420
+ group: Hn,
1421
+ list: qn,
1422
+ variants: Jn
1414
1423
  };
1415
- function Vn(e) {
1424
+ function Xn(e) {
1416
1425
  return o.object(e);
1417
1426
  }
1418
1427
  //#endregion
1419
1428
  //#region src/shared/spline.ts
1420
- function Hn(e) {
1429
+ function Zn(e) {
1421
1430
  if (e.length < 2) return "";
1422
1431
  let t = e[0], n = e[1];
1423
1432
  if (!t || !n) return "";
@@ -1444,14 +1453,14 @@ function Hn(e) {
1444
1453
  }
1445
1454
  //#endregion
1446
1455
  //#region src/theme.ts
1447
- function Un() {
1456
+ function Qn() {
1448
1457
  return document.documentElement.classList.contains("dark");
1449
1458
  }
1450
1459
  //#endregion
1451
1460
  //#region src/version.ts
1452
- var Wn = {
1461
+ var $n = {
1453
1462
  name: "@glasshome/widget-sdk",
1454
- version: "1.11.1",
1463
+ version: "1.12.0",
1455
1464
  description: "SDK for building GlassHome dashboard widgets with SolidJS",
1456
1465
  keywords: [
1457
1466
  "glasshome",
@@ -1511,7 +1520,7 @@ var Wn = {
1511
1520
  },
1512
1521
  peerDependencies: {
1513
1522
  "@glasshome/sync-layer": "0.7.2",
1514
- "@glasshome/ui": "1.3.0",
1523
+ "@glasshome/ui": "1.5.0",
1515
1524
  "solid-js": "^1.9.11"
1516
1525
  },
1517
1526
  dependencies: {
@@ -1526,7 +1535,7 @@ var Wn = {
1526
1535
  zod: "^4.1.13"
1527
1536
  },
1528
1537
  devDependencies: {
1529
- "@glasshome/ui": "1.3.0",
1538
+ "@glasshome/ui": "1.5.0",
1530
1539
  "@solidjs/testing-library": "^0.8.10",
1531
1540
  "@types/bun": "latest",
1532
1541
  "@types/node": "^25.2.2",
@@ -1547,4 +1556,4 @@ var Wn = {
1547
1556
  engines: { node: ">=18" }
1548
1557
  }.version;
1549
1558
  //#endregion
1550
- export { Se as Badge, Ce as Button, we as ColorSlider, Te as ColorWheel, Ee as Input, De as Label, Oe as ResponsiveDialog, ke as ResponsiveDialogContent, Ae as ResponsiveDialogDescription, je as ResponsiveDialogHeader, Me as ResponsiveDialogTitle, Wn as SDK_VERSION, Ne as SchemaForm, Pe as Select, Fe as SelectContent, Ie as SelectItem, Le as SelectTrigger, Re as SelectValue, ze as Slider, Be as Switch, bn as ToneSchema, H as Widget, lt as WidgetContent, L as WidgetCtx, tn as WidgetDialog, pt as WidgetIcon, r as WidgetManifestSchema, Ze as WidgetSizeCtx, st as WidgetSliderFill, ht as WidgetStatus, vt as WidgetTitle, At as WidgetValue, g as byDomain, yt as calculateLightGroup, bt as calculateSensorGroup, Tt as countActiveEntities, Vn as defineConfig, We as defineWidget, t as deprecations, Bn as field, n as formatDeprecation, i as formatSchemaError, wt as getEntityAttribute, s as getForecasts, c as getStream, l as getWebRtcClientConfig, u as hassMediaUrl, rt as injectTokens, Un as isDark, Ct as isEntityActive, Hn as monotoneCubicPath, Ve as parseColor, d as sendWebRtcCandidate, f as startWebRtcSession, p as state, yn as svgColors, m as trackEntityHistory, h as untrackEntityHistory, _ as useArea, v as useCalendarEvents, ee as useCamera, y as useConnection, b as useCurrency, te as useEntities, ne as useEntity, re as useEntityHistory, x as useEntityStatistics, ie as useForecast, ae as useHassConfig, nn as useIntersectionPause, oe as useLocale, rn as useReducedMotion, qe as useService, se as useStore, ce as useTemperatureUnit, Xe as useToggle, Ye as useTurnOff, Je as useTurnOn, fe as useUnitSystem, Ge as useWidgetContext, an as useWidgetDialog, Qe as useWidgetDimensions, on as useWidgetEntityGroup, gn as useWidgetGestures, xn as widgetFields, a as z };
1559
+ export { Se as Badge, Ce as Button, we as Carousel, Te as CarouselContent, Ee as CarouselDots, De as CarouselItem, Oe as CarouselNext, ke as CarouselPrevious, Ae as ColorSlider, je as ColorWheel, Me as Input, Ne as Label, Pe as ResponsiveDialog, Fe as ResponsiveDialogContent, Ie as ResponsiveDialogDescription, Le as ResponsiveDialogHeader, Re as ResponsiveDialogTitle, $n as SDK_VERSION, ze as SchemaForm, Be as Select, Ve as SelectContent, He as SelectItem, Ue as SelectTrigger, We as SelectValue, Ge as Slider, Ke as Switch, On as ToneSchema, H as Widget, _t as WidgetContent, L as WidgetCtx, un as WidgetDialog, xt as WidgetIcon, r as WidgetManifestSchema, at as WidgetSizeCtx, ht as WidgetSliderFill, Ct as WidgetStatus, Et as WidgetTitle, Rt as WidgetValue, g as byDomain, Dt as calculateLightGroup, Ot as calculateSensorGroup, Nt as countActiveEntities, Xn as defineConfig, Qe as defineWidget, t as deprecations, Yn as field, n as formatDeprecation, i as formatSchemaError, Mt as getEntityAttribute, s as getForecasts, c as getStream, l as getWebRtcClientConfig, u as hassMediaUrl, qe as imageUrl, dt as injectTokens, Qn as isDark, jt as isEntityActive, Je as mediaUrl, Zn as monotoneCubicPath, Ye as parseColor, d as sendWebRtcCandidate, f as startWebRtcSession, p as state, Dn as svgColors, m as trackEntityHistory, h as untrackEntityHistory, _ as useArea, v as useCalendarEvents, ee as useCamera, y as useConnection, b as useCurrency, te as useEntities, ne as useEntity, re as useEntityHistory, x as useEntityStatistics, ie as useForecast, ae as useHassConfig, dn as useIntersectionPause, oe as useLocale, fn as useReducedMotion, tt as useService, se as useStore, ce as useTemperatureUnit, it as useToggle, rt as useTurnOff, nt as useTurnOn, fe as useUnitSystem, $e as useWidgetContext, pn as useWidgetDialog, ot as useWidgetDimensions, mn as useWidgetEntityGroup, wn as useWidgetGestures, kn as widgetFields, a as z };
package/dist/ui.d.ts CHANGED
@@ -14,4 +14,4 @@
14
14
  * `@glasshome/ui/solid` is a vite external of this package: these re-exports
15
15
  * resolve to the host-provided singleton at runtime, never a bundled copy.
16
16
  */
17
- export { Badge, Button, type Color, ColorSlider, ColorWheel, Input, Label, parseColor, ResponsiveDialog, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogHeader, ResponsiveDialogTitle, SchemaForm, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Switch, } from "@glasshome/ui/solid";
17
+ export { Badge, Button, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type CarouselTransition, type Color, ColorSlider, ColorWheel, imageUrl, Input, Label, mediaUrl, parseColor, ResponsiveDialog, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogHeader, ResponsiveDialogTitle, SchemaForm, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Switch, } from "@glasshome/ui/solid";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-sdk",
3
- "version": "1.11.1",
3
+ "version": "1.12.0",
4
4
  "description": "SDK for building GlassHome dashboard widgets with SolidJS",
5
5
  "keywords": [
6
6
  "glasshome",
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@glasshome/sync-layer": "0.7.2",
63
- "@glasshome/ui": "1.3.0",
63
+ "@glasshome/ui": "1.5.0",
64
64
  "solid-js": "^1.9.11"
65
65
  },
66
66
  "dependencies": {
@@ -75,7 +75,7 @@
75
75
  "zod": "^4.1.13"
76
76
  },
77
77
  "devDependencies": {
78
- "@glasshome/ui": "1.3.0",
78
+ "@glasshome/ui": "1.5.0",
79
79
  "@solidjs/testing-library": "^0.8.10",
80
80
  "@types/bun": "latest",
81
81
  "@types/node": "^25.2.2",