@glasshome/widget-sdk 0.3.6 → 0.4.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/README.md CHANGED
@@ -68,6 +68,24 @@ Provides a `@source` directive for Tailwind v4 so the compiler scans widget SDK
68
68
  @source "@glasshome/widget-sdk/tailwind-sources";
69
69
  ```
70
70
 
71
+ ## Escape patterns, when widgets own their visual surface
72
+
73
+ Most widgets route through the channel API: `<Widget tone>` / `<Widget color colorTo>` / `<Widget.Icon color>`. A small number of widgets intentionally own their entire visual surface and bypass the channel. These are supported escape patterns, not anti-patterns.
74
+
75
+ ### Weather, full-background scenes
76
+
77
+ The `weather` widget renders a `<WeatherBackground condition>` component that replaces the shell gradient entirely with an animated per-condition scene (sunny rays, rain droplets, snow particles). Channel vars do not apply to the shell; `Widget.Icon color` still receives a CSS string per condition for the icon badge.
78
+
79
+ ### Media-player, vinyl gradient
80
+
81
+ The `media-player` widget composes a custom `<VinylRecord>` element with an album-art radial overlay. The visual identity is content-driven (album artwork) rather than tone-driven; the channel base color stays neutral underneath.
82
+
83
+ ### Area, per-metric pill colors
84
+
85
+ The `area` widget renders quick-glance metric pills (CO2 traffic-light, humidity range, temperature) where each pill's color encodes the metric's *semantic state* (CO2 green/amber/red, humidity dry/comfortable/humid). These per-metric color rules are intentionally semantic-per-metric, not channel-driven, and live in the widget's own helpers.
86
+
87
+ If your widget needs full visual control (a chart, a video stream, a custom animated surface), follow these patterns: keep the `<Widget>` shell neutral (no `tone`/`color`), place your custom DOM inside `<Widget.Content>`, and document the choice in the widget's README.
88
+
71
89
  ## Peer Dependencies
72
90
 
73
91
  | Package | Required | Notes |
@@ -1,24 +1,36 @@
1
1
  /**
2
2
  * Glow Component
3
3
  *
4
- * Background glow effect for widgets.
5
- * Renders a radial gradient background at the BACKGROUND z-index layer.
4
+ * Channel-driven background glow. Renders a blurred radial gradient at the
5
+ * BACKGROUND z-index layer using the Widget's channel color. Defaults to the
6
+ * parent Widget's `--widget-color`; pass `color` to override locally.
6
7
  *
7
8
  * @example
8
9
  * ```tsx
9
- * <Glow color="blue" />
10
+ * <Widget tone="info">
11
+ * <Glow />
12
+ * </Widget>
13
+ * ```
14
+ *
15
+ * @example With local override
16
+ * ```tsx
17
+ * <Glow color="oklch(0.7 0.2 30)" />
10
18
  * ```
11
19
  */
12
20
  import type { JSX } from "solid-js";
13
- import type { ColorVariant } from "../types";
14
- export interface GlowProps {
15
- /** Glow color (Tailwind color name or CSS color) */
16
- color: ColorVariant;
21
+ interface GlowProps {
22
+ /**
23
+ * Optional CSS color string override (oklch, hsl, rgb, hex, var()).
24
+ * Sets `--widget-color` locally on the Glow element. When omitted the
25
+ * parent Widget's channel color cascades in.
26
+ * BREAKING (Phase 26): previously a Tailwind color variant key.
27
+ */
28
+ color?: string;
17
29
  /** Additional CSS classes */
18
30
  class?: string;
19
31
  }
20
32
  /**
21
- * Glow effect component
22
- * Applies a blurred radial gradient background effect
33
+ * Glow effect component, channel-driven radial gradient.
23
34
  */
24
35
  export declare function Glow(props: GlowProps): JSX.Element;
36
+ export {};
@@ -1,33 +1,44 @@
1
1
  /**
2
2
  * WidgetSliderFill Component
3
3
  *
4
- * Animated fill overlay that follows a slider value.
5
- * Automatically adapts direction based on widget orientation.
4
+ * Animated fill overlay that follows a slider value. Background and glow are
5
+ * rendered by the `.glasshome-widget-slider-fill` CSS rule in tokens.css via
6
+ * the channel vars (`--widget-icon-color` with fallback to `--widget-color`).
7
+ * The `color` prop is the optional per-fill override: when provided it is
8
+ * written inline as `--widget-icon-color`, mirroring `Widget.Icon.color`
9
+ * (Phase 26 VIS-A05). Orientation is inherited from the parent Widget context
10
+ * and drives the `clip-path` direction.
6
11
  *
7
- * @example
12
+ * @example Default, inherits parent Widget channel color
8
13
  * ```tsx
