Widget SDK
Build custom dashboard widgets for the Hiclaro desktop and mobile clients. Plugins can ship widget bundles alongside their service — no framework changes required.
Overview
Widget bundles are optional additions to a plugin zip. The desktop client renders widgets as Custom Elements (Web Components). The mobile client renders widgets as React Native components. Both bundle types are independently optional — a plugin can ship one, both, or neither.
Once installed, the widget picker in the dashboard shows a live preview of each widget. Users can add, configure, and remove widget instances without any backend involvement.
Declaring widgets in plugin.json
Each widget your plugin provides must be declared in the widgets[] array in plugin.json. These entries are stored in the database at install time and power the widget picker, config form, and preview.
widgets[] fields
| Field | Type | Required | Description |
|---|---|---|---|
tag | string | Yes | Custom element tag name. Must be globally unique across all installed widgets and must contain a hyphen (Web Components requirement), e.g. my-plugin-sensor. |
name | string | Yes | Human-readable display name shown in the widget picker. |
version | string | Yes | Semantic version string, e.g. 1.0.0. |
frameworkRequires | string | Yes | Semver range of compatible Hiclaro framework versions, e.g. >=1.0.0 <2.0.0. |
description | string | No | Short description shown beneath the widget name in the picker. |
author | string | No | Widget author name. |
inputs | object | Yes | Config form schema. A map of field name to InputField descriptor. Pass {} if the widget requires no user configuration. |
preview | object | Yes | Static data used to render a live preview in the widget picker. Contains instanceConfig (prop values passed to the widget) and telemetry (latest/history snapshots served by the preview API). |
Input field types
The inputs object maps config key names to InputField descriptors. These drive the form shown when a user adds or edits a widget instance. The resolved values are passed to the widget as instanceConfig.
| type | Description |
|---|---|
string | Free-text input. |
number | Numeric input. Optional: min, max, step, unit. |
boolean | Toggle / checkbox. |
select | Dropdown. Requires options: [{ label, value }]. Set multiple: true for multi-select. |
datasource | Datasource picker. The resolved value stored in instanceConfig is a database UUID string — pass it directly to subscribeTelemetry({ datasourceIds: [datasourceId] }). Use accepts: ['number'] (an array) to restrict which datasource types the user can pick. Omit accepts to allow all types. Set multiple: true to allow selecting several. |
asset | Asset picker. The resolved value is a database UUID string. Set multiple: true to allow several. |
range | A [min, max] numeric pair. Optional: min, max, step, unit. |
array | Repeatable list of sub-objects. Requires items: Record<string, InputField>. |
object | A nested object. Requires fields: Record<string, InputField>. |
stringList | A list of free-text strings, rendered as an add/remove tag input. |
map | A dynamic key→value string map rendered as editable rows. |
Preview data
The preview object provides static data the picker uses to render a live widget preview without a real device connected. instanceConfig is passed directly to the widget as its config. telemetry.latest and telemetry.history are served by the preview widgetApi when the widget calls subscribeTelemetry. Use the preview:: namespace for datasource and device IDs so they never collide with real IDs.
Widget background color
Add a top-level widgetColor field to plugin.json to give all widgets from your plugin a distinctive background color. This makes it easy for users to identify at a glance which plugin a widget belongs to.
When widgetColor is omitted, the dashboard falls back to the default widget background: white in light mode and #007399 in dark mode.
Use a color that represents your plugin's brand or the hardware it integrates — for example, a Tapo plugin might use #00A2E0 (TP-Link blue) and a solar inverter plugin might use #F5A623 (amber). Keep in mind the color will be the full background of the widget card, so pick something that leaves the widget content readable.