@glasshome/widget-sdk 0.4.0 → 0.4.2

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.
@@ -22,11 +22,8 @@
22
22
  import { type JSX } from "solid-js";
23
23
  import type { WidgetSliderFill as WidgetSliderFillType } from "../backgrounds/WidgetSliderFill";
24
24
  import type { WidgetContent as WidgetContentType } from "../components/WidgetContent";
25
- import type { WidgetEmptyState as WidgetEmptyStateType } from "../components/WidgetEmptyState";
26
25
  import type { WidgetIcon as WidgetIconType } from "../components/WidgetIcon";
27
- import type { WidgetMetrics as WidgetMetricsType } from "../components/WidgetMetrics";
28
26
  import type { WidgetStatus as WidgetStatusType } from "../components/WidgetStatus";
29
- import type { WidgetSubtitle as WidgetSubtitleType } from "../components/WidgetSubtitle";
30
27
  import type { WidgetTitle as WidgetTitleType } from "../components/WidgetTitle";
31
28
  import type { WidgetValue as WidgetValueType } from "../components/WidgetValue";
32
29
  import type { GestureHandlers } from "../gestures/use-widget-gestures";
@@ -89,11 +86,8 @@ interface WidgetComponent {
89
86
  Content: typeof WidgetContentType;
90
87
  Icon: typeof WidgetIconType;
91
88
  Title: typeof WidgetTitleType;
92
- Subtitle: typeof WidgetSubtitleType;
93
89
  Status: typeof WidgetStatusType;
94
90
  Value: typeof WidgetValueType;
95
- Metrics: typeof WidgetMetricsType;
96
- EmptyState: typeof WidgetEmptyStateType;
97
91
  SliderFill: typeof WidgetSliderFillType;
98
92
  }
99
93
  export declare const Widget: WidgetComponent;
@@ -1,14 +1,8 @@
1
1
  /**
2
2
  * Framework Hooks - Barrel Export
3
3
  *
4
- * All hooks for widget development: context, responsive, dialog, form,
5
- * config, entity, entity group, debug data, and gestures.
4
+ * Hooks for widget development: context, dialog, entity group.
6
5
  */
7
- export { type UseDebugDataOptions, useDebugData } from "./use-debug-data";
8
- export { type UseWidgetConfigOptions, type UseWidgetConfigReturn, useWidgetConfig, } from "./use-widget-config";
9
- export { type BridgeableWidgetContext, type BridgeFns, type ReactiveWidgetContext, useWidgetContext, warnIfStub, WidgetCtx, } from "./use-widget-context";
6
+ export { type BridgeableWidgetContext, type BridgeFns, type ReactiveWidgetContext, useWidgetContext, WidgetCtx, } from "./use-widget-context";
10
7
  export { useWidgetDialog, type WidgetDialogReturn } from "./use-widget-dialog";
11
- export { type UseWidgetEntityOptions, type UseWidgetEntityResult, useWidgetEntity, } from "./use-widget-entity";
12
8
  export { type AggregationPreset, type UseWidgetEntityGroupOptions, type UseWidgetEntityGroupResult, useWidgetEntityGroup, } from "./use-widget-entity-group";
13
- export { type UseWidgetFormOptions, type UseWidgetFormReturn, useWidgetForm, } from "./use-widget-form";
14
- export { useWidgetResponsive, type WidgetResponsiveUtils } from "./use-widget-responsive";
@@ -57,11 +57,6 @@ export interface BridgeableWidgetContext extends ReactiveWidgetContext {
57
57
  /** Setter functions called by Widget.tsx createEffect to push real values */
58
58
  _bridge: BridgeFns;
59
59
  }
60
- /**
61
- * Emit a one-time dev-mode console.warn when stub context values are read
62
- * before Widget has mounted and bridged real measured values.
63
- */
64
- export declare function warnIfStub(isStub: () => boolean): void;
65
60
  /**
66
61
  * Widget context
67
62
  * Uses reactive accessor pattern for SolidJS
@@ -10,8 +10,6 @@
10
10
  * Widget,
11
11
  * useWidgetGestures,
12
12
  * useWidgetDialog,
13
- * spacing,
14
- * cn,
15
13
  * } from "@glasshome/widget-sdk";
16
14
  *
17
15
  * export function MyWidget(props) {
@@ -33,25 +31,15 @@
33
31
  */
34
32
  export { Widget } from "./core/Widget";
35
33
  export { WidgetContent } from "./components/WidgetContent";