9
- * <Widget gestures={{ slide: { value, onChange } }}>
10
- * <Widget.SliderFill value={brightness} color="rgb(255, 200, 0)" />
14
+ * <Widget tone="info" gestures={{ slide: { value, onChange } }}>
15
+ * <Widget.SliderFill value={position} />
11
16
  * <Widget.Content>...</Widget.Content>
12
17
  * </Widget>
13
18
  * ```
19
+ *
20
+ * @example Per-fill override (sets --widget-icon-color, not background directly)
21
+ * ```tsx
22
+ * <Widget.SliderFill value={brightness} color={bulbColor} />
23
+ * ```
14
24
  */
15
25
  import type { JSX } from "solid-js";
16
- export interface WidgetSliderFillProps {
26
+ interface WidgetSliderFillProps {
17
27
  /** Current value (0-100) */
18
28
  value: number;
19
- /** Fill color (CSS color string) */
29
+ /**
30
+ * Optional channel override: sets `--widget-icon-color` inline on the fill
31
+ * root. When omitted the fill renders in the parent Widget's channel color
32
+ * (var(--widget-color)). Mirrors Widget.Icon.color (Phase 26 VIS-A05).
33
+ */
20
34
  color?: string;
21
- /** Show glow effect */
22
- glow?: boolean;
23
- /** Opacity of the fill (0-1) */
24
- opacity?: number;
25
- /** Whether slider is currently being dragged (disables transition) */
35
+ /** Whether the slider is currently being dragged (disables transition) */
26
36
  isDragging?: boolean;
27
37
  /** Additional CSS classes */
28
38
  class?: string;
29
39
  }
30
40
  /**
31
- * Animated slider fill that adapts to widget orientation
41
+ * Animated slider fill that adapts to widget orientation.
32
42
  */
33
43
  export declare function WidgetSliderFill(props: WidgetSliderFillProps): JSX.Element;
44
+ export {};
@@ -16,7 +16,7 @@
16
16
  * ```
17
17
  */
18
18
  import type { JSX } from "solid-js";
