diff --git a/doc.sh b/doc.sh
new file mode 100644
index 0000000..1ddb7d7
--- /dev/null
+++ b/doc.sh
@@ -0,0 +1,5 @@
+sources=$(find bricks -name "*.js" -exec grep -l '.register(' {} \; -print|sort -u)
+for s in $sources
+do
+ t2t -p prompt.md -o docs/ai $s
+done
diff --git a/docs/ai/accordion.md b/docs/ai/accordion.md
new file mode 100644
index 0000000..5b11f55
--- /dev/null
+++ b/docs/ai/accordion.md
@@ -0,0 +1,68 @@
+# 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/asr.md b/docs/ai/asr.md
new file mode 100644
index 0000000..e03fee7
--- /dev/null
+++ b/docs/ai/asr.md
@@ -0,0 +1,116 @@
+# 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/audio.md b/docs/ai/audio.md
new file mode 100644
index 0000000..875cb07
--- /dev/null
+++ b/docs/ai/audio.md
@@ -0,0 +1,282 @@
+# 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/bar.md b/docs/ai/bar.md
new file mode 100644
index 0000000..d337562
--- /dev/null
+++ b/docs/ai/bar.md
@@ -0,0 +1,88 @@
+# 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/brief.md b/docs/ai/brief.md
new file mode 100644
index 0000000..30322fb
--- /dev/null
+++ b/docs/ai/brief.md
@@ -0,0 +1,106 @@
+# bricks框架简介
+## 目录
+* bricks目标
+* bricks概念
+* bricks开发方法
+* bricks运行
+
+## bricks目标
+* 无前端代码或极少代码
+* 降低前端开发技术难度
+* 数据驱动
+* 常用控件包装
+* 纯json开发
+
+## bricks概念
+* 控件与控件继承
+* 事件以及事件处理
+* 控件嵌套和页面组装
+
+### 控件与控件继承
+bricks采用控件这一概念来描述web GUI的显示部件,每个控件均映射到一个html
+的标签类型的一个javascript类。每个控件均可以实例化,并可在页面显示。
+控件分为:基本控件,容器控件。
+
+* 基本控件
+基本控件是一个原子控件,不能有子控件。
+* 容器控件
+容器控件可以有子控件,bricks通过在容器控件添加子控件,以及在子容器控件中
+在添加子子控件的方式来构造复杂的web页面。
+
+控件的详细介绍请参看[控件说明](widgets.md)
+
+### 控件扩展
+如果现有的控件没法满足系统要求,bricks支持控件扩展,控件扩展需遵守:
+* 控件class继承自某一个控件的class
+
+* 按照需求实现控件逻辑
+
+* 在需要的地方用this.dispatch触发此控件的事件
+
+假设需要扩展一个名字叫ExtContainer的控件
+```
+bricks.ExtContainer = class extends bricks.VBox {
+ constructor(opts){
+ super(opts);
+ /* 新控件的创建代码 */
+ }
+ ......
+ /* 对象的其他方法,在需要的时候,在某个方法中,使用this.dispatch('new_event', data)方法引发事件 */
+}
+bricks.register('ExtContainer', bricks.ExtContainer); /* 注册新控件 */
+```
+新控件的使用,example.ui
+```
+{
+ "widgettype":"ExtContainer",
+ "options":{
+ ....
+ },
+ "subwidgets":[
+ ...
+ ],
+ "binds":[
+ {
+ "wid":"self",
+ "event":"new_event",
+ "actiontype":"urlwidget",
+ "target":"some_container",
+ "options":{
+ "url":"{{entire_url('./some_ui.ui')}}"
+ }
+ }
+ ]
+}
+```
+
+### 事件以及事件处理
+每个控件都能触发所映射dom元素的事件,以及控件js类的成员函数以及祖先类的
+成员函数中dispatch出的事件
+
+所以bricks控件的事件来源于两类,dom元素原生事件以及控件类中创造的事件。
+两类事件处理方式相同。
+
+### 控件表达形式
+在服务器的后台,以json文件的形式表达控件,每个ui文件定义一个控件,
+对于容器控件,可以在ui文件中的subwidgets子属性中为此控件添加子控件
+
+#### id属性
+字符串属性,定义控件的id,让控件可以用getWidgetById找到,如果不给定,系统会自动生成一个id
+#### options属性
+字典属性,创建控件时的选项,每个控件可接受的选项请参看控件选项说明
+#### binds属性
+数组属性,定义零到多个事件响应,每个bind字典需要遵守[事件](event.md)要求
+#### 容器控件特有属性
+##### subwidgets
+数组属性,定义容器控件的子控件,每个元素定义一个子控件,子控件遵守控件的数据要素要求
+
+## 开发
+使用存放在服务器后台的.ui后缀的json格式文件来开发,每个.ui文件定义一个控件, 支持基本控件和容器空间。
+
+关于如何书写ui文件请参考[UI文件格式](descjson.md)
+
+## 调试
+ui文件可以直接调试,如在服务器根目录下的test目录下有一个hello.ui文件,
+就可以在浏览器中用url:https://sername/test/hello.ui调试
+
diff --git a/docs/ai/button.md b/docs/ai/button.md
new file mode 100644
index 0000000..f7ee81d
--- /dev/null
+++ b/docs/ai/button.md
@@ -0,0 +1,92 @@
+# Button
+
+按钮控件(Button)是 Bricks.js 框架中用于触发用户交互行为的**普通控件**,继承自 `bricks.Layout`。它通常用于提交表单、打开弹窗、执行脚本或导航等操作。Button 支持图标、文本标签、自定义样式以及事件绑定,适用于各种 UI 场景。
+
+## 主要方法
+
+- **`target_clicked(event)`**
+ 内部方法,当按钮被点击时触发,阻止事件冒泡并派发 `click` 事件,同时处理配置的 `action` 行为。
+
+- **`create()`**
+ 创建底层 DOM 元素(`