# widgets

`contributes.widgets` 中的每一项对应一种可放置的超级块。完整开发过程见[创建超级块](../guides/widgets.md)。

## 页面与配置

`page` 相对插件根目录，`configPage` 相对主页面所在目录。配置字段使用 [WidgetSettings](./settings.md)，它与动作的 [Schema](./schema.md)分开定义。

## 手势与页面交互

如果组件是一个只读显示界面，可以通过 `customizableGestures` 让用户配置点击、长按等动作。如果页面自己处理按钮或滑块交互，使用 `instanceActions` 向后台提交操作。

## Widget

清单位置：`manifest.contributes.widgets[]`。

### `Widget.id`

`string` · 必填

超级块类型 ID，在本插件的 `widgets` 中唯一。

### `Widget.title`

`string` · 必填

目录中显示的名称。

### `Widget.description`

`string` · 可选

组件用途说明，最多 240 个字符。

### `Widget.category`

`string` · 可选

超级块目录分类，最多 48 个字符。

### `Widget.page`

`string` · 必填

主页面路径，例如 `pages/counter/index.html`。页面放在独立资源目录中。

### `Widget.configPage`

`string` · 可选

配置页面相对主页面目录的路径，例如 `settings.html`，最多 128 个字符。

### `Widget.defaultSize`

`WidgetSize` · 必填

默认占用的网格大小。

### `Widget.allowedSizes`

`WidgetSize[]` · 可选

用户可选的大小，最多 16 项，并包含 `defaultSize`。省略时只允许默认大小。每个规格都应验证实际页面内容区的排版；网格占位不等于 iframe 宽高，详见[响应式布局最佳实践](../guides/responsive-widgets.md)。

### `Widget.stateSource`

`string` · 可选

页面订阅的状态来源 ID，该来源应允许超级块读取。

### `Widget.customizableGestures`

`string[]` · 可选

可配置的手势：`click`、`doubleClick`、`swipeLeft`、`swipeRight`、`longPress`。填写非空、不重复的列表。

### `Widget.instanceActions`

`WidgetInstanceAction[]` · 可选

页面提交给后台的操作，最多 16 项。

### `Widget.settingsSchema`

`WidgetSettings` · 可选

每个放置实例的配置字段，见 [WidgetSettings](./settings.md)。

## WidgetSize

清单位置：`manifest.contributes.widgets[].defaultSize`。

### `WidgetSize.cols`

`integer` · 必填

横向占用的网格数，1–16。

### `WidgetSize.rows`

`integer` · 必填

纵向占用的网格数，1–16。

## WidgetInstanceAction

清单位置：`manifest.contributes.widgets[].instanceActions[]`。

### `WidgetInstanceAction.id`

`string` · 必填

实例动作 ID，使用小写字母开头，可包含小写字母、数字和 `-`，最多 32 个字符。

### `WidgetInstanceAction.title`

`string` · 可选

流程选择器显示的名称，最多 64 个字符。

### `WidgetInstanceAction.argsSchema`

`Schema` · 可选

实例动作参数，根 `type` 为 `object`。省略时只接收空对象。

### `WidgetInstanceAction.execution`

`ActionExecution` · 可选

使用与[普通动作](./actions.md#actionexecution)相同的超时、并发和资源声明。默认与同插件普通动作共用串行队列；可显式声明 `resource`、`hostResource` 或 `concurrency`。

## 可复用的数值控件

### `Widget.valueControl`

`true` · 可选

声明此页面是由用户绑定目标的数值控件。要求宿主能力 `widgets.valueControl` v1。用户在“编辑超级块 → 控制目标”中选择显式声明 Action.valueControl 的数值设置动作；参数由声明确定，范围和默认反馈自动填入，用户可调整范围、更换或清除反馈。其他必需参数在同一界面填写；目标可以属于任何已安装、兼容的平台插件，无需双向依赖。控制目标也可以是可写入的数字类型自定义状态，要求宿主能力 `widgets.stateControl` v1；宿主按状态 Schema 校验范围与步长，状态不可用或超出可见范围时绑定无效。

页面先通过 `window.FlyonDeckWidget.getControlValue()` 获取 `{minimum,maximum,step,value,available,title,icon?,updatedAt?,message?}`；`value` 为 null 表示尚无可用反馈。调用 `setValue(number)` 提交目标单位中的实际值。用户绑定保存在宿主布局，页面不能传入目标插件、动作、反馈路径或固定参数。设备布局也不包含绑定详情。

首版支持显式开放的普通动作顶层 number/integer 参数，不支持枚举数值、流程输入、跨实例私有状态。反馈必须是全局可见、允许小组件读取的全局数值字段；没有反馈也可只写。目标停止、状态缺失或配置无效会显示不可用，不自动替换目标。

框架保留 `set-value` 实例动作和 `control-value` 数据查询名称；声明 valueControl 后不能再为同一小组件声明这些端点。宿主重新读取真实布局并走统一动作执行器；旧的排队请求在绑定改变后失效。

内置“通用控件 → 通用滑块”使用此协议，拖动只改变预览，松手或键盘提交时执行；每 1.5 秒读取反馈，宿主合并同一实例的待执行数值。它不依赖音量、天气等业务插件。

动作反馈绑定可选保存 `state.availabilityPath`，由动作的默认反馈声明初始化，用户可以更换或清除。该路径必须指向反馈来源中已声明的布尔字段；值为 `true` 才使用数值，缺失或为 `false` 时反馈不可用。没有声明时不检查可用性，宿主不会对 `available` 等业务字段名作特殊处理。

绑定策略集中在独立的 WidgetControlBindings 模块，通过布局、动作目录、状态和执行入口工作；它不依赖 Electron、HTTP、WebSocket 或具体控件插件。通信层仅识别框架端点并转交。不可用标题取自控件声明，无法取得声明时使用“数值控件”。
