@devicechain/widgets 0.19.0-rc.1 → 0.20.0-rc.4

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.
@@ -1,2 +1,34 @@
1
- import { type WidgetProps } from '../widget';
2
- export declare function Label({ widget }: WidgetProps): import("react").JSX.Element;
1
+ import { type WidgetProps } from '@devicechain/widget-sdk';
2
+ export declare function Label({ widget }: WidgetProps<null>): import("react").JSX.Element;
3
+ export declare const labelWidget: import("@devicechain/widget-sdk").WidgetDefinition<"none", {
4
+ readonly title: {
5
+ readonly kind: 'string';
6
+ readonly labelId: 'widgetLabelTitle';
7
+ readonly doc: 'Heading shown in the widget frame. Blank hides the frame heading.';
8
+ };
9
+ readonly text: {
10
+ readonly kind: "string";
11
+ readonly required: true;
12
+ readonly labelId: "widgetLabelText";
13
+ readonly doc: "The text to show. Rendered as plain text — markup is never interpreted.";
14
+ };
15
+ readonly align: {
16
+ readonly kind: "enum";
17
+ readonly values: readonly ["left", "center", "right"];
18
+ readonly labelId: "widgetLabelAlign";
19
+ readonly valueLabelIds: {
20
+ readonly left: "widgetAlignLeft";
21
+ readonly center: "widgetAlignCenter";
22
+ readonly right: "widgetAlignRight";
23
+ };
24
+ readonly placeholderId: "widgetPlaceholderDefault";
25
+ readonly doc: "Horizontal alignment of the text. Default center.";
26
+ };
27
+ readonly fontSize: {
28
+ readonly kind: "number";
29
+ readonly min: 1;
30
+ readonly labelId: "widgetLabelFontSize";
31
+ readonly helpId: "widgetHintFontSize";
32
+ readonly doc: "Text size in pixels. Default 16.";
33
+ };
34
+ }>;
@@ -1,2 +1,43 @@
1
- import { type WidgetProps } from '../widget';
1
+ import { type WidgetProps } from '@devicechain/widget-sdk';
2
2
  export declare function LatestCard({ widget, data }: WidgetProps): import("react").JSX.Element;
3
+ export declare const latestCardWidget: import("@devicechain/widget-sdk").WidgetDefinition<"measurement", {
4
+ readonly title: {
5
+ readonly kind: 'string';
6
+ readonly labelId: 'widgetLabelTitle';
7
+ readonly doc: 'Heading shown in the widget frame. Defaults to the displayed measurement name.';
8
+ };
9
+ readonly measurement: {
10
+ readonly kind: "string";
11
+ readonly labelId: "widgetLabelMeasurement";
12
+ readonly helpId: "widgetHintMeasurement";
13
+ readonly doc: "Which measurement to display. Defaults to the first the datasource selects.";
14
+ };
15
+ readonly unit: {
16
+ readonly kind: 'string';
17
+ readonly labelId: 'widgetLabelUnit';
18
+ readonly doc: 'Unit suffix shown beside the value.';
19
+ };
20
+ readonly precision: {
21
+ readonly kind: 'number';
22
+ readonly integer: true;
23
+ readonly min: 0;
24
+ readonly max: 100;
25
+ readonly labelId: 'widgetLabelPrecision';
26
+ readonly helpId: 'widgetHintPrecision';
27
+ readonly doc: 'Decimal places to round displayed values to. Unset shows the raw value.';
28
+ };
29
+ readonly flashOnChange: {
30
+ readonly kind: 'boolean';
31
+ readonly labelId: 'widgetFlashOnChange';
32
+ readonly helpId: 'widgetFlashOnChangeHint';
33
+ readonly doc: 'Briefly tint a value green on a rise and red on a fall when it changes.';
34
+ };
35
+ readonly window: {
36
+ readonly kind: 'number';
37
+ readonly integer: true;
38
+ readonly min: 1;
39
+ readonly labelId: 'widgetLabelWindow';
40
+ readonly helpId: 'widgetHintWindow';
41
+ readonly doc: 'Samples retained across ALL of the widget\'s measurements before the oldest are dropped. Bounds memory; only the chart draws them. Default 300.';
42
+ };
43
+ }>;
@@ -1,3 +1,23 @@
1
- import type { LocationStreamState } from '../hooks';
2
- import { type WidgetProps } from '../widget';
1
+ import { type LocationStreamState, type WidgetProps } from '@devicechain/widget-sdk';
3
2
  export declare function MapWidget({ widget, data }: WidgetProps<LocationStreamState>): import("react").JSX.Element;
