@glasshome/widget-sdk 1.17.0 → 1.18.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.
package/dist/index.js CHANGED
@@ -727,87 +727,30 @@ function ir(e) {
727
727
  let n = t.createElement("style");
728
728
  n.setAttribute("data-glasshome-tokens", ""), n.textContent = $n, t.head.appendChild(n), er = !0;
729
729
  }
730
+ //#endregion
731
+ //#region src/framework/variants/built-in-variants.ts
730
732
  var ar = {
731
- "classic-glass": {
732
- id: "classic-glass",
733
- name: "Classic Glass",
734
- description: "Default glassmorphism design with blur background and gradient",
735
- styles: { cssVars: {
736
- "--widget-padding": "1.5rem",
737
- "--widget-backdrop": "blur(var(--glass-blur, var(--material-blur, 24px))) saturate(1.8)"
738
- } },
739
- layout: {
740
- type: "flex",
741
- direction: "column",
742
- align: "start",
743
- justify: "start",
744
- gap: "0.75rem"
745
- },
746
- interactions: {
747
- hover: !0,
748
- active: !0,
749
- focus: !0,
750
- hoverScale: 1.02,
751
- activeScale: .98
752
- }
753
- },
754
- minimal: {
755
- id: "minimal",
756
- name: "Minimal",
757
- description: "Clean, minimal design with no background effects",
758
- styles: { cssVars: {
759
- "--widget-padding": "1rem",
760
- "--glass-base": "transparent",
761
- "--glass-wash": "0%",
762
- "--glass-light": "0",
763
- "--glass-rim": "0",
764
- "--glass-lift": "0",
765
- "--glass-edge": "transparent"
766
- } },
767
- layout: {
768
- type: "flex",
769
- direction: "column",
770
- align: "start",
771
- justify: "start",
772
- gap: "0.5rem"
773
- },
774
- elements: { visible: {
775
- background: !1,
776
- decorations: !1
777
- } },
778
- interactions: {
779
- hover: !1,
780
- active: !1,
781
- focus: !0
782
- }
783
- },
784
- "compact-horizontal": {
785
- id: "compact-horizontal",
786
- name: "Compact Horizontal",
787
- description: "Horizontal layout for compact widgets",
788
- styles: { cssVars: {
789
- "--widget-padding": "1rem",
790
- "--widget-icon-size": "2.5rem",
791
- "--widget-backdrop": "blur(16px) saturate(1.8)"
792
- } },
793
- layout: {
794
- type: "flex",
795
- direction: "row",
796
- align: "center",
797
- justify: "start",
798
- gap: "1rem"
799
- },
800
- interactions: {
801
- hover: !0,
802
- active: !0,
803
- focus: !0,
804
- hoverScale: 1.02,
805
- activeScale: .98
806
- }
807
- }
733
+ "classic-glass": { cssVars: {
734
+ "--widget-padding": "1.5rem",
735
+ "--widget-backdrop": "blur(var(--glass-blur, var(--material-blur, 24px))) saturate(1.8)"
736
+ } },
737
+ minimal: { cssVars: {
738
+ "--widget-padding": "1rem",
739
+ "--glass-base": "transparent",
740
+ "--glass-wash": "0%",
741
+ "--glass-light": "0",
742
+ "--glass-rim": "0",
743
+ "--glass-lift": "0",
744
+ "--glass-edge": "transparent"
745
+ } },
746
+ "compact-horizontal": { cssVars: {
747
+ "--widget-padding": "1rem",
748
+ "--widget-icon-size": "2.5rem",
749
+ "--widget-backdrop": "blur(16px) saturate(1.8)"
750
+ } }
808
751
  };
809
752
  function or(e) {
810
- return ar[e];
753
+ return Object.hasOwn(ar, e) ? ar[e] : void 0;
811
754
  }
812
755
  //#endregion
813
756
  //#region src/framework/backgrounds/WidgetSliderFill.tsx