36
- export { WidgetEmptyState } from "./components/WidgetEmptyState";
37
34
  export { WidgetIcon } from "./components/WidgetIcon";
38
- export { WidgetMetrics } from "./components/WidgetMetrics";
39
35
  export { WidgetStatus } from "./components/WidgetStatus";
40
- export { WidgetSubtitle } from "./components/WidgetSubtitle";
41
36
  export { WidgetTitle } from "./components/WidgetTitle";
42
37
  export { WidgetValue } from "./components/WidgetValue";
43
- export { Glow } from "./backgrounds/Glow";
44
38
  export { WidgetSliderFill } from "./backgrounds/WidgetSliderFill";
45
- export { WidgetStack } from "./layout/WidgetStack";
46
39
  export { WidgetDialog, type WidgetDialogProps, type WidgetDialogTab } from "./dialogs";
47
- export { type AggregationPreset, type BridgeableWidgetContext, type BridgeFns, type ReactiveWidgetContext, type UseDebugDataOptions, type UseWidgetConfigOptions, type UseWidgetConfigReturn, type UseWidgetEntityGroupOptions, type UseWidgetEntityGroupResult, type UseWidgetEntityOptions, type UseWidgetEntityResult, type UseWidgetFormOptions, type UseWidgetFormReturn, useDebugData, useWidgetConfig, useWidgetContext, useWidgetDialog, useWidgetEntity, useWidgetEntityGroup, useWidgetForm, useWidgetResponsive, warnIfStub, WidgetCtx, type WidgetDialogReturn, type WidgetResponsiveUtils, } from "./hooks";
40
+ export { type AggregationPreset, type BridgeableWidgetContext, type BridgeFns, type ReactiveWidgetContext, type UseWidgetEntityGroupOptions, type UseWidgetEntityGroupResult, useWidgetContext, useWidgetDialog, useWidgetEntityGroup, WidgetCtx, type WidgetDialogReturn, } from "./hooks";
48
41
  export { type GestureHandlers, useWidgetGestures } from "./gestures/use-widget-gestures";
49
- export { getSpacingClass, spacing } from "./design-system/spacing";
50
- export { typography } from "./design-system/typography";
51
- export { WIDGET_Z, type WidgetZIndex } from "./design-system/z-index";
52
- export { GRADIENT_NAMES, GRADIENT_PRESET_KEYS, GRADIENT_PRESETS, type GradientPreset, getGradient, getGradientFromString, gradientColorPresets, injectTokens, stateColors, type Tone, ToneSchema, type WidgetColorPreset, } from "./theming";
53
- export { applyCssVars, applyLayout, builtInVariants, classicGlass, compactHorizontal, composeVariants, createFlexLayout, extendVariant, getBuiltInVariant, getBuiltInVariantIds, isBuiltInVariant, mergeVariants, minimal, } from "./variants";
42
+ export { injectTokens, type Tone, ToneSchema, } from "./theming";
54
43
  export { widgetFields } from "./fields";
55
- export { extractDefaults, toFormSchema } from "./to-form-schema";
56
- export { allEntitiesInState, anyEntityInState, calculateLightGroup, calculateSensorGroup, cn, countActiveEntities, countAvailableEntities, countEntitiesByState, createEmptyStateConfig, type EmptyStateConfigOptions, formatValue, getEntityAttribute, getEntityState, interpretValue, isEntityActive, isEntityAvailable, type LightGroupResult, type SensorGroupResult, type SensorGroupType, type WidgetEmptyStateConfig, } from "./utils";
57
- export type { AbsoluteLayoutStrategy, BaseComponentProps, CustomLayoutStrategy, ElementConfig, EntityView, FlexLayoutStrategy, GestureConfig, GradientConfig, GridLayoutStrategy, HoldGestureConfig, ImageOverlay, InteractionConfig, LayoutStrategy, PositionConfig, SlideGestureConfig, SpacingScale, VariantPlugins, VariantRegistry, WidgetContextValue, WidgetDimensions, WidgetElement, WidgetOrientation, WidgetSize, WidgetStyles, WidgetVariant, WidgetVariantConfig, } from "./types";
44
+ export { calculateLightGroup, calculateSensorGroup, countActiveEntities, getEntityAttribute, isEntityActive, type LightGroupResult, type SensorGroupResult, type SensorGroupType, } from "./utils";
45
+ export type { EntityView, WidgetContextValue, WidgetDimensions, WidgetOrientation, WidgetSize, WidgetStyles, WidgetVariantConfig, } from "./types";
@@ -1,9 +1,7 @@
1
1
  /**
2
- * Widget Theming - Shared Colors
2
+ * Widget Theming
3
3
  *
4
- * Simple color palette for entity states.
5
- * Widgets can use these or define their own logic.
4
+ * Tone schema and token injection.
6
5
  */