3
+ export declare const mapWidget: import("@devicechain/widget-sdk").WidgetDefinition<"location", {
4
+ readonly title: {
5
+ readonly kind: 'string';
6
+ readonly labelId: 'widgetLabelTitle';
7
+ readonly doc: 'Heading shown in the widget frame. Blank hides the frame heading.';
8
+ };
9
+ readonly tileUrl: {
10
+ readonly kind: "string";
11
+ readonly labelId: "widgetLabelTileUrl";
12
+ readonly helpId: "widgetTileUrlHint";
13
+ readonly control: "basemap";
14
+ readonly doc: "Raster tile URL template, e.g. https://tiles.example.com/{z}/{x}/{y}.png. Leave empty to inherit the tenant's basemap; setting one overrides it for this board only.";
15
+ };
16
+ readonly attribution: {
17
+ readonly kind: "string";
18
+ readonly labelId: "widgetLabelAttribution";
19
+ readonly helpId: "widgetAttributionHint";
20
+ readonly control: "basemap";
21
+ readonly doc: "Credit line the tile source requires, shown on the map. Set whatever the provider you chose asks for.";
22
+ };
23
+ }>;
@@ -1,2 +1,32 @@
1
- import { type WidgetProps } from '../widget';
1
+ import { type WidgetProps } from '@devicechain/widget-sdk';
2
2
  export declare function Table({ widget, data }: WidgetProps): import("react").JSX.Element;
3
+ export declare const tableWidget: import("@devicechain/widget-sdk").WidgetDefinition<"measurement", {
4
+ readonly title: {
5
+ readonly kind: 'string';
6
+ readonly labelId: 'widgetLabelTitle';
7
+ readonly doc: 'Heading shown in the widget frame. Blank hides the frame heading.';
8
+ };
9
+ readonly precision: {
10
+ readonly kind: 'number';
11
+ readonly integer: true;
12
+ readonly min: 0;
13
+ readonly max: 100;
14
+ readonly labelId: 'widgetLabelPrecision';
15
+ readonly helpId: 'widgetHintPrecision';
16
+ readonly doc: 'Decimal places to round displayed values to. Unset shows the raw value.';
17
+ };
18
+ readonly flashOnChange: {
19
+ readonly kind: 'boolean';
20
+ readonly labelId: 'widgetFlashOnChange';
21
+ readonly helpId: 'widgetFlashOnChangeHint';
22
+ readonly doc: 'Briefly tint a value green on a rise and red on a fall when it changes.';
23
+ };
24
+ readonly window: {
25
+ readonly kind: 'number';
26
+ readonly integer: true;
27
+ readonly min: 1;
28
+ readonly labelId: 'widgetLabelWindow';
29
+ readonly helpId: 'widgetHintWindow';
30
+ readonly doc: 'Samples retained across ALL of the widget\'s measurements before the oldest are dropped. Bounds memory; only the chart draws them. Default 300.';
31
+ };
32
+ }>;
@@ -1,2 +1,17 @@
1
- import { type WidgetProps } from '../widget';
1
+ import { type WidgetProps } from '@devicechain/widget-sdk';
2
2
  export declare function TimeSeriesChart({ widget, data }: WidgetProps): import("react").JSX.Element;