@@ -922,7 +865,8 @@ function xr(e = 2e3) {
922
865
  //#endregion
923
866
  //#region src/framework/utils/entity-aggregation.ts
924
867
  function Sr(e, t = !1) {
925
- if (e.length === 0) return {
868
+ let n = e[0];
869
+ if (!n) return {
926
870
  isGroup: !1,
927
871
  state: "unknown",
928
872
  isOn: !1,
@@ -934,84 +878,85 @@ function Sr(e, t = !1) {
934
878
  totalCount: 0,
935
879
  description: "No entities"
936
880
  };
937
- let n = e.length > 1;
938
- if (!n) {
939
- let t = e[0], n = t.state === "on", r = t.attributes?.brightness || 0, i = Math.round(r / 255 * 100);
881
+ let r = e.length > 1;
882
+ if (!r) {
883
+ let e = n, t = e.state === "on", r = e.attributes?.brightness || 0, i = Math.round(r / 255 * 100);
940
884
  return {
941
885
  isGroup: !1,
942
- state: t.state,
943
- isOn: n,
944
- isUnavailable: t.state === "unavailable",
886
+ state: e.state,
887
+ isOn: t,
888
+ isUnavailable: e.state === "unavailable",
945
889
  brightness: r,
946
890
  brightnessPercent: i,
947
- color: Tr(t),
948
- onCount: +!!n,
891
+ color: Tr(e),
892
+ onCount: +!!t,
949
893
  totalCount: 1,
950
- description: n ? "On" : "Off"
894
+ description: t ? "On" : "Off"
951
895
  };
952
896
  }
953
- let r = 0, i = 0, a = 0, o = 0, s = 0, c = 0, l = [];
897
+ let i = 0, a = 0, o = 0, s = 0, c = 0, l = 0, u = [];
954
898
  for (let t of e) switch (t.state) {
955
899
  case "on":
956
- if (r++, t.attributes?.brightness !== void 0 && (s += t.attributes.brightness, c++), t.attributes?.rgb_color) l.push(t.attributes.rgb_color);
900
+ if (i++, t.attributes?.brightness !== void 0 && (c += t.attributes.brightness, l++), t.attributes?.rgb_color) u.push(t.attributes.rgb_color);
957
901
  else if (t.attributes?.hs_color) {
958
902
  let [e, n] = t.attributes.hs_color;
959
- l.push(wr(e, n));
903
+ u.push(wr(e, n));
960
904
  }
961
905
  break;
962
906
  case "off":
963
- i++;
907
+ a++;
964
908
  break;
965
909
  case "unknown":
966
- a++;
910
+ o++;
967
911
  break;
968
- case "unavailable": o++;
912
+ case "unavailable": s++;
969
913
  }
970
- let u = e.length, d = o === u, f = a + o === u, p = r > 0, m = r === u, h = i === u, g, _;
971
- t ? d ? (g = "unavailable", _ = !1) : a > 0 || o > 0 ? (g = "unknown", _ = !1) : i > 0 ? (g = "off", _ = !1) : (g = "on", _ = !0) : d ? (g = "unavailable", _ = !1) : f ? (g = "unknown", _ = !1) : p ? (g = "on", _ = !0) : (g = "off", _ = !1);
972
- let v = c > 0 ? Math.round(s / c) : 0, y = Math.round(v / 255 * 100), b;
973
- if (l.length > 0) {
974
- 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;
975
- b = `rgb(${Math.round(e * r)}, ${Math.round(t * r)}, ${Math.round(n * r)})`;
976
- } else b = Tr(e[0]);
977
- let x;
978
- return x = m ? "All on" : h ? "All off" : r > 0 ? `${r} of ${u} on` : "Off", {
979
- isGroup: n,
980
- state: g,
981
- isOn: _,
982
- isUnavailable: g === "unavailable",
983
- brightness: v,
984
- brightnessPercent: y,
985
- color: b,
986
- onCount: r,
987
- totalCount: u,
988
- description: x
914
+ let d = e.length, f = s === d, p = o + s === d, m = i > 0, h = i === d, g = a === d, _, v;
915
+ t ? f ? (_ = "unavailable", v = !1) : o > 0 || s > 0 ? (_ = "unknown", v = !1) : a > 0 ? (_ = "off", v = !1) : (_ = "on", v = !0) : f ? (_ = "unavailable", v = !1) : p ? (_ = "unknown", v = !1) : m ? (_ = "on", v = !0) : (_ = "off", v = !1);
916
+ let y = l > 0 ? Math.round(c / l) : 0, b = Math.round(y / 255 * 100), x;
917
+ if (u.length > 0) {
918
+ let e = Math.round(u.reduce((e, t) => e + t[0], 0) / u.length), t = Math.round(u.reduce((e, t) => e + t[1], 0) / u.length), n = Math.round(u.reduce((e, t) => e + t[2], 0) / u.length), r = y / 255;
919
+ x = `rgb(${Math.round(e * r)}, ${Math.round(t * r)}, ${Math.round(n * r)})`;
920
+ } else x = Tr(n);
921
+ let S;
922
+ return S = h ? "All on" : g ? "All off" : i > 0 ? `${i} of ${d} on` : "Off", {
923
+ isGroup: r,
924
+ state: _,
925
+ isOn: v,
926
+ isUnavailable: _ === "unavailable",
927
+ brightness: y,
928
+ brightnessPercent: b,
929
+ color: x,
930
+ onCount: i,
931
+ totalCount: d,
932
+ description: S
989
933
  };
990
934
  }
991
935
  function Cr(e, t = "mean", n = !0) {
992
- if (e.length === 0) return {
936
+ let r = e[0];
937
+ if (!r) return {
993
938
  isGroup: !1,
994
939
  state: "unknown",
995
940
  numericValue: null,
996
941
  isUnavailable: !0,
997
942
  description: "No entities"
998
943
  };
999
- let r = e.length > 1;
1000
- if (!r) {
1001
- let t = e[0], n = Number.parseFloat(t.state), r = t.state;
1002
- return Number.isNaN(n) || (r = Number.isInteger(n) ? n.toString() : n.toFixed(1)), {
944
+ let i = e.length > 1;
945
+ if (!i) {
946
+ let e = r, t = Number.parseFloat(e.state), n = e.state;
947
+ return Number.isNaN(t) || (n = Number.isInteger(t) ? t.toString() : t.toFixed(1)), {
1003
948
  isGroup: !1,
1004
- state: r,
1005
- numericValue: Number.isNaN(n) ? null : n,
1006
- isUnavailable: t.state === "unavailable",
1007
- unit: t.unitOfMeasurement ?? void 0,
1008
- description: r
949
+ state: n,
950
+ numericValue: Number.isNaN(t) ? null : t,
951
+ isUnavailable: e.state === "unavailable",
952
+ unit: e.unitOfMeasurement ?? void 0,
953
+ description: n
1009
954
  };
1010
955
  }
1011
- let i = [], a = [], o = 0, s;
956
+ let a = [], o = [], s = 0, c;
1012
957
  for (let t of e) {
1013
- if (!s && t.unitOfMeasurement && (s = t.unitOfMeasurement), t.state === "unavailable") {
1014
- o++, a.push({
958
+ if (!c && t.unitOfMeasurement && (c = t.unitOfMeasurement), t.state === "unavailable") {
959
+ s++, o.push({
1015
960
  entityId: t.id,
1016
961
  value: "unavailable",
1017
962
  friendly_name: t.friendlyName
@@ -1019,69 +964,69 @@ function Cr(e, t = "mean", n = !0) {
1019
964
  continue;
1020
965
  }
1021
966
  let e = Number.parseFloat(t.state);
1022
- isNaN(e) ? n || a.push({
967
+ isNaN(e) ? n || o.push({
1023
968
  entityId: t.id,
1024
969
  value: t.state,
1025
970
  friendly_name: t.friendlyName
1026
- }) : (i.push(e), a.push({
971
+ }) : (a.push(e), o.push({
1027
972
  entityId: t.id,
1028
973
  value: e,
1029
974
  friendly_name: t.friendlyName
1030
975
  }));
1031
976
  }
1032
- let c = o === e.length, l = i.length === 0;
1033
- if (c || l) return {
1034
- isGroup: r,
1035
- state: c ? "unavailable" : "unknown",
977
+ let l = s === e.length, u = a.at(-1);
978
+ if (l || u === void 0) return {
979
+ isGroup: i,
980
+ state: l ? "unavailable" : "unknown",
1036
981
  numericValue: null,
1037
- isUnavailable: c,
1038
- unit: s,
1039
- description: c ? "Unavailable" : "No numeric values",
1040
- memberValues: a
982
+ isUnavailable: l,
983
+ unit: c,
984
+ description: l ? "Unavailable" : "No numeric values",
985
+ memberValues: o
1041
986
  };
1042
- let u, d;
987
+ let d, f;
1043
988
  switch (t) {
1044
989
  case "min":
1045
- u = Math.min(...i), d = "Minimum";
990
+ d = Math.min(...a), f = "Minimum";
1046
991
  break;
1047
992
  case "max":
1048
- u = Math.max(...i), d = "Maximum";
993
+ d = Math.max(...a), f = "Maximum";
1049
994
  break;
1050
995
  case "mean":
1051
- u = i.reduce((e, t) => e + t, 0) / i.length, d = "Average";
996
+ d = a.reduce((e, t) => e + t, 0) / a.length, f = "Average";
1052
997
  break;
1053
998
  case "median": {
1054
- let e = [...i].sort((e, t) => e - t), t = Math.floor(e.length / 2);
1055
- u = e.length % 2 == 0 ? (e[t - 1] + e[t]) / 2 : e[t], d = "Median";
999
+ let e = [...a].sort((e, t) => e - t), t = Math.floor(e.length / 2), n = e[t] ?? u;
1000
+ d = e.length % 2 == 0 ? ((e[t - 1] ?? n) + n) / 2 : n, f = "Median";
1056
1001
  break;
1057
1002
  }
1058
1003
  case "sum":
1059
- u = i.reduce((e, t) => e + t, 0), d = "Sum";
1004
+ d = a.reduce((e, t) => e + t, 0), f = "Sum";
1060
1005
  break;
1061
1006
  case "last":
1062
- u = i[i.length - 1], d = "Latest";
1007
+ d = u, f = "Latest";
1063
1008
  break;
1064
1009
  case "range":
1065
- u = Math.max(...i) - Math.min(...i), d = "Range";
1010
+ d = Math.max(...a) - Math.min(...a), f = "Range";
1066
1011
  break;
1067
1012
  case "product":
1068
- u = i.reduce((e, t) => e * t, 1), d = "Product";
1013
+ d = a.reduce((e, t) => e * t, 1), f = "Product";
1069
1014
  break;
1070
1015
  case "std_dev": {
1071
- let e = i.reduce((e, t) => e + t, 0) / i.length, t = i.reduce((t, n) => t + (n - e) ** 2, 0) / i.length;
1072
- u = Math.sqrt(t), d = "Std Dev";
1016
+ let e = a.reduce((e, t) => e + t, 0) / a.length, t = a.reduce((t, n) => t + (n - e) ** 2, 0) / a.length;
1017
+ d = Math.sqrt(t), f = "Std Dev";
1073
1018
  break;
1074
1019
  }
1075
- default: u = i.reduce((e, t) => e + t, 0) / i.length, d = "Average";
1020
+ default: d = a.reduce((e, t) => e + t, 0) / a.length, f = "Average";
1076
1021
  }
1077
1022
  return {
1078
- isGroup: r,
1079
- state: Number.isInteger(u) ? u.toString() : u.toFixed(1),
1080
- numericValue: u,
1023
+ isGroup: i,
1024
+ state: Number.isInteger(d) ? d.toString() : d.toFixed(1),
1025
+ numericValue: d,
1081
1026
  isUnavailable: !1,
1082
- unit: s,
1083
- description: `${d} of ${i.length}`,
1084
- memberValues: a
1027
+ unit: c,
1028
+ description: `${f} of ${a.length}`,
1029
+ memberValues: o
1085
1030
  };
1086
1031
  }
1087
1032
  function wr(e, t) {
@@ -1206,13 +1151,13 @@ function Vr(t) {
1206
1151
  };
1207
1152
  n && Object.defineProperty(d, tn, { value: n });
1208
1153
  let f = D(() => {
1209
- if (t.variant) return typeof t.variant == "string" ? or(t.variant) : t.variant;
1154
+ if (t.variant) return typeof t.variant == "string" ? or(t.variant) : t.variant.styles;
1210
1155
  }), p = e(() => t.gradient, "widget.gradient"), m = D(() => ({
1211
1156
  "container-type": "size",
1212
1157
  "container-name": "widget",
1213
1158
  "touch-action": o() && !t.isEditMode ? o()?.touchAction() : void 0,
1214
- ...f()?.styles?.container,
1215
- ...f()?.styles?.cssVars || {},
1159
+ ...f()?.container,
1160
+ ...f()?.cssVars || {},
1216
1161
  ...t.tone ? { "--widget-color": `var(--tone-${t.tone})` } : {},
1217
1162
  ...t.color ? { "--widget-color": t.color } : {},
1218
1163
  ...t.tone && t.tone !== "neutral" || t.color ? { "--glass-tone": "var(--widget-color)" } : {},
@@ -1295,7 +1240,7 @@ function Vr(t) {
1295
1240
  return P((t) => R(e, "z-index", K.OVERLAY)), e;
1296
1241
  })();
1297
1242
  })(), null), P((r) => {
1298
- var i = X("glasshome-widget glass", "relative h-full w-full select-none overflow-hidden rounded-xl", f()?.styles?.class, t.class), a = m(), o = t.confirmed || void 0, s = h() ? 0 : void 0, c = K.CONTENT;
1243
+ var i = X("glasshome-widget glass", "relative h-full w-full select-none overflow-hidden rounded-xl", f()?.class, t.class), a = m(), o = t.confirmed || void 0, s = h() ? 0 : void 0, c = K.CONTENT;
1299
1244
  return i !== r.e && M(e, r.e = i), r.t = z(e, a, r.t), o !== r.a && L(e, "data-confirmed", r.a = o), s !== r.o && L(e, "tabindex", r.o = s), c !== r.i && R(n, "z-index", r.i = c), r;
1300
1245
  }, {
1301
1246
  e: void 0,
@@ -1797,7 +1742,7 @@ function ki(e) {
1797
1742
  let t = e.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ");
1798
1743
  return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
1799
1744
  }
1800
- var Ai = (e) => typeof e != "object" || !e;
1745
+ var Ai = (e) => e === null || typeof e != "object" && typeof e != "function";
1801
1746
  function ji(e) {
1802
1747
  return e == null ? "None" : String(e);
1803
1748
  }
@@ -1884,7 +1829,7 @@ function Ii(e) {
1884
1829
  })();
1885
1830
  }
1886
1831
  function Li(e) {
1887
- let t = D(() => Object.entries(e.record)), n = D(() => t().filter(([, e]) => Ai(e))), r = D(() => t().filter(([, e]) => !Ai(e)));
1832
+ let t = D(() => Object.entries(e.record)), n = D(() => t().flatMap(([e, t]) => Ai(t) ? [[e, t]] : [])), r = D(() => t().filter(([, e]) => !Ai(e)));
1888
1833
  return N(w, {
1889
1834
  get when() {
1890
1835
  return t().length > 0;
@@ -2829,7 +2774,7 @@ function Qa() {
2829
2774
  //#region src/version.ts
2830
2775
  var $a = {
2831
2776
  name: "@glasshome/widget-sdk",
2832
- version: "1.17.0",
2777
+ version: "1.18.0",
2833
2778
  description: "SDK for building GlassHome dashboard widgets with SolidJS",
2834
2779
  keywords: [
2835
2780
  "glasshome",
@@ -2885,16 +2830,16 @@ var $a = {
2885
2830
  test: "bun test src && vitest run",
2886
2831
  "test:dom": "vitest run",
2887
2832
  "test:dom:watch": "vitest",
2888
- "typecheck:test": "tsc --noEmit -p tsconfig.test.json"
2833
+ "typecheck:test": "tsc --noEmit -p tsconfig.test.json",
2834
+ "check:dead": "fallow dead-code --fail-on-issues"
2889
2835
  },
2890
2836
  peerDependencies: {
2891
- "@glasshome/sync-layer": "0.9.0",
2892
- "@glasshome/ui": "1.20.0",
2837
+ "@glasshome/sync-layer": "0.9.1",
2838
+ "@glasshome/ui": "1.21.1",
2893
2839
  "solid-js": "^1.9.11"
2894
2840
  },
2895
2841
  dependencies: {
2896
2842
  "@glasshome/widget-contract": "0.3.0",
2897
- "@modular-forms/solid": "^0.25.1",
2898
2843
  "@tailwindcss/vite": "^4.1.13",
2899
2844
  clsx: "^2.1.1",
2900
2845
  "happy-dom": "^20.0.0",
@@ -2904,10 +2849,11 @@ var $a = {
2904
2849
  zod: "^4.1.13"
2905
2850
  },
2906
2851
  devDependencies: {
2907
- "@glasshome/ui": "1.20.0",
2852
+ "@glasshome/ui": "1.21.1",
2908
2853
  "@solidjs/testing-library": "^0.8.10",
2909
2854
  "@types/bun": "^1.4.0",
2910
2855
  "@types/node": "^25.2.2",
2856
+ fallow: "3.17.0",
2911
2857
  typescript: "^7.0.2",
2912
2858
  vite: "^8.1.0",
2913
2859
  "vite-plugin-solid": "^2.11.12",
@@ -67,6 +67,7 @@ export declare function createUiImportTracker(warned?: Set<string>): {
67
67
  /** Offending files this run has not reported yet; marks them reported. */
68
68
  take(): string[];
69
69
  };
70
+ export declare function dropSelfReferencingVars(css: string): string;
70
71
  /**
71
72
  * Widgets render inside a closed shadow root in the host, which cuts them off
72
73
  * from the host document stylesheet. Every widget bundle must therefore carry