@jboltai/tokui 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README_EN.md +1 -1
- package/dist/tokui.cjs +11 -9
- package/dist/tokui.cjs.map +1 -1
- package/dist/tokui.css +1 -1
- package/dist/tokui.mjs +5647 -2723
- package/dist/tokui.mjs.map +1 -1
- package/dist/tokui.umd.js +10 -8
- package/dist/tokui.umd.js.map +1 -1
- package/package.json +2 -2
- package/src/index.d.ts +33 -0
- package/src/server/tokui-builder.js +38 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jboltai/tokui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "TokUI — Zero-dependency streaming UI description & rendering framework for AI chat. Describe UI with a tiny DSL, stream over SSE, render to real DOM incrementally.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tokui",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"typecheck": "tsc",
|
|
90
90
|
"coverage": "c8 --include='src/**/*.js' --exclude='src/server/**' npm run test:all",
|
|
91
91
|
"server": "node demo/server/sse-server.js",
|
|
92
|
-
"demo:sync": "npm run build && cp dist/tokui.umd.js dist/tokui.css demo/lib/",
|
|
92
|
+
"demo:sync": "npm run build && cp dist/tokui.umd.js dist/tokui.css demo/lib/ && perl -i -ne 'print unless m{^//# sourceMappingURL=}' demo/lib/tokui.umd.js && cp src/server/tokui-builder.js demo/server/tokui-builder.js",
|
|
93
93
|
"dev": "vite",
|
|
94
94
|
"build": "vite build --mode lib",
|
|
95
95
|
"build:lib": "vite build --mode lib",
|
package/src/index.d.ts
CHANGED
|
@@ -25,6 +25,13 @@ export interface TokUIOptions {
|
|
|
25
25
|
container?: string | HTMLElement | null;
|
|
26
26
|
/** 主题名称,如 'default' / 'dark',默认 'default' */
|
|
27
27
|
theme?: string;
|
|
28
|
+
/**
|
|
29
|
+
* 界面语言(组件骨架级文案:aria-label / placeholder / 空态 / 默认按钮字等)。
|
|
30
|
+
* 接受 'zh-CN' / 'en-US' / 'en' / 'zh' 等,自动规整;缺省按
|
|
31
|
+
* documentElement.lang → navigator.language → 'zh-CN' 自动探测。
|
|
32
|
+
* 注:业务 DSL 文案(tt:/l:/tx:/opt: 等)不归此管,需后端按 locale 发不同 DSL。
|
|
33
|
+
*/
|
|
34
|
+
locale?: string;
|
|
28
35
|
/** 是否启用流式渲染模式,默认 true */
|
|
29
36
|
streaming?: boolean;
|
|
30
37
|
/** 事件回调,如接收到 ('streamEnd', {}) */
|
|
@@ -58,6 +65,12 @@ export class TokUI {
|
|
|
58
65
|
/** 一次性渲染完整 DSL 文本到容器 */
|
|
59
66
|
render(tokuiString: string, targetContainer?: HTMLElement): void;
|
|
60
67
|
|
|
68
|
+
/**
|
|
69
|
+
* 用当前 locale / theme 就地重画最近一次渲染的内容(清容器 + 重新 render 缓存的 DSL)。
|
|
70
|
+
* 典型用途:setLocale() 后刷新已渲染 DOM 的 chrome 文案。无缓存内容或无容器返回 false。
|
|
71
|
+
*/
|
|
72
|
+
rerender(targetContainer?: HTMLElement): boolean;
|
|
73
|
+
|
|
61
74
|
/** 开始流式渲染(初始化流式解析器) */
|
|
62
75
|
startStream(targetContainer?: HTMLElement): void;
|
|
63
76
|
|
|
@@ -90,6 +103,23 @@ export declare function setTheme(themeName: string): void;
|
|
|
90
103
|
/** 获取当前主题名称 */
|
|
91
104
|
export declare function getTheme(): string;
|
|
92
105
|
|
|
106
|
+
/**
|
|
107
|
+
* 设置当前界面语言(组件骨架级文案)。已渲染的 DOM 不会自动更新,
|
|
108
|
+
* 需重新渲染或应用层自行刷新。接受 'zh-CN' / 'en-US' / 'en' / 'zh' 等,自动规整。
|
|
109
|
+
* @returns 规整后实际生效的 locale(如传 'en' 返回 'en-US')
|
|
110
|
+
*/
|
|
111
|
+
export declare function setLocale(locale: string): string;
|
|
112
|
+
|
|
113
|
+
/** 获取当前界面语言(规整后的 locale,如 'zh-CN' / 'en-US') */
|
|
114
|
+
export declare function getLocale(): string;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 注册/合并新语种字典(内置仅 zh-CN + en-US,其余语种由此注入)。
|
|
118
|
+
* @param locale - 语种 key,如 'ja-JP'
|
|
119
|
+
* @param dict - key→译文 映射,可仅传部分 key(增量合并)
|
|
120
|
+
*/
|
|
121
|
+
export declare function registerLocale(locale: string, dict: Record<string, string>): void;
|
|
122
|
+
|
|
93
123
|
/**
|
|
94
124
|
* DOM 创建快捷方法
|
|
95
125
|
* @param tag - 标签名
|
|
@@ -109,6 +139,9 @@ export interface TokUINamespace {
|
|
|
109
139
|
removeHandler: typeof removeHandler;
|
|
110
140
|
setTheme: typeof setTheme;
|
|
111
141
|
getTheme: typeof getTheme;
|
|
142
|
+
setLocale: typeof setLocale;
|
|
143
|
+
getLocale: typeof getLocale;
|
|
144
|
+
registerLocale: typeof registerLocale;
|
|
112
145
|
el: typeof el;
|
|
113
146
|
}
|
|
114
147
|
|
|
@@ -36,8 +36,9 @@ class TokUIBuilder {
|
|
|
36
36
|
let val = String(v);
|
|
37
37
|
// 转义值中的双引号
|
|
38
38
|
val = val.replace(/"/g, '\\"');
|
|
39
|
-
//
|
|
40
|
-
|
|
39
|
+
// opt 简写值含 : ; 分隔符,必须强制双引号(parser 引号感知整串作字面值);
|
|
40
|
+
// 其余含空格/引号/换行/] 的值同样需引号
|
|
41
|
+
if (k === 'opt' || val.includes(' ') || val.includes('"') || val.includes('\n') || val.includes(']')) {
|
|
41
42
|
return `${k}:"${val}"`;
|
|
42
43
|
}
|
|
43
44
|
return `${k}:${val}`;
|
|
@@ -228,13 +229,26 @@ class TokUIBuilder {
|
|
|
228
229
|
/** 自定义选择器 */
|
|
229
230
|
picker(attrs) { return this._open('picker', attrs); }
|
|
230
231
|
/** 下拉选择框 */
|
|
231
|
-
select(attrs) {
|
|
232
|
+
select(attrs) {
|
|
233
|
+
return attrs && attrs.opt
|
|
234
|
+
? this._selfClosing('select', null, attrs)
|
|
235
|
+
: this._open('select', attrs);
|
|
236
|
+
}
|
|
232
237
|
/** 选项 */
|
|
233
238
|
opt(attrs) { return this._selfClosing('opt', null, attrs); }
|
|
234
239
|
/** 单选按钮组 */
|
|
235
|
-
radio(attrs) {
|
|
240
|
+
radio(attrs) {
|
|
241
|
+
return attrs && attrs.opt
|
|
242
|
+
? this._selfClosing('radio', null, attrs)
|
|
243
|
+
: this._open('radio', attrs);
|
|
244
|
+
}
|
|
236
245
|
/** 复选框 */
|
|
237
|
-
checkbox(attrs) {
|
|
246
|
+
checkbox(attrs) {
|
|
247
|
+
// 简写 opt:"..." → 自闭合;多选容器 multi → _open;单布尔 → 自闭合
|
|
248
|
+
if (attrs && attrs.opt) return this._selfClosing('checkbox', null, attrs);
|
|
249
|
+
if (attrs && attrs.multi !== undefined) return this._open('checkbox', attrs);
|
|
250
|
+
return this._selfClosing('checkbox', null, attrs);
|
|
251
|
+
}
|
|
238
252
|
/** 开关组件(方法名 switcher 避开 JS 关键字) */
|
|
239
253
|
switcher(attrs) { return this._selfClosing('switch', null, attrs); }
|
|
240
254
|
/** 多行文本框 */
|
|
@@ -355,6 +369,10 @@ class TokUIBuilder {
|
|
|
355
369
|
|
|
356
370
|
/** Empty 空状态(自闭合) */
|
|
357
371
|
empty(attrs) { return this._selfClosing('empty', null, attrs); }
|
|
372
|
+
/** Code128 条形码:tx 数据 / l 标签 / s 尺寸(sm/md/lg) */
|
|
373
|
+
barcode(attrs) { return this._selfClosing('barcode', null, attrs); }
|
|
374
|
+
/** QR 二维码:tx 数据 / l 标签 / s 尺寸 / ec 纠错级(L/M/Q/H) */
|
|
375
|
+
qrcode(attrs) { return this._selfClosing('qrcode', null, attrs); }
|
|
358
376
|
/** Result 结果页(自闭合) */
|
|
359
377
|
result(attrs) { return this._selfClosing('result', null, attrs); }
|
|
360
378
|
/** Stat 统计数值(自闭合) */
|
|
@@ -407,8 +425,21 @@ class TokUIBuilder {
|
|
|
407
425
|
|
|
408
426
|
// ========== 动态更新 ==========
|
|
409
427
|
|
|
410
|
-
/** Upd 异步更新指令(自闭合),推送状态更新到已有组件
|
|
411
|
-
|
|
428
|
+
/** Upd 异步更新指令(自闭合),推送状态更新到已有组件
|
|
429
|
+
* 注意:serializeAttrs 默认跳过 false 值(初始渲染 [input dis:false] 会被 parser
|
|
430
|
+
* 读成字符串 'false' 误判为 truthy → 反而禁用,故 false 必须省略)。
|
|
431
|
+
* 但 upd 的 dis:false / ro:false / chk:false 是「主动关闭」语义,渲染端 _update
|
|
432
|
+
* 专门判 === 'false'。故此处把 false 预规范成 'false' 字符串再序列化,让 toggle-off 生效。*/
|
|
433
|
+
upd(attrs) {
|
|
434
|
+
if (attrs && typeof attrs === 'object') {
|
|
435
|
+
const norm = {};
|
|
436
|
+
for (const [k, v] of Object.entries(attrs)) {
|
|
437
|
+
norm[k] = v === false ? 'false' : v;
|
|
438
|
+
}
|
|
439
|
+
return this._selfClosing('upd', null, norm);
|
|
440
|
+
}
|
|
441
|
+
return this._selfClosing('upd', null, attrs);
|
|
442
|
+
}
|
|
412
443
|
|
|
413
444
|
// ========== 交互组件 ==========
|
|
414
445
|
|