19
- export interface WidgetContentProps {
19
+ interface WidgetContentProps {
20
20
  /** Additional CSS classes */
21
21
  class?: string;
22
22
  /** Content children */
@@ -27,3 +27,4 @@ export interface WidgetContentProps {
27
27
  * Ensures proper z-index layering for title, status, and controls
28
28
  */
29
29
  export declare function WidgetContent(props: WidgetContentProps): JSX.Element;
30
+ export {};
@@ -15,7 +15,7 @@
15
15
  * ```
16
16
  */
17
17
  import type { JSX } from "solid-js";
18
- export interface WidgetEmptyStateProps {
18
+ interface WidgetEmptyStateProps {
19
19
  /** Icon to display (optional) */
20
20
  icon?: JSX.Element;
21
21
  /** Main title/heading */
@@ -32,3 +32,4 @@ export interface WidgetEmptyStateProps {
32
32
  * Shows centered placeholder when widget has no content
33
33
  */
34
34
  export declare function WidgetEmptyState(props: WidgetEmptyStateProps): JSX.Element;
35
+ export {};
@@ -1,48 +1,46 @@
1
1
  /**
2
2
  * WidgetIcon Component
3
3
  *
4
- * Icon component with automatic sizing and glow effect.
5
- * Supports both Tailwind classes and dynamic CSS colors for background/glow.
4
+ * Channel-driven icon. Background and glow read from `--widget-icon-color`
5
+ * (with fallback to `--widget-color`) and `--widget-glow-strength` via the
6
+ * `.glasshome-widget-icon` CSS rule in tokens.css. The `color` prop is the
7
+ * optional per-icon override, pass any CSS color string (oklch, rgb, hex,
8
+ * hsl, var(...)).
6
9
  *
7
- * @example Static color (Tailwind classes)
10
+ * @example Default, inherits the parent Widget's channel color
8
11
  * ```tsx
9
- * <Widget.Icon
10
- * icon={<Power />}
11
- * color="bg-blue-500 dark:bg-blue-400"
12
- * glow="shadow-blue-500/50 dark:shadow-blue-400/50"
13
- * />
12
+ * <Widget tone="info">
13
+ * <Widget.Icon icon={<Power />} />
14
+ * </Widget>
14
15
  * ```
15
16
  *
16
- * @example Dynamic color (CSS color string adaptive contrast)
17
+ * @example Per-icon override (e.g. light bulb showing its actual rgb_color)
17
18
  * ```tsx
18
- * <Widget.Icon
19
- * icon={<Lightbulb />}
20
- * dynamicColor="hsl(320, 100%, 50%)"
21
- * />
19
+ * <Widget.Icon icon={<Lightbulb />} color="oklch(0.85 0.2 60)" />
22
20
  * ```
23
21
  */
24
22
  import type { JSX } from "solid-js";
25
- export interface WidgetIconProps {
23
+ interface WidgetIconProps {
26
24
  /** Icon component (JSX.Element) */
27
25
  icon: JSX.Element;
28
- /** Background color as Tailwind class (e.g. "bg-blue-500 dark:bg-blue-400") */
29
- color?: string;
30
- /** Glow/shadow effect as Tailwind class (e.g. "shadow-blue-500/50") */
31
- glow?: string;
32
26
  /**
33
- * Dynamic CSS color string (rgb, hsl, hex).
34
- * When provided, icon background and glow are derived adaptively from this color.
35
- * Takes precedence over `color` and `glow` props.
27
+ * Optional CSS color string (oklch, hsl, rgb, hex, var()).
28
+ * Sets `--widget-icon-color` inline on the icon root, overriding the
29
+ * channel base color for the icon only. When omitted the channel's
30
+ * `--widget-color` flows through via the tokens.css rule.
31
+ * BREAKING (Phase 26): previously accepted Tailwind class strings.
36
32
  */
37
- dynamicColor?: string;
33
+ color?: string;
38
34
  /** Reduce opacity */
39
35
  dimmed?: boolean;
40
- /** Number of entities - creates stacked background effect (1 = single, 2+ = stacked backgrounds) */
36
+ /** Number of entities, creates stacked background effect (1 = single, 2+ = stacked backgrounds) */
41
37
  entityCount?: number;
42
38
  /** Additional CSS classes */
43
39
  class?: string;
44
40
  }
45
41
  /**
46
- * Widget icon component with auto-responsive sizing
42
+ * Widget icon component with auto-responsive sizing.
43
+ * Background + glow rendered by the `.glasshome-widget-icon` CSS rule.
47
44
  */
48
45
  export declare function WidgetIcon(props: WidgetIconProps): JSX.Element;
46
+ export {};
@@ -14,7 +14,7 @@
14
14
  * ```
15
15
  */
16
16
  import type { JSX } from "solid-js";
17
- export interface WidgetMetricsProps {
17
+ interface WidgetMetricsProps {
18
18
  /** Layout direction (default: "auto" - horizontal for horizontal widgets, vertical for others) */
19
19
  direction?: "horizontal" | "vertical" | "auto";
20
20
  /** Additional CSS classes */
@@ -22,11 +22,11 @@ export interface WidgetMetricsProps {
22
22
  /** Metric items */
23
23
  children: JSX.Element;
24
24
  }
25
- export interface WidgetMetricsComponent {
25
+ interface WidgetMetricsComponent {
26
26
  (props: WidgetMetricsProps): JSX.Element;
27
27
  Item: typeof WidgetMetricsItem;
28
28
  }
29
- export interface WidgetMetricsItemProps {
29
+ interface WidgetMetricsItemProps {
30
30
  /** Metric label */
31
31
  label: string;
32
32
  /** Metric value */
@@ -43,5 +43,6 @@ export interface WidgetMetricsItemProps {
43
43
  /**
44
44
  * Individual metric item
45
45
  */
46
- export declare function WidgetMetricsItem(props: WidgetMetricsItemProps): JSX.Element;
46
+ declare function WidgetMetricsItem(props: WidgetMetricsItemProps): JSX.Element;
47
47
  export declare const WidgetMetrics: WidgetMetricsComponent;
48
+ export {};
@@ -9,7 +9,7 @@
9
9
  * ```
10
10
  */
11
11
  import type { JSX } from "solid-js";
12
- export interface WidgetStatusProps {
12
+ interface WidgetStatusProps {
13
13
  /** Reduce opacity further */
14
14
  dimmed?: boolean;
15
15
  /** Additional CSS classes */
@@ -24,3 +24,4 @@ export interface WidgetStatusProps {
24
24
  * Positioned above other content with proper z-index
25
25
  */
26
26
  export declare function WidgetStatus(props: WidgetStatusProps): JSX.Element;
27
+ export {};
@@ -14,7 +14,7 @@
14
14
  * ```
15
15
  */
16
16
  import type { JSX } from "solid-js";
17
- export interface WidgetSubtitleProps {
17
+ interface WidgetSubtitleProps {
18
18
  /** Whether to dim the subtitle */
19
19
  dimmed?: boolean;
20
20
  /** Additional CSS classes */
@@ -26,3 +26,4 @@ export interface WidgetSubtitleProps {
26
26
  * Widget subtitle component with auto-responsive typography
27
27
  */
28
28
  export declare function WidgetSubtitle(props: WidgetSubtitleProps): JSX.Element;
29
+ export {};
@@ -14,7 +14,7 @@
14
14
  * ```
15
15
  */
16
16
  import type { JSX } from "solid-js";
17
- export interface WidgetTitleProps {
17
+ interface WidgetTitleProps {
18
18
  /** Optional badge count */
19
19
  badge?: number;
20
20
  /** Additional CSS classes */
@@ -27,3 +27,4 @@ export interface WidgetTitleProps {
27
27
  * Positioned above other content with proper z-index
28
28
  */
29
29
  export declare function WidgetTitle(props: WidgetTitleProps): JSX.Element;
30
+ export {};
@@ -15,7 +15,7 @@
15
15
  * ```
16
16
  */
17
17
  import type { JSX } from "solid-js";
18
- export interface WidgetValueProps {
18
+ interface WidgetValueProps {
19
19
  /** The value to display */
20
20
  value: number | string;
21
21
  /** Unit of measurement */
@@ -29,3 +29,4 @@ export interface WidgetValueProps {
29
29
  * Widget value component with auto-formatting and interpretation
30
30
  */
31
31
  export declare function WidgetValue(props: WidgetValueProps): JSX.Element;
32
+ export {};
@@ -12,9 +12,9 @@
12
12
  * </Widget>
13
13
  * ```
14
14
  *
15
- * @example With gradient and loading
15
+ * @example With CSS gradient and loading
16
16
  * ```tsx
17
- * <Widget gradient="bg-gradient-to-br from-blue-500/40 to-blue-700/40" loading={isLoading}>
17
+ * <Widget gradient="linear-gradient(135deg, oklch(0.7 0.2 30), oklch(0.5 0.18 270))" loading={isLoading}>
18
18
  * {children}
19
19
  * </Widget>
20
20
  * ```
@@ -30,8 +30,9 @@ import type { WidgetSubtitle as WidgetSubtitleType } from "../components/WidgetS
30
30
  import type { WidgetTitle as WidgetTitleType } from "../components/WidgetTitle";
31
31
  import type { WidgetValue as WidgetValueType } from "../components/WidgetValue";
32
32
  import type { GestureHandlers } from "../gestures/use-widget-gestures";
33
- import type { WidgetOrientation, WidgetSize, WidgetVariantConfig } from "../types";
34
- export interface WidgetEmptyStateConfig {
33
+ import type { WidgetVariantConfig } from "../types";
34
+ import type { Tone } from "../theming/tone";
35
+ interface WidgetEmptyStateConfig {
35
36
  /** Icon to display */
36
37
  icon?: JSX.Element;
37
38
  /** Main title/heading */
@@ -39,22 +40,40 @@ export interface WidgetEmptyStateConfig {
39
40
  /** Descriptive message */
40
41
  message?: string;
41
42
  }
42
- export interface WidgetProps {
43
+ interface WidgetProps {
43
44
  /** Widget variant (string ID or inline config) */
44
45
  variant?: string | WidgetVariantConfig;
45
- /** Gradient background (Tailwind classes like "bg-gradient-to-br from-cyan-600/40 to-blue-700/40") */
46
+ /**
47
+ * Semantic tone (success, warning, danger, info, neutral, accent).
48
+ * Resolves to `--widget-color: var(--tone-{name})` inline on the widget root.
49
+ * Phase 26 channel API, preferred path for state-driven semantic widgets.
50
+ */
51
+ tone?: Tone;
52
+ /**
53
+ * CSS color string (oklch, hsl, hex, rgb, var()).
54
+ * Sets `--widget-color` directly. Overrides `tone` when both supplied.
55
+ */
56
+ color?: string;
57
+ /**
58
+ * Optional second-stop CSS color string for two-stop gradient identity.
59
+ * Sets `--widget-color-to`. When omitted the shell formula falls back to `--widget-color`.
60
+ */
61
+ colorTo?: string;
62
+ /**
63
+ * Full CSS gradient string (e.g. `linear-gradient(135deg, oklch(...), oklch(...))`).
64
+ * Sets `--widget-gradient` and overrides the auto-derived shell gradient verbatim.
65
+ * BREAKING (Phase 26): previously accepted Tailwind class strings; now expects raw CSS.
66
+ */
46
67
  gradient?: string;
47
68
  /** Show loading overlay */
48
69
  loading?: boolean;
49
- /** Background glow color (Tailwind color like "bg-blue-500") (runtime override) */
50
- backgroundGlow?: string;
51
70
  /** Additional CSS classes */
52
71
  class?: string;
53
72
  /** Is edit mode (disables gestures) */
54
73
  isEditMode?: boolean;
55
74
  /** Called when delete button is clicked (only shown in edit mode) */
56
75
  onDelete?: () => void;
57
- /** Empty state configuration - when provided, shows empty state and applies gray gradient */
76
+ /** Empty state configuration, when provided shows empty state UI inside the shell */
58
77
  emptyState?: WidgetEmptyStateConfig;
59
78
  /**
60
79
  * Gesture handlers from `useWidgetGestures`. When provided, Widget binds
@@ -65,7 +84,7 @@ export interface WidgetProps {
65
84
  /** Child elements */
66
85
  children?: JSX.Element;
67
86
  }
68
- export interface WidgetComponent {
87
+ interface WidgetComponent {
69
88
  (props: WidgetProps): JSX.Element;
70
89
  Content: typeof WidgetContentType;
71
90
  Icon: typeof WidgetIconType;
@@ -77,19 +96,5 @@ export interface WidgetComponent {
77
96
  EmptyState: typeof WidgetEmptyStateType;
78
97
  SliderFill: typeof WidgetSliderFillType;
79
98
  }
80
- /**
81
- * Classify widget size based on grid dimensions
82
- */
83
- export declare function classifySize(gridWidth: number, gridHeight: number): WidgetSize;
84
- /**
85
- * Detect orientation from dimensions based on aspect ratio
86
- * Used for gesture direction (slide horizontal vs vertical)
87
- */
88
- export declare function detectOrientation(width: number, height: number): WidgetOrientation;
89
- /**
90
- * Detect content layout direction
91
- * Used for UI arrangement (stack vertically vs horizontally)
92
- * Considers height threshold - tall widgets benefit from vertical stacking
93
- */
94
- export declare function detectContentLayout(width: number, height: number): WidgetOrientation;
95
99
  export declare const Widget: WidgetComponent;
100
+ export {};
@@ -3,7 +3,7 @@
3
3
  * Each cursor is a data URI embedded inline — no external files needed.
4
4
  * Hotspot coordinates are included for proper click positioning.
5
5
  */
6
- export interface CursorDef {
6
+ interface CursorDef {
7
7
  css: string;
8
8
  hotspotX: number;
9
9
  hotspotY: number;
@@ -15,3 +15,4 @@ export declare const cursors: {
15
15
  readonly slideVertical: CursorDef;
16
16
  readonly slideAuto: CursorDef;
17
17
  };
18
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Haptic feedback for gesture transitions.
3
+ *
4
+ * Resolution order at runtime:
5
+ * 1. Capacitor Haptics plugin (Android/iOS native) — richer patterns
6
+ * 2. `navigator.vibrate` (Android Chrome/WebView)
7
+ * 3. silent (desktop, iOS Safari)
8
+ *
9
+ * No build-time dependency on @capacitor/haptics — the host app installs the
10
+ * plugin; we probe `window.Capacitor.Plugins.Haptics` at call time.
11
+ */
12
+ export declare const haptics: {
13
+ /** Light confirmation — fires when slide gesture arms after user holds still. */
14
+ tick(): void;
15
+ /** Medium bump — fires when hold gesture commits (detail opening). */
16
+ bump(): void;
17
+ /** Stronger pulse — reserved for edit-mode pickup (future use). */
18
+ pulse(): void;
19
+ };
@@ -1,32 +1,22 @@
1
1
  /**
2
- * Widget Gestures Hook
2
+ * Widget Gestures Hook — Mobile-aware
3
3
  *
4
- * Provides gesture handling for widgets with automatic conflict resolution.
5
- * Ported from React reference, adapted for SolidJS:
6
- * - Uses mutable state object instead of useRef (imperative gesture tracking)
7
- * - Accepts config/orientation as accessors for reactivity
8
- * - Returns native PointerEvent handlers (not React.PointerEvent)
9
- * - Callers bind via on:pointerdown={handlers.onPointerDown}
4
+ * Two grammars by pointer type:
10
5
  *
11
- * @example
12
- * ```tsx
13
- * const gestures = useWidgetGestures(
14
- * () => ({
15
- * tap: handleTap,
16
- * hold: { action: handleHold, delay: 300 },
17
- * slide: {
18
- * value: brightness(),
19
- * onChange: setBrightness,
20
- * min: 0,
21
- * max: 100,
22
- * orientation: "auto",
23
- * },
24
- * }),
25
- * () => ctx.orientation(),
26
- * );
6
+ * TOUCH (phone, tablet):
7
+ * - tap → primary action
8
+ * - hold → detail dialog (with haptic bump)
9
+ * - slide → DISABLED. Fine control lives in the detail dialog instead.
10
+ * This eliminates the slide-vs-page-scroll conflict that makes mobile
11
+ * gestures fragile. `touch-action: manipulation` ensures the browser
12
+ * handles scroll natively without our interference.
27
13
  *
28
- * return <div on:pointerdown={gestures.onPointerDown} on:pointermove={gestures.onPointerMove} on:pointerup={gestures.onPointerUp} on:pointercancel={gestures.onPointerCancel}>...</div>;
29
- * ```
14
+ * MOUSE / PEN (desktop, hybrid devices):
15
+ * - tap, hold, slide all active. Slide arms immediately on pointerdown —
16
+ * no scroll conflict to worry about (mouse uses wheel for scroll).
17
+ *
18
+ * Pointer type is decided per press at pointerdown. A hybrid device (tablet
19
+ * + bluetooth mouse) gets the right grammar based on which input fired.
30
20
  */
31
21
  import type { GestureConfig, WidgetOrientation } from "../types";
32
22
  export interface GestureHandlers {
@@ -43,24 +33,12 @@ export interface GestureHandlers {
43
33
  */
44
34
  bindElement: (el: HTMLElement) => void;
45
35
  /**
46
- * CSS `touch-action` value for the gesture root. Horizontal slide `pan-y`
47
- * (page scrolls vertically, slider owns horizontal). Vertical slide `pan-x`.
48
- * Tap/hold only `manipulation`. Without this, mobile browsers cancel the
49
- * pointer mid-slide once they decide the touch is a pan.
36
+ * CSS `touch-action` for the gesture root. Always `manipulation` when any
37
+ * gesture is configured mobile slide is intentionally dropped, so the
38
+ * browser owns scroll completely on touch surfaces.
50
39
  */
51
40
  touchAction: () => string;
52
- /** Cancel any pending hold/slide timers. Call on component unmount via onCleanup. */
41
+ /** Cancel any pending hold timer. Call on component unmount via onCleanup. */
53
42
  dispose: () => void;
54
43
  }
55
- /**
56
- * Widget gestures hook with conflict resolution
57
- *
58
- * Features:
59
- * - Axis locking: Once slide direction is detected, locks to that axis
60
- * - Scroll prevention: Blocks page scroll when sliding along widget axis
61
- * - Tap/hold/slide gesture support with automatic conflict resolution
62
- *
63
- * @param config - Accessor returning gesture configuration
64
- * @param orientation - Accessor returning widget orientation (for auto slide orientation)
65
- */
66
44
  export declare function useWidgetGestures(config: () => GestureConfig, orientation?: () => WidgetOrientation): GestureHandlers;
@@ -4,7 +4,6 @@
4
4
  * All hooks for widget development: context, responsive, dialog, form,
5
5
  * config, entity, entity group, debug data, and gestures.
6
6
  */
7
- export { type GestureHandlers, useWidgetGestures } from "../gestures/use-widget-gestures";
8
7
  export { type UseDebugDataOptions, useDebugData } from "./use-debug-data";
9
8
  export { type UseWidgetConfigOptions, type UseWidgetConfigReturn, useWidgetConfig, } from "./use-widget-config";
10
9
  export { type BridgeableWidgetContext, type BridgeFns, type ReactiveWidgetContext, useWidgetContext, warnIfStub, WidgetCtx, } from "./use-widget-context";
@@ -49,9 +49,9 @@ export { type GestureHandlers, useWidgetGestures } from "./gestures/use-widget-g
49
49
  export { getSpacingClass, spacing } from "./design-system/spacing";
50
50
  export { typography } from "./design-system/typography";
51
51
  export { WIDGET_Z, type WidgetZIndex } from "./design-system/z-index";
52
- export { type AdaptiveIconColors, deriveAdaptiveIconColors, GRADIENT_NAMES, GRADIENT_PRESET_KEYS, GRADIENT_PRESETS, type GradientPreset, getGradient, getGradientFromString, gradientColorPresets, stateColors, type WidgetColorPreset, } from "./theming";
52
+ export { GRADIENT_NAMES, GRADIENT_PRESET_KEYS, GRADIENT_PRESETS, type GradientPreset, getGradient, getGradientFromString, gradientColorPresets, injectTokens, stateColors, type Tone, ToneSchema, type WidgetColorPreset, } from "./theming";
53
53
  export { applyCssVars, applyLayout, builtInVariants, classicGlass, compactHorizontal, composeVariants, createFlexLayout, extendVariant, getBuiltInVariant, getBuiltInVariantIds, isBuiltInVariant, mergeVariants, minimal, } from "./variants";
54
54
  export { widgetFields } from "./fields";
55
55
  export { extractDefaults, toFormSchema } from "./to-form-schema";
56
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, ColorVariant, 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";
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";
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import type { JSX } from "solid-js";
16
16
  import type { SpacingScale } from "../types";
17
- export interface WidgetStackProps {
17
+ interface WidgetStackProps {
18
18
  /** Spacing between items (default: "S2") */
19
19
  spacing?: SpacingScale;
20
20
  /** Additional CSS classes */
@@ -26,3 +26,4 @@ export interface WidgetStackProps {
26
26
  * Vertical stack layout with responsive spacing
27
27
  */
28
28
  export declare function WidgetStack(props: WidgetStackProps): JSX.Element;
29
+ export {};
@@ -4,5 +4,6 @@
4
4
  * Simple color palette for entity states.
5
5
  * Widgets can use these or define their own logic.
6
6
  */
7
- export { type AdaptiveIconColors, deriveAdaptiveIconColors } from "./adaptive-color";
8
7
  export { GRADIENT_NAMES, GRADIENT_PRESET_KEYS, GRADIENT_PRESETS, type GradientPreset, getGradient, getGradientFromString, gradientColorPresets, stateColors, type WidgetColorPreset, } from "./colors";
8
+ export { ToneSchema, type Tone } from "./tone";
9
+ export { injectTokens } from "./tokens";
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Minimal document-shape needed for token injection. Allows tests to pass
3
+ * a stub without a full DOM implementation.
4
+ */
5
+ interface InjectTokensRoot {
6
+ head: {
7
+ appendChild: (node: unknown) => void;
8
+ querySelector?: (sel: string) => unknown;
9
+ };
10
+ createElement: (tag: string) => {
11
+ setAttribute: (name: string, value: string) => void;
12
+ textContent: string | null;
13
+ };
14
+ }
15
+ /**
16
+ * Inject the SDK tokens stylesheet into <head>. Idempotent across:
17
+ * - Repeated calls within the same module instance (boolean sentinel).
18
+ * - Multiple SDK module instances (DOM sentinel data-glasshome-tokens).
19
+ * - SSR / non-browser environments (no-op when document is undefined).
20
+ */
21
+ export declare function injectTokens(doc?: InjectTokensRoot): void;
22
+ /** Test-only: reset the module-level sentinel. Not exported from the package root. */
23
+ export declare function __resetInjectedForTests(): void;
24
+ export {};
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ export declare const ToneSchema: z.ZodEnum<{
3
+ success: "success";
4
+ warning: "warning";
5
+ danger: "danger";
6
+ info: "info";
7
+ neutral: "neutral";
8
+ accent: "accent";
9
+ }>;
10
+ export type Tone = z.infer<typeof ToneSchema>;
@@ -96,10 +96,6 @@ export interface GestureConfig {
96
96
  * Spacing scale
97
97
  */
98
98
  export type SpacingScale = "S1" | "S2" | "S3" | "S4";
99
- /**
100
- * Color variants for common components
101
- */
102
- export type ColorVariant = "blue" | "green" | "red" | "yellow" | "purple" | "gray" | string;
103
99
  /**
104
100
  * Image overlay types
105
101
  */