@glasshome/widget-sdk 0.5.1 → 1.0.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/data.d.ts +10 -0
- package/dist/framework/dialogs/WidgetDialog.d.ts +3 -0
- package/dist/framework/gestures/use-widget-gestures.d.ts +5 -22
- package/dist/framework/hooks/use-widget-context.d.ts +3 -0
- package/dist/framework/hooks/use-widget-dialog.d.ts +17 -9
- package/dist/framework/theming/tokens.d.ts +9 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +531 -465
- package/dist/schemas.d.ts +6 -106
- package/dist/schemas.js +13 -77
- package/dist/types.d.ts +3 -0
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.js +206 -122
- package/package.json +6 -2
package/dist/data.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Home Assistant data and service hooks, re-exported from
|
|
3
|
+
* @glasshome/sync-layer. Widgets must import these from the SDK instead of
|
|
4
|
+
* sync-layer directly: the single store instance lives in the host (via the
|
|
5
|
+
* import map), and a direct import would bundle a second, disconnected
|
|
6
|
+
* store. Phase 4 routes these through capability checks.
|
|
7
|
+
*/
|
|
8
|
+
export { getForecasts, getStream, getWebRtcClientConfig, sendWebRtcCandidate, startWebRtcSession, state, trackEntityHistory, untrackEntityHistory, } from "@glasshome/sync-layer";
|
|
9
|
+
export type { AreaView } from "@glasshome/sync-layer";
|
|
10
|
+
export { byDomain, useArea, useCamera, useConnection, useCurrency, useEntities, useEntity, useEntityHistory, useEntityStatistics, useForecast, useHassConfig, useLocale, useService, useStore, useTemperatureUnit, useToggle, useTurnOn, useUnitSystem, } from "@glasshome/sync-layer/solid";
|
|
@@ -21,6 +21,9 @@ export interface WidgetDialogProps {
|
|
|
21
21
|
class?: string;
|
|
22
22
|
maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
|
|
23
23
|
defaultTab?: string;
|
|
24
|
+
/** Controlled active tab (pair with `onActiveTabChange`); overrides `defaultTab`. */
|
|
25
|
+
activeTab?: string;
|
|
26
|
+
onActiveTabChange?: (tab: string) => void;
|
|
24
27
|
headerActions?: JSX.Element;
|
|
25
28
|
configSchema?: ZodType;
|
|
26
29
|
config?: Record<string, unknown>;
|
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Widget Gestures Hook —
|
|
2
|
+
* Widget Gestures Hook — tap, hold, and slide on every pointer type.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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.
|
|
13
|
-
*
|
|
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.
|
|
4
|
+
* Touch slide vs page scroll is split per axis: `touch-action` cedes the
|
|
5
|
+
* cross axis to the browser, and a press only commits to sliding when
|
|
6
|
+
* movement is dominantly on the slide axis.
|
|
20
7
|
*/
|
|
21
8
|
import type { GestureConfig } from "../types";
|
|
22
9
|
type GestureOrientation = "horizontal" | "vertical" | "square";
|
|
@@ -33,11 +20,7 @@ export interface GestureHandlers {
|
|
|
33
20
|
* receives the pointer handlers.
|
|
34
21
|
*/
|
|
35
22
|
bindElement: (el: HTMLElement) => void;
|
|
36
|
-
/**
|
|
37
|
-
* CSS `touch-action` for the gesture root. Always `manipulation` when any
|
|
38
|
-
* gesture is configured — mobile slide is intentionally dropped, so the
|
|
39
|
-
* browser owns scroll completely on touch surfaces.
|
|
40
|
-
*/
|
|
23
|
+
/** CSS `touch-action` for the gesture root. */
|
|
41
24
|
touchAction: () => string;
|
|
42
25
|
/** Cancel any pending hold timer. Call on component unmount via onCleanup. */
|
|
43
26
|
dispose: () => void;
|
|
@@ -20,6 +20,9 @@ export interface ReactiveWidgetContext {
|
|
|
20
20
|
updateConfig: (config: Record<string, unknown>) => void;
|
|
21
21
|
/** Measured shell dimensions in CSS px. (0,0) before first layout. */
|
|
22
22
|
dimensions: () => WidgetDimensions;
|
|
23
|
+
/** Host RPC: `useWidgetDialog` registers its opener here so the host can
|
|
24
|
+
open the widget's dialog on a chosen tab. Called with `null` on cleanup. */
|
|
25
|
+
registerDialogOpener?: (open: ((tab?: string) => void) | null) => void;
|
|
23
26
|
}
|
|
24
27
|
export declare const WidgetCtx: import("solid-js").Context<ReactiveWidgetContext | undefined>;
|
|
25
28
|
export declare function useWidgetContext(): ReactiveWidgetContext;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Widget Dialog Hook
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Single source of truth for a widget's dialog state: open/closed and the
|
|
5
|
+
* active tab. Registers an imperative opener on the host context so the
|
|
6
|
+
* host can open the dialog on a chosen tab (e.g. dashboard edit mode
|
|
7
|
+
* opening "edit" directly).
|
|
5
8
|
*
|
|
6
9
|
* @example
|
|
7
10
|
* ```tsx
|
|
8
11
|
* function MyWidget() {
|
|
9
|
-
* const {
|
|
12
|
+
* const { openDialog, dialogProps } = useWidgetDialog();
|
|
10
13
|
*
|
|
11
14
|
* return (
|
|
12
15
|
* <>
|
|
13
16
|
* <Widget gestures={{ hold: { action: openDialog } }}>
|
|
14
17
|
* {/* widget content *\/}
|
|
15
18
|
* </Widget>
|
|
16
|
-
* <WidgetDialog
|
|
17
|
-
* open={showDialog()}
|
|
18
|
-
* onOpenChange={setShowDialog}
|
|
19
|
-
* />
|
|
19
|
+
* <WidgetDialog {...dialogProps} />
|
|
20
20
|
* </>
|
|
21
21
|
* );
|
|
22
22
|
* }
|
|
@@ -27,19 +27,27 @@ export interface WidgetDialogReturn {
|
|
|
27
27
|
showDialog: () => boolean;
|
|
28
28
|
/** Set dialog state directly */
|
|
29
29
|
setShowDialog: (open: boolean) => void;
|
|
30
|
-
/** Open the dialog */
|
|
31
|
-
openDialog: () => void;
|
|
30
|
+
/** Open the dialog, optionally landing on a specific tab */
|
|
31
|
+
openDialog: (tab?: string) => void;
|
|
32
32
|
/** Close the dialog */
|
|
33
33
|
closeDialog: () => void;
|
|
34
34
|
/** Current active tab accessor */
|
|
35
35
|
activeTab: () => string;
|
|
36
36
|
/** Set active tab */
|
|
37
37
|
setActiveTab: (tab: string) => void;
|
|
38
|
+
/** Spread onto `<WidgetDialog>` to wire open + tab state. */
|
|
39
|
+
dialogProps: {
|
|
40
|
+
open: boolean;
|
|
41
|
+
onOpenChange: (open: boolean) => void;
|
|
42
|
+
activeTab: string;
|
|
43
|
+
onActiveTabChange: (tab: string) => void;
|
|
44
|
+
};
|
|
38
45
|
}
|
|
39
46
|
/**
|
|
40
47
|
* Hook for managing widget dialog state
|
|
41
48
|
*
|
|
42
|
-
* @param defaultTab -
|
|
49
|
+
* @param defaultTab - Tab the dialog lands on when no explicit tab is
|
|
50
|
+
* requested (default: "controls")
|
|
43
51
|
* @returns Dialog state and control functions
|
|
44
52
|
*/
|
|
45
53
|
export declare function useWidgetDialog(defaultTab?: string): WidgetDialogReturn;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Minimal document-shape needed for token injection. Allows tests to pass
|
|
3
3
|
* a stub without a full DOM implementation.
|
|
4
4
|
*/
|
|
5
|
-
interface InjectTokensRoot {
|
|
5
|
+
export interface InjectTokensRoot {
|
|
6
6
|
head: {
|
|
7
7
|
appendChild: (node: unknown) => void;
|
|
8
8
|
querySelector?: (sel: string) => unknown;
|
|
@@ -13,12 +13,17 @@ interface InjectTokensRoot {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Inject the SDK tokens stylesheet into
|
|
16
|
+
* Inject the SDK tokens stylesheet into the widget's root.
|
|
17
|
+
*
|
|
18
|
+
* ShadowRoot: adopts a shared constructed CSSStyleSheet (one instance for
|
|
19
|
+
* all widget shadow roots), idempotent per root via WeakSet.
|
|
20
|
+
*
|
|
21
|
+
* Document (or no argument, legacy): appends a <style> to <head>.
|
|
22
|
+
* Idempotent across:
|
|
17
23
|
* - Repeated calls within the same module instance (boolean sentinel).
|
|
18
24
|
* - Multiple SDK module instances (DOM sentinel data-glasshome-tokens).
|
|
19
25
|
* - SSR / non-browser environments (no-op when document is undefined).
|
|
20
26
|
*/
|
|
21
|
-
export declare function injectTokens(
|
|
27
|
+
export declare function injectTokens(root?: Document | ShadowRoot): void;
|
|
22
28
|
/** Test-only: reset the module-level sentinel. Not exported from the package root. */
|
|
23
29
|
export declare function __resetInjectedForTests(): void;
|
|
24
|
-
export {};
|