3
+ export declare const timeSeriesChartWidget: import("@devicechain/widget-sdk").WidgetDefinition<"measurement", {
4
+ readonly title: {
5
+ readonly kind: 'string';
6
+ readonly labelId: 'widgetLabelTitle';
7
+ readonly doc: 'Heading shown in the widget frame. Blank hides the frame heading.';
8
+ };
9
+ readonly window: {
10
+ readonly kind: 'number';
11
+ readonly integer: true;
12
+ readonly min: 1;
13
+ readonly labelId: 'widgetLabelWindow';
14
+ readonly helpId: 'widgetHintWindow';
15
+ readonly doc: 'Samples retained across ALL of the widget\'s measurements before the oldest are dropped. Bounds memory; only the chart draws them. Default 300.';
16
+ };
17
+ }>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devicechain/widgets",
3
- "version": "0.19.0-rc.1",
4
- "description": "DeviceChain presentational dashboard widgets across five channels — telemetry (time-series chart + gauge over Apache ECharts, latest card, table, label, image), alarm (table, count), control (command button), selection (entity selector), and location (map over MapLibre GL, lazily loaded, tile source supplied by the host app) — plus the renderer that lays them out. Themed via CSS custom properties, no Tailwind leakage.",
3
+ "version": "0.20.0-rc.4",
4
+ "description": "DeviceChain's built-in dashboard widgets across six channels — telemetry (time-series chart + gauge over Apache ECharts, latest card, table), static (label, image; no data), alarm (table, count), control (command button), selection (entity selector), and location (map over MapLibre GL, lazily loaded, tile source supplied by the host app) — plus the renderer that lays them out. Each is a registration built on @devicechain/widget-sdk. Themed via CSS custom properties, no Tailwind leakage.",
5
5
  "keywords": [
6
6
  "devicechain",
7
7
  "iot",
@@ -49,29 +49,30 @@
49
49
  "pretest": "node ../../scripts/build-packages.mjs",
50
50
  "test": "vitest run"
51
51
  },
52
- "dependencies": {
53
- "echarts": "^6.0.0"
54
- },
55
52
  "peerDependencies": {
56
- "@devicechain/client": "0.19.0-rc.1",
57
- "@devicechain/dashboards": "0.19.0-rc.1",
58
- "maplibre-gl": "^6.7.0",
59
- "react": "^19.2.8",
60
- "react-dom": "^19.2.8"
53
+ "@devicechain/client": "0.20.0-rc.4",
54
+ "@devicechain/dashboards": "0.20.0-rc.4",
55
+ "@devicechain/widget-sdk": "0.20.0-rc.4",
56
+ "echarts": "^6.0.0",
57
+ "maplibre-gl": "^6.11.2",
58
+ "react": "^19.3.0",
59
+ "react-dom": "^19.3.0"
61
60
  },
62
61
  "devDependencies": {
63
- "@devicechain/client": "0.19.0-rc.1",
64
- "@devicechain/dashboards": "0.19.0-rc.1",
62
+ "@devicechain/client": "0.20.0-rc.4",
63
+ "@devicechain/dashboards": "0.20.0-rc.4",
64
+ "@devicechain/widget-sdk": "0.20.0-rc.4",
65
65
  "@testing-library/react": "^16.3.3",
66
- "@types/node": "^26.4.1",
67
- "@types/react": "^19.2.18",
68
- "@types/react-dom": "^19.2.7",
66
+ "@types/node": "^26.6.4",
67
+ "@types/react": "^19.3.0",
68
+ "@types/react-dom": "^19.3.0",
69
+ "echarts": "^6.0.0",
69
70
  "esbuild": "^0.28.2",
70
- "jsdom": "^30.0.1",
71
- "maplibre-gl": "^6.7.0",
72
- "react": "^19.2.8",
73
- "react-dom": "^19.2.8",
71
+ "jsdom": "^30.1.1",
72
+ "maplibre-gl": "^6.11.2",
73
+ "react": "^19.3.0",
74
+ "react-dom": "^19.3.0",
74
75
  "typescript": "~7.0.2",
75
- "vitest": "^5.0.0"
76
+ "vitest": "^5.0.3"
76
77
  }
77
78
  }
