diff --git a/README.md b/README.md
index d9a412e..59a8b49 100755
--- a/README.md
+++ b/README.md
@@ -2,21 +2,11 @@
A new web application development framework to make web application development more easier like play bricks
## Documentation
-We have English and Chinese versions documents,
-Documents in English, please read from [docs](docs/README.md), 中文资料看[这里](docs/cn/README.md)
-## Development base on components
+We have documents in 3 language
-We built web development components which use a options objects as API.
-third party can develops their component suply the standard of components API
+* [中文](docs/zh/brief.md)
+* [日本語](docs/ja/brief.md)
+* [English](docs/en/brief.md)
-Most front-end development tools only help user to build the front-end UI, and use script to build the app's logic.
-
-Bricks not only build the UI but also the front-end logic.
-
-Bricks provide a new mathiciam to description the event fire, and event handler, Bricks use json data to descripts event and it handler, when event fire, according the json data, Bricks dynamicly constructs the event handler.
-
-
-## Dependanance
-
-[Marked](https://github.com/yumoqing/marked) is a tool for markdown text parser, extends from [MarkedJs marked](https://github.com/markedjs/marked), we extends audio and video link, user can directly use `!v[text](url)` pattern to show a video player, and `!a[text](url)` pattern to show a audio player
+NOTE: all the documents was generated by Qwen3-max
diff --git a/bricks/echartsext.js b/bricks/echartsext.js
index 65f896b..77ac65f 100644
--- a/bricks/echartsext.js
+++ b/bricks/echartsext.js
@@ -22,6 +22,10 @@ bricks.EchartsExt = class extends bricks.VBox {
if(!this.idField) this.idField = 'id';
if(!this.nameField) this.nameField = 'name';
if(!this.valueFields) this.valueFields = ['value'];
+ // === 新增:处理 refresh_period ===
+ this.refresh_period = opts.refresh_period; // 单位:秒
+ this._refresh_timer = null;
+
this.build_title_widget();
this.build_description_widget();
this.holder = new bricks.Filler({});
@@ -33,7 +37,49 @@ bricks.EchartsExt = class extends bricks.VBox {
schedule_once(this.render_urldata.bind(this), 0.1);
}
this.bind('element_resize', this.chart.resize.bind(this.chart));
+ // === 启动定时刷新(如果配置了 refresh_period)===
+ if (this.refresh_period && this.data_url) {
+ this.start_auto_refresh();
+ }
}
+ // === 启动自动刷新任务 ===
+ start_auto_refresh() {
+ if (this._refresh_timer) return; // 防止重复启动
+
+ const doRefresh = () => {
+ this.render_urldata().then(() => {
+ // 继续下一轮
+ if (this._refresh_timer) { // 检查是否已被取消
+ this._refresh_timer = setTimeout(doRefresh, this.refresh_period * 1000);
+ }
+ }).catch(err => {
+ console.error('Auto-refresh failed:', err);
+ this._refresh_timer = setTimeout(doRefresh, this.refresh_period * 1000); // 失败也重试
+ });
+ };
+
+ // 初始延迟后开始第一轮,之后循环
+ this._refresh_timer = setTimeout(doRefresh, this.refresh_period * 1000);
+ }
+
+ // === 停止自动刷新 ===
+ stop_auto_refresh() {
+ if (this._refresh_timer) {
+ clearTimeout(this._refresh_timer);
+ this._refresh_timer = null;
+ }
+ }
+
+ // === 覆盖 destroy 方法,清理定时器 ===
+ destroy() {
+ this.stop_auto_refresh(); // 清理资源
+ if (this.chart) {
+ this.chart.dispose();
+ this.chart = null;
+ }
+ super.destroy();
+ }
+
pivotify(data){
var series = [];
data.forEach(x => {
@@ -83,7 +129,6 @@ bricks.EchartsExt = class extends bricks.VBox {
this.valueFields = this.get_series(data);
data = this.pivotify(data);
}
- this.chart = echarts.init(this.holder.dom_element);
var opts = this.setup_options(data);
opts.grid = {
left: '3%',
diff --git a/docs/HBox.md b/docs/HBox.md
deleted file mode 100644
index f3d5bb3..0000000
--- a/docs/HBox.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# HBox
-Hbox是一个水平布局小部件,它按水平方向布局子小部件
-## 用法
-```html
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-
-
-**注意:hbox控件是水平排列的控件,相当于一个容器,可以容纳其他的控件,如button,form等**
-
diff --git a/docs/ai.old/.DS_Store b/docs/ai.old/.DS_Store
deleted file mode 100644
index 072fb17..0000000
Binary files a/docs/ai.old/.DS_Store and /dev/null differ
diff --git a/docs/ai.old/accordion.md b/docs/ai.old/accordion.md
deleted file mode 100644
index 5b11f55..0000000
--- a/docs/ai.old/accordion.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Accordion
-用于实现手风琴式折叠面板效果,允许用户通过点击选项卡切换显示对应的内容区域;类型为容器控件,继承自bricks.VBox。
-
-## 主要方法
-| 方法名 | 功能说明 | 参数/选项 |
-|--------|----------|-----------|
-| `constructor(opts)` | 初始化手风琴控件,创建选项卡按钮并默认展开第一个选项卡内容 | - `item_size`:选项卡高度,默认值为`25px` - `items`:选项卡配置数组,每个项需包含`name`(唯一标识)、`icon`(图标类名)、`label`(选项卡文本)、`content`(选项卡对应的内容控件JSON)、`refresh`(是否每次切换都重新构建内容,默认`false`) - `item_css`:选项卡按钮的CSS类,默认`accordion-button` - `content_css`:内容区域的CSS类,默认`accordion-content` |
-| `async change_content(event)` | 点击选项卡按钮时触发,切换显示对应的内容区域。若`refresh`为`true`或内容未构建过,则重新构建内容控件 | - `event`:事件对象,`target.bricks_widget`指向被点击的选项卡按钮 |
-
-## 主要事件
-| 事件名 | 触发时机 |
-|--------|----------|
-| `click`(选项卡按钮) | 用户点击手风琴的任意选项卡按钮时触发,进而执行内容切换逻辑 |
-
-## 源码例子
-```json
-{
- "id": "demo_accordion", // 手风琴控件唯一ID
- "widgettype": "Accordion", // 控件类型为Accordion
- "options": {
- "item_size": "30px", // 自定义选项卡高度为30px
- "items": [ // 选项卡配置数组
- {
- "name": "tab_home", // 选项卡唯一标识
- "icon": "icon-home", // 选项卡图标类名
- "label": "首页", // 选项卡文本
- "content": { // 首页对应的内容控件(Label)
- "widgettype": "Label",
- "options": {
- "text": "欢迎使用手风琴控件演示",
- "align": "center"
- }
- }
- },
- {
- "name": "tab_info",
- "icon": "icon-info",
- "label": "信息",
- "content": { // 信息页对应的内容控件(VBox容器,包含Label和Button)
- "widgettype": "VBox",
- "options": {
- "align": "left"
- },
- "subwidgets": [
- {
- "widgettype": "Label",
- "options": {"text": "手风琴支持动态加载内容"}
- },
- {
- "widgettype": "Button",
- "options": {"label": "查看详情"},
- "binds": [ // 按钮事件绑定
- {
- "actiontype": "script",
- "wid": "infoBtn", // 按钮ID
- "event": "click",
- "target": "demo_accordion",
- "script": "console.log('点击了查看详情按钮');" // 执行自定义脚本
- }
- ]
- }
- ]
- }
- }
- ]
- }
-}
-```
\ No newline at end of file
diff --git a/docs/ai.old/asr.md b/docs/ai.old/asr.md
deleted file mode 100644
index e03fee7..0000000
--- a/docs/ai.old/asr.md
+++ /dev/null
@@ -1,116 +0,0 @@
-# ASRClient
-
-用于实现语音识别(ASR,Automatic Speech Recognition)功能的前端控件。用户点击按钮开始录音,控件通过浏览器的 `MediaRecorder API` 获取麦克风音频流,并将音频数据编码为 Base64 后通过 WebSocket 实时发送至后端服务器进行语音识别。识别结果由服务器返回,控件触发 `transtext` 事件将文本内容传递给上层逻辑处理。
-
-**类型**:普通控件(继承自 `bricks.VBox`)
-
----
-
-## 主要方法
-
-- **`toggle_button()`**
- 切换录音状态(开始/停止),并更新按钮图标。
-
-- **`start_recording()`**
- 异步方法,请求用户授权麦克风权限,启动 `MediaRecorder` 每秒采集音频片段并通过 WebSocket 发送。
-
-- **`stop_recording()`**
- 停止 `MediaRecorder` 录音,关闭媒体流。
-
-- **`response_data(event)`**
- WebSocket 接收到服务器消息时调用,解析 JSON 数据并派发 `transtext` 事件。
-
-- **`response_log(event)`**
- 默认的日志处理函数,在控制台输出识别结果,可通过重写来自定义日志行为。
-
----
-
-## 主要事件
-
-- **`start`**
- 当用户点击按钮开始录音时触发,无参数。
-
-- **`stop`**
- 当用户停止录音时触发,无参数。
-
-- **`transtext`**
- 服务器返回识别文本时触发,参数结构如下:
- ```json
- {
- "content": "识别出的文本",
- "speaker": "说话人标识(可选)",
- "start": "起始时间戳",
- "end": "结束时间戳"
- }
- ```
-
----
-
-## 源码例子
-
-```json
-{
- "id": "asr_widget",
- "widgettype": "ASRClient",
- "options": {
- // 开始录音时显示的图标(可选)
- "start_icon": "imgs/start_recording.svg",
- // 停止录音时显示的图标(可选)
- "stop_icon": "imgs/stop_recording.png",
- // WebSocket 连接地址(必须)
- "ws_url": "wss://example.com/api/asr/stream",
- // 图标控件的额外配置(如大小、样式等,可选)
- "icon_options": {
- "width": "50px",
- "height": "50px"
- },
- // 发送给 WebSocket 的附加参数(例如模型类型、语言等)
- "ws_params": {
- "lang": "zh-CN",
- "model": "asr-general"
- }
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "asr_widget",
- "event": "transtext",
- "target": "text_display",
- "dispatch_event": "update_text",
- "params": {
- "from": "ASR"
- },
- "rtdata": {
- "msg": "{content}"
- }
- },
- {
- "actiontype": "script",
- "wid": "asr_widget",
- "event": "start",
- "target": "logger",
- "script": "console.log('ASR recording started...');"
- },
- {
- "actiontype": "script",
- "wid": "asr_widget",
- "event": "stop",
- "target": "logger",
- "script": "console.log('ASR recording stopped.');"
- }
- ]
-}
-```
-
-> ✅ **说明与注释**:
->
-> - `widgettype: "ASRClient"` 表示使用已注册的语音识别控件。
-> - `options.ws_url` 必须是一个有效的 WebSocket 地址(`ws://` 或 `wss://`)。
-> - `binds` 中监听了 `transtext` 事件,将识别结果动态更新到 ID 为 `text_display` 的控件中。
-> - 使用 `{content}` 占位符可在运行时自动替换为实际识别内容(基于 bricks 数据绑定机制)。
-> - 可结合 `registerfunction` 调用全局函数进一步处理识别结果,如语义理解、TTS 回复等。
-
----
-
-📌 **应用场景建议**:
-适用于语音输入、实时字幕、语音助手交互等需要前端采集语音并实时获取识别结果的场景。需确保后端支持 WebSocket 流式 ASR 解码。
\ No newline at end of file
diff --git a/docs/ai.old/audio.md b/docs/ai.old/audio.md
deleted file mode 100644
index 875cb07..0000000
--- a/docs/ai.old/audio.md
+++ /dev/null
@@ -1,282 +0,0 @@
-# AudioPlayer
-
-用于播放音频文件的普通控件,继承自 `JsWidget`。支持本地或远程音频资源播放、自动播放、播放控制(暂停/继续)、播放队列管理以及通过流式响应动态加载多个音频片段。
-
-**类型:** 普通控件(非容器控件)
-
----
-
-## 主要方法
-
-- `play()`
- 异步方法,开始播放当前音频。如果音频已暂停,则恢复播放。
-
-- `toggle_play()`
- 异步方法,切换播放/暂停状态。若当前为暂停状态则播放,否则暂停。
-
-- `set_url(url)`
- 设置音频源并立即开始播放。参数 `url` 为音频文件的 URL 地址。
-
-- `set_source(url)`
- 设置音频源(仅更新 `` 标签和 `audio.src`),不自动播放。
-
-- `add_url(url)`
- 将指定 URL 添加到播放列表末尾。如果当前音频处于“错误”或“结束”状态,则立即切换播放该音频;否则加入队列等待自动播放下一首。
-
-- `get_status()`
- 获取当前播放器的状态,返回值为以下之一:
- - `"playing"`:正在播放
- - `"paused"`:已暂停
- - `"loading"`:加载中(数据不足)
- - `"ended"`:播放结束
- - `"error"`:发生错误
-
-- `set_stream_urls(response)`
- 接收一个 `Response` 对象(如从 `fetch` 流式接口获取),解析其流中的每一段音频 URL,并逐个播放。适用于服务器推送多个音频片段的场景。
-
-- `play_srclist(event)`
- 内部异步方法,用于从 `srcList` 中按顺序播放未播放过的音频片段。
-
----
-
-## 主要事件
-
-- `ended`
- 当所有音频播放完毕(包括播放列表中的最后一个)时触发。可用于通知上层组件播放完成。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "player1",
- "widgettype": "AudioPlayer",
- "options": {
- "url": "/audio/intro.mp3", // 初始音频URL
- "autoplay": true // 是否自动播放
- },
- "binds": [
- {
- "actiontype": "method",
- "wid": "btn_toggle",
- "event": "click",
- "target": "player1",
- "method": "toggle_play",
- "params": {}
- },
- {
- "actiontype": "method",
- "wid": "btn_next",
- "event": "click",
- "target": "player1",
- "method": "add_url",
- "params": {
- "url": "/audio/chapter2.mp3"
- }
- },
- {
- "actiontype": "script",
- "wid": "player1",
- "event": "ended",
- "target": "Popup",
- "script": "bricks.alert('播放完成!');"
- }
- ]
-}
-```
-
-> **注释说明:**
-> - 此控件 ID 为 `player1`,初始加载并自动播放 `/audio/intro.mp3`。
-> - 点击 ID 为 `btn_toggle` 的按钮会调用 `toggle_play()` 方法实现播放/暂停切换。
-> - 点击 `btn_next` 按钮将添加新的音频到播放队列。
-> - 当音频播放结束后,弹出提示框告知用户“播放完成”。
-
----
-
-# AudioRecorder
-
-音频录制控件,继承自 `HBox`(水平布局容器控件)。提供麦克风录音功能,支持 WAV 格式录音、实时录音时长显示、录音开始/结束事件派发,并可配置上传 URL 实现录音文件自动上传。
-
-**类型:** 容器控件(继承自 HBox,包含子控件)
-
----
-
-## 主要方法
-
-- `start_recording()`
- 开始录音。若尚未打开麦克风权限,则先请求授权并初始化录音器。
-
-- `stop_recording()`
- 停止录音,生成 Blob 对象并派发 `record_ended` 事件,携带录音数据与播放 URL。
-
-- `pause_recording()`
- 暂停录音(如有支持)。
-
-- `resume_recording()`
- 恢复暂停的录音。
-
-- `upload()`
- 异步方法,将最近一次录音的数据通过 FormData 上传至 `upload_url` 配置的地址,使用 POST 请求发送文件 `recorder.wav`。
-
-- `download()`
- 下载当前录音文件,生成临时链接并触发浏览器下载行为。
-
-- `recOpen()` / `recClose()`
- 内部方法,用于打开/关闭麦克风访问权限及初始化 Recorder 实例。
-
----
-
-## 主要事件
-
-- `record_started`
- 当录音开始前触发,可用于 UI 更新(如切换图标、启用播放预览等)。
-
-- `record_ended`
- 录音停止后触发,携带数据对象 `{ data: Blob, url: string, duration: number }`,可用于预览或上传。
-
-- `uploaded`
- 成功上传录音后触发,携带服务器返回结果 `ret`。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "recorder1",
- "widgettype": "AudioRecorder",
- "options": {
- "upload_url": "/api/upload_audio", // 录音上传地址
- "start_icon": "imgs/start_recording.svg", // 开始录音图标
- "stop_icon": "imgs/stop_recording.svg", // 停止录音图标
- "icon_rate": 2 // SVG 图标缩放比例
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "recorder1",
- "event": "record_started",
- "target": "status_text",
- "dispatch_event": "set_text",
- "params": {
- "text": "正在录音..."
- }
- },
- {
- "actiontype": "event",
- "wid": "recorder1",
- "event": "record_ended",
- "target": "status_text",
- "dispatch_event": "set_text",
- "params": {
- "text": "录音结束,正在上传..."
- }
- },
- {
- "actiontype": "registerfunction",
- "wid": "recorder1",
- "event": "uploaded",
- "rfname": "onAudioUploaded",
- "params": {
- "recorderId": "recorder1"
- }
- },
- {
- "actiontype": "method",
- "wid": "btn_download",
- "event": "click",
- "target": "recorder1",
- "method": "download",
- "params": {}
- }
- ]
-}
-```
-
-> **注释说明:**
-> - 控件 ID 为 `recorder1`,使用自定义图标进行视觉反馈。
-> - 录音开始时,向 `status_text` 文本控件派发 `set_text` 事件更新状态。
-> - 录音结束后提示“正在上传”,并在上传成功后调用全局注册函数 `onAudioUploaded` 处理后续逻辑。
-> - 提供一个下载按钮 `btn_download`,允许用户手动下载录音文件。
-
----
-
-# TextedAudioPlayer
-
-带文本同步显示的音频播放器,继承自 `VBox`(垂直容器控件)。常用于语音朗读+字幕同步场景。能够接收流式 JSON 数据,其中包含音频 Base64 编码片段和对应文本内容,实现边接收边播放边展示文本的效果。
-
-**类型:** 容器控件(可包含子控件)
-
----
-
-## 主要方法
-
-- `set_stream_urls(response)`
- 接收一个 `Response` 流对象,从中读取 JSON 数据流(每个 JSON 包含 `audio` 和 `text` 字段),解码后缓存至内部队列。
-
-- `load_stream_data(json)`
- 内部异步方法,处理每一个流式到达的 JSON 数据块,将其推入播放缓冲区,并尝试触发播放。
-
-- `playnext()`
- 从缓冲区取出下一条音频+文本数据,设置音频播放,并更新文本区域内容。当播放完当前音频后自动触发下一首。
-
----
-
-## 主要事件
-
-无自定义事件对外暴露,但内部监听 `AudioPlayer` 的 `ended` 事件以驱动连续播放。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "texted_player",
- "widgettype": "TextedAudioPlayer",
- "options": {
- "height": "300px",
- "width": "100%"
- },
- "subwidgets": [],
- "binds": [
- {
- "actiontype": "urlwidget",
- "wid": "btn_start_read",
- "event": "click",
- "target": "texted_player",
- "options": {
- "url": "/api/stream-audio-text",
- "method": "POST",
- "params": {
- "text": "{{input_text}}"
- }
- },
- "mode": "replace"
- },
- {
- "actiontype": "method",
- "wid": "texted_player",
- "event": "ended",
- "target": "bricks",
- "method": "notify",
- "params": {
- "message": "全部朗读完成"
- }
- }
- ]
-}
-```
-
-> **注释说明:**
-> - 控件 ID 为 `texted_player`,是一个垂直布局容器,内部包含一个 `AudioPlayer` 和一个带滚动的文本区域。
-> - 点击 `btn_start_read` 按钮时,向 `/api/stream-audio-text` 发起 POST 请求,传入动态文本内容(例如来自输入框的 `input_text`)。
-> - 服务器以流式 JSON 响应返回多个 `{ audio: base64str, text: '...' }` 数据块,客户端逐步播放音频并同步显示文本。
-> - 所有内容播放完成后,调用 `bricks.notify` 显示完成通知。
-
----
-
-> ✅ **备注:**
-> 上述三个控件均已通过 `bricks.Factory.register` 注册,可在 `.ui` 文件中直接使用 `widgettype` 调用。
-> 使用时需确保引入依赖库:[Recorder.js](https://gitee.com/xiangyuecn/Recorder) 用于录音功能。
\ No newline at end of file
diff --git a/docs/ai.old/bar.md b/docs/ai.old/bar.md
deleted file mode 100644
index d337562..0000000
--- a/docs/ai.old/bar.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# ChartBar
-
-ChartBar 是一个基于 ECharts 的柱状图控件,用于可视化展示分类数据的数值对比。该控件继承自 `bricks.EchartsExt`,属于**普通控件**(非容器控件),不支持包含子控件。
-
----
-
-## 主要方法
-
-- **`values_from_data(data, name)`**
- 从传入的数据数组中提取指定字段的值,返回值数组。常用于构建 ECharts 的 series 数据。
-
-- **`lineinfo_from_data(data, name)`**
- 根据字段名生成单个柱状序列(series)的配置对象,类型为 `'bar'`。
-
-- **`setup_options(data)`**
- 核心方法,接收原始数据并生成完整的 ECharts 配置项(options),包括:
- - tooltip:轴触发提示
- - legend:图例(基于 nameField 字段)
- - xAxis:类别轴(横轴)
- - yAxis:数值轴(纵轴)
- - series:多个柱状图序列
-
----
-
-## 主要事件
-
-该控件未定义自定义事件,但继承了 `EchartsExt` 基类所支持的标准事件,例如:
-
-- `'click'`:用户点击图表时触发,可通过 binds 监听。
-- `'legendselectchanged'`:图例选择变化时触发。
-
-这些事件可用于与其他控件联动或执行脚本逻辑。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "chart_sales_bar",
- "widgettype": "ChartBar",
- "options": {
- "data_url": "/api/sales/data", // 从后端接口获取数据
- "method": "GET", // 请求方式,默认可省略
- "params": { // 请求参数
- "year": 2024,
- "region": "north"
- },
- "nameField": "month", // 用作 X 轴显示的字段(如月份)
- "valueFields": ["sales", "target"] // 多个指标字段,分别绘制为不同柱子
- },
- "binds": [
- {
- "actiontype": "bricks",
- "wid": "btn_refresh_chart",
- "event": "click",
- "target": "chart_sales_bar",
- "options": {
- "widgettype": "ChartBar",
- "options": {
- "data_url": "/api/sales/data",
- "params": {
- "year": "{{widget('input_year').getValue()}}", // 动态取输入框年份
- "region": "north"
- },
- "nameField": "month",
- "valueFields": ["sales", "target"]
- }
- },
- "mode": "replace"
- },
- {
- "actiontype": "script",
- "wid": "chart_sales_bar",
- "event": "click",
- "script": "async function({ params }) { console.log('柱状图点击:', params); }",
- "params": {}
- }
- ]
-}
-```
-
-> ✅ **注释说明:**
-> - 此控件通过 `data_url` 和 `params` 自动加载远程数据并渲染柱状图。
-> - `nameField` 定义 X 轴标签(如 “1月”, “2月”)。
-> - `valueFields` 支持多个字段,每个字段对应一个柱状系列(如销售额、目标额)。
-> - 使用 `binds` 实现按钮刷新图表和点击日志输出。
-> - `{{widget(...)}}` 表达式可在运行时动态获取其他控件的值,实现交互过滤。
\ No newline at end of file
diff --git a/docs/ai.old/button.md b/docs/ai.old/button.md
deleted file mode 100644
index f7ee81d..0000000
--- a/docs/ai.old/button.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Button
-
-按钮控件(Button)是 Bricks.js 框架中用于触发用户交互行为的**普通控件**,继承自 `bricks.Layout`。它通常用于提交表单、打开弹窗、执行脚本或导航等操作。Button 支持图标、文本标签、自定义样式以及事件绑定,适用于各种 UI 场景。
-
-## 主要方法
-
-- **`target_clicked(event)`**
- 内部方法,当按钮被点击时触发,阻止事件冒泡并派发 `click` 事件,同时处理配置的 `action` 行为。
-
-- **`create()`**
- 创建底层 DOM 元素(`` 标签),由框架自动调用。
-
-- **`opts_setup()`**
- 初始化按钮内容:根据 `opts.icon` 和 `opts.label` 创建图标和文本子控件,并添加到布局中。
-
-- **`add_widget(widget)`**
- 继承自父类,用于向按钮内部添加子控件(如 Icon 或 Text)。
-
-- **`bind(event, handler)`**
- 绑定自定义事件处理器(例如 `'click'` 事件)。
-
-## 主要事件
-
-- **`click`**
- 当按钮被用户点击时触发。可通过 `binds` 配置监听此事件,并执行相应动作(如调用方法、跳转页面、发送请求等)。
-
-## 源码例子
-
-```json
-{
- "id": "btn_submit", // 控件唯一标识
- "widgettype": "Button", // 控件类型:Button
- "options": {
- "name": "btn_submit", // 按钮名称(用于 DOM ID 设置)
- "label": "Submit", // 显示的文字标签(支持 i18n 国际化)
- "icon": "icons/submit.png", // 图标路径(可选)
- "color": "#ffffff", // 文字颜色
- "bgcolor": "#007BFF", // 背景色
- "item_rate": 1.2, // 图标与文字的比例系数
- "orientation": "horizontal", // 布局方向:horizontal(图标在左) / vertical
- "css": "custom-btn", // 自定义 CSS 类名
- "nonepack": false, // 是否去除默认 padding 和边框
- "action": {
- "actiontype": "method", // 点击后执行的动作类型
- "wid": "form_main", // 目标组件 ID
- "method": "submit", // 调用的方法名
- "params": {} // 方法参数
- }
- },
- "binds": [
- {
- "actiontype": "method", // 动作类型:调用方法
- "wid": "btn_submit", // 触发组件 ID
- "event": "click", // 监听事件:点击
- "target": "form_main", // 目标组件 ID
- "method": "validateAndSubmit", // 执行方法
- "params": {
- "showLoading": true
- }
- },
- {
- "actiontype": "script", // 执行脚本
- "wid": "btn_submit",
- "event": "click",
- "target": "", // script 类型无需 target
- "script": "console.log('Button clicked:', params);",
- "params": {
- "message": "Hello from Button!"
- }
- },
- {
- "actiontype": "event", // 派发自定义事件
- "wid": "btn_submit",
- "event": "click",
- "target": "Popup", // 向弹窗系统派发事件
- "dispatch_event": "open_dialog",
- "params": {
- "dialogId": "confirm_save"
- }
- }
- ]
-}
-```
-
-> ✅ **注释说明:**
->
-> - `widgettype: "Button"` 表示使用已注册的 Button 控件。
-> - `options` 中的 `action` 是按钮内置的行为配置,也可通过 `binds` 实现更复杂的逻辑。
-> - `binds` 数组允许一个按钮绑定多个不同类型的响应动作(方法调用、脚本执行、事件派发等)。
-> - 图标和文本会自动按 `orientation` 排列,`item_rate` 控制大小比例。
-> - 使用 `i18n: true`(隐式支持)时,`label` 可以从语言包中读取多语言值。
-> - `nonepack: true` 可用于创建无边距/无背景的纯净按钮,适合嵌入工具栏等场景。
\ No newline at end of file
diff --git a/docs/ai.old/camera.md b/docs/ai.old/camera.md
deleted file mode 100644
index ba92fd8..0000000
--- a/docs/ai.old/camera.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# Camera
-
-**控件用途**:
-`Camera` 是一个用于调用用户设备摄像头的弹窗式控件,支持拍照和视频录制功能。它继承自 `Popup` 控件,属于**容器控件**,可包含子控件(如按钮、图像显示区域等),并通过内置逻辑实现媒体流的获取与处理。
-
-- **类型**:容器控件(继承自 `bricks.Popup`)
-
----
-
-## 主要方法
-
-| 方法名 | 描述 |
-|--------|------|
-| `startCamera(vpos)` | 异步启动摄像头,使用指定的视频设备索引(vpos)初始化媒体流并开始预览。 |
-| `show_picture()` | 在画布上绘制当前视频帧,并实时更新到 `Image` 子控件中,实现取景器效果。 |
-| `switch_camera(btn, event)` | 切换当前使用的摄像头(前后置或多个摄像头之间切换)。 |
-| `take_picture(event)` | 拍摄当前画面并触发 `shot` 事件,传出图片的 Data URL。 |
-| `switch_recording()` | 切换录制状态:开始或停止视频录制。 |
-| `videorecorder_start()` | 启动 `MediaRecorder` 开始录制视频,保存数据片段。 |
-| `videorecorder_stop()` | 停止视频录制,并生成 Blob 文件,派发 `recorded` 事件。 |
-
----
-
-## 主要事件
-
-| 事件名 | 触发时机 | 参数 |
-|--------|---------|------|
-| `shot` | 拍照完成时触发 | `dataurl`: 当前截图的 JPEG 格式 Data URL 字符串 |
-| `recorded` | 视频录制结束时触发 | `file`: 生成的 WebM 格式视频文件对象(File) |
-| `dismiss` | 用户点击取消按钮关闭弹窗时触发 | 无参数(由 `del_btn` 的 click 绑定触发) |
-
----
-
-## 源码例子
-
-```json
-{
- "id": "camera_popup",
- "widgettype": "Camera",
- "options": {
- "type": "picture", // 可选 'picture' 或 'recorder'
- "fps": 60, // 帧率,默认为60
- "title": "拍照/录像" // 弹窗标题
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "shot_btn", // 实际ID会自动生成,此处仅为示意
- "event": "shot",
- "target": "image_preview",
- "dispatch_event": "setValue",
- "rtdata": {
- "value": "{data}" // 动态插入拍摄的图片URL
- }
- },
- {
- "actiontype": "event",
- "wid": "camera_popup",
- "event": "recorded",
- "target": "video_list",
- "dispatch_event": "addItem",
- "rtdata": {
- "item": {
- "name": "录制视频",
- "url": "{data}",
- "type": "video/webm"
- }
- }
- },
- {
- "actiontype": "method",
- "wid": "del_btn",
- "event": "click",
- "target": "camera_popup",
- "method": "dismiss"
- }
- ],
- "subwidgets": [
- // Camera 自身管理子控件,一般无需手动定义 subwidgets
- // 内部已构建:HBox(按钮栏)、Filler(图像展示区)、Svg按钮等
- ]
-}
-```
-
-> ✅ **注释说明**:
-> - `widgettype: "Camera"` 表示使用注册的 Camera 控件。
-> - `options.type` 决定是拍照模式还是录像模式:
-> - `"picture"`:显示拍照按钮,点击后触发 `shot` 事件;
-> - `"recorder"`:显示录制控制按钮,支持开始/停止录制,触发 `recorded` 事件。
-> - `binds` 中通过事件绑定将拍摄结果传递给其他控件进行后续处理(如显示或上传)。
-> - `target` 支持指向其他控件 ID,实现组件间通信。
-> - 使用 `{data}` 占位符可在运行时自动替换为事件携带的数据。
-
----
-
-💡 **提示**:
-该控件依赖全局 `bricks.app` 提供的 `start_camera(vpos)` 方法和 `video_devices` 设备列表,需确保平台支持 getUserMedia 并已正确初始化媒体权限。
\ No newline at end of file
diff --git a/docs/ai.old/cols.md b/docs/ai.old/cols.md
deleted file mode 100644
index 41f6f23..0000000
--- a/docs/ai.old/cols.md
+++ /dev/null
@@ -1,151 +0,0 @@
-# Cols
-
-**用途**:`Cols` 是一个用于展示分页滚动数据列表的容器控件,适用于移动端或响应式布局中以卡片形式展示多条记录(如新闻、商品、消息等)。它支持无限滚动加载前一页和后一页数据,具备自动触发加载机制,并可通过点击选中某一条记录。
-
-**类型**:容器控件,继承自 `bricks.VBox`
-
----
-
-## 主要方法
-
-| 方法名 | 说明 |
-|--------|------|
-| `load_first_page(params)` | 首次加载数据,可传入额外参数 `params` 合并到请求中。若配置了 `data_url`,则从服务器拉取数据;否则使用本地数据 `this.data`。 |
-| `load_previous_page()` | 加载上一页数据,当用户滚动到顶部时自动触发(绑定在 `min_threshold` 事件上)。 |
-| `load_next_page()` | 加载下一页数据,当用户滚动到底部时自动触发(绑定在 `max_threshold` 事件上)。 |
-| `dataHandle(d)` | 处理返回的数据 `d`,将每条记录渲染为一个子控件并插入主容器 `main` 中,支持逆序插入(用于上翻页)。 |
-| `delete_page(page)` | 删除指定页码的所有 DOM 元素及其对应的控件实例,用于清理不再需要的页面内容。 |
-| `create_main_widget()` | 创建内部显示区域的主控件 `DynamicColumn`,用于管理列数和响应式布局。 |
-| `show_with_data(data)` | 直接传入静态数据进行展示,不依赖远程 URL,适合临时数据显示。 |
-| `command_handle(event)` | 工具栏命令处理函数,派发工具栏按钮对应的事件名称。 |
-
----
-
-## 主要事件
-
-| 事件名 | 触发条件 | 携带数据 |
-|--------|----------|---------|
-| `record_click` | 用户点击某一条记录项时触发 | 当前记录的数据对象(`rw.user_data`) |
-| `command` | 工具栏按钮被点击时(由 `Toolbar` 控件发出),通过 `command_handle` 转发为同名事件 | 按钮定义中的 `name` 参数 |
-
-> 注:`min_threshold` 和 `max_threshold` 是 `VScrollPanel` 提供的滚动边界事件,分别表示滚动到顶部和底部,用于驱动分页加载。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "cols_example",
- "widgettype": "Cols",
- "options": {
- // 数据源地址,返回符合 PageDataLoader 格式的 JSON
- "data_url": "/api/news/list",
-
- // 请求参数
- "data_params": {
- "category": "tech",
- "page_size": 10
- },
-
- // HTTP 方法,默认 GET
- "data_method": "GET",
-
- // 每页显示行数
- "page_rows": 10,
-
- // 缓存页数限制
- "cache_limit": 5,
-
- // 列宽设置(百分比)
- "col_cwidth": "48%",
-
- // 移动端列数
- "mobile_cols": 1,
-
- // 标题文本(支持国际化)
- "title": "最新资讯",
- "i18n": true,
-
- // 描述信息(Markdown 支持)
- "description": "这里是科技类新闻列表",
-
- // 工具栏定义
- "toolbar": {
- "items": [
- {
- "type": "button",
- "text": "刷新",
- "name": "refresh"
- },
- {
- "type": "button",
- "text": "新增",
- "name": "add_new"
- }
- ]
- },
-
- // 每条记录的视图模板
- "record_view": {
- "widgettype": "CardWidget",
- "options": {
- "title": "{title}", // 动态字段替换
- "subtitle": "发布时间: {ctime}",
- "content": "{summary}",
- "thumbnail": "{image_url}"
- }
- }
- },
-
- // 绑定事件
- "binds": [
- {
- "actiontype": "event",
- "wid": "cols_example",
- "event": "record_click",
- "target": "detail_panel",
- "rtdata": {
- "action": "show_detail"
- },
- "dataparams": {
- "source_event": "record_click"
- }
- },
- {
- "actiontype": "method",
- "wid": "cols_example",
- "event": "refresh",
- "target": "cols_example",
- "method": "load_first_page",
- "params": {}
- },
- {
- "actiontype": "urlwidget",
- "wid": "cols_example",
- "event": "add_new",
- "target": "Popup",
- "mode": "replace",
- "options": {
- "url": "/forms/news_edit.ui",
- "method": "GET",
- "params": {}
- }
- }
- ]
-}
-```
-
-### ✅ 注释说明:
-
-- `"data_url"`:服务端接口路径,返回格式需包含 `rows`, `page`, `pos_rate` 等字段。
-- `"record_view"`:定义每个数据项如何渲染成 UI 控件,支持字段插值 `{field}`。
-- `"binds"`:
- - 当用户点击某条记录时,派发 `record_click` 事件,通知 `detail_panel` 显示详情。
- - 工具栏“刷新”按钮重新加载第一页数据。
- - “新增”按钮打开弹窗(Popup),加载 `/forms/news_edit.ui` 表单界面。
-- `VScrollPanel` 自动监听滚动位置,在接近边界时调用 `load_previous_page` / `load_next_page` 实现懒加载。
-
----
-
-> 💡 **提示**:`Cols` 特别适合构建类似微博、朋友圈、电商商品列表等需要长列表无限滚动的场景,结合 `PageDataLoader` 实现高效内存管理和数据缓存。
\ No newline at end of file
diff --git a/docs/ai.old/conform.md b/docs/ai.old/conform.md
deleted file mode 100644
index bc49e10..0000000
--- a/docs/ai.old/conform.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Conform
-
-控件用于在用户执行关键操作前弹出确认对话框,提供“确认”和“取消”两个选项。属于**容器控件**,继承自 `bricks.PopupWindow`。
-
-## 主要方法
-
-- `constructor(opts)`
- 构造函数,接收配置参数 `opts`,自动设置超时为0、自动打开,并调用父类构造函数初始化弹窗。
-
-- `create_conform()`
- 创建整体布局结构,包含消息区域和工具栏。
-
-- `create_message(widget)`
- 在指定容器中创建消息显示区域,使用 `Text` 控件展示带换行的消息内容,支持国际化(i18n)。
-
-- `create_toolbar(widget)`
- 创建底部按钮栏(`IconTextBar`),包含“确认”和“取消”按钮,可自定义图标与标签。
-
-- `conform_hndl(event)`
- 点击“确认”按钮时触发,关闭弹窗并派发 `conformed` 事件。
-
-- `discard_hndl(event)`
- 点击“取消”按钮时触发,关闭弹窗并派发 `cancelled` 事件。
-
-## 主要事件
-
-| 事件名 | 触发条件 | 携带数据 |
-|--------------|------------------------|----------|
-| `conformed` | 用户点击“确认”按钮 | 无 |
-| `cancelled` | 用户点击“取消”按钮 | 无 |
-
-## 源码例子
-
-```json
-{
- "id": "confirm_delete",
- "widgettype": "Conform",
- "options": {
- "message": "Are you sure you want to delete this item?", // 要显示的提示信息
- "i18n": true, // 支持国际化
- "conform": { // 自定义“确认”按钮
- "label": "Delete",
- "icon": "imgs/delete.svg"
- },
- "discard": { // 自定义“取消”按钮
- "label": "Keep",
- "icon": "imgs/keep.svg"
- }
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "confirm_delete",
- "event": "conformed",
- "target": "data_manager",
- "method": "deleteItem",
- "params": {
- "itemId": "{#input_form.getValue('id')}" // 动态获取表单中的ID值
- },
- "description": "当用户确认删除时,调用数据管理器删除对应项目"
- },
- {
- "actiontype": "script",
- "wid": "confirm_delete",
- "event": "cancelled",
- "script": "console.log('Delete operation was cancelled by user.');",
- "description": "用户取消删除操作时输出日志"
- }
- ]
-}
-```
-
-### 注释说明:
-
-- `"widgettype": "Conform"`:必须确保该控件已在 bricks 框架中注册。
-- `options.message`:支持静态文本或 i18n 键名,若启用 `i18n: true`,会自动翻译。
-- `conform` 和 `discard` 字段是可选的,用于覆盖默认按钮样式与行为。
-- `binds` 中通过监听 `conformed` 和 `cancelled` 事件实现后续逻辑处理。
-- 使用 `{#...}` 表达式可在运行时动态求值,如从其他控件获取数据。
-
-> 💡 提示:此控件常用于删除、退出、覆盖等需要二次确认的操作场景,提升用户体验与安全性。
\ No newline at end of file
diff --git a/docs/ai.old/continueaudio.md b/docs/ai.old/continueaudio.md
deleted file mode 100644
index 3bc4b18..0000000
--- a/docs/ai.old/continueaudio.md
+++ /dev/null
@@ -1,145 +0,0 @@
-# ContinueAudioPlayer
-
-该控件是一个**容器控件**,继承自 `bricks.VBox`,用于在浏览器中连续播放通过 WebSocket 或 Base64 编码传输的音频数据。它基于 Web Audio API 实现高精度、低延迟的音频播放控制,支持暂停、恢复、重新开始、音量调节和静音功能。适用于语音播报、实时通信、在线教育等需要无缝播放多个音频片段的场景。
-
----
-
-## 主要方法
-
-- **`initAudioContext()`**
- 初始化 Web Audio API 的上下文(AudioContext)和增益节点(GainNode),为后续音频播放做准备。
-
-- **`base64ToArrayBuffer(base64)`**
- 将 Base64 编码的音频字符串转换为 ArrayBuffer,供 `decodeAudioData` 使用。
-
-- **`handleAudioTrack(arrayBuffer)`**
- 解码并播放传入的音频数据(ArrayBuffer),自动管理播放时间线,确保多个音频连续播放不重叠。
-
-- **`pauseAudio()`**
- 暂停当前播放的音频(实际是挂起 AudioContext)。
-
-- **`resumeAudio()`**
- 恢复被暂停的音频播放。
-
-- **`restart()`**
- 关闭当前 AudioContext 并重新初始化,从头开始播放。
-
-- **`setVolume(value)`**
- 设置音量(0.0 ~ 1.0),自动更新增益节点,并触发 `onVolumeChange` 事件。
-
-- **`toggleMute()`**
- 切换静音状态,同时更新增益值并发出音量变化事件。
-
-- **`emit(eventName, ...args)`**
- 触发配置中的回调函数,如 `onStart`、`onEnd` 等。
-
----
-
-## 主要事件
-
-这些事件可通过 `options` 配置传入回调函数,在特定时刻执行逻辑:
-
-- **`onStart`**:当一个音频轨道开始播放时触发。
-- **`onEnd`**:当一个音频轨道播放结束后触发。
-- **`onPause`**:调用 `pauseAudio` 成功后触发。
-- **`onResume`**:调用 `resumeAudio` 成功后触发。
-- **`onVolumeChange`**:音量或静音状态改变时触发,参数为当前有效音量(静音时为 0)。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "audioPlayerContainer",
- "widgettype": "ContinueAudioPlayer",
- "options": {
- "ws_url": "wss://example.com/audio-stream", // 可选:WebSocket 地址(若使用流式接收)
- "onStart": "function() { console.log('音频开始播放'); }",
- "onEnd": "function() { console.log('音频播放结束'); }",
- "onPause": "function() { bricks.getWidget('playBtn').setValue('▶️ 播放'); }",
- "onResume": "function() { bricks.getWidget('playBtn').setValue('⏸️ 暂停'); }",
- "onVolumeChange": "function(vol) { bricks.getWidget('volumeSlider').setValue(vol); }"
- },
- "subwidgets": [
- {
- "id": "controlBar",
- "widgettype": "HBox",
- "subwidgets": [
- {
- "id": "playBtn",
- "widgettype": "Button",
- "options": {
- "value": "▶️ 播放",
- "onClick": "function() { var player = bricks.getWidget('audioPlayerContainer'); if (player.audioContext.state === 'running') { player.pauseAudio(); } else { player.resumeAudio(); } }"
- }
- },
- {
- "id": "restartBtn",
- "widgettype": "Button",
- "options": {
- "value": "🔁 重新开始",
- "onClick": "function() { bricks.getWidget('audioPlayerContainer').restart(); }"
- }
- },
- {
- "id": "muteBtn",
- "widgettype": "Button",
- "options": {
- "value": "🔊 静音",
- "onClick": "function() { var player = bricks.getWidget('audioPlayerContainer'); player.toggleMute(); this.setValue(player.muted ? '🔇 取消静音' : '🔊 静音'); }"
- }
- },
- {
- "id": "volumeSlider",
- "widgettype": "Slider",
- "options": {
- "min": 0,
- "max": 1,
- "step": 0.01,
- "value": 1,
- "onChange": "function(val) { bricks.getWidget('audioPlayerContainer').setVolume(val); }"
- }
- }
- ]
- }
- ],
- "binds": [
- {
- "actiontype": "method",
- "wid": "externalStartTrigger",
- "event": "click",
- "target": "audioPlayerContainer",
- "method": "resumeAudio",
- "conform": {
- "title": "确认播放",
- "message": "确定要开始播放音频吗?",
- "confirmButtonText": "确定",
- "cancelButtonText": "取消"
- }
- },
- {
- "actiontype": "script",
- "wid": "dataReceiver",
- "event": "audioDataReady",
- "target": "audioPlayerContainer",
- "datascript": "return base64EncodedAudioChunk;", // 假设外部脚本提供了此变量
- "script": "const buf = widget.base64ToArrayBuffer(rtdata); widget.handleAudioTrack(buf);"
- }
- ]
-}
-```
-
-> ✅ **注释说明:**
->
-> - `ContinueAudioPlayer` 本身作为容器,包含一组控制按钮(播放/暂停、重启、静音、音量滑块)。
-> - `binds` 中定义了两个行为:
-> 1. 点击外部元素 `externalStartTrigger` 时,调用播放器的 `resumeAudio` 方法,带确认弹窗。
-> 2. 当 `dataReceiver` 组件触发 `audioDataReady` 事件时,执行脚本将 Base64 数据转为 ArrayBuffer 并交给播放器处理。
-> - 所有 UI 控件通过 ID 获取实例并与 `ContinueAudioPlayer` 实例交互。
-> - 回调函数使用字符串形式的 `function(){}` 写法,符合 Bricks.js 对 options 中函数的序列化要求。
-
----
-
-💡 **提示:**
-要实现真正的“持续”播放,需保证不断向 `handleAudioTrack` 方法传入新的音频数据块(ArrayBuffer)。可结合 WebSocket 接收流式音频并解码推送至此控件。
\ No newline at end of file
diff --git a/docs/ai.old/countdown.md b/docs/ai.old/countdown.md
deleted file mode 100644
index 9571944..0000000
--- a/docs/ai.old/countdown.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# TimePassed
-
-用于显示从开始计时起经过的时间(格式为 `hh:mm:ss`),是一个容器控件,继承自 `bricks.VBox`。该控件每秒自动更新一次时间显示,适用于需要展示运行时长的场景,如计时器、任务耗时统计等。
-
-**类型**:容器控件(继承自 `bricks.VBox`)
-
-## 主要方法
-
-- **start()**
- 开始计时,启动一个周期性任务,每秒调用一次 `add_one_second()` 方法以递增时间并更新界面。
-
-- **stop()**
- 停止计时,取消当前正在执行的周期性任务,防止继续更新时间。
-
-- **add_one_second()**
- 内部私有方法,用于将内部秒数加1,并格式化后更新到子控件 `Text` 中;之后再次调度自身,实现循环计时。
-
-## 主要事件
-
-无自定义事件派发。仅依赖父类 `VBox` 的基础事件能力。
-
-## 源码例子
-
-```json
-{
- "id": "time_passed_widget",
- "widgettype": "TimePassed",
- "options": {
- // 可选参数,例如可以扩展 text_rate 控制文本刷新频率
- // "text_rate": 1000 // 示例:表示文本更新速率(毫秒)
- },
- "subwidgets": [],
- "binds": [
- {
- "actiontype": "method",
- "wid": "btn_start_timer",
- "event": "click",
- "target": "time_passed_widget",
- "method": "start",
- "rtdata": {},
- "conform": null,
- "description": "当点击“开始”按钮时,启动计时器"
- },
- {
- "actiontype": "method",
- "wid": "btn_stop_timer",
- "event": "click",
- "target": "time_passed_widget",
- "method": "stop",
- "rtdata": {},
- "conform": null,
- "description": "当点击“停止”按钮时,停止计时器"
- }
- ]
-}
-```
-
-> ✅ **说明**:
-> - `TimePassed` 是一个简单的计时显示器,初始化时时间为 `00:00:00`。
-> - 使用 `start()` 启动后,会持续递增时间直到被 `stop()` 停止。
-> - 子控件中包含一个 `Text` 控件用于显示时间字符串。
-> - 时间格式通过全局函数 `bricks.formatTime(seconds)` 统一处理,确保格式一致。
-
----
-
-# Countdown
-
-倒计时控件,用于从指定时间开始倒数至零,结束后触发 `timeout` 事件。它是一个容器控件,继承自 `bricks.VBox`,内部使用一个 `Text` 控件显示剩余时间。
-
-**类型**:容器控件(继承自 `bricks.VBox`)
-
-## 主要方法
-
-- **start()**
- 启动倒计时,首次调用 `time_down_second()` 并设置1秒延迟执行,开始递减过程。
-
-- **time_down_second()**
- 内部私有方法:每次被调用时将剩余秒数减1,重新格式化时间并更新显示;若时间归零,则派发 `timeout` 事件并终止倒计时。
-
-## 主要事件
-
-- **timeout**
- 当倒计时结束(即时间到达 `00:00:00`)时自动触发。可用于绑定后续操作,如弹窗提醒、跳转页面或播放提示音。
-
-## 源码例子
-
-```json
-{
- "id": "countdown_timer",
- "widgettype": "Countdown",
- "options": {
- "limit_time": "00:05:00", // 倒计时总时长:5分钟
- "text_rate": 1000 // 文本更新频率(可选,默认1秒刷新一次)
- },
- "subwidgets": [],
- "binds": [
- {
- "actiontype": "method",
- "wid": "btn_start_countdown",
- "event": "click",
- "target": "countdown_timer",
- "method": "start",
- "rtdata": {},
- "description": "用户点击‘开始倒计时’按钮时启动倒计时"
- },
- {
- "actiontype": "event",
- "wid": "countdown_timer",
- "event": "timeout",
- "target": "Popup",
- "dispatch_event": "showMessage",
- "params": {
- "title": "倒计时结束",
- "content": "您的5分钟倒计时已结束!",
- "level": "info"
- },
- "description": "倒计时结束后弹出提示框通知用户"
- }
- ]
-}
-```
-
-> ✅ **说明**:
-> - `limit_time` 必须是 `"hh:mm:ss"` 格式的字符串,支持部分格式如 `"30"`(表示30秒)、`"2:30"`(表示2分30秒)等。
-> - 倒计时精度为1秒,使用 `schedule_once(..., 1)` 实现定时。
-> - 当时间耗尽时,通过 `this.dispatch('timeout')` 触发事件,外部可通过 `binds` 监听此事件进行响应。
-> - 此控件适合用于限时答题、会议提醒、休息倒计等功能模块。
-
----
-
-📌 **备注**:两个控件均已通过 `bricks.Factory.register()` 注册,可在 `.ui` 文件中直接作为 `widgettype` 使用。
\ No newline at end of file
diff --git a/docs/ai.old/datagrid.md b/docs/ai.old/datagrid.md
deleted file mode 100644
index 68a27b1..0000000
--- a/docs/ai.old/datagrid.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# DataGrid
-
-DataGrid 是一个用于展示结构化数据的容器控件,支持分页加载、冻结列、行选择、工具栏集成等功能。它是 `bricks` 框架中用于替代传统表格(table)的高级布局控件,继承自 `VBox`,属于**容器控件**。
-
----
-
-## 主要方法
-
-| 方法名 | 描述 |
-|--------|------|
-| `add_row(data, index)` | 向表格中添加一行数据,可指定插入位置(index)。 |
-| `add_rows(records, direction)` | 批量添加多行记录,支持从顶部或底部添加(direction: 'up'/'down')。 |
-| `clear_data()` | 清空所有数据行,包括冻结区和正常区的内容。 |
-| `loadData(params)` | 重新加载数据,传入参数给后端请求。 |
-| `create_header()` | 根据字段定义创建表头。 |
-| `create_parts()` | 创建整体布局结构:冻结列区域、主内容区域、滚动同步等。 |
-| `coscroll(event)` | 实现两个垂直滚动面板之间的同步滚动(用于冻结列与主体列对齐)。 |
-| `miniform_input(event)` | 响应搜索表单输入事件,触发数据重载。 |
-| `command_handle(event)` | 处理来自工具栏的命令事件(如“新增”、“删除”等),需开发者扩展实现。 |
-| `del_old_rows(cnt, direction)` | 删除旧的行(从开头或结尾),用于缓冲加载策略。 |
-
----
-
-## 主要事件
-
-| 事件名 | 触发时机 | 参数说明 |
-|-------|---------|----------|
-| `row_click` | 用户点击某一行时触发 | 回调参数为被点击的 `Row` 实例对象,可通过其 `.data` 获取原始数据 |
-| `min_threshold` | 滚动接近顶部边界时触发 | 通常用于加载上一页数据 |
-| `max_threshold` | 滚动接近底部边界时触发 | 通常用于加载下一页数据 |
-| `scroll` | 滚动发生时触发 | 用于实现双列滚动同步 |
-
-> 注:这些事件通过 `bind()` 进行监听,例如绑定到 `normal_body` 或 `freeze_body` 的滚动行为。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "my_datagrid",
- "widgettype": "DataGrid",
- "options": {
- // 数据源配置
- "dataurl": "/api/users", // 从该 URL 异步获取数据
- "method": "GET", // 请求方式,默认为 GET
- "params": { "page_size": 80 }, // 请求参数
-
- // 显示配置
- "title": "用户列表", // 表格标题(支持 i18n)
- "description": "所有注册用户的详细信息", // 描述文本
- "show_info": true, // 是否显示信息栏
- "row_height": "40px", // 每行高度
- "header_css": "grid_header", // 表头样式类名
- "body_css": "grid_body", // 表体样式类名
-
- // 功能开关
- "check": false, // 是否显示复选框列
- "lineno": true, // 是否显示行号列
-
- // 工具栏与搜索
- "miniform": {
- "fields": [
- {
- "name": "keyword",
- "uitype": "text",
- "label": "搜索关键词",
- "i18n": true,
- "uioptions": {
- "placeholder": "请输入用户名..."
- }
- },
- {
- "name": "status",
- "uitype": "select",
- "label": "状态",
- "i18n": true,
- "uioptions": {
- "options": [
- { "label": "全部", "value": "" },
- { "label": "启用", "value": "active" },
- { "label": "禁用", "value": "inactive" }
- ]
- }
- }
- ]
- },
- "toolbar": {
- "buttons": [
- {
- "name": "add_user",
- "label": "新增用户",
- "icon": "add",
- "action": {
- "actiontype": "newwindow",
- "target": "/user/add",
- "mode": "popup",
- "width": 800,
- "height": 600
- }
- },
- {
- "name": "refresh",
- "label": "刷新",
- "icon": "refresh",
- "action": {
- "actiontype": "method",
- "wid": "my_datagrid",
- "method": "loadData",
- "params": {}
- }
- }
- ]
- },
-
- // 字段定义
- "fields": [
- {
- "name": "username",
- "label": "用户名",
- "uitype": "text",
- "width": 120,
- "freeze": true, // 冻结此列(固定左侧)
- "i18n": true
- },
- {
- "name": "email",
- "label": "邮箱",
- "uitype": "text",
- "width": 180,
- "i18n": true
- },
- {
- "name": "status",
- "label": "状态",
- "uitype": "label",
- "width": 100,
- "uioptions": {
- "css_map": {
- "active": "success",
- "inactive": "danger"
- }
- }
- },
- {
- "name": "last_login",
- "label": "最后登录时间",
- "uitype": "datetime",
- "width": 160
- },
- {
- "name": "action",
- "label": "操作",
- "uitype": "button",
- "width": 100,
- "icon": "edit",
- "action": {
- "actiontype": "newwindow",
- "target": "/user/edit?id={id}",
- "mode": "popup",
- "width": 900,
- "height": 700
- }
- }
- ]
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "my_datagrid",
- "event": "row_click",
- "target": "detail_panel",
- "dispatch_event": "update_detail",
- "params": {
- "source": "my_datagrid"
- },
- "datawidget": "my_datagrid",
- "datamethod": "getValue",
- "dataparams": {},
- "rtdata": {
- "section": "user_profile"
- }
- },
- {
- "actiontype": "script",
- "wid": "my_datagrid",
- "event": "row_click",
- "script": "console.log('用户点击了行:', params.row_data);",
- "params": {
- "row_data": "{source.getValue()}"
- }
- }
- ]
-}
-```
-
-### 注释说明:
-
-- **`dataurl`**: 设置远程数据接口地址,框架会自动发起请求并渲染数据。
-- **`miniform`**: 内置迷你搜索表单,用户输入后自动调用 `loadData()` 刷新数据。
-- **`toolbar`**: 工具栏按钮支持弹窗、刷新等操作。
-- **`fields[].freeze`**: 设为 `true` 可将列固定在左侧(常用于关键字段如 ID、姓名)。
-- **`uitype: button`**: 在表格内嵌按钮,支持动态绑定动作(如编辑、删除)。
-- **`binds`**:
- - 第一条:当某行被点击时,向 `detail_panel` 控件派发 `update_detail` 自定义事件,传递当前行数据。
- - 第二条:执行脚本输出调试日志,演示如何获取运行时数据。
-
-> 💡 提示:结合 `BufferedDataLoader`,DataGrid 支持大数据量下的虚拟滚动与分页预加载,适用于成千上万条记录的场景。
\ No newline at end of file
diff --git a/docs/ai.old/datarow.md b/docs/ai.old/datarow.md
deleted file mode 100644
index 8bfd69e..0000000
--- a/docs/ai.old/datarow.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# DataRow
-
-**用处**:`DataRow` 是一个用于展示数据行的容器控件,常用于表格或列表中的一行数据展示。支持表头与数据行的分别渲染,可配置字段显示、列宽、隐藏字段等,适用于构建数据浏览界面(如数据表格)。
-
-**类型**:容器控件,继承自 `bricks.HBox`
-
----
-
-## 主要方法
-
-- `render_header()`
- 渲染表头部分(通常包含字段名),调用 `render(true)` 实现。
-
-- `render_data()`
- 渲染数据内容部分,调用 `render(false)` 实现。
-
-- `render(header: Boolean)`
- 根据 `header` 参数决定是否渲染为表头。若为 `true`,则显示字段标签;否则显示实际数据值。
-
-- `renew(record: Object)`
- 更新当前行绑定的数据记录,并重新渲染数据部分。`record` 为新的数据对象。
-
-- `get_check_state(e: Event)`
- 处理复选框状态变化事件,更新内部数据并派发 `check_changed` 事件。
-
-- `build_toolbar(header: Boolean)`
- 构建工具栏(如操作图标按钮),根据 `header` 判断是否在表头区域创建空白占位。
-
-- `my_dispatch(event_name: String)`
- 返回一个闭包函数,用于在工具栏按钮点击时派发对应事件。
-
-- `_build_fields(header: Boolean, containerWidget: Widget)`
- 内部方法,遍历 `fields` 配置并生成对应的视图控件(如文本、图标等),添加到指定容器中。
-
----
-
-## 主要事件
-
-- `check_changed`
- 当复选框状态改变时触发,携带当前组件实例作为参数。可用于监听选中状态变更。
-
-- 自定义工具栏事件(由 `toolbar.tools.name` 定义)
- 如 `edit`, `delete` 等,通过 `IconBar` 绑定后会派发同名事件,可通过 `binds` 监听处理。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "data_row_001",
- "widgettype": "DataRow",
- "options": {
- // 表格字段定义
- "fields": [
- {
- "name": "id",
- "label": "编号",
- "uitype": "str",
- "cwidth": 5
- },
- {
- "name": "name",
- "label": "姓名",
- "uitype": "str",
- "cwidth": 10
- },
- {
- "name": "status",
- "label": "状态",
- "uitype": "label", // 使用标签控件显示
- "cwidth": 8
- }
- ],
- // 是否启用选择框
- "checkField": "selected",
- // 浏览器字段配置(控制列宽和隐藏)
- "browserfields": {
- "exclouded": ["internal_id"], // 不显示的字段
- "cwidths": {
- "status": 12
- }
- },
- // 工具栏配置
- "toolbar": {
- "tools": [
- {
- "name": "edit",
- "icon": "pencil",
- "tip": "编辑"
- },
- {
- "name": "delete",
- "icon": "trash",
- "tip": "删除"
- }
- ]
- },
- // 自定义样式
- "css": "data-row-item",
- "header_css": "header-row"
- },
- "subwidgets": [],
- "binds": [
- // 监听复选框变化
- {
- "actiontype": "event",
- "wid": "data_row_001",
- "event": "check_changed",
- "target": "data_grid_controller",
- "dispatch_event": "row_selected",
- "params": {
- "rowid": "{data_row_001.getValue().id}"
- }
- },
- // 编辑按钮点击
- {
- "actiontype": "method",
- "wid": "data_row_001",
- "event": "edit", // 来自 IconBar 的事件
- "target": "popup_manager",
- "method": "openEditPopup",
- "params": {
- "recordId": "{data_row_001.getValue().id}"
- }
- },
- // 删除按钮确认并执行
- {
- "actiontype": "event",
- "wid": "data_row_001",
- "event": "delete",
- "target": "data_row_001",
- "dispatch_event": "confirm_delete",
- "conform": {
- "title": "确认删除",
- "message": "确定要删除该条记录吗?",
- "confirmButtonText": "删除",
- "cancelButtonText": "取消"
- }
- }
- ]
-}
-```
-
-> **注释说明**:
->
-> - `fields` 定义了要展示的字段及其 UI 类型(`uitype`),框架会自动查找对应的 ViewBuilder 创建子控件。
-> - `checkField` 启用行选择功能,会在最前插入一个复选框。
-> - `toolbar.tools` 定义操作图标,每个 `name` 将作为事件名被 `DataRow` 派发。
-> - `binds` 中通过 `event` 类型将内部事件转发给外部控制器处理。
-> - `conform` 提供弹出确认对话框的能力,在危险操作前使用。
-> - `{}` 中的表达式是 bricks 支持的运行时数据绑定语法,动态获取组件值。
\ No newline at end of file
diff --git a/docs/ai.old/dataviewer.md b/docs/ai.old/dataviewer.md
deleted file mode 100644
index 5cf240f..0000000
--- a/docs/ai.old/dataviewer.md
+++ /dev/null
@@ -1,129 +0,0 @@
-# DataViewer
-
-DataViewer 是一个用于展示分页数据的容器控件,支持动态加载远程数据、滚动加载前后页、内置增删改查操作工具栏,并可通过子类扩展自定义记录视图。它继承自 `bricks.VBox`,属于**容器控件**。
-
----
-
-## 主要方法
-
-| 方法名 | 说明 |
-|--------|------|
-| `render(params)` | 根据参数从服务器加载数据并渲染列表,默认会缓存请求参数避免重复加载 |
-| `build_row(record, page, pos)` | 构建单条记录对应的控件,并插入到滚动面板中(可被重写) |
-| `build_record_view(record)` | 创建每条数据的显示控件,子类需重写此方法以实现自定义 UI |
-| `add_record()` | 打开新增记录弹窗 |
-| `update_record(row)` | 打开编辑当前选中行记录的弹窗 |
-| `clone_record(row)` | 克隆当前选中记录并打开新增表单 |
-| `delete_record(row)` | 删除指定行记录,触发确认对话框 |
-| `load_previous_page()` | 向上滚动时加载前一页数据(支持无限滚动) |
-| `load_next_page()` | 向下滚动时加载后一页数据 |
-| `command_event_handle(event)` | 处理工具栏按钮点击事件(如 add/update/delete 等) |
-| `get_edit_fields()` | 获取可编辑字段列表,排除配置中设置的字段 |
-| `get_hidefields()` | 获取隐藏字段(通常为过滤条件或上下文参数) |
-| `build_add_form()` / `build_update_form(data)` / `build_clone_form(data)` | 分别构建新增、更新、克隆用的表单控件 |
-| `build_window(icon, title, form)` | 创建弹出窗口包裹表单 |
-
----
-
-## 主要事件
-
-| 事件名 | 触发时机 | 携带数据 |
-|--------|--------|---------|
-| `row_check_changed` | 当某一行的选择状态发生变化时 | 被选中行的数据对象(`user_data`) |
-| 自定义命令事件(如 `'add'`, `'update'` 等) | 用户点击工具栏按钮时 | 当前行数据(如有) |
-
-> 注:这些事件可通过 `binds` 进行监听和处理。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "dataviewer_main",
- "widgettype": "DataViewer",
- "options": {
- // 数据源配置
- "data_url": "/api/list_records", // 获取数据的接口地址
- "data_method": "GET", // 请求方式
- "data_params": { // 静态请求参数
- "category": "news"
- },
- "page_rows": 20, // 每页加载多少条数据
- "cache_limit": 5, // 最多缓存几个页面的数据
-
- // 编辑功能配置(启用工具栏)
- "editable": {
- "add_icon": "imgs/add.svg",
- "update_icon": "imgs/edit.svg",
- "clone_icon": "imgs/clone.svg",
- "delete_icon": "imgs/delete.svg",
- "new_data_url": "/api/create_record", // 新增提交地址
- "update_data_url": "/api/update_record", // 更新提交地址
- "delete_data_url": "/api/delete_record" // 删除提交地址
- },
-
- // 行记录选项(传递给 build_record_view)
- "row_options": {
- "fields": [
- { "name": "title", "label": "标题", "uitype": "text" },
- { "name": "author", "label": "作者", "uitype": "text" },
- { "name": "pub_date", "label": "发布时间", "uitype": "date" }
- ],
- "editexclouded": ["pub_date"] // 编辑时不显示的字段
- }
- },
- "subwidgets": [], // DataViewer 自动管理子控件(通过 dataHandle 渲染),一般不手动添加
- "binds": [
- {
- "actiontype": "method",
- "wid": "dataviewer_main",
- "event": "row_check_changed",
- "target": "logger_panel",
- "method": "setValue",
- "dataparams": {
- "message": "Selected row changed: {{value}}"
- },
- "datamethod": "getValue", // 从事件中获取数据
- "datawidget": "dataviewer_main"
- },
- {
- "actiontype": "event",
- "wid": "dataviewer_main",
- "event": "add",
- "target": "global_event_bus",
- "dispatch_event": "open_statistics_panel",
- "params": {
- "action": "add",
- "from": "DataViewer"
- }
- },
- {
- "actiontype": "bricks",
- "wid": "dataviewer_main",
- "event": "update",
- "target": "Popup",
- "mode": "replace",
- "options": {
- "widgettype": "Message",
- "options": {
- "title": "Success",
- "message": "Record updated successfully!",
- "level": "info"
- }
- }
- }
- ]
-}
-```
-
-### ✅ 注释说明:
-
-- `"data_url"` 和 `"data_params"` 配合使用,由 `PageDataLoader` 自动发起请求。
-- `"editable"` 开启后会在顶部生成包含增删改克隆图标的工具栏。
-- `build_record_view()` 必须在子类中重写才能正确显示内容;否则默认显示一个空白方块。
-- 工具栏按钮点击后会派发对应名称的事件(如 `add`, `update`),可用于联动其他模块。
-- 使用 `binds` 可将用户操作与日志、提示、跳转等行为连接起来。
-- 支持垂直滚动加载更多数据(上拉刷新 / 下拉加载)。
-
-> 💡 提示:若要完全自定义界面,请继承 `DataViewer` 并重写 `build_record_view(record)` 方法返回你想要的控件结构。
\ No newline at end of file
diff --git a/docs/ai.old/docxviewer.md b/docs/ai.old/docxviewer.md
deleted file mode 100644
index 6f5aaea..0000000
--- a/docs/ai.old/docxviewer.md
+++ /dev/null
@@ -1,184 +0,0 @@
-# DOCXviewer
-
-用于在前端界面中嵌入并渲染 `.docx`(Word 文档)文件的容器控件,继承自 `VBox`。通过 `mammoth.js` 将二进制 Word 文档转换为 HTML 并显示在页面中。
-
-## 主要方法
-
-- **`set_url(url)`**
- 异步方法,接收一个文档 URL,使用 `HttpArrayBuffer` 获取二进制数据,并通过 `mammoth.convertToHtml` 转换为 HTML 后插入到控件的 DOM 中。
-
-## 主要事件
-
-- **`on_parent`**
- 当控件被挂载到父级组件时触发,自动调用 `set_url(this.url)` 开始加载文档内容。
-
-## 源码例子
-
-```json
-{
- "id": "docx_viewer_1",
- "widgettype": "DOCXviewer",
- "options": {
- "url": "/documents/report.docx" // 要加载的 .docx 文件路径
- },
- "binds": [
- {
- "actiontype": "bricks",
- "wid": "btn_refresh_docx",
- "event": "click",
- "target": "docx_viewer_1",
- "options": {
- "widgettype": "method",
- "method": "set_url",
- "params": {
- "url": "/documents/report_updated.docx"
- }
- },
- "rtdata": {},
- "conform": {
- "title": "刷新确认",
- "message": "确定要重新加载文档吗?",
- "confirm_text": "确定",
- "cancel_text": "取消"
- }
- }
- ]
-}
-```
-
-> 注释:
-> - `widgettype: DOCXviewer` 表示这是一个基于 Mammoth.js 渲染 Word 文档的控件。
-> - `options.url` 指定远程 `.docx` 文件地址。
-> - 使用 `binds` 可以绑定按钮点击事件来动态更新文档源。
-> - 需提前引入 [mammoth.js](https://github.com/mwilliamson/mammoth.js) 库支持。
-
----
-
-# EXCELviewer
-
-用于在 Web 界面中展示 `.xlsx` 或 `.xls` Excel 文件内容的容器控件,继承自 `VBox`。支持多工作表切换查看,依赖 `SheetJS (xlsx)` 库解析 Excel 数据并渲染为 HTML 表格。
-
-## 主要方法
-
-- **`set_url(url)`**
- 异步方法,根据传入的 Excel 文件 URL 加载二进制数据,使用 `XLSX.read()` 解析工作簿,并生成页签栏供用户切换不同 sheet。
-
-- **`show_sheet_by_name(sheetname, tw)`**
- 切换显示指定名称的工作表,高亮当前选中标签,并将对应表格内容渲染至滚动面板中。
-
-## 主要事件
-
-- **`on_parent`**
- 控件挂载后触发,自动调用 `set_url(this.url)` 初始化数据加载。
-
-- **`click` on tab text widget**
- 点击某个工作表标签时,切换显示该工作表内容。
-
-## 源码例子
-
-```json
-{
- "id": "excel_viewer_1",
- "widgettype": "EXCELviewer",
- "options": {
- "url": "/data/sales_report.xlsx", // Excel 文件地址
- "height": "600px"
- },
- "subwidgets": [],
- "binds": [
- {
- "actiontype": "method",
- "wid": "btn_load_another_excel",
- "event": "click",
- "target": "excel_viewer_1",
- "method": "set_url",
- "params": {
- "url": "/data/inventory.xlsx"
- },
- "conform": {
- "title": "加载新文件",
- "message": "是否加载新的库存表格?"
- }
- }
- ]
-}
-```
-
-> 注释:
-> - `EXCELviewer` 自动创建顶部可滚动的 sheet 标签栏和下方内容区。
-> - 每个标签是一个 `Text` 控件,带有 `'clickable'` 和 `'selected'` CSS 类控制样式。
-> - 内容使用 `XLSX.utils.sheet_to_html` 直接生成表格 HTML 插入 `VScrollPanel` 实现滚动。
-> - 必须确保全局已加载 `xlsx.full.min.js`(如 SheetJS)。
-
----
-
-# PDFviewer
-
-用于在前端展示 `.pdf` 文件的容器控件,继承自 `VBox`。利用 `pdfjsLib`(Mozilla PDF.js)解析 PDF 二进制流,并逐页渲染为 `` 元素进行显示。
-
-## 主要方法
-
-- **`set_url(url)`**
- 异步方法,从指定 URL 获取 PDF 二进制数据,初始化 `pdfjsLib.getDocument` 并遍历所有页面进行渲染。
-
-- **`add_page_content(page)`**
- 接收一个 PDF 页面对象,创建 canvas 元素并调用 `page.render()` 绘制可视内容,添加到控件中。
-
-## 主要事件
-
-- **`on_parent`**
- 控件挂载完成后触发,启动 PDF 加载流程。
-
-## 源码例子
-
-```json
-{
- "id": "pdf_viewer_1",
- "widgettype": "PDFviewer",
- "options": {
- "url": "/docs/manual.pdf", // PDF 文件路径
- "width": "100%",
- "height": "800px"
- },
- "binds": [
- {
- "actiontype": "script",
- "wid": "btn_print_pdf",
- "event": "click",
- "target": "Popup",
- "script": "window.open(target.options.url, '_blank', 'print=yes');",
- "params": {
- "target": "pdf_viewer_1"
- },
- "rtdata": {
- "msg": "正在打开打印窗口..."
- }
- },
- {
- "actiontype": "method",
- "wid": "btn_reload_pdf",
- "event": "click",
- "target": "pdf_viewer_1",
- "method": "set_url",
- "params": {
- "url": "{{last_pdf_url}}" // 动态参数,来自运行时数据或变量
- }
- }
- ]
-}
-```
-
-> 注释:
-> - `PDFviewer` 使用 `pdfjsLib` 的标准 API 加载和渲染 PDF。
-> - 每页生成一个 `` 并插入控件内部,页间可用 `Splitter` 分隔(代码中逻辑未完全闭合,需注意循环变量作用域)。
-> - 需引入 PDF.js 并设置 `pdfjsLib.GlobalWorkerOptions.workerSrc`。
-> - 示例中使用 `script` 动作实现“打印”功能,弹出新窗口预览 PDF。
-> - `{{last_pdf_url}}` 表示支持模板变量注入,可用于动态刷新最近访问的文档。
-
----
-
-> ✅ 所有三个控件均为**容器控件**,均继承自 `VBox`,可通过 `add_widget` 动态添加子控件。
-> ⚠️ 使用前请确保相关第三方库已正确加载:
-> - DOCXviewer → `mammoth`
-> - EXCELviewer → `xlsx`
-> - PDFviewer → `pdfjsLib`
\ No newline at end of file
diff --git a/docs/ai.old/dynamicaccordion.md b/docs/ai.old/dynamicaccordion.md
deleted file mode 100644
index a76f410..0000000
--- a/docs/ai.old/dynamicaccordion.md
+++ /dev/null
@@ -1,219 +0,0 @@
-# DynamicAccordion
-
-动态手风琴控件(DynamicAccordion)是一个容器控件,用于以分页、可折叠的方式展示大量数据记录。它继承自 `bricks.VScrollPanel`,支持懒加载、无限滚动、编辑操作和内容动态渲染,适用于需要高效展示结构化数据的场景(如后台管理列表、日志查看器等)。该控件结合了数据加载、视图模板、工具栏配置与交互逻辑,是 bricks 框架中功能较完整的复合型容器控件。
-
-类型:容器控件,继承自 `VScrollPanel`
-
----
-
-## 主要方法
-
-- **`render(params)`**
- 根据参数重新加载并渲染数据。若传入 `params`,会作为请求参数发送至后端接口。此方法触发数据加载与界面更新。
-
-- **`build_item(record)`**
- 构建单个手风琴项(AccordionItem),包含标题信息区域和隐藏的内容区域。如果 record 存在,则绑定点击事件以展开内容。
-
-- **`toggle_content(info, content, record, event)`**
- 切换指定项的内容区域显示/隐藏状态。首次展开时按需加载并渲染 `content_view` 定义的子控件。
-
-- **`line_clicked(info, content, record, event)`**
- 行点击回调函数,处理选中高亮及内容切换逻辑。
-
-- **`load_previous_page()` / `load_next_page()`**
- 分别加载前一页或下一页数据,实现“无限滚动”效果,基于 `min_threshold` 和 `max_threshold` 事件触发。
-
-- **`add_record(info)`**
- 添加新记录,通常通过表单输入完成,并提交到服务器。
-
-- **`update_record(info, record)`**
- 更新当前记录,弹出可编辑表单。
-
-- **`delete_record(info, record)`**
- 删除指定记录,弹出确认对话框防止误操作。
-
-- **`build_record_toolbar(info, record)`**
- 构建每行右侧的操作工具栏(如增删改图标按钮),支持自定义扩展事件。
-
-- **`fire_event(event_name, data)`**
- 向外派发自定义事件,供外部监听使用(例如用于联动其他组件)。
-
-- **`select_line(info)`**
- 设置某行为选中状态,并取消之前选中的行样式。
-
----
-
-## 主要事件
-
-| 事件名 | 触发时机 |
-|--------------------|--------|
-| `row_selected` | 当用户点击某一行时触发,携带被点击行的信息组件 `info` 作为参数。可用于与其他控件联动。 |
-| `conformed` | 在删除确认弹窗中点击“确定”后触发,执行实际删除动作。 |
-| `submited` | 表单提交成功后触发,常用于刷新视图或关闭弹窗。 |
-| `cancel` | 编辑/新增表单取消时触发,关闭表单区域。 |
-| `min_threshold` | 垂直滚动条接近顶部时触发,由 `container` 内部发出,用于加载上一页数据。 |
-| `max_threshold` | 垂直滚动条接近底部时触发,用于加载下一页数据。 |
-
----
-
-## 源码例子
-
-```json
-{
- "id": "dynamic_accordion_example",
- "widgettype": "DynamicAccordion",
- "options": {
- // 数据源 URL,返回符合 PageDataLoader 格式的 JSON
- "data_url": "/api/records/list",
- "data_params": {
- "category": "news"
- },
- "data_method": "GET",
-
- // 分页设置
- "page_rows": 10,
- "cache_limit": 5,
-
- // 每行高度倍数(相对于标准行高)
- "row_cheight": 1.5,
-
- // 是否启用编辑功能
- "editable": {
- "form_cheight": 8,
- "add_icon": "/static/icons/add.svg",
- "update_icon": "/static/icons/edit.svg",
- "delete_icon": "/static/icons/trash.svg",
- "new_data_url": "/api/records/create",
- "update_data_url": "/api/records/update",
- "delete_data_url": "/api/records/delete"
- },
-
- // 头部标题与描述(可选)
- "title": "新闻列表",
- "description": "点击查看详细内容",
-
- // 工具栏定义(可选)
- "toolbar": {
- "tools": [
- { "name": "refresh", "icon": "/static/icons/refresh.svg", "tip": "刷新列表" }
- ]
- },
-
- // 字段定义,用于构建表单或标题展示
- "fields": [
- { "name": "title", "label": "标题", "uitype": "text" },
- { "name": "author", "label": "作者", "uitype": "text" },
- { "name": "pub_date", "label": "发布时间", "uitype": "date" }
- ],
-
- // 每行记录的视图模板(用于 header 显示)
- "record_view": {
- "widgettype": "HBox",
- "options": { "padding": 10 },
- "subwidgets": [
- {
- "widgettype": "Text",
- "options": {
- "otext": "{title}",
- "i18n": false,
- "halign": "left",
- "style": { "font-weight": "bold", "margin-right": "10px" }
- }
- },
- {
- "widgettype": "Text",
- "options": {
- "otext": "by {author}",
- "i18n": false,
- "halign": "left",
- "style": { "color": "#666", "font-size": "0.9em" }
- }
- }
- ]
- },
-
- // 展开后显示的详细内容视图
- "content_view": {
- "widgettype": "Form",
- "options": {
- "submit_url": "/api/records/update",
- "fields": [
- { "name": "title", "label": "标题", "uitype": "text" },
- { "name": "content", "label": "正文", "uitype": "textarea", "cheight": 5 },
- { "name": "status", "label": "状态", "uitype": "select", "options": ["草稿", "已发布"] }
- ]
- }
- },
-
- // 自定义每行的操作按钮(除编辑外)
- "record_toolbar": {
- "cwidth": 2.5,
- "tools": [
- { "name": "share", "icon": "/static/icons/share.svg", "tip": "分享此条目" },
- { "name": "export", "icon": "/static/icons/export.svg", "tip": "导出为 PDF" }
- ]
- },
-
- // 控制何时才渲染 content_view(条件依赖字段)
- "content_rely_on": "has_detail",
- "content_rely_value": true
- },
-
- // 绑定事件
- "binds": [
- {
- "actiontype": "bricks",
- "wid": "dynamic_accordion_example",
- "event": "row_selected",
- "target": "another_panel",
- "options": {
- "widgettype": "Text",
- "options": {
- "otext": "Selected: {user_data.title}",
- "i18n": false
- }
- },
- "mode": "replace"
- },
- {
- "actiontype": "urlwidget",
- "wid": "dynamic_accordion_example",
- "event": "refresh",
- "target": "dynamic_accordion_example",
- "options": {
- "url": "/api/records/list",
- "method": "GET",
- "params": { "force_refresh": true }
- },
- "mode": "replace"
- },
- {
- "actiontype": "event",
- "wid": "dynamic_accordion_example",
- "event": "share",
- "target": "Popup",
- "dispatch_event": "show_share_dialog",
- "params": { "record": "{user_data}" }
- }
- ]
-}
-```
-
-> ✅ **注释说明:**
->
-> - `data_url` 提供分页数据接口,返回格式应为 `{ rows: [...], page: 1, total: 100 }`
-> - `record_view` 定义每一行如何显示简略信息。
-> - `content_view` 定义展开后的详细内容,仅在点击时动态加载。
-> - `editable` 开启内置增删改功能,自动添加操作图标。
-> - `binds` 中监听 `row_selected` 实现跨组件通信;`refresh` 按钮重新加载数据。
-> - 使用 `{field_name}` 占位符可在文本或参数中引用运行时数据(来自 record)。
-> - `content_rely_on` 可控制是否显示展开内容,提高性能。
-
----
-
-📌 **总结:**
-`DynamicAccordion` 是一个高度集成的数据展示控件,适合构建复杂的数据浏览界面。其核心优势在于:
-- 支持大数据量下的分页懒加载;
-- 提供灵活的视图定制能力;
-- 内建 CRUD 支持与事件系统;
-- 易于通过 JSON 配置实现复杂交互逻辑。
\ No newline at end of file
diff --git a/docs/ai.old/dynamiccolumn.md b/docs/ai.old/dynamiccolumn.md
deleted file mode 100644
index 43f287f..0000000
--- a/docs/ai.old/dynamiccolumn.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# DynamicColumn
-
-`DynamicColumn` 是一个**容器控件**,继承自 `bricks.Layout`。它用于实现响应式网格布局,能够根据屏幕宽度动态调整列数和列宽,特别适用于移动端与桌面端自适应的卡片式布局场景。
-
-该控件通过 CSS Grid 实现布局,并在窗口尺寸变化或父容器更新时自动重新计算列宽与间隙,确保内容均匀分布且美观。
-
----
-
-## 主要方法
-
-- **`set_column_width()`**
- 核心方法,负责根据当前设备类型(移动端/桌面端)、字符单位大小(`charsize`)以及配置参数动态设置 `gridTemplateColumns` 和 `gap` 样式属性。
-
- - 在移动端竖屏下使用固定的列数(由 `mobile_cols` 控制)
- - 在桌面端根据 `col_cwidth`(以字符为单位的列宽)或直接指定的 `col_width`(像素值)来计算每列最小宽度
- - 使用 `minmax(cw + "px", 1fr)` 配合 `repeat(auto-fill, ...)` 实现自动换行和等分布局
-
-- **构造函数 `constructor(opts)`**
- 初始化控件选项并绑定事件:
- - 自动补全默认值:`col_cwidth`, `col_cgap`, `mobile_cols`
- - 设置 `display: grid`
- - 绑定生命周期和窗口 resize 事件以触发布局重算
-
----
-
-## 主要事件
-
-- **`on_parent`**
- 当控件被添加到父容器后触发,用于首次设置列宽。
-
-- **`resize`**
- 浏览器窗口大小改变时触发,动态调整网格列数和间距。
-
-- **`charsize` (全局事件)**
- 字符尺寸变化时触发(通常因主题切换或缩放引起),重新计算基于字符单位的列宽。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "dynamicGrid",
- "widgettype": "DynamicColumn",
- "options": {
- "col_cwidth": 20, // 每列最小宽度 = 20ch(字符单位),推荐方式
- "col_cgap": 0.5, // 列间间隙 = 0.5ch
- "mobile_cols": 1, // 移动端显示为单列
- "style": {
- "padding": "10px"
- }
- },
- "subwidgets": [
- {
- "id": "card1",
- "widgettype": "Div",
- "options": {
- "text": "卡片 1",
- "style": {
- "background": "#f0f0f0",
- "border": "1px solid #ccc",
- "padding": "20px",
- "textAlign": "center",
- "borderRadius": "8px"
- }
- }
- },
- {
- "id": "card2",
- "widgettype": "Div",
- "options": {
- "text": "卡片 2",
- "style": {
- "background": "#e0e0e0",
- "border": "1px solid #bbb",
- "padding": "20px",
- "textAlign": "center",
- "borderRadius": "8px"
- }
- }
- },
- {
- "id": "card3",
- "widgettype": "Div",
- "options": {
- "text": "卡片 3",
- "style": {
- "background": "#d0d0d0",
- "border": "1px solid #aaa",
- "padding": "20px",
- "textAlign": "center",
- "borderRadius": "8px"
- }
- }
- }
- ],
- "binds": [
- {
- "actiontype": "method",
- "wid": "dynamicGrid",
- "event": "resize",
- "target": "dynamicGrid",
- "method": "set_column_width",
- "params": {}
- },
- {
- "actiontype": "method",
- "wid": "dynamicGrid",
- "event": "on_parent",
- "target": "dynamicGrid",
- "method": "set_column_width",
- "params": {}
- }
- ]
-}
-```
-
-> ✅ **注释说明:**
-> - `col_cwidth`: 推荐使用字符单位(ch),可保证文字排版对齐一致性
-> - `col_cgap`: 间隙也基于字符单位,随字体缩放而变化,提升可访问性
-> - `mobile_cols`: 竖屏手机强制显示为单列,提升阅读体验
-> - 所有子控件将自动填入网格中,浏览器自行处理换行与对齐
-> - `binds` 中显式调用 `set_column_width` 确保初始和变更时正确渲染
-
----
-
-💡 **使用建议:**
-
-- 若希望固定列数,请结合 `minmax()` 和 `auto-fit` 使用其他布局策略
-- 可配合 `urlwidget` 动态加载子项,实现无限滚动卡片墙
-- 支持国际化文本变动引起的宽度变化,只要触发 `charsize` 更新即可自动适配
\ No newline at end of file
diff --git a/docs/ai.old/factory.md b/docs/ai.old/factory.md
deleted file mode 100644
index 4b845de..0000000
--- a/docs/ai.old/factory.md
+++ /dev/null
@@ -1,320 +0,0 @@
-# Button
-
-按钮控件,用于触发用户交互操作。类型:普通控件,继承自 `JsWidget`
-
-## 主要方法
-
-- `setValue(text: string)`
- 设置按钮显示的文本内容。
-
-- `getValue(): string`
- 获取按钮当前显示的文本。
-
-- `enable()`
- 启用按钮,允许用户点击。
-
-- `disable()`
- 禁用按钮,禁止用户点击并呈现灰化状态。
-
-- `show()`
- 显示按钮。
-
-- `hide()`
- 隐藏按钮。
-
-## 主要事件
-
-- `click`
- 用户点击按钮时触发。
-
-- `focus`
- 按钮获得焦点时触发。
-
-- `blur`
- 按钮失去焦点时触发。
-
-## 源码例子
-
-```json
-{
- "id": "btn_submit", // 控件唯一ID
- "widgettype": "Button", // 控件类型:Button
- "options": {
- "value": "提交", // 初始按钮文本
- "disabled": false, // 是否禁用,默认为false
- "style": "primary", // 可选样式:primary, secondary, danger等
- "tooltip": "点击提交表单" // 鼠标悬停提示
- },
- "binds": [
- {
- "actiontype": "method", // 动作类型:调用方法
- "wid": "btn_submit", // 触发组件ID
- "event": "click", // 监听点击事件
- "target": "form_data", // 目标组件ID
- "method": "submit", // 调用目标的方法名
- "params": {} // 方法参数
- },
- {
- "actiontype": "script", // 执行脚本动作
- "wid": "btn_submit",
- "event": "click",
- "target": "btn_submit",
- "script": "console.log('按钮被点击:', data); return true;",
- "params": {
- "data": "提交日志记录"
- }
- }
- ]
-}
-```
-
----
-
-# Panel
-
-面板控件,用于布局容器,可包含多个子控件。类型:容器控件,继承自 `JsWidget`
-
-## 主要方法
-
-- `addSubwidget(widgetJson)`
- 动态添加一个子控件(JSON 描述)到面板中。
-
-- `removeSubwidget(widgetId: string)`
- 移除指定 ID 的子控件。
-
-- `clear()`
- 清空所有子控件。
-
-- `show()`
- 显示整个面板。
-
-- `hide()`
- 隐藏面板。
-
-- `setTitle(title: string)`
- 设置面板标题(如果支持标题栏)。
-
-## 主要事件
-
-- `init`
- 面板初始化完成后触发。
-
-- `rendered`
- 所有子控件渲染完成时触发。
-
-- `childadded`
- 添加子控件后触发,携带新控件信息。
-
-## 源码例子
-
-```json
-{
- "id": "panel_user_info", // 容器ID
- "widgettype": "Panel", // 控件类型:Panel
- "options": {
- "title": "用户信息", // 面板标题
- "collapsible": true, // 是否可折叠
- "collapsed": false, // 初始是否折叠
- "border": true, // 是否显示边框
- "layout": "vertical" // 布局方式:vertical / horizontal
- },
- "subwidgets": [ // 子控件数组
- {
- "id": "label_name",
- "widgettype": "Label",
- "options": {
- "value": "姓名:张三"
- }
- },
- {
- "id": "label_age",
- "widgettype": "Label",
- "options": {
- "value": "年龄:28"
- }
- },
- {
- "id": "btn_edit",
- "widgettype": "Button",
- "options": {
- "value": "编辑"
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "btn_edit",
- "event": "click",
- "target": "panel_user_info",
- "dispatch_event": "editmode_enter",
- "params": {
- "user_id": 1001
- }
- }
- ]
- }
- ],
- "binds": [
- {
- "actiontype": "bricks", // 在本地创建新的Bricks组件
- "wid": "panel_user_info",
- "event": "init",
- "target": "Popup", // 特殊目标:弹窗管理器
- "mode": "append",
- "options": {
- "widgettype": "Toast",
- "options": {
- "text": "用户面板已加载",
- "duration": 2000
- }
- }
- }
- ]
-}
-```
-
----
-
-# UrlWidget
-
-远程组件加载控件,用于动态从服务器加载界面模块。类型:普通控件或容器控件(取决于加载内容),继承自 `JsWidget`
-
-## 主要方法
-
-- `reload(params?: Object)`
- 使用新的参数重新请求远程URL,刷新组件。
-
-- `getLoadedWidget(): JsWidget | null`
- 获取已加载的实际控件实例,若未加载完成则返回 null。
-
-- `isLoading(): boolean`
- 判断是否正在加载远程资源。
-
-## 主要事件
-
-- `loadstart`
- 开始加载远程组件时触发。
-
-- `loadsuccess`
- 成功加载并渲染完成远程组件后触发。
-
-- `loaderror`
- 加载失败时触发,携带错误信息。
-
-## 源码例子
-
-```json
-{
- "id": "dynamic_content",
- "widgettype": "UrlWidget", // 特殊控件类型,用于远程加载
- "options": {
- "url": "/api/widgets/profile.ui", // 远程 .ui 文件地址
- "method": "GET", // HTTP 方法
- "params": { // 请求参数
- "userid": "{% userid %}", // 支持模板变量注入
- "lang": "zh-CN"
- }
- },
- "binds": [
- {
- "actiontype": "urlwidget",
- "wid": "dynamic_content",
- "event": "click", // 示例:通过点击重新加载
- "target": "dynamic_content",
- "mode": "replace",
- "options": {
- "url": "/api/widgets/profile.ui",
- "method": "POST",
- "params": {
- "userid": "12345",
- "refresh": true
- }
- }
- },
- {
- "actiontype": "registerfunction",
- "wid": "dynamic_content",
- "event": "loadsuccess",
- "target": "_t_", // 全局上下文
- "rfname": "trackPageView", // 调用注册过的全局函数
- "params": {
- "page": "UserProfile"
- }
- },
- {
- "actiontype": "conform", // 错误处理示例
- "wid": "dynamic_content",
- "event": "loaderror",
- "target": "Popup",
- "rtdata": {
- "title": "加载失败",
- "content": "无法获取用户资料,请稍后再试。"
- },
- "conform": {
- "title": "网络错误",
- "content": "加载用户数据失败,是否重试?",
- "buttons": ["Cancel", "Retry"],
- "onConfirm": {
- "actiontype": "method",
- "target": "dynamic_content",
- "method": "reload"
- }
- }
- }
- ]
-}
-```
-
-> 注:`UrlWidget` 是实现模块化开发的核心控件,支持按需加载 `.ui` 文件,提升首屏性能和代码分割能力。
-
----
-
-# Label
-
-标签控件,用于展示静态文本信息。类型:普通控件,继承自 `JsWidget`
-
-## 主要方法
-
-- `setValue(text: string)`
- 设置标签显示的文本内容。
-
-- `getValue(): string`
- 获取当前显示的文本。
-
-- `setHtml(html: string)`
- 设置 HTML 内容(注意 XSS 防护)。
-
-## 主要事件
-
-- `click`
- 用户点击标签时触发(可用于可交互标签)。
-
-- `dblclick`
- 双击事件。
-
-## 源码例子
-
-```json
-{
- "id": "lbl_instructions",
- "widgettype": "Label",
- "options": {
- "value": "请填写以下必填字段 *", // 显示文本
- "cssClass": "instruction-text", // 自定义CSS类
- "align": "left", // 对齐方式:left/center/right
- "html": false // 是否解析HTML
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "lbl_instructions",
- "event": "click",
- "target": "help_dialog",
- "dispatch_event": "open"
- }
- ]
-}
-```
-
----
-
-> **说明**:以上控件文档遵循 Bricks.js 框架的 JSON 结构规范,适用于 `.ui` 文件编写与可视化工具生成。每个控件均以 `id` 唯一标识,并通过 `binds` 实现事件驱动逻辑,支持动态加载、脚本执行、方法调用等多种交互模式。
\ No newline at end of file
diff --git a/docs/ai.old/floaticonbar.md b/docs/ai.old/floaticonbar.md
deleted file mode 100644
index 255b60e..0000000
--- a/docs/ai.old/floaticonbar.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# IconBar
-
-用于创建一个图标工具栏,支持多个可点击的图标按钮,常用于顶部或侧边导航工具条。属于**容器控件**,继承自 `bricks.HBox`。
-
-## 主要方法
-
-- `build_item(opts)`
- 根据传入的图标配置项创建单个图标控件(`Svg` 或 `BlankIcon`),并绑定点击事件。
-
-- `regen_event(desc, event)`
- 处理图标点击后的逻辑:触发对应图标的命名事件和统一的 `'command'` 事件,并管理选中状态样式。
-
-## 主要事件
-
-- `dispatch(desc.name, desc)`
- 当某个图标被点击时,会派发以该图标 `name` 命名的自定义事件,携带图标描述对象作为参数。
-
-- `dispatch('command', desc)`
- 所有图标点击都会统一触发 `'command'` 事件,可用于集中处理工具栏命令。
-
-## 源码例子
-
-```json
-{
- "id": "icon_toolbar",
- "widgettype": "IconBar",
- "options": {
- "margin": "10px", // 图标之间的左右外边距
- "rate": 1, // 缩放比率,影响图标大小
- "cheight": 2, // 图标高度单位(基于字符高度)
- "tools": [ // 工具图标列表
- {
- "name": "save", // 图标唯一标识名称
- "icon": "/static/icons/save.svg", // SVG 图标路径
- "tip": "保存文件", // 提示文本(可选)
- "rate": 1 // 单独设置此图标的缩放比例
- },
- {
- "name": "print",
- "icon": "/static/icons/print.svg",
- "tip": "打印当前页面"
- },
- {
- "name": "blankicon" // 特殊类型:空白占位图标
- }
- ]
- },
- "binds": [
- {
- "actiontype": "event",
- "wid": "icon_toolbar",
- "event": "save", // 监听名为 'save' 的事件(由点击 save 图标触发)
- "target": "main_app",
- "dispatch_event": "onSave",
- "params": {
- "from": "toolbar"
- }
- },
- {
- "actiontype": "script",
- "wid": "icon_toolbar",
- "event": "command", // 监听所有命令
- "target": "Popup",
- "script": "console.log('执行命令:', params.name); if(params.tip) showTip(params.tip);",
- "params": {
- "name": "{data.name}", // 动态获取事件数据中的 name 字段
- "tip": "{data.tip}"
- }
- }
- ],
- "subwidgets": [] // IconBar 自身是容器,但通常不手动添加 subwidgets,由 tools 自动生成
-}
-```
-
-> ✅ **注释说明:**
-> - `tools` 数组中每个对象代表一个图标按钮;
-> - `name` 是事件分发的关键标识;
-> - `icon` 必须指向有效的 SVG 资源 URL;
-> - 使用 `blankicon` 可插入空格占位符;
-> - 通过 `binds` 可监听具体图标事件或统一的 `command` 事件进行响应;
-> - `FloatIconBar` 和 `IconTextBar` 分别扩展了浮动显示与图文混合功能。
\ No newline at end of file
diff --git a/docs/ai.old/form.md b/docs/ai.old/form.md
deleted file mode 100644
index 60df4bd..0000000
--- a/docs/ai.old/form.md
+++ /dev/null
@@ -1,159 +0,0 @@
-# InlineForm
-
-`InlineForm` 是一个轻量级的表单控件,用于在界面中嵌入行内表单输入区域。它继承自 `FormBase`,属于**普通控件**(虽然其内部结构可包含多个子控件,但本身不作为容器管理布局),主要用于快速构建无需独立弹窗或页面的表单操作场景。
-
----
-
-## 主要方法
-
-| 方法名 | 说明 |
-|-------|------|
-| `build_fields(form, parent, fields)` | 通过 `FieldGroup` 构建字段集合,根据字段类型生成对应的输入控件并添加到父容器中。 |
-| `save_origin_data()` | 保存当前所有字段的初始值,用于后续比对是否发生更改(配合 `submit_changed` 使用)。 |
-| `get_formdata()` | 获取表单数据,支持 `FormData` 格式输出,并可选择仅提交变更字段。若验证失败则返回 `null`。 |
-| `validation()` | 验证表单必填项,触发提交事件并可向服务器发送请求(如果配置了 `submit_url`)。过程中会显示“正在提交”动画。 |
-| `reset_data()` | 将所有输入控件重置为其初始值。 |
-| `cancel()` | 派发 `cancel` 自定义事件,通常用于关闭表单或取消操作流程。 |
-
----
-
-## 主要事件
-
-| 事件名 | 触发时机 | 参数说明 |
-|--------|---------|----------|
-| `submit` | 用户点击“提交”按钮后,通过验证时触发 | 包含表单数据的对象(如 `{ name: "value" }`) |
-| `submited` | 提交完成后,从服务器收到响应时触发 | `Response` 对象(来自 `fetch` 的响应) |
-| `cancel` | 点击“取消”按钮时触发 | 无参数 |
-| `command` | 工具栏按钮点击时由 `IconTextBar` 派发,被 `command_handle` 处理 | `{ name: 'submit' \| 'reset' \| 'cancel' }` |
-
----
-
-## 源码例子
-
-```json
-{
- "id": "user_profile_inline",
- "widgettype": "InlineForm",
- "options": {
- // 表单整体宽度和高度自适应
- "width": "100%",
- "height": "auto",
-
- // 定义表单项列表
- "fields": [
- {
- "name": "username",
- "label": "用户名",
- "uitype": "textinput",
- "required": true,
- "placeholder": "请输入用户名"
- },
- {
- "name": "email",
- "label": "邮箱地址",
- "uitype": "email",
- "required": true,
- "placeholder": "example@domain.com"
- },
- {
- "name": "age",
- "label": "年龄",
- "uitype": "number",
- "min": 1,
- "max": 120
- },
- {
- "name": "gender",
- "label": "性别",
- "uitype": "select",
- "options": [
- { "label": "男", "value": "male" },
- { "label": "女", "value": "female" }
- ]
- }
- ],
-
- // 设置为 true 时只提交修改过的字段(默认 false)
- "submit_changed": false,
-
- // 提交目标 URL
- "submit_url": "/api/update_profile",
-
- // 使用 PUT 方法更新数据
- "method": "PUT"
- },
-
- // 绑定事件处理逻辑
- "binds": [
- {
- "actiontype": "bricks",
- "wid": "user_profile_inline",
- "event": "submit",
- "target": "Popup",
- "mode": "append",
- "options": {
- "widgettype": "Running",
- "message": "正在保存..."
- },
- "rtdata": {
- "form_id": "user_profile_inline"
- },
- "conform": null
- },
- {
- "actiontype": "urlwidget",
- "wid": "user_profile_inline",
- "event": "submited",
- "target": "content_area",
- "mode": "replace",
- "options": {
- "url": "/views/profile_summary.ui",
- "params": {},
- "method": "GET"
- },
- "rtdata": {
- "refresh": true
- }
- },
- {
- "actiontype": "event",
- "wid": "user_profile_inline",
- "event": "cancel",
- "target": "ModalDialog",
- "dispatch_event": "close"
- },
- {
- "actiontype": "script",
- "wid": "user_profile_inline",
- "event": "submit",
- "target": "",
- "script": "console.log('表单提交数据:', params.data);",
- "params": {
- "data": "{getDataFromWidget('user_profile_inline')}"
- }
- }
- ]
-}
-```
-
-> **注释说明:**
->
-> - `InlineForm` 不创建新页面或弹窗,适合嵌入现有布局。
-> - `fields` 中每个字段使用 `uitype` 定义输入类型,框架自动调用 `Input.factory()` 创建对应控件。
-> - `binds` 实现了完整的交互闭环:
-> - 提交前显示加载提示(`Running` 动画);
-> - 提交成功后刷新内容区(通过 `urlwidget` 加载新视图);
-> - 取消时通知模态框关闭;
-> - 同时记录日志脚本用于调试。
-> - 支持国际化字段(`i18n: true` 在底层 Text 控件中已启用)。
-
----
-
-✅ **适用场景:**
-- 内联编辑用户信息
-- 快速填写短表单(如搜索、筛选条件)
-- 在卡片或列表项中直接编辑数据
-
-🔧 **注意事项:**
-- 若涉及文件上传(`file`, `video`, `audio` 类型),需确保 `need_formdata = true`,框架将自动使用 `FormData` 提交。
-- 所有字段必须有唯一 `name`,否则无法正确收集数据。
\ No newline at end of file
diff --git a/docs/ai.old/gobang.md b/docs/ai.old/gobang.md
deleted file mode 100644
index 1678245..0000000
--- a/docs/ai.old/gobang.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# GobangPoint
-
-用于表示围棋棋盘上的一个交叉点,根据状态(空、黑子、白子)动态加载对应图片资源。继承自 `bricks.Image`,属于**普通控件**。
-
-## 主要方法
-
-- `calc_url()`
- 根据当前点的坐标 `(p_x, p_y)` 和状态 `p_status` 计算应显示的图片路径。规则如下:
- - 坐标边缘情况:上下左右用 `'t'`, `'b'`, `'l'`, `'r'` 表示,中间为 `'c'`
- - 状态映射:0 → `'empty'`,1 → `'black'`,2 → `'white'`
- - 图片命名格式:`imgs/[vpos][hpos]_[status].png`,例如 `imgs/cl_black.png`
-
-- `getValue()`
- 返回该点的状态对象,包含:
- ```js
- {
- status: this.p_status,
- x: this.p_x,
- y: this.p_y
- }
- ```
- 可用于获取棋子位置和颜色信息。
-
-- `str()`
- 返回该点的字符串表示,格式为 `(status,x,y)`,主要用于调试输出。
-
-- `set_current_position(flg)`
- 鼠标移入时设置 CSS 类 `curpos` 为 false(实际是通过 `!flg` 控制),可用于高亮当前悬停位置(需配合样式定义)。
-
-## 主要事件
-
-- `mouseover`
- 触发时调用 `set_current_position(true)`,可用来实现悬停视觉反馈。
-
-- `mouseout`
- 触发时调用 `set_current_position(false)`,取消悬停效果。
-
-## 源码例子
-
-```json
-{
- "id": "point_3_4",
- "widgettype": "GobangPoint",
- "options": {
- "p_status": 0, // 当前状态:0=空,1=黑,2=白
- "p_x": 3, // 横向坐标,范围 1-15
- "p_y": 4, // 纵向坐标,范围 1-15
- "tip": "(3,4)" // 提示文本,鼠标悬停时显示
- },
- "binds": [
- {
- "actiontype": "method",
- "wid": "point_3_4",
- "event": "click",
- "target": "game_controller", // 假设存在游戏控制器组件
- "method": "makeMove",
- "params": {
- "datawidget": "point_3_4",
- "datamethod": "getValue" // 调用 getValue 获取坐标与状态
- }
- }
- ]
-}
-```
-
-> ✅ **注释说明**:
-> - 此控件通过 `p_status`, `p_x`, `p_y` 构造参数决定其外观。
-> - 使用 `binds` 在点击时将自身数据传递给主控制器进行落子逻辑处理。
-> - 图片资源路径由 `calc_url()` 自动生成,依赖于项目中 `/imgs/` 目录下的切图资源。
-
----
-
-# Gobang
-
-代表一个完整的围棋对弈界面控件,管理15×15的棋盘点阵,并支持响应式布局调整。继承自 `bricks.VBox`,属于**容器控件**。
-
-## 主要方法
-
-- `render_empty_area()`
- 创建15×15的 `GobangPoint` 网格并填充到内部的 `VBox` 中,初始状态均为“空”。使用嵌套循环生成行列结构,并保存引用至 `this.area[i][j]` 数组以便后续操作。
-
-- `resize_area()`
- 根据父容器尺寸自动缩放每个棋盘点的大小。取 `filler` 容器宽高中较小值除以15作为单个格子尺寸,确保棋盘等比适应窗口变化。
-
-- `inform_go(party)`
- (目前为空实现)预留方法,用于通知轮到哪一方下棋(如 `'black'` 或 `'white'`),可用于AI触发或状态提示。
-
-## 主要事件
-
-- `element_resize`(来自 `Filler` 子控件)
- 当填充区域尺寸改变时触发,自动调用 `resize_area()` 方法重绘棋盘格子大小,实现自适应布局。
-
-## 源码例子
-
-```json
-{
- "id": "gobang_game",
- "widgettype": "Gobang",
- "options": {},
- "subwidgets": [], // 实际上在构造函数中动态创建,无需在 JSON 中显式列出
- "binds": [
- {
- "actiontype": "script",
- "wid": "gobang_game",
- "event": "load", // 假设框架支持 load 事件
- "script": "console.log('围棋游戏已加载完成');"
- },
- {
- "actiontype": "method",
- "wid": "some_button",
- "event": "click",
- "target": "gobang_game",
- "method": "inform_go",
- "params": {
- "party": "black"
- }
- }
- ]
-}
-```
-
-> ✅ **注释说明**:
-> - `Gobang` 是一个复合容器控件,在初始化时通过代码动态构建子控件网格(`GobangPoint`),因此 `subwidgets` 在 JSON 中留空。
-> - 使用 `Filler` 占位并监听其 `element_resize` 事件,实现响应式设计。
-> - 可扩展绑定外部按钮来控制回合切换,未来可集成 AI 对手或网络对战功能。
-> - 若需远程加载此游戏模块,可用 `urlwidget` 方式按需加载。
-
----
-
-📌 **总结建议**:
-以上两个控件共同构成一个可交互、可扩展的围棋界面基础。`GobangPoint` 封装视觉与状态逻辑,`Gobang` 负责整体布局与协调。结合 bricks 的模块化能力(如 `urlwidget` 动态加载),非常适合开发复杂交互类 Web 应用。
\ No newline at end of file
diff --git a/docs/ai.old/html.md b/docs/ai.old/html.md
deleted file mode 100644
index 82f223d..0000000
--- a/docs/ai.old/html.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Html
-
-Html 是一个用于在页面中插入原始 HTML 内容的**普通控件**,继承自 `JsWidget`。它允许开发者通过配置 `html` 选项直接渲染任意 HTML 字符串,适用于展示富文本、静态内容或嵌入第三方 HTML 片段。
-
----
-
-## 主要方法
-
-- **`setValue(html: string)`**
- 更新控件内的 HTML 内容,等同于重新设置 `innerHTML`。
-
-- **`getValue(): string`**
- 返回当前控件容器内的 HTML 字符串内容。
-
-- **`clear()`**
- 清空控件中的所有 HTML 内容。
-
----
-
-## 主要事件
-
-Html 控件不触发任何默认交互事件(如点击、输入等),但可以通过绑定父级容器或其他控件来监听 DOM 事件。若需响应内部元素的事件,建议使用 `binds` 绑定到具体操作目标。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "html_welcome", // 控件唯一标识
- "widgettype": "Html", // 控件类型:Html
- "options": {
- "html": "欢迎使用 Bricks.js 这是一个使用 Html 控件插入的富文本内容。
"
- // html 字段指定要渲染的 HTML 字符串
- },
- "binds": [
- {
- "actiontype": "script",
- "wid": "html_welcome",
- "event": "click",
- "target": "html_welcome",
- "script": "console.log('用户点击了 Html 控件区域');",
- "conform": {
- "title": "确认操作",
- "message": "你确定要查看控制台吗?",
- "confirmText": "确定",
- "cancelText": "取消"
- }
- }
- ]
-}
-```
-
-> ✅ **注释说明:**
-> - 此例创建了一个 ID 为 `html_welcome` 的 Html 控件。
-> - `options.html` 中定义了带样式的标题和段落文本。
-> - 使用 `binds` 监听点击事件,当用户点击该控件时,弹出确认对话框并输出日志到浏览器控制台。
-> - 注意:由于是普通控件,不能包含 `subwidgets` 子控件数组。
\ No newline at end of file
diff --git a/docs/ai.old/iconbarpage.md b/docs/ai.old/iconbarpage.md
deleted file mode 100644
index 75dee9f..0000000
--- a/docs/ai.old/iconbarpage.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# IconbarPage
-
-**用途**:`IconbarPage` 是一个容器控件,用于构建具有图标工具栏(IconTextBar)和内容区域的页面布局。工具栏可放置在页面顶部或底部,点击工具栏中的图标按钮会动态加载并显示对应的内容模块。常用于导航式界面设计,如管理后台、多标签页应用等。
-
-**类型**:容器控件,继承自 `bricks.VBox`
-
----
-
-## 主要方法
-
-- `constructor(opts)`
- 构造函数,初始化布局结构。根据 `opts.bar_at` 决定工具栏位置(top/bottom),创建 `IconTextBar` 工具栏和 `Filler` 内容容器,并绑定命令事件。
-
-- `command_handle(event)`
- 工具栏触发 `'command'` 事件时的处理函数,接收选中工具项信息,并调用 `show_content` 切换内容。
-
-- `show_content(tool)`
- 异步方法,根据传入的 `tool` 配置动态构建其 `content` 对应的控件,并替换当前内容区域的子控件。
-
----
-
-## 主要事件
-
-- `'command'`
- 当用户点击工具栏上的某个工具项时,由 `IconTextBar` 触发此事件,携带 `tool` 数据作为参数,被 `command_handle` 捕获用于切换内容。
-
----
-
-## 源码例子
-
-```json
-{
- "id": "main_iconbar_page",
- "widgettype": "IconbarPage",
- "options": {
- "bar_at": "top", // 可选 'top' 或 'bottom',指定工具栏位置
- "bar_opts": {
- "margin": "5px", // 工具栏外边距
- "rate": 1, // 布局比例
- "tools": [
- {
- "name": "dashboard",
- "icon": "fa fa-tachometer", // 图标类名(如 Font Awesome)
- "label": "仪表盘", // 显示文本(可选)
- "tip": "进入系统仪表盘", // 提示文字
- "dynsize": false, // 是否动态调整大小
- "rate": 1,
- "content": {
- "widgettype": "Label",
- "options": {
- "text": "欢迎来到仪表盘页面!"
- }
- }
- },
- {
- "name": "users",
- "icon": "fa fa-users",
- "label": "用户管理",
- "tip": "管理所有用户信息",
- "content": {
- "widgettype": "urlwidget",
- "options": {
- "url": "/widgets/users.ui", // 远程加载用户管理界面
- "method": "GET",
- "params": {}
- }
- }
- },
- {
- "name": "settings",
- "icon": "fa fa-cog",
- "label": "系统设置",
- "tip": "配置系统参数",
- "content": {
- "widgettype": "VBox",
- "options": {},
- "subwidgets": [
- {
- "widgettype": "Label",
- "options": {
- "text": "这里是系统设置页面"
- }
- },
- {
- "widgettype": "Button",
- "options": {
- "text": "保存设置"
- },
- "binds": [
- {
- "actiontype": "script",
- "wid": "main_iconbar_page",
- "event": "click",
- "target": "main_iconbar_page",
- "script": "alert('设置已保存')",
- "conform": {
- "title": "确认保存",
- "message": "您确定要保存这些设置吗?"
- }
- }
- ]
- }
- ]
- }
- }
- ]
- }
- },
- "subwidgets": [], // 此控件自身不在此处定义子控件,而是通过 bar_opts.tools 动态加载
- "binds": [
- {
- "actiontype": "method",
- "wid": "main_iconbar_page",
- "event": "init",
- "target": "main_iconbar_page",
- "method": "show_content",
- "params": {
- "tool": {
- "content": {
- "widgettype": "Label",
- "options": {
- "text": "初始化默认内容"
- }
- }
- }
- }
- }
- ]
-}
-```
-
-> **注释说明**:
-> - `IconbarPage` 使用 `bar_opts.tools` 数组定义多个功能入口,每个 `tool` 包含一个 `content` 字段,描述要加载的子界面。
-> - `urlwidget` 类型可用于懒加载远程 `.ui` 文件,实现按需加载模块。
-> - 通过 `binds` 绑定初始化行为,可在页面加载后自动显示默认内容。
-> - `conform` 提供操作前的确认弹窗,增强用户体验与安全性。
\ No newline at end of file
diff --git a/docs/ai.old/iframe.md b/docs/ai.old/iframe.md
deleted file mode 100644
index 3d878ac..0000000
--- a/docs/ai.old/iframe.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Iframe
-
-Iframe 是一个容器控件,继承自 `bricks.Layout`,属于普通控件(虽然继承自容器类 Layout,但通常不用于放置子控件,而是嵌入外部网页内容)。该控件用于在当前页面中嵌入一个 `