7
- export { GRADIENT_NAMES, GRADIENT_PRESET_KEYS, GRADIENT_PRESETS, type GradientPreset, getGradient, getGradientFromString, gradientColorPresets, stateColors, type WidgetColorPreset, } from "./colors";
8
6
  export { ToneSchema, type Tone } from "./tone";
9
7
  export { injectTokens } from "./tokens";
@@ -46,15 +46,6 @@ export interface WidgetContextValue {
46
46
  /** Whether widget is in edit mode */
47
47
  isEditMode: boolean;
48
48
  }
49
- /**
50
- * Gradient configuration
51
- */
52
- export interface GradientConfig {
53
- /** Tailwind gradient from class (e.g., "from-blue-500") */
54
- from: string;
55
- /** Tailwind gradient to class (e.g., "to-blue-700") */
56
- to: string;
57
- }
58
49
  /**
59
50
  * Slide gesture configuration
60
51
  */
@@ -96,22 +87,8 @@ export interface GestureConfig {
96
87
  * Spacing scale
97
88
  */
98
89
  export type SpacingScale = "S1" | "S2" | "S3" | "S4";
99
- /**
100
- * Image overlay types
101
- */
102
- export type ImageOverlay = "gradient" | "dark" | "none";
103
- /**
104
- * Base props that all framework components accept
105
- */
106
- export interface BaseComponentProps {
107
- /** Additional CSS classes (SolidJS uses `class` instead of `className`) */
108
- class?: string;
109
- /** Child elements */
110
- children?: JSX.Element;
111
- }
112
90
  /**
113
91
  * CSS variable-based styling configuration
114
- * Replaces brittle Tailwind class strings with type-safe CSS variables
115
92
  */
116
93
  export interface WidgetStyles {
117
94
  /** Inline CSS properties applied to widget container */
@@ -126,17 +103,11 @@ export interface WidgetStyles {
126
103
  */
127
104
  export interface FlexLayoutStrategy {
128
105
  type: "flex";
129
- /** Flex direction */
130
106
  direction: "row" | "column" | "row-reverse" | "column-reverse";
131
- /** Align items */
132
107
  align: "start" | "center" | "end" | "stretch";
133
- /** Justify content */
134
108
  justify: "start" | "center" | "end" | "between" | "around";
135
- /** Flex wrap */
136
109
  wrap?: boolean;
137
- /** Gap between items (CSS value) */
138
110
  gap?: string;
139
- /** Custom order for specific elements */
140
111
  order?: Partial<Record<WidgetElement, number>>;
141
112
  }
142
113
  /**
@@ -144,15 +115,10 @@ export interface FlexLayoutStrategy {
144
115
  */
145
116
  export interface GridLayoutStrategy {
146
117
  type: "grid";
147
- /** Grid template areas string */
148
118
  areas: string;
149
- /** Grid template columns */
150
119
  columns?: string;
151
- /** Grid template rows */
152
120
  rows?: string;
153
- /** Gap between items (CSS value) */
154
121
  gap?: string;
155
- /** Grid area assignments for elements */
156
122
  elementAreas: Partial<Record<WidgetElement, string>>;
157
123
  }
158
124
  /**
@@ -160,7 +126,6 @@ export interface GridLayoutStrategy {
160
126
  */
161
127
  export interface AbsoluteLayoutStrategy {
162
128
  type: "absolute";
163
- /** Position configurations for specific elements */
164
129
  positions: Partial<Record<WidgetElement, PositionConfig>>;
165
130
  }
166
131
  /**
@@ -168,12 +133,10 @@ export interface AbsoluteLayoutStrategy {
168
133
  */
169
134
  export interface CustomLayoutStrategy {
170
135
  type: "custom";
171
- /** Custom render function or component */
172
136
  renderer: string;
173
137
  }
174
138
  /**
175
139
  * Discriminated union of all layout strategies
176
- * Ensures type safety - can't use gridArea with flex, etc.
177
140
  */
178
141
  export type LayoutStrategy = FlexLayoutStrategy | GridLayoutStrategy | AbsoluteLayoutStrategy | CustomLayoutStrategy;
179
142
  /**
@@ -194,68 +157,42 @@ export type WidgetElement = "icon" | "title" | "subtitle" | "status" | "value" |
194
157
  * Element-specific configuration
195
158
  */
196
159
  export interface ElementConfig {
197
- /** Show/hide specific elements */
198
160
  visible?: Partial<Record<WidgetElement, boolean>>;
199
- /** Element-specific styling */
200
161
  styles?: Partial<Record<WidgetElement, JSX.CSSProperties>>;
201
- /** Element-specific CSS classes */
202
162
  classNames?: Partial<Record<WidgetElement, string>>;
203
163
  }
204
164
  /**
205
165
  * Plugin system configuration (serializable)
206
- * Uses string IDs instead of JSX.Element for serializability
207
166
  */
208
167
  export interface VariantPlugins {
209
- /** Background plugin ID */
210
168
  background?: string;
211
- /** Overlay plugin ID */
212
169
  overlay?: string;
213
- /** Decoration plugin IDs */
214
170
  decorations?: string[];
215
171
  }
216
172
  /**
217
173
  * Interaction configuration
218
174
  */
219
175
  export interface InteractionConfig {
220
- /** Enable hover effects */
221
176
  hover?: boolean;
222
- /** Enable active/pressed state */
223
177
  active?: boolean;
224
- /** Enable focus ring */
225
178
  focus?: boolean;
226
- /** Custom hover scale (e.g., 1.02) */
227
179
  hoverScale?: number;
228
- /** Custom active scale (e.g., 0.98) */
229
180
  activeScale?: number;
230
181
  }
231
182
  /**
232
183
  * Complete variant configuration
233
- * This is the core of the variant system
234
184
  */
235
185
  export interface WidgetVariantConfig {
236
- /** Unique variant identifier */
237
186
  id: string;
238
- /** Human-readable name */
239
187
  name: string;
240
- /** Description of variant purpose/style */
241
188
  description?: string;
242
- /** Styling configuration */
243
189
  styles?: WidgetStyles;
244
- /** Layout strategy */
245
190
  layout?: LayoutStrategy;
246
- /** Element-specific configuration */
247
191
  elements?: ElementConfig;
248
- /** Plugin configurations */
249
192
  plugins?: VariantPlugins;
250
- /** Interaction behavior */
251
193
  interactions?: InteractionConfig;
252
- /** Base variant to extend (enables composition) */
253
194
  extends?: string;
254
195
  }
255
- /**
256
- * Variant type union (built-in + custom)
257
- */
258
- export type WidgetVariant = "classic-glass" | "minimal" | "compact-horizontal" | (string & {});
259
196
  /**
260
197
  * Variant registry type
261
198
  */
@@ -284,8 +221,13 @@ export interface EntityView {
284
221
  domain: EntityDomain;
285
222
  /** Current state value */
286
223
  state: string;
287
- /** Entity attributes */
288
- attributes: Record<string, any>;
224
+ /**
225
+ * Entity attributes from Home Assistant, excluding keys that are
226
+ * surfaced as canonical resolved fields elsewhere on EntityView
227
+ * (`deviceClass`, `unitOfMeasurement`, `friendlyName`, `icon`).
228
+ * Use those fields instead of reaching into `attributes`.
229
+ */
230
+ attributes: Omit<Record<string, any>, "device_class" | "unit_of_measurement" | "friendly_name" | "icon">;
289
231
  /** When the state last changed */
290
232
  lastChanged: Date;
291
233
  /** When the state was last updated (even if unchanged) */
@@ -8,18 +8,6 @@
8
8
  * (calculateLightGroup, calculateSensorGroup).
9
9
  */
10
10
  import type { EntityView } from "../types";
11
- /**
12
- * Check if entity is available (not unavailable/unknown)
13
- *
14
- * @example
15
- * ```typescript
16
- * const isAvailable = isEntityAvailable(entity);
17
- * if (isAvailable) {
18
- * // Entity is available, can display state
19
- * }
20
- * ```
21
- */
22
- export declare function isEntityAvailable(entity: EntityView | null | undefined): boolean;
23
11
  /**
24
12
  * Check if entity is active (on, open, locked, etc.)
25
13
  * Domain-aware state checking
@@ -31,16 +19,6 @@ export declare function isEntityAvailable(entity: EntityView | null | undefined)
31
19
  * ```
32
20
  */
33
21
  export declare function isEntityActive(entity: EntityView | null | undefined): boolean;
34
- /**
35
- * Get entity state with fallback
36
- *
37
- * @example
38
- * ```typescript
39
- * const state = getEntityState(entity, "unknown");
40
- * return <Widget.Status>{state}</Widget.Status>;
41
- * ```
42
- */
43
- export declare function getEntityState(entity: EntityView | null | undefined, fallback?: string): string;
44
22
  /**
45
23
  * Get entity attribute with type safety
46
24
  *
@@ -51,26 +29,6 @@ export declare function getEntityState(entity: EntityView | null | undefined, fa
51
29
  * ```
52
30
  */
53
31
  export declare function getEntityAttribute<T = unknown>(entity: EntityView | null | undefined, attributeName: string, fallback?: T): T | undefined;
54
- /**
55
- * Count entities by state
56
- *
57
- * @example
58
- * ```typescript
59
- * const onCount = countEntitiesByState(entities, "on");
60
- * return <Widget.Status>{onCount} lights on</Widget.Status>;
61
- * ```
62
- */
63
- export declare function countEntitiesByState(entities: EntityView[], state: string): number;
64
- /**
65
- * Count available entities (excludes unavailable/unknown)
66
- *
67
- * @example
68
- * ```typescript
69
- * const availableCount = countAvailableEntities(entities);
70
- * const unavailableCount = entities.length - availableCount;
71
- * ```
72
- */
73
- export declare function countAvailableEntities(entities: EntityView[]): number;
74
32
  /**
75
33
  * Count active entities (on, open, etc.)
76
34
  *
@@ -81,23 +39,3 @@ export declare function countAvailableEntities(entities: EntityView[]): number;
81
39
  * ```
82
40
  */
83
41
  export declare function countActiveEntities(entities: EntityView[]): number;
84
- /**
85
- * Check if all entities match state
86
- *
87
- * @example
88
- * ```typescript
89
- * const allOn = allEntitiesInState(entities, "on");
90
- * const statusText = allOn ? "All on" : "Mixed";
91
- * ```
92
- */
93
- export declare function allEntitiesInState(entities: EntityView[], state: string): boolean;
94
- /**
95
- * Check if any entity matches state
96
- *
97
- * @example
98
- * ```typescript
99
- * const anyOpen = anyEntityInState(entities, "open");
100
- * const iconColor = anyOpen ? "red" : "green";
101
- * ```
102
- */
103
- export declare function anyEntityInState(entities: EntityView[], state: string): boolean;
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Framework Utilities - Barrel Export
2
+ * Framework Utilities - Barrel Export (internal)
3
3
  *
4
- * Helper functions for value formatting, entity state management,
5
- * and class name composition.
4
+ * Public exports are routed through src/framework/index.ts. Files that remain
5
+ * in this directory are still consumed internally even when not part of the
6
+ * public re-export surface.
6
7
  */
7
8
  export { cn } from "./cn";
8
- export { createEmptyStateConfig, type EmptyStateConfigOptions, type WidgetEmptyStateConfig, } from "./empty-state";
9
9
  export { calculateLightGroup, calculateSensorGroup, type LightGroupResult, type SensorGroupResult, type SensorGroupType, } from "./entity-aggregation";
10
- export { allEntitiesInState, anyEntityInState, countActiveEntities, countAvailableEntities, countEntitiesByState, getEntityAttribute, getEntityState, isEntityActive, isEntityAvailable, } from "./entity-state";
10
+ export { countActiveEntities, getEntityAttribute, isEntityActive, } from "./entity-state";
11
11
  export { formatValue } from "./format-value";
12
12
  export { interpretValue } from "./interpret-value";
package/dist/index.d.ts CHANGED
@@ -1,8 +1,6 @@
1
- export type { Entity } from "./create-entity";
2
- export { createEntity } from "./create-entity";
3
1
  export { defineWidget } from "./define-widget";
4
2
  export * from "./framework";
5
- export { formatSchemaError, GridSizeSchema, PublishBodySchema, PublishConfirmSchema, PublishRequestSchema, parseGridSize, serializeGridSize, WidgetManifestSchema, } from "./schemas";
6
- export { getThemeToken, isDark } from "./theme";
3
+ export { formatSchemaError, WidgetManifestSchema } from "./schemas";
4
+ export { isDark } from "./theme";
7
5
  export type { GridSize, WidgetContext, WidgetDefinition, WidgetManifest, } from "./types";
8
6
  export { SDK_VERSION } from "./version";