@@ -1,14 +0,0 @@
1
- import type { MeasurementSample } from '@devicechain/dashboards';
2
- import type { EChartOption } from './echart';
3
- import type { ElementSize } from './hooks';
4
- import type { ChartTheme } from './theme';
5
- export interface LineChartOptions {
6
- measurements?: string[];
7
- }
8
- export declare function buildLineOption(samples: MeasurementSample[], theme: ChartTheme, options?: LineChartOptions, size?: ElementSize): EChartOption;
9
- export interface GaugeChartOptions {
10
- min?: number;
11
- max?: number;
12
- unit?: string;
13
- }
14
- export declare function buildGaugeOption(value: number | null, theme: ChartTheme, options?: GaugeChartOptions, size?: ElementSize): EChartOption;
package/dist/echart.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import * as echarts from 'echarts/core';
2
- export type EChartOption = echarts.EChartsCoreOption;
3
- export interface EChartProps {
4
- option: EChartOption;
5
- className?: string;
6
- style?: React.CSSProperties;
7
- }
8
- export declare function EChart({ option, className, style }: EChartProps): import("react").JSX.Element;
package/dist/flash.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import { type CSSProperties } from 'react';
2
- export type FlashDirection = 'up' | 'down' | null;
3
- export declare function useFlashOnChange(value: number | null | undefined, enabled: boolean, identity?: string | number): FlashDirection;
4
- export declare function flashTextStyle(direction: FlashDirection, fadeMs?: number): CSSProperties;
5
- export declare function flashBackgroundStyle(direction: FlashDirection, fadeMs?: number): CSSProperties;
6
- export declare function FlashValue({ value, precision, enabled, identity, baseColor, style, }: {
7
- value: number | null | undefined;
8
- precision?: number;
9
- enabled: boolean;
10
- identity?: string | number;
11
- baseColor?: string;
12
- style?: CSSProperties;
13
- }): import("react").JSX.Element;
package/dist/format.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare function formatTimestamp(iso: string | null): string;
2
- export declare function formatDateTime(iso: string | null): string;
3
- export declare function formatValue(value: number | null | undefined, precision?: number): string;
package/dist/frame.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import { type CSSProperties, type ReactNode } from 'react';
2
- import type { SelectionCandidate, SelectionTarget } from '@devicechain/dashboards';
3
- export declare function WidgetSubjectProvider({ label, children, }: {
4
- label: string | undefined;
5
- children: ReactNode;
6
- }): import("react").JSX.Element;
7
- export type WidgetSelect = (target: SelectionTarget) => void;
8
- export declare function WidgetSelectProvider({ select, children, }: {
9
- select: WidgetSelect | undefined;
10
- children: ReactNode;
11
- }): import("react").JSX.Element;
12
- export declare function useWidgetSelect(): WidgetSelect | undefined;
13
- export type WidgetCandidates = (slot: string) => Promise<SelectionCandidate[]>;
14
- export declare function WidgetCandidatesProvider({ candidates, children, }: {
15
- candidates: WidgetCandidates | undefined;
16
- children: ReactNode;
17
- }): import("react").JSX.Element;
18
- export declare function useWidgetCandidates(): WidgetCandidates | undefined;
19
- export interface WidgetFrameProps {
20
- title?: string;
21
- subtitle?: string;
22
- children: ReactNode;
23
- bodyStyle?: CSSProperties;
24
- }
25
- export declare function WidgetFrame({ title, subtitle, children, bodyStyle }: WidgetFrameProps): import("react").JSX.Element;
package/dist/hooks.d.ts DELETED
@@ -1,54 +0,0 @@
1
- import type { AlarmRow, AlarmSubscription, CommandRow, CommandSubscription, DashboardDefinition, DatasourceSelector, EntityCandidateLister, LocationSample, LocationSubscription, MemberResolver, MeasurementSample, SelectionCandidate, SlotBinding, WidgetDataSource } from '@devicechain/dashboards';
2
- import { type RefObject } from 'react';
3
- import { type WidgetCandidates } from './frame';
4
- import { type ChartTheme } from './theme';
5
- export declare function useResolvedBindings(definition: DashboardDefinition, base: Record<string, SlotBinding>, selection: Record<string, SlotBinding>, resolver: MemberResolver): Record<string, SlotBinding>;
6
- export declare function useSlotCandidates(definition: DashboardDefinition, bindings: Record<string, SlotBinding>, resolver: MemberResolver, lister: EntityCandidateLister | undefined): WidgetCandidates | undefined;
7
- export interface CandidatesState {
8
- candidates: SelectionCandidate[];
9
- loading: boolean;
10
- error: unknown | null;
11
- wired: boolean;
12
- }
13
- export declare function useCandidates(slot: string | undefined): CandidatesState;
14
- export interface MeasurementStreamState {
15
- latest: Record<string, MeasurementSample>;
16
- samples: MeasurementSample[];
17
- error: unknown | null;
18
- }
19
- export interface AlarmStreamState {
20
- alarms: AlarmRow[];
21
- total: number;
22
- loading: boolean;
23
- error: unknown | null;
24
- }
25
- export interface CommandStreamState {
26
- deviceToken: string | null;
27
- commands: CommandRow[];
28
- total: number;
29
- loading: boolean;
30
- error: unknown | null;
31
- }
32
- export interface LocationStreamState {
33
- locations: LocationSample[];
34
- deviceTokens: string[];
35
- forbidden: boolean;
36
- loading: boolean;
37
- error: unknown | null;
38
- }
39
- export interface MeasurementStreamOptions {
40
- window?: number;
41
- initialSamples?: MeasurementSample[];
42
- }
43
- export declare function useMeasurementStream(hub: WidgetDataSource, datasource: DatasourceSelector | undefined, options?: MeasurementStreamOptions): MeasurementStreamState;
44
- export declare function useAlarmStream(hub: WidgetDataSource, subscription: AlarmSubscription): AlarmStreamState;
45
- export declare function useCommandStream(hub: WidgetDataSource, subscription: CommandSubscription): CommandStreamState;
46
- export declare function useLocationStream(hub: WidgetDataSource, subscription: LocationSubscription): LocationStreamState;
47
- export type DatasourceAvailability = 'unknown' | 'available' | 'unavailable';
48
- export declare function useDatasourceAvailability(hub: WidgetDataSource, datasource: DatasourceSelector | undefined): DatasourceAvailability;
49
- export interface ElementSize {
50
- width: number;
51
- height: number;
52
- }
53
- export declare function useElementSize<T extends HTMLElement>(): [RefObject<T | null>, ElementSize];
54
- export declare function useChartTheme(): ChartTheme;
package/dist/theme.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export declare function css(name: ThemeVar): string;
2
- export type ThemeVar = 'background' | 'foreground' | 'card' | 'card-foreground' | 'muted' | 'muted-foreground' | 'primary' | 'border' | 'destructive';
3
- export interface ChartTheme {
4
- foreground: string;
5
- mutedForeground: string;
6
- border: string;
7
- series: string[];
8
- }
9
- export declare function resolveChartTheme(el: Element): ChartTheme;
package/dist/widget.d.ts DELETED
@@ -1,16 +0,0 @@
1
- import type { MeasurementSample, WidgetActions, WidgetInstance } from '@devicechain/dashboards';
2
- import type { ComponentType } from 'react';
3
- import type { MeasurementStreamState } from './hooks';
4
- export interface WidgetProps<D = MeasurementStreamState> {
5
- widget: WidgetInstance;
6
- data: D;
7
- actions?: WidgetActions;
8
- }
9
- export type WidgetComponent<D = MeasurementStreamState> = ComponentType<WidgetProps<D>>;
10
- export declare function pickSample(latest: Record<string, MeasurementSample>, name: string | undefined): MeasurementSample | undefined;
11
- type Options = Record<string, unknown> | undefined;
12
- export declare function optString(options: Options, key: string): string | undefined;
13
- export declare function optNumber(options: Options, key: string): number | undefined;
14
- export declare function optBoolean(options: Options, key: string): boolean;
15
- export declare function primaryMeasurementName(widget: WidgetInstance): string | undefined;
16
- export {};