weifuwu 0.93.2 → 0.94.0
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 +5 -5
- package/dist/client/components/ActionSheet/ActionSheet.d.ts +1 -1
- package/dist/client/components/AlertGroup/AlertGroup.d.ts +1 -1
- package/dist/client/components/Anchor/Anchor.d.ts +1 -1
- package/dist/client/components/AppShell/AppShell.d.ts +20 -3
- package/dist/client/components/AuthPage/AuthPage.d.ts +1 -1
- package/dist/client/components/AutoComplete/AutoComplete.d.ts +1 -1
- package/dist/client/components/AvatarGroup/AvatarGroup.d.ts +1 -1
- package/dist/client/components/Button/Button.d.ts +8 -2
- package/dist/client/components/Chart/Chart.d.ts +1 -1
- package/dist/client/components/Chart/chart-utils.d.ts +1 -1
- package/dist/client/components/ChatInput/ChatInput.d.ts +3 -1
- package/dist/client/components/CodeBlock/CodeBlock.d.ts +1 -1
- package/dist/client/components/CodeBlock/highlight.d.ts +1 -1
- package/dist/client/components/Confirm/Confirm.d.ts +1 -1
- package/dist/client/components/CronPicker/CronPicker.d.ts +31 -0
- package/dist/client/components/DatePicker/DatePicker.d.ts +1 -1
- package/dist/client/components/DatePicker/calendar-utils.d.ts +1 -1
- package/dist/client/components/Descriptions/Descriptions.d.ts +1 -1
- package/dist/client/components/Drawer/Drawer.d.ts +4 -1
- package/dist/client/components/DropZone/DropZone.d.ts +1 -1
- package/dist/client/components/Dropdown/Dropdown.d.ts +1 -1
- package/dist/client/components/Editor/Editor.d.ts +1 -1
- package/dist/client/components/Editor/edit-events.d.ts +1 -1
- package/dist/client/components/Editor/model/apply.d.ts +1 -1
- package/dist/client/components/Editor/model/diff.d.ts +1 -1
- package/dist/client/components/Editor/model/dom.d.ts +1 -1
- package/dist/client/components/Editor/model/history.d.ts +1 -1
- package/dist/client/components/Editor/model/html.d.ts +1 -1
- package/dist/client/components/Editor/model/inverse.d.ts +1 -1
- package/dist/client/components/Editor/model/types.d.ts +1 -1
- package/dist/client/components/Editor/tools/table.d.ts +1 -1
- package/dist/client/components/Editor/tools/toolbar.d.ts +1 -1
- package/dist/client/components/Editor/tools/types.d.ts +1 -1
- package/dist/client/components/FilePreview/FilePreview.d.ts +1 -1
- package/dist/client/components/FilePreview/markdown.d.ts +1 -1
- package/dist/client/components/FileTree/FileTree.d.ts +1 -1
- package/dist/client/components/FileUpload/FileUpload.d.ts +1 -1
- package/dist/client/components/FloatButton/FloatButton.d.ts +1 -1
- package/dist/client/components/Grid/Grid.d.ts +1 -1
- package/dist/client/components/Highlight/Highlight.d.ts +1 -1
- package/dist/client/components/HoverCard/HoverCard.d.ts +1 -1
- package/dist/client/components/Icon/Icon.d.ts +1 -1
- package/dist/client/components/Img/Img.d.ts +1 -1
- package/dist/client/components/InView/InView.d.ts +1 -1
- package/dist/client/components/Input/Input.d.ts +6 -0
- package/dist/client/components/InputNumber/InputNumber.d.ts +1 -1
- package/dist/client/components/JSONViewer/JSONViewer.d.ts +1 -1
- package/dist/client/components/Layout/Layout.d.ts +1 -1
- package/dist/client/components/Link/Link.d.ts +1 -1
- package/dist/client/components/List/List.d.ts +1 -1
- package/dist/client/components/ListScaffold/ListScaffold.d.ts +40 -0
- package/dist/client/components/LogViewer/LogViewer.d.ts +1 -1
- package/dist/client/components/Markdown/Markdown.d.ts +1 -1
- package/dist/client/components/Markdown/parser.d.ts +1 -1
- package/dist/client/components/Menu/Menu.d.ts +3 -1
- package/dist/client/components/MessageBubble/MessageBubble.d.ts +1 -1
- package/dist/client/components/Modal/Modal.d.ts +5 -1
- package/dist/client/components/NavBar/NavBar.d.ts +1 -1
- package/dist/client/components/NavMenu/NavMenu.d.ts +1 -1
- package/dist/client/components/OfficeEditor/ai/ai-bridge.d.ts +1 -1
- package/dist/client/components/OfficeEditor/model/apply.d.ts +1 -1
- package/dist/client/components/OfficeEditor/model/types.d.ts +1 -1
- package/dist/client/components/PasswordInput/PasswordInput.d.ts +1 -1
- package/dist/client/components/Popconfirm/Popconfirm.d.ts +1 -1
- package/dist/client/components/Popover/Popover.d.ts +1 -1
- package/dist/client/components/PromptTemplate/PromptTemplate.d.ts +1 -1
- package/dist/client/components/RelationGraph/RelationGraph.d.ts +1 -1
- package/dist/client/components/Result/Result.d.ts +1 -1
- package/dist/client/components/Scrollbar/Scrollbar.d.ts +1 -1
- package/dist/client/components/SheetGrid/SheetGrid.d.ts +2 -2
- package/dist/client/components/Skeleton/Skeleton.d.ts +1 -1
- package/dist/client/components/SlideCanvas/SlideCanvas.d.ts +2 -2
- package/dist/client/components/Space/Space.d.ts +1 -1
- package/dist/client/components/StatusDot/StatusDot.d.ts +25 -0
- package/dist/client/components/TabBar/TabBar.d.ts +1 -1
- package/dist/client/components/TagsInput/TagsInput.d.ts +1 -1
- package/dist/client/components/Textarea/Textarea.d.ts +6 -0
- package/dist/client/components/ThemeSwitch/ThemeSwitch.d.ts +1 -1
- package/dist/client/components/Timeline/Timeline.d.ts +1 -1
- package/dist/client/components/Tooltip/Tooltip.d.ts +1 -1
- package/dist/client/components/VirtualTable/VirtualTable.d.ts +1 -1
- package/dist/client/components/WordCloud/WordCloud.d.ts +1 -1
- package/dist/client/components/index.d.ts +9 -3
- package/dist/client/components/index.js +36 -36
- package/dist/client/components/style.css +1 -1
- package/dist/client/layout/decl.d.ts +9 -0
- package/dist/client/layout/define.d.ts +41 -0
- package/dist/client/layout/index.d.ts +20 -0
- package/dist/client/layout/index.js +17 -0
- package/dist/client/layout/weifuwu-layout.css +1 -1
- package/dist/client/vdom/context/UIContext.d.ts +1 -1
- package/dist/client/vdom/core/create-component.d.ts +42 -0
- package/dist/client/vdom/core/create-item.d.ts +52 -0
- package/dist/client/vdom/core/vnode.d.ts +8 -2
- package/dist/client/vdom/hooks/env.d.ts +12 -0
- package/dist/client/vdom/hooks/field.d.ts +54 -0
- package/dist/client/vdom/hooks/overlay.d.ts +60 -0
- package/dist/client/vdom/hooks/signal.d.ts +25 -0
- package/dist/client/vdom/index.d.ts +9 -2
- package/dist/client/vdom/index.js +3 -3
- package/dist/client/vdom/jsx-runtime.d.ts +4 -4
- package/dist/client/vdom/jsx-runtime.js +1 -1
- package/dist/client/vdom/testing.js +2 -2
- package/dist/dev/index.js +7 -6
- package/dist/server/ai/index.js +7 -0
- package/dist/server/ai/types.d.ts +1 -1
- package/dist/server/email/index.js +1 -0
- package/dist/server/index.js +235 -5
- package/dist/server/messager/index.js +1 -0
- package/dist/server/postgres/index.js +56 -0
- package/dist/server/queue/index.js +1 -0
- package/dist/server/redis/index.js +3 -0
- package/dist/server/scheduler/index.js +1 -0
- package/dist/server/ui/index.d.ts +1 -1
- package/dist/server/ui/index.js +15 -0
- package/dist/server/user/index.js +1 -0
- package/dist/server/user/token.d.ts +1 -1
- package/dist/server/workflows/index.js +24 -0
- package/dist/shared/router/index.js +2 -0
- package/docs/client.md +143 -10
- package/docs/layout.md +14 -14
- package/docs/server.md +1 -1
- package/package.json +66 -12
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/client/layout — 原语声明(defineLayout——生成器消费——BEM 直拼单源)
|
|
3
|
+
*
|
|
4
|
+
* W4 样本:row/stack 族(机制验证——生成 = 手写逐属性等价——等价后手写
|
|
5
|
+
* _row.css/_stack.css 删除——生成器输出进 bundle 汇编)。
|
|
6
|
+
* 声明添加 = 新原语(组合缺省(gap/align defaults)声明即生成)。
|
|
7
|
+
*/
|
|
8
|
+
import type { StructureDecl } from './define.ts';
|
|
9
|
+
export declare const structures: StructureDecl[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/client/layout — defineLayout(布局原语声明 + 生成器)
|
|
3
|
+
*
|
|
4
|
+
* 设计(2027-09——分层抽象 W4):layout 174 类手写实证——原语 = **声明**:
|
|
5
|
+
* 语义词 → 属性组合(stack/row/grid、组合缺省、零优先级默认、断点变体)。
|
|
6
|
+
* 生成器输出 = 与手写**逐属性等价**的 CSS(硬验收——diff 等价才迁移)。
|
|
7
|
+
*
|
|
8
|
+
* 生成规则(与手写纪律对齐):
|
|
9
|
+
* - **基规则**(正常优先级——display 等结构面)
|
|
10
|
+
* - **零优先级默认**(`:where()`——gap/align 默认被覆盖工具靠优先级获胜,
|
|
11
|
+
* 不依赖 import 顺序——L3 定案)
|
|
12
|
+
* - **变体**(wf-row-reverse——继承基 + cover 覆盖;变体默认零优先级同基)
|
|
13
|
+
* - 输出格式稳定(单行规则——注释头)
|
|
14
|
+
*
|
|
15
|
+
* 用法(build 期——bundle.ts 调 generateLayoutCss 拼入汇编):
|
|
16
|
+
* const css = generateLayoutCss([
|
|
17
|
+
* structure({ class: 'wf-row', base: { display: 'flex', 'flex-wrap': 'wrap' },
|
|
18
|
+
* defaults: { gap: 'var(--wf-gap, var(--wf-gap-md))', 'align-items': 'var(--wf-align, center)' },
|
|
19
|
+
* variants: { 'wf-row-reverse': { cover: { 'flex-direction': 'row-reverse' } } } }),
|
|
20
|
+
* ])
|
|
21
|
+
*/
|
|
22
|
+
/** 结构原语声明(class + 基/默认/变体) */
|
|
23
|
+
export interface StructureDecl {
|
|
24
|
+
/** 基类(wf-row) */
|
|
25
|
+
class: string;
|
|
26
|
+
/** 基规则(正常优先级——display 等结构面) */
|
|
27
|
+
base?: Record<string, string>;
|
|
28
|
+
/** 零优先级默认(:where() 包装——gap/align 默认) */
|
|
29
|
+
defaults?: Record<string, string>;
|
|
30
|
+
/** 变体(wf-row-reverse——继承基 + cover 覆盖;变体默认零优先级同基) */
|
|
31
|
+
variants?: Record<string, {
|
|
32
|
+
cover?: Record<string, string>;
|
|
33
|
+
defaults?: Record<string, string>;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
/** 生成器:声明 → CSS(规则序:基 → 零优先级默认 → 变体基/默认——手写序对齐) */
|
|
37
|
+
export declare function generateLayoutCss(decls: StructureDecl[]): string;
|
|
38
|
+
/** 逐属性等价(生成 vs 手写——解析比对——硬验收用) */
|
|
39
|
+
export declare function parseProps(css: string): Map<string, Map<string, string>>;
|
|
40
|
+
/** 等价断言(生成 ⊆ 手写——声明覆盖的选择器逐属性相等;手写多余 = 未迁移面) */
|
|
41
|
+
export declare function isEquivalent(generated: string, handwritten: string): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/client/layout — 布局原语声明 + 装配(defineLayout 生态公共面)
|
|
3
|
+
*
|
|
4
|
+
* 三面:
|
|
5
|
+
* - **原语声明**(define.ts):StructureDecl/generateLayoutCss/parseProps/
|
|
6
|
+
* isEquivalent——自定义布局语言(构建期声明 → 生成 CSS——声明比实现短
|
|
7
|
+
* 且机械部分全消失判据)
|
|
8
|
+
* - **内建声明**(decl.ts):row/stack/items 族(生成 = 旧手写逐属性等价冻结快照)
|
|
9
|
+
* - **装配**(bundle.ts):bundleLayout/bundleComponents/layerMapOf/LAYER_OF/
|
|
10
|
+
* LAYER_ORDER——node 构建管线(build.mjs/审计脚本共用——装配单源)
|
|
11
|
+
*
|
|
12
|
+
* 注意:bundle 面含 node:fs 依赖(构建期工具)——浏览器消费只引
|
|
13
|
+
* `weifuwu/client/layout/weifuwu-layout.css`(CSS 面);JS 面是构建期工具。
|
|
14
|
+
*/
|
|
15
|
+
export type { StructureDecl } from './define.ts';
|
|
16
|
+
export { generateLayoutCss, parseProps, isEquivalent } from './define.ts';
|
|
17
|
+
export { structures } from './decl.ts';
|
|
18
|
+
export { LAYER_ORDER, LAYER_OF } from './bundle.ts';
|
|
19
|
+
export type { CssBundle } from './bundle.ts';
|
|
20
|
+
export { layoutEntryFiles, isLayoutSourceDir, bundleLayout, bundleComponents, layerMapOf } from './bundle.ts';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
var g=(a,t)=>t&&Object.keys(t).length?`${a} { ${Object.entries(t).map(([i,e])=>`${i}: ${e};`).join(" ")} }`:"",v=a=>a.replace(/^0\\.|^0\\./gm,"").replace(/\s+/g," ").trim();function w(a){let t=[];for(let i of a){let e=`.${i.class}`,o=g(e,i.base??{});o&&t.push(o);let c=g(`:where(${e})`,i.defaults??{});c&&t.push(c);for(let[s,n]of Object.entries(i.variants??{})){let r=`.${s}`,l=g(r,{...i.base??{},...n.cover??{}});l&&t.push(l);let f=g(`:where(${r})`,{...i.defaults??{},...n.defaults??{}});f&&t.push(f)}}return t.join(`
|
|
2
|
+
`)}function y(a){let t=new Map,i=a.replace(/\/\*[\s\S]*?\*\//g,""),e=/([^{}]+)\{([^{}]*)\}/g,o;for(;o=e.exec(i);){let c=o[1].replace(/\s+/g," ").trim(),s=new Map;for(let r of o[2].split(";")){let l=r.indexOf(":");l<0||s.set(r.slice(0,l).trim(),r.slice(l+1).trim())}let n=t.get(c);if(n)for(let[r,l]of s)n.set(r,l);else t.set(c,s)}return t}function j(a,t){let i=y(a),e=y(t);for(let[o,c]of i){let s=e.get(o);if(!s)return!1;for(let[n,r]of c)if(v(s.get(n)??"")!==v(r))return!1}return!0}var m=[{class:"wf-stack",base:{display:"flex","flex-direction":"column"},defaults:{gap:"var(--wf-gap, var(--wf-gap-md))","align-items":"var(--wf-align, stretch)"}},{class:"wf-row",base:{display:"flex","flex-wrap":"wrap"},defaults:{gap:"var(--wf-gap, var(--wf-gap-md))","align-items":"var(--wf-align, center)"},variants:{"wf-row-reverse":{cover:{"flex-direction":"row-reverse"}}}},{class:"wf-items-start",base:{"--wf-align":"flex-start"}},{class:"wf-items-center",base:{"--wf-align":"center"}},{class:"wf-items-end",base:{"--wf-align":"flex-end"}},{class:"wf-items-stretch",base:{"--wf-align":"stretch"}},{class:"wf-grid",base:{display:"grid","grid-template-columns":"var(--wf-cols, repeat(auto-fill, minmax(280px, 1fr)))"},defaults:{gap:"var(--wf-gap, var(--wf-gap-lg))"}},{class:"wf-center",base:{display:"flex","flex-direction":"column","align-items":"center","justify-content":"center"}},{class:"wf-justify-between",base:{display:"flex","justify-content":"space-between"},defaults:{"align-items":"var(--wf-align, center)",gap:"var(--wf-gap, var(--wf-gap-md))"}},{class:"wf-justify-end",base:{display:"flex","justify-content":"flex-end"},defaults:{"align-items":"var(--wf-align, center)",gap:"var(--wf-gap, var(--wf-gap-md))"}},{class:"wf-justify-center",base:{display:"flex","justify-content":"center"},defaults:{"align-items":"var(--wf-align, center)",gap:"var(--wf-gap, var(--wf-gap-md))"}},{class:"wf-fill",base:{flex:"1","min-width":"0","min-height":"0"}},{class:"wf-fill-hover",base:{"border-radius":"var(--wf-radius-sm)",padding:"2px 4px",margin:"-2px -4px",transition:"background 0.15s ease"}},{class:"wf-cover",base:{position:"fixed",inset:"0",display:"flex","align-items":"center","justify-content":"center","z-index":"var(--wf-z, var(--wf-cover-z))"}}];import{readFile as b,readdir as _}from"node:fs/promises";import{join as p,resolve as h}from"node:path";var k=["tokens","base","layout","components","utilities"],x={_tokens:"tokens",_dark:"tokens",_presets:"tokens",_props:"tokens",_base:"base",_stack:"layout",_row:"layout",_split:"layout",_center:"layout",_justify:"layout",_fill:"layout",_grid:"layout",_cluster:"layout",_cover:"layout",_position:"layout",_sticky:"layout",_overflow:"layout","_safe-area":"layout",_layer:"layout","_align-self":"layout",_nowrap:"layout",_shrink:"layout",_container:"layout","_app-shell":"layout",_surface:"utilities",_spacing:"utilities",_border:"utilities",_text:"utilities",_hidden:"utilities",_block:"utilities",_flex:"utilities",_popup:"layout"},E="tokens",O=a=>a.replace(/@import\s+['"][^'"]+['"]\s*;?\s*\n?/g,"");async function $(a){let t=await b(p(a,"weifuwu-layout.css"),"utf-8"),i=[];for(let e of t.split(`
|
|
3
|
+
`)){let o=e.match(/@import\s+['"]([^'"]+)['"]/);o&&i.push(o[1].replace(/^\.\//,""))}if(!i.length)throw new Error(`layout \u5165\u53E3\u65E0 @import\uFF08${a}/weifuwu-layout.css\uFF09\u2014\u2014\u88C5\u914D\u5355\u6E90\u5931\u6548`);return i}async function L(a){try{let t=await _(a);return t.includes("weifuwu-layout.css")&&t.some(i=>/^_[a-z-]+\.css$/.test(i))}catch{return!1}}async function R(a){let t=h(a),i=await $(t),e=[p(t,"weifuwu-layout.css")],o=[];for(let s of i){if(s==="_stack.css"){e.push(p(t,"decl.ts"),p(t,"define.ts")),o.push(`@layer ${x._stack} {
|
|
4
|
+
${w(m)}
|
|
5
|
+
}`);continue}if(s==="_row.css")continue;let n=p(t,s);e.push(n);let r=O(await b(n,"utf-8")).trim(),l=s.replace(/\.css$/,""),f=x[l];if(!f)throw new Error(`layout \u6587\u4EF6\u672A\u767B\u8BB0 @layer \u6620\u5C04: ${s}\uFF08\u5728 src/client/layout/bundle.ts LAYER_OF \u4E2D\u767B\u8BB0\uFF09`);o.push(f===E?r:`@layer ${f} {
|
|
6
|
+
${r}
|
|
7
|
+
}`)}return{css:`/* weifuwu/client/layout \u2014 CSS \u5E03\u5C40\u539F\u8BED + \u8BBE\u8BA1 Token\uFF08\u88C5\u914D\u5355\u6E90\uFF1Asrc/client/layout/bundle.ts\uFF09 */
|
|
8
|
+
|
|
9
|
+
@layer ${k.join(", ")};
|
|
10
|
+
|
|
11
|
+
${o.join(`
|
|
12
|
+
|
|
13
|
+
`)}
|
|
14
|
+
`,inputs:e}}async function S(a,t){let{css:i,inputs:e}=await R(a),o=h(t),c=(await _(o,{withFileTypes:!0})).filter(n=>n.isDirectory()).map(n=>n.name),s=`${i}@layer components {
|
|
15
|
+
`;for(let n of c){let r=p(o,n,`${n}.css`);try{s+=`${await b(r,"utf-8")}
|
|
16
|
+
`,e.push(r)}catch{}}return s+=`}
|
|
17
|
+
`,{css:s,inputs:e}}function C(a){let t=new Map,i=/\.wf-[a-z0-9]+(?:-[a-z0-9]+)*(?:--[a-z-]+)?/g,e=a.replace(/\/\*[\s\S]*?\*\//g,""),o=(n,r)=>{for(let l of n.matchAll(i)){let f=l[0].slice(1);t.has(f)||t.set(f,r)}},c="",s=0;for(;s<e.length;){let n=e.indexOf("@layer",s);if(n===-1){c+=e.slice(s);break}let r=e.indexOf("{",n),l=e.indexOf(";",n);if(l!==-1&&(r===-1||l<r)){c+=e.slice(s,l+1),s=l+1;continue}if(r===-1){c+=e.slice(s);break}let f=e.slice(n+6,r).trim(),d=0,u=r;for(;u<e.length;u++)if(e[u]==="{")d++;else if(e[u]==="}"&&(d--,d===0)){u++;break}c+=e.slice(s,n),o(e.slice(r+1,u-1),f),s=u}return o(c,"unlayered"),t}export{x as LAYER_OF,k as LAYER_ORDER,S as bundleComponents,R as bundleLayout,w as generateLayoutCss,j as isEquivalent,L as isLayoutSourceDir,C as layerMapOf,$ as layoutEntryFiles,y as parseProps,m as structures};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer tokens,base,layout,components,utilities;:root{--wf-brand-seed: #4f6ef7;--wf-brand-500: var(--wf-brand-seed);--wf-brand-600: color-mix(in srgb, var(--wf-brand-seed) 85%, #000);--wf-brand-700: color-mix(in srgb, var(--wf-brand-seed) 70%, #000);--wf-brand-50: color-mix(in srgb, var(--wf-brand-seed) 12%, #fff);--wf-green-500: #22c55e;--wf-green-50: #f0fdf4;--wf-green-700: #15803d;--wf-amber-500: #f59e0b;--wf-amber-50: #fffbeb;--wf-amber-700: #b45309;--wf-red-500: #ef4444;--wf-red-50: #fef2f2;--wf-red-700: #b91c1c;--wf-sky-500: #1677ff;--wf-sky-50: #e6f4ff;--wf-sky-700: #0369a1;--wf-slate-900: #0f172a;--wf-slate-500: #64748b;--wf-slate-400: #94a3b8;--wf-slate-300: #cbd5e1;--wf-slate-200: #e2e8f0;--wf-slate-100: #f1f5f9;--wf-slate-50: #f8fafc;--wf-white: #ffffff;--wf-dark-brand-seed: #6b8aff;--wf-dark-brand-500: var(--wf-dark-brand-seed);--wf-dark-brand-600: color-mix(in srgb, var(--wf-dark-brand-seed) 78%, #fff);--wf-dark-brand-50: color-mix(in srgb, var(--wf-dark-brand-seed) 12%, #0f172a);--wf-dark-green-500: #4ade80;--wf-dark-green-50: #14532d;--wf-dark-amber-500: #fbbf24;--wf-dark-amber-50: #451a03;--wf-dark-red-500: #f87171;--wf-dark-red-50: #451a1a;--wf-dark-sky-500: #60a5fa;--wf-dark-sky-50: #172554;--wf-dark-slate-900: #f1f5f9;--wf-dark-slate-500: #94a3b8;--wf-dark-slate-400: #64748b;--wf-dark-slate-300: #475569;--wf-dark-slate-200: #334155;--wf-dark-slate-100: #1e293b;--wf-dark-bg: #0f172a;--wf-dark-overlay: rgba(0, 0, 0, .6);--wf-dark-fill: var(--wf-dark-slate-200);--wf-dark-bg-hover: var(--wf-dark-state-hover);--wf-dark-state-hover: rgba(255, 255, 255, .06);--wf-dark-state-pressed: rgba(255, 255, 255, .1);--wf-dark-surface-shadow: var(--wf-dark-shadow);--wf-dark-shadow-sm: 0 1px 2px rgba(0, 0, 0, .2);--wf-dark-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, .3);--wf-dark-shadow: 0 1px 3px rgba(0, 0, 0, .3);--wf-dark-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--wf-dark-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .4)}:root{--wf-space-xs: 4px;--wf-space-sm: 8px;--wf-space: 12px;--wf-space-md: 16px;--wf-space-lg: 24px;--wf-space-xl: 32px;--wf-space-2xl: 40px;--wf-gap-xs: var(--wf-space-xs);--wf-gap-sm: var(--wf-space-sm);--wf-gap-md: var(--wf-space);--wf-gap-lg: var(--wf-space-md);--wf-gap-xl: var(--wf-space-lg);--wf-gap-2xl: var(--wf-space-xl);--wf-radius-xs: 2px;--wf-radius-sm: 4px;--wf-radius: 6px;--wf-radius-md: 8px;--wf-radius-lg: 12px;--wf-radius-xl: 20px;--wf-surface-radius: var(--wf-radius-md);--wf-surface-shadow: var(--wf-shadow);--wf-shadow-sm: 0 1px 2px rgba(0,0,0,.05);--wf-shadow-inset: inset 0 1px 2px rgba(0,0,0,.04);--wf-shadow: 0 1px 3px rgba(0,0,0,.08);--wf-shadow-md: 0 4px 12px rgba(0,0,0,.1);--wf-shadow-lg: 0 10px 15px -3px rgba(0,0,0,.1);--wf-z-sticky: 40;--wf-z-overlay: 80;--wf-z-modal: 100;--wf-tour-min-width: 240px;--wf-kanban-col-min-width: 200px;--wf-layout-sider-width: 240px;--wf-layout-sider-collapsed-width: 64px;--wf-layout-header-height: 56px;--wf-kanban-col-max-width: 300px;--wf-treeselect-min-width: 200px;--wf-navmenu-min-width: 160px;--wf-select-menu-min-width: 200px;--wf-treeselect-max-width: 320px;--wf-treeselect-dropdown-max-height: 260px;--wf-z-popover: 120;--wf-z-toast: 140;--wf-z-tooltip: 160;--wf-z-dropdown: var(--wf-z-popover);--wf-pop-z: var(--wf-z-popover);--wf-cover-z: var(--wf-z-modal);--wf-color-primary: var(--wf-brand-500);--wf-color-primary-hover: var(--wf-brand-600);--wf-color-primary-bg: var(--wf-brand-50);--wf-color-success: var(--wf-green-500);--wf-color-success-bg: var(--wf-green-50);--wf-color-warning: var(--wf-amber-500);--wf-color-warning-bg: var(--wf-amber-50);--wf-color-error: var(--wf-red-500);--wf-color-error-bg: var(--wf-red-50);--wf-color-text: var(--wf-slate-900);--wf-color-text-secondary: var(--wf-slate-500);--wf-color-text-tertiary: var(--wf-slate-400);--wf-color-text-disabled: var(--wf-slate-300);--wf-color-bg: var(--wf-white);--wf-color-bg-secondary: var(--wf-slate-50);--wf-color-bg-tertiary: var(--wf-slate-100);--wf-color-border: var(--wf-slate-200);--wf-color-border-light: var(--wf-slate-100);--wf-color-border-dark: var(--wf-slate-300);--wf-surface-bg: var(--wf-color-bg);--wf-color-bg-elevated: var(--wf-color-bg);--wf-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;--wf-font-mono: "SF Mono", "Fira Code", "JetBrains Mono", "PingFang SC", "Microsoft YaHei", monospace;--wf-font-size-xs: 12px;--wf-font-size-sm: 13px;--wf-font-size-base: 14px;--wf-font-size-lg: 15px;--wf-font-size-xl: 16px;--wf-font-size-2xl: 21px;--wf-font-size-3xl: 24px;--wf-font-size-4xl: 30px;--wf-font-size-5xl: 36px;--wf-font-size-display: 30px;--wf-heading-case: none;--wf-heading-tracking: 0;--wf-font-weight-normal: 400;--wf-font-weight-medium: 500;--wf-font-weight-semibold: 600;--wf-font-weight-bold: 700;--wf-line-height-tight: 1.25;--wf-line-height: 1.5;--wf-line-height-relaxed: 1.75;--wf-border-width: 1px;--wf-focus-ring: 0 0 0 2px var(--wf-color-primary-bg), 0 0 0 1px var(--wf-color-primary);--wf-transition-duration: var(--wf-dur-fast);--wf-transition-timing: var(--wf-ease-out);--wf-transition: var(--wf-transition-duration) var(--wf-transition-timing);--wf-dur-fast: .12s;--wf-dur-base: .2s;--wf-dur-slow: .3s;--wf-ease-out: cubic-bezier(.16, 1, .3, 1);--wf-ease-in: cubic-bezier(.4, 0, 1, 1);--wf-ease-in-out: cubic-bezier(.4, 0, .2, 1);--wf-ease-snap: cubic-bezier(.34, 1.56, .64, 1);--wf-ease-standard: ease;--wf-dur-md: var(--wf-dur-base);--wf-motion-sm: 4px;--wf-dur-spin: .6s;--wf-dur-pulse: 1.2s;--wf-dur-blink: 1.1s;--wf-dur-progress: 1.4s;--wf-color-info: var(--wf-sky-500);--wf-color-info-bg: var(--wf-sky-50);--wf-color-primary-text: var(--wf-brand-700);--wf-color-success-text: var(--wf-green-700);--wf-color-warning-text: var(--wf-amber-700);--wf-color-error-text: var(--wf-red-700);--wf-color-info-text: var(--wf-sky-700);--wf-color-fill: var(--wf-slate-100);--wf-color-bg-subtle: var(--wf-color-fill);--wf-state-hover: rgba(0, 0, 0, .04);--wf-state-pressed: rgba(0, 0, 0, .08);--wf-color-bg-hover: var(--wf-state-hover);--wf-color-on-brand: #fff;--wf-color-on-warning: #451a03;--wf-overlay: rgba(0, 0, 0, .4);--wf-overlay-blur: 4px;--wf-accent-color: var(--wf-color-primary);--wf-caret-color: var(--wf-color-primary);--wf-control-pad-y: 10px;--wf-control-height: 36px;--wf-field-height: var(--wf-control-height);--wf-field-radius: var(--wf-radius);--wf-bp-sm: 640px;--wf-bp-md: 768px;--wf-bp-lg: 1024px;--wf-bp-xl: 1280px;--wf-sidebar-width: 240px;--wf-opacity-disabled: .5;--wf-letter-spacing-wide: .5px;--wf-heading-display-tracking: -.5px;--wf-nums: "tabular-nums"}@supports not (color: color-mix(in srgb,red 50%,blue)){:root{--wf-brand-600: #3b5ae0;--wf-brand-700: #4338ca;--wf-brand-50: #eef1ff;--wf-dark-brand-600: #8ba3ff;--wf-dark-brand-50: #1e293b}}:root[data-theme=dark]{color-scheme:dark;--wf-color-primary: var(--wf-dark-brand-500);--wf-color-primary-hover: var(--wf-dark-brand-600);--wf-color-primary-bg: var(--wf-dark-brand-50);--wf-color-success: var(--wf-dark-green-500);--wf-color-success-bg: var(--wf-dark-green-50);--wf-color-warning: var(--wf-dark-amber-500);--wf-color-warning-bg: var(--wf-dark-amber-50);--wf-color-error: var(--wf-dark-red-500);--wf-color-error-bg: var(--wf-dark-red-50);--wf-color-info: var(--wf-dark-sky-500);--wf-color-info-bg: var(--wf-dark-sky-50);--wf-color-text: var(--wf-dark-slate-900);--wf-color-text-secondary: var(--wf-dark-slate-500);--wf-color-text-tertiary: var(--wf-dark-slate-400);--wf-color-text-disabled: var(--wf-dark-slate-300);--wf-color-bg: var(--wf-dark-bg);--wf-color-bg-secondary: var(--wf-dark-slate-100);--wf-color-bg-tertiary: var(--wf-dark-slate-200);--wf-color-fill: var(--wf-dark-fill);--wf-color-bg-subtle: var(--wf-dark-fill);--wf-color-bg-hover: var(--wf-dark-bg-hover);--wf-state-hover: var(--wf-dark-state-hover);--wf-state-pressed: var(--wf-dark-state-pressed);--wf-color-bg-elevated: var(--wf-dark-slate-100);--wf-color-border: var(--wf-dark-slate-200);--wf-color-border-light: var(--wf-dark-slate-100);--wf-color-border-dark: var(--wf-dark-slate-300);--wf-surface-bg: var(--wf-color-bg);--wf-surface-shadow: var(--wf-dark-surface-shadow);--wf-shadow-sm: var(--wf-dark-shadow-sm);--wf-shadow: var(--wf-dark-shadow);--wf-shadow-md: var(--wf-dark-shadow-md);--wf-shadow-lg: var(--wf-dark-shadow-lg);--wf-shadow-inset: var(--wf-dark-shadow-inset);--wf-color-primary-text: var(--wf-dark-brand-500);--wf-color-success-text: var(--wf-dark-green-500);--wf-color-warning-text: var(--wf-dark-amber-500);--wf-color-error-text: var(--wf-dark-red-500);--wf-color-info-text: var(--wf-dark-sky-500);--wf-overlay: var(--wf-dark-overlay)}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){color-scheme:dark;--wf-color-primary: var(--wf-dark-brand-500);--wf-color-primary-hover: var(--wf-dark-brand-600);--wf-color-primary-bg: var(--wf-dark-brand-50);--wf-color-success: var(--wf-dark-green-500);--wf-color-success-bg: var(--wf-dark-green-50);--wf-color-warning: var(--wf-dark-amber-500);--wf-color-warning-bg: var(--wf-dark-amber-50);--wf-color-error: var(--wf-dark-red-500);--wf-color-error-bg: var(--wf-dark-red-50);--wf-color-info: var(--wf-dark-sky-500);--wf-color-info-bg: var(--wf-dark-sky-50);--wf-color-text: var(--wf-dark-slate-900);--wf-color-text-secondary: var(--wf-dark-slate-500);--wf-color-text-tertiary: var(--wf-dark-slate-400);--wf-color-text-disabled: var(--wf-dark-slate-300);--wf-color-bg: var(--wf-dark-bg);--wf-color-bg-secondary: var(--wf-dark-slate-100);--wf-color-bg-tertiary: var(--wf-dark-slate-200);--wf-color-fill: var(--wf-dark-fill);--wf-color-bg-subtle: var(--wf-dark-fill);--wf-color-bg-hover: var(--wf-dark-bg-hover);--wf-state-hover: var(--wf-dark-state-hover);--wf-state-pressed: var(--wf-dark-state-pressed);--wf-color-bg-elevated: var(--wf-dark-slate-100);--wf-color-border: var(--wf-dark-slate-200);--wf-color-border-light: var(--wf-dark-slate-100);--wf-color-border-dark: var(--wf-dark-slate-300);--wf-surface-bg: var(--wf-color-bg);--wf-surface-shadow: var(--wf-dark-surface-shadow);--wf-shadow-sm: var(--wf-dark-shadow-sm);--wf-shadow: var(--wf-dark-shadow);--wf-shadow-md: var(--wf-dark-shadow-md);--wf-shadow-lg: var(--wf-dark-shadow-lg);--wf-shadow-inset: var(--wf-dark-shadow-inset);--wf-color-primary-text: var(--wf-dark-brand-500);--wf-color-success-text: var(--wf-dark-green-500);--wf-color-warning-text: var(--wf-dark-amber-500);--wf-color-error-text: var(--wf-dark-red-500);--wf-color-info-text: var(--wf-dark-sky-500);--wf-overlay: var(--wf-dark-overlay)}}:root[data-preset=minimal]{--wf-brand-seed: #64748b;--wf-dark-brand-seed: #94a3b8}:root[data-preset=compact]{--wf-control-height: 32px;--wf-control-pad-y: 6px;--wf-space-xs: 3px;--wf-space-sm: 6px;--wf-space: 9px;--wf-space-md: 12px;--wf-space-lg: 18px;--wf-space-xl: 24px;--wf-space-2xl: 30px;--wf-font-size-sm: 12px;--wf-font-size-base: 13px}:root[data-preset=rounded]{--wf-radius-sm: 8px;--wf-radius: 12px;--wf-radius-md: 16px;--wf-radius-lg: 20px;--wf-radius-xl: 28px;--wf-surface-radius: var(--wf-radius-md);--wf-btn-radius: 999px;--wf-field-radius: var(--wf-radius-md)}@property --wf-gap{syntax: "*"; inherits: false;}@property --wf-align{syntax: "*"; inherits: false;}@property --wf-justify{syntax: "*"; inherits: false;}@property --wf-cols{syntax: "*"; inherits: false;}@property --wf-max{syntax: "*"; inherits: false;}@property --wf-w-sm{syntax: "*"; inherits: false;}@property --wf-z{syntax: "*"; inherits: false;}@property --wf-offset{syntax: "*"; inherits: false;}@property --wf-popup-max{syntax: "*"; inherits: false;}@layer base{*,*:before,*:after{box-sizing:border-box}::selection{background:var(--wf-color-primary-bg);color:var(--wf-color-primary-text)}*{scrollbar-width:thin;scrollbar-color:var(--wf-color-border-dark) transparent}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--wf-color-border-dark);border-radius:var(--wf-radius-sm);border:2px solid transparent;background-clip:padding-box}::-webkit-scrollbar-thumb:hover{background:var(--wf-color-text-secondary);background-clip:padding-box;border:2px solid transparent}:root{color-scheme:light}body{margin:0;background:var(--wf-color-bg);color:var(--wf-color-text);font-family:var(--wf-font-sans);font-size:var(--wf-font-size-base);line-height:var(--wf-line-height);-webkit-font-smoothing:antialiased}a{color:var(--wf-color-primary-text);text-decoration:none}a:hover{color:var(--wf-color-primary-hover);text-decoration:underline}input,textarea,select,button{font-family:inherit;font-size:inherit;line-height:inherit}input,textarea,select{accent-color:var(--wf-accent-color);caret-color:var(--wf-caret-color);background:var(--wf-color-bg);color:var(--wf-color-text);border:var(--wf-border-width) solid var(--wf-color-border);border-radius:var(--wf-radius);padding:var(--wf-control-pad-y) var(--wf-space)}input:focus,textarea:focus,select:focus{outline:none;box-shadow:var(--wf-focus-ring);border-color:var(--wf-color-primary)}input:disabled,textarea:disabled,select:disabled,button:disabled{opacity:var(--wf-opacity-disabled);cursor:not-allowed}button{accent-color:var(--wf-accent-color);background:var(--wf-color-bg);color:var(--wf-color-text);border:var(--wf-border-width) solid var(--wf-color-border);border-radius:var(--wf-radius);padding:var(--wf-control-pad-y) var(--wf-space-md);min-height:var(--wf-control-height);cursor:pointer;transition:border-color var(--wf-dur-fast) var(--wf-ease-out),color var(--wf-dur-fast) var(--wf-ease-out),box-shadow var(--wf-dur-fast) var(--wf-ease-out),background-color var(--wf-dur-fast) var(--wf-ease-out),filter var(--wf-dur-fast) var(--wf-ease-out)}button:hover{border-color:var(--wf-color-primary);color:var(--wf-color-primary-text)}button:active:not(:disabled),[role=button]:active{filter:brightness(.95)}button:focus-visible,[tabindex]:focus-visible{outline:none;box-shadow:var(--wf-focus-ring)}[role=button]{cursor:pointer;transition:background-color var(--wf-dur-fast) var(--wf-ease-out),border-color var(--wf-dur-fast) var(--wf-ease-out),box-shadow var(--wf-dur-fast) var(--wf-ease-out),color var(--wf-dur-fast) var(--wf-ease-out),filter var(--wf-dur-fast) var(--wf-ease-out)}@media(pointer:coarse){button,[role=button],input,textarea,select,.wf-card--clickable,.wf-table-th--sortable,.wf-accordion-summary,.wf-tag-close,.wf-checkbox,.wf-switch,.wf-radio,.wf-datepicker-cell{min-height:44px;min-width:44px}}h1,h2,h3,h4,h5,h6{font-weight:var(--wf-font-weight-semibold);line-height:var(--wf-line-height-tight);color:var(--wf-color-text)}p{line-height:var(--wf-line-height-relaxed)}small{font-size:var(--wf-font-size-sm);color:var(--wf-color-text-tertiary)}label{font-size:var(--wf-font-size-base);font-weight:var(--wf-font-weight-medium);color:var(--wf-color-text)}table{width:100%;border-collapse:collapse}th{text-align:left;font-weight:var(--wf-font-weight-medium);font-size:var(--wf-font-size-xs);color:var(--wf-color-text-tertiary);text-transform:var(--wf-heading-case);letter-spacing:var(--wf-heading-tracking);padding:var(--wf-space) var(--wf-space-sm);border-bottom:var(--wf-border-width) solid var(--wf-color-border);background:var(--wf-color-bg-secondary)}td{padding:var(--wf-space) var(--wf-space-sm);border-bottom:var(--wf-border-width) solid var(--wf-color-border);color:var(--wf-color-text);font-size:var(--wf-font-size-base)}hr{border:none;border-top:var(--wf-border-width) solid var(--wf-color-border);margin:var(--wf-space-md) 0}pre,code{font-family:var(--wf-font-mono);font-size:var(--wf-font-size-sm)}pre{background:var(--wf-color-bg-secondary);border:var(--wf-border-width) solid var(--wf-color-border);border-radius:var(--wf-radius);padding:var(--wf-space) var(--wf-space-md);overflow-x:auto;white-space:pre}code{background:var(--wf-color-bg-secondary);padding:2px 6px;border-radius:var(--wf-radius-sm)}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}body.wf-dragging{user-select:none;-webkit-user-select:none}@keyframes wf-stream-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.wf-stream-in{animation:wf-stream-in var(--wf-dur-base) var(--wf-ease-out) both}@media(prefers-reduced-motion:reduce){.wf-stream-in{animation-duration:.01ms}}.wf-hero-cursor{animation:wf-hero-blink 1s step-end infinite;color:var(--wf-color-primary)}@keyframes wf-hero-blink{0%,to{opacity:1}50%{opacity:0}}}@layer layout{.wf-stack{display:flex;flex-direction:column}:where(.wf-stack){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, stretch)}}@layer layout{.wf-row{display:flex;flex-wrap:wrap}:where(.wf-row){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, center)}.wf-row-reverse{display:flex;flex-direction:row-reverse;flex-wrap:wrap}:where(.wf-row-reverse){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, center)}.wf-items-start{--wf-align: flex-start}.wf-items-center{--wf-align: center}.wf-items-end{--wf-align: flex-end}.wf-items-stretch{--wf-align: stretch}}@layer layout{.wf-split{display:flex;justify-content:space-between}:where(.wf-split){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-split>:last-child{flex-shrink:0}}@layer layout{.wf-center{display:flex;flex-direction:column;align-items:center;justify-content:center}}@layer layout{.wf-justify-between{display:flex;justify-content:space-between}:where(.wf-justify-between){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-justify-end{display:flex;justify-content:flex-end}:where(.wf-justify-end){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-justify-center{display:flex;justify-content:center}:where(.wf-justify-center){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}}@layer layout{.wf-fill{flex:1;min-width:0;min-height:0}.wf-fill-hover{border-radius:var(--wf-radius-sm);padding:2px 4px;margin:-2px -4px;transition:background .15s ease}.wf-fill-hover:hover{background:var(--wf-color-bg-secondary)}}@layer layout{.wf-grid{display:grid;grid-template-columns:var(--wf-cols, repeat(auto-fill, minmax(280px, 1fr)))}:where(.wf-grid){gap:var(--wf-gap, var(--wf-gap-lg))}}@layer layout{.wf-cluster{display:flex;flex-wrap:wrap}:where(.wf-cluster){gap:var(--wf-gap, var(--wf-gap-sm));justify-content:var(--wf-justify, center);align-items:var(--wf-align, center)}}@layer layout{.wf-cover{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:var(--wf-z, var(--wf-cover-z))}}@layer layout{.wf-relative{position:relative}.wf-absolute{position:absolute}}@layer layout{.wf-sticky{position:sticky;top:var(--wf-offset, 0)}}@layer layout{.wf-overflow-auto{overflow:auto}.wf-overflow-hidden{overflow:hidden}.wf-overflow-x{overflow-x:auto}}@layer layout{.wf-safe-bottom{padding-bottom:env(safe-area-inset-bottom)}.wf-safe-top{padding-top:env(safe-area-inset-top)}}@layer layout{.wf-layer{position:relative;z-index:var(--wf-z, 1)}}@layer layout{.wf-self-start{align-self:flex-start}.wf-self-center{align-self:center}.wf-self-end{align-self:flex-end}.wf-self-stretch{align-self:stretch}}@layer layout{.wf-nowrap{display:flex;flex-wrap:nowrap}:where(.wf-nowrap){gap:var(--wf-gap, var(--wf-gap-md))}}@layer layout{.wf-shrink{min-width:0;min-height:0}.wf-min-width-0{min-width:0}}@layer layout{.wf-container{width:100%;max-width:var(--wf-max, 1200px);margin:0 auto;padding:0 var(--wf-gap, var(--wf-gap-lg))}}@layer layout{.wf-app-shell{display:grid;grid-template-columns:var(--wf-sidebar-width, 240px) minmax(0,1fr);height:100vh;overflow:hidden}.wf-sidebar{display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto;background:var(--wf-color-bg-secondary);border-right:var(--wf-border-width) solid var(--wf-color-border)}.wf-sidebar-header{display:flex;align-items:center;gap:var(--wf-gap-sm);padding:var(--wf-space-md);border-bottom:var(--wf-border-width) solid var(--wf-color-border-light);flex-shrink:0}.wf-sidebar-body{flex:1;padding:var(--wf-space-sm);overflow-y:auto}.wf-sidebar-footer{padding:var(--wf-space-sm);border-top:var(--wf-border-width) solid var(--wf-color-border-light);flex-shrink:0}.wf-nav{display:flex;flex-direction:column;gap:2px}.wf-nav-group{font-size:var(--wf-font-size-xs);font-weight:var(--wf-font-weight-medium);color:var(--wf-color-text-tertiary);text-transform:var(--wf-heading-case);letter-spacing:var(--wf-heading-tracking);padding:var(--wf-space-md) var(--wf-space-sm) var(--wf-space-xs)}.wf-nav-item{display:flex;align-items:center;gap:var(--wf-gap-sm);padding:var(--wf-space-sm) var(--wf-space);border-radius:var(--wf-radius);color:var(--wf-color-text-secondary);font-size:var(--wf-font-size-base);text-decoration:none;cursor:pointer;border:none;background:none;width:100%;text-align:left;font-family:inherit;transition:background var(--wf-transition),color var(--wf-transition)}.wf-nav-item:hover{background:var(--wf-color-bg-tertiary);color:var(--wf-color-text);text-decoration:none}.wf-nav-item:focus-visible{outline:none;box-shadow:var(--wf-focus-ring)}.wf-nav-item--active{background:var(--wf-color-primary-bg);color:var(--wf-color-primary-text);font-weight:var(--wf-font-weight-medium)}.wf-nav-item--active:hover{background:var(--wf-color-primary-bg);color:var(--wf-color-primary-text)}.wf-nav--collapsed .wf-nav-item{justify-content:center;gap:0;padding:var(--wf-space-sm)}.wf-nav--collapsed .wf-nav-label{display:none}.wf-nav--collapsed .wf-nav-group{text-align:center;padding-left:0;padding-right:0;overflow:hidden;white-space:nowrap}.wf-main{padding:var(--wf-space-lg);min-width:0;min-height:0;overflow-y:auto;background:var(--wf-color-bg);--wf-main-max: none}.wf-main>*{max-width:var(--wf-main-max);margin-inline:auto}@media(pointer:coarse){.wf-nav-item{min-height:44px}}@media(max-width:767.98px){.wf-app-shell{grid-template-columns:1fr;height:auto;overflow:visible}.wf-sidebar{position:static;height:auto;border-right:none;border-bottom:var(--wf-border-width) solid var(--wf-color-border)}.wf-main{padding:var(--wf-space-md);overflow:visible}}}@layer utilities{.wf-surface{border-radius:var(--wf-surface-radius);box-shadow:var(--wf-surface-shadow);background:var(--wf-surface-bg)}.wf-surface--flat{box-shadow:none}.wf-bg-secondary{background:var(--wf-color-bg-secondary)}.wf-bg-tertiary{background:var(--wf-color-bg-tertiary)}.wf-bg-primary{background:var(--wf-color-primary-bg)}.wf-bg-warning{background:var(--wf-color-warning-bg)}.wf-bg-error{background:var(--wf-color-error-bg)}.wf-bg-none{background:transparent}.wf-pill{border-radius:999px}.wf-radius-sm{border-radius:var(--wf-radius-sm)}.wf-radius{border-radius:var(--wf-radius)}.wf-radius-md{border-radius:var(--wf-radius-md)}.wf-radius-lg{border-radius:var(--wf-radius-lg)}.wf-shadow{box-shadow:var(--wf-shadow)}.wf-elevate{transition:box-shadow var(--wf-dur-fast) var(--wf-ease-out),transform var(--wf-dur-fast) var(--wf-ease-out)}.wf-elevate:hover{box-shadow:var(--wf-shadow-md);transform:translateY(-2px)}.wf-elevate:focus-visible{outline:none;box-shadow:var(--wf-shadow-md),var(--wf-focus-ring)}.wf-panel-in{animation:wf-panel-in var(--wf-dur-fast) var(--wf-ease-out);transform-origin:top center}@keyframes wf-panel-in{0%{opacity:0;transform:translateY(calc(var(--wf-motion-sm) * -1)) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.wf-bubble{display:inline-block;max-width:70%;padding:var(--wf-space-sm) var(--wf-space-md);border-radius:var(--wf-radius-md);background:var(--wf-color-bg-secondary);color:var(--wf-color-text);font-size:var(--wf-font-size-base);line-height:var(--wf-line-height);white-space:pre-wrap;word-break:break-word}.wf-bubble--own{background:var(--wf-color-primary);color:var(--wf-color-on-brand);border-bottom-right-radius:var(--wf-radius-sm)}.wf-bubble--ai{background:var(--wf-color-primary-bg);border:var(--wf-border-width) solid var(--wf-color-border-light);border-bottom-left-radius:var(--wf-radius-sm)}.wf-rounded-sm{border-radius:var(--wf-radius-sm)}.wf-rounded-md{border-radius:var(--wf-radius-md)}.wf-card-outline{border:var(--wf-border-width) solid var(--wf-color-border)}}@layer utilities{.wf-border{border:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-top{border-top:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-bottom{border-bottom:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-left{border-left:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-right{border-right:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-none{border:none}}@layer utilities{.wf-text-left{text-align:left}.wf-text-center{text-align:center}.wf-text-right{text-align:right}.wf-font-xs{font-size:var(--wf-font-size-xs)}.wf-font-sm{font-size:var(--wf-font-size-sm)}.wf-font-base{font-size:var(--wf-font-size-base)}.wf-font-lg{font-size:var(--wf-font-size-lg)}.wf-font-2xl{font-size:var(--wf-font-size-2xl)}.wf-font-3xl{font-size:var(--wf-font-size-3xl)}.wf-font-4xl{font-size:var(--wf-font-size-4xl)}.wf-nums{font-variant-numeric:var(--wf-nums)}.wf-text-secondary{color:var(--wf-color-text-secondary)}.wf-text-tertiary{color:var(--wf-color-text-tertiary)}.wf-text-danger{color:var(--wf-color-error-text)}.wf-text-primary{color:var(--wf-color-primary-text)}.wf-text-success{color:var(--wf-color-success-text)}.wf-text-warning{color:var(--wf-color-warning-text)}.wf-font-mono{font-family:var(--wf-font-mono)}.wf-text-error{color:var(--wf-color-error-text)}.wf-text-on-brand{color:var(--wf-color-on-brand)}.wf-text-on-warning{color:var(--wf-color-on-warning)}.wf-medium{font-weight:var(--wf-font-weight-medium)}.wf-semibold{font-weight:var(--wf-font-weight-semibold)}.wf-bold{font-weight:var(--wf-font-weight-bold)}.wf-tracking-wide{letter-spacing:var(--wf-letter-spacing-wide)}.wf-uppercase{text-transform:uppercase}.wf-pre-wrap{white-space:pre-wrap;word-break:break-word}.wf-break-word{overflow-wrap:break-word;word-break:break-word}.wf-text-nowrap{white-space:nowrap}.wf-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@layer utilities{.wf-padding-none{padding:0}.wf-padding-xs{padding:var(--wf-space-xs)}.wf-padding-sm{padding:var(--wf-space-sm)}.wf-padding-md{padding:var(--wf-space-md)}.wf-padding-lg{padding:var(--wf-space-lg)}.wf-padding-xl{padding:var(--wf-space-xl)}.wf-padding-x-xs{padding-left:var(--wf-space-xs);padding-right:var(--wf-space-xs)}.wf-padding-x-sm{padding-left:var(--wf-space-sm);padding-right:var(--wf-space-sm)}.wf-padding-x-md{padding-left:var(--wf-space-md);padding-right:var(--wf-space-md)}.wf-padding-y-xs{padding-top:var(--wf-space-xs);padding-bottom:var(--wf-space-xs)}.wf-padding-y-sm{padding-top:var(--wf-space-sm);padding-bottom:var(--wf-space-sm)}.wf-padding-y-md{padding-top:var(--wf-space-md);padding-bottom:var(--wf-space-md)}.wf-padding-y-lg{padding-top:var(--wf-space-lg);padding-bottom:var(--wf-space-lg)}.wf-padding-top-sm{padding-top:var(--wf-space-sm)}.wf-padding-left-sm{padding-left:var(--wf-space-sm)}.wf-padding-bottom-xs{padding-bottom:var(--wf-space-xs)}.wf-padding-bottom-sm{padding-bottom:var(--wf-space-sm)}.wf-padding-bottom-md{padding-bottom:var(--wf-space-md)}.wf-margin-none{margin:0}.wf-margin-top-none{margin-top:0}.wf-margin-top-xs{margin-top:var(--wf-space-xs)}.wf-margin-top-sm{margin-top:var(--wf-space-sm)}.wf-margin-top-md{margin-top:var(--wf-space-md)}.wf-margin-bottom-xs{margin-bottom:var(--wf-space-xs)}.wf-margin-bottom-sm{margin-bottom:var(--wf-space-sm)}.wf-margin-bottom-md{margin-bottom:var(--wf-space-md)}.wf-margin-bottom-lg{margin-bottom:var(--wf-space-lg)}.wf-margin-left-xs{margin-left:var(--wf-space-xs)}.wf-margin-left-sm{margin-left:var(--wf-space-sm)}.wf-margin-x-auto{margin-left:auto;margin-right:auto}.wf-margin-y-xs{margin-top:var(--wf-space-xs);margin-bottom:var(--wf-space-xs)}.wf-gap-none{gap:0}.wf-gap-xs{gap:var(--wf-gap-xs)}.wf-gap-sm{gap:var(--wf-gap-sm)}.wf-gap-md{gap:var(--wf-gap-md)}.wf-gap-lg{gap:var(--wf-gap-lg)}.wf-gap-xl{gap:var(--wf-gap-xl)}.wf-width-full{width:100%}.wf-width-sm{width:var(--wf-w-sm, 480px)}.wf-height-full{height:100%}}@layer utilities{:where(.wf-block){display:block}}@layer utilities{:where(.wf-flex){display:flex}@media(min-width:640px){.wf-flex\@sm{display:flex}}@media(min-width:1024px){.wf-flex\@lg{display:flex}}}@layer utilities{:where(.wf-hidden){display:none}@media(min-width:1024px){.wf-hidden\@lg{display:none}}.wf-dim{opacity:.7}.wf-pointer{cursor:pointer}}@layer layout{.wf-popup{max-width:min(var(--wf-popup-max, 480px),calc(100vw - 32px));box-sizing:border-box}.wf-popup-mask{position:fixed;inset:0;z-index:var(--wf-z-overlay);background:var(--wf-overlay)}}
|
|
1
|
+
@layer tokens,base,layout,components,utilities;@layer layout{.wf-stack{display:flex;flex-direction:column}:where(.wf-stack){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, stretch)}.wf-row{display:flex;flex-wrap:wrap}:where(.wf-row){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, center)}.wf-row-reverse{display:flex;flex-wrap:wrap;flex-direction:row-reverse}:where(.wf-row-reverse){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, center)}.wf-items-start{--wf-align: flex-start}.wf-items-center{--wf-align: center}.wf-items-end{--wf-align: flex-end}.wf-items-stretch{--wf-align: stretch}.wf-grid{display:grid;grid-template-columns:var(--wf-cols, repeat(auto-fill, minmax(280px, 1fr)))}:where(.wf-grid){gap:var(--wf-gap, var(--wf-gap-lg))}.wf-center{display:flex;flex-direction:column;align-items:center;justify-content:center}.wf-justify-between{display:flex;justify-content:space-between}:where(.wf-justify-between){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-justify-end{display:flex;justify-content:flex-end}:where(.wf-justify-end){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-justify-center{display:flex;justify-content:center}:where(.wf-justify-center){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-fill{flex:1;min-width:0;min-height:0}.wf-fill-hover{border-radius:var(--wf-radius-sm);padding:2px 4px;margin:-2px -4px;transition:background .15s ease}.wf-cover{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:var(--wf-z, var(--wf-cover-z))}}:root{--wf-brand-seed: #4f6ef7;--wf-brand-500: var(--wf-brand-seed);--wf-brand-600: color-mix(in srgb, var(--wf-brand-seed) 85%, #000);--wf-brand-700: color-mix(in srgb, var(--wf-brand-seed) 70%, #000);--wf-brand-50: color-mix(in srgb, var(--wf-brand-seed) 12%, #fff);--wf-green-500: #22c55e;--wf-green-50: #f0fdf4;--wf-green-700: #15803d;--wf-amber-500: #f59e0b;--wf-amber-50: #fffbeb;--wf-amber-700: #b45309;--wf-red-500: #ef4444;--wf-red-50: #fef2f2;--wf-red-700: #b91c1c;--wf-sky-500: #1677ff;--wf-sky-50: #e6f4ff;--wf-sky-700: #0369a1;--wf-slate-900: #0f172a;--wf-slate-500: #64748b;--wf-slate-400: #94a3b8;--wf-slate-300: #cbd5e1;--wf-slate-200: #e2e8f0;--wf-slate-100: #f1f5f9;--wf-slate-50: #f8fafc;--wf-white: #ffffff;--wf-dark-brand-seed: #6b8aff;--wf-dark-brand-500: var(--wf-dark-brand-seed);--wf-dark-brand-600: color-mix(in srgb, var(--wf-dark-brand-seed) 78%, #fff);--wf-dark-brand-50: color-mix(in srgb, var(--wf-dark-brand-seed) 12%, #0f172a);--wf-dark-green-500: #4ade80;--wf-dark-green-50: #14532d;--wf-dark-amber-500: #fbbf24;--wf-dark-amber-50: #451a03;--wf-dark-red-500: #f87171;--wf-dark-red-50: #451a1a;--wf-dark-sky-500: #60a5fa;--wf-dark-sky-50: #172554;--wf-dark-slate-900: #f1f5f9;--wf-dark-slate-500: #94a3b8;--wf-dark-slate-400: #64748b;--wf-dark-slate-300: #475569;--wf-dark-slate-200: #334155;--wf-dark-slate-100: #1e293b;--wf-dark-bg: #0f172a;--wf-dark-overlay: rgba(0, 0, 0, .6);--wf-dark-fill: var(--wf-dark-slate-200);--wf-dark-bg-hover: var(--wf-dark-state-hover);--wf-dark-state-hover: rgba(255, 255, 255, .06);--wf-dark-state-pressed: rgba(255, 255, 255, .1);--wf-dark-surface-shadow: var(--wf-dark-shadow);--wf-dark-shadow-sm: 0 1px 2px rgba(0, 0, 0, .2);--wf-dark-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, .3);--wf-dark-shadow: 0 1px 3px rgba(0, 0, 0, .3);--wf-dark-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--wf-dark-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .4)}:root{--wf-space-xs: 4px;--wf-space-sm: 8px;--wf-space: 12px;--wf-space-md: 16px;--wf-space-lg: 24px;--wf-space-xl: 32px;--wf-space-2xl: 40px;--wf-gap-xs: var(--wf-space-xs);--wf-gap-sm: var(--wf-space-sm);--wf-gap-md: var(--wf-space);--wf-gap-lg: var(--wf-space-md);--wf-gap-xl: var(--wf-space-lg);--wf-gap-2xl: var(--wf-space-xl);--wf-radius-xs: 2px;--wf-radius-sm: 4px;--wf-radius: 6px;--wf-radius-md: 8px;--wf-radius-lg: 12px;--wf-radius-xl: 20px;--wf-surface-radius: var(--wf-radius-md);--wf-surface-shadow: var(--wf-shadow);--wf-shadow-sm: 0 1px 2px rgba(0,0,0,.05);--wf-shadow-inset: inset 0 1px 2px rgba(0,0,0,.04);--wf-shadow: 0 1px 3px rgba(0,0,0,.08);--wf-shadow-md: 0 4px 12px rgba(0,0,0,.1);--wf-shadow-lg: 0 10px 15px -3px rgba(0,0,0,.1);--wf-z-sticky: 40;--wf-z-overlay: 80;--wf-z-modal: 100;--wf-tour-min-width: 240px;--wf-kanban-col-min-width: 200px;--wf-layout-sider-width: 240px;--wf-layout-sider-collapsed-width: 64px;--wf-layout-header-height: 56px;--wf-kanban-col-max-width: 300px;--wf-treeselect-min-width: 200px;--wf-navmenu-min-width: 160px;--wf-select-menu-min-width: 200px;--wf-treeselect-max-width: 320px;--wf-treeselect-dropdown-max-height: 260px;--wf-z-popover: 120;--wf-z-toast: 140;--wf-z-tooltip: 160;--wf-z-dropdown: var(--wf-z-popover);--wf-pop-z: var(--wf-z-popover);--wf-cover-z: var(--wf-z-modal);--wf-color-primary: var(--wf-brand-500);--wf-color-primary-hover: var(--wf-brand-600);--wf-color-primary-bg: var(--wf-brand-50);--wf-color-success: var(--wf-green-500);--wf-color-success-bg: var(--wf-green-50);--wf-color-warning: var(--wf-amber-500);--wf-color-warning-bg: var(--wf-amber-50);--wf-color-error: var(--wf-red-500);--wf-color-error-bg: var(--wf-red-50);--wf-color-text: var(--wf-slate-900);--wf-color-text-secondary: var(--wf-slate-500);--wf-color-text-tertiary: var(--wf-slate-400);--wf-color-text-disabled: var(--wf-slate-300);--wf-color-bg: var(--wf-white);--wf-color-bg-secondary: var(--wf-slate-50);--wf-color-bg-tertiary: var(--wf-slate-100);--wf-color-border: var(--wf-slate-200);--wf-color-border-light: var(--wf-slate-100);--wf-color-border-dark: var(--wf-slate-300);--wf-surface-bg: var(--wf-color-bg);--wf-color-bg-elevated: var(--wf-color-bg);--wf-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", sans-serif;--wf-font-mono: "SF Mono", "Fira Code", "JetBrains Mono", "PingFang SC", "Microsoft YaHei", monospace;--wf-font-size-xs: 12px;--wf-font-size-sm: 13px;--wf-font-size-base: 14px;--wf-font-size-lg: 15px;--wf-font-size-xl: 16px;--wf-font-size-2xl: 21px;--wf-font-size-3xl: 24px;--wf-font-size-4xl: 30px;--wf-font-size-5xl: 36px;--wf-font-size-display: 30px;--wf-heading-case: none;--wf-heading-tracking: 0;--wf-font-weight-normal: 400;--wf-font-weight-medium: 500;--wf-font-weight-semibold: 600;--wf-font-weight-bold: 700;--wf-line-height-tight: 1.25;--wf-line-height: 1.5;--wf-line-height-relaxed: 1.75;--wf-border-width: 1px;--wf-focus-ring: 0 0 0 2px var(--wf-color-primary-bg), 0 0 0 1px var(--wf-color-primary);--wf-transition-duration: var(--wf-dur-fast);--wf-transition-timing: var(--wf-ease-out);--wf-transition: var(--wf-transition-duration) var(--wf-transition-timing);--wf-dur-fast: .12s;--wf-dur-base: .2s;--wf-dur-slow: .3s;--wf-ease-out: cubic-bezier(.16, 1, .3, 1);--wf-ease-in: cubic-bezier(.4, 0, 1, 1);--wf-ease-in-out: cubic-bezier(.4, 0, .2, 1);--wf-ease-snap: cubic-bezier(.34, 1.56, .64, 1);--wf-ease-standard: ease;--wf-dur-md: var(--wf-dur-base);--wf-motion-sm: 4px;--wf-dur-spin: .6s;--wf-dur-pulse: 1.2s;--wf-dur-blink: 1.1s;--wf-dur-progress: 1.4s;--wf-color-info: var(--wf-sky-500);--wf-color-info-bg: var(--wf-sky-50);--wf-color-primary-text: var(--wf-brand-700);--wf-color-success-text: var(--wf-green-700);--wf-color-warning-text: var(--wf-amber-700);--wf-color-error-text: var(--wf-red-700);--wf-color-info-text: var(--wf-sky-700);--wf-color-fill: var(--wf-slate-100);--wf-color-bg-subtle: var(--wf-color-fill);--wf-state-hover: rgba(0, 0, 0, .04);--wf-state-pressed: rgba(0, 0, 0, .08);--wf-color-bg-hover: var(--wf-state-hover);--wf-color-on-brand: #fff;--wf-color-on-warning: #451a03;--wf-overlay: rgba(0, 0, 0, .4);--wf-overlay-blur: 4px;--wf-accent-color: var(--wf-color-primary);--wf-caret-color: var(--wf-color-primary);--wf-control-pad-y: 10px;--wf-control-height: 36px;--wf-field-height: var(--wf-control-height);--wf-field-radius: var(--wf-radius);--wf-bp-sm: 640px;--wf-bp-md: 768px;--wf-bp-lg: 1024px;--wf-bp-xl: 1280px;--wf-sidebar-width: 240px;--wf-opacity-disabled: .5;--wf-letter-spacing-wide: .5px;--wf-heading-display-tracking: -.5px;--wf-nums: "tabular-nums"}@supports not (color: color-mix(in srgb,red 50%,blue)){:root{--wf-brand-600: #3b5ae0;--wf-brand-700: #4338ca;--wf-brand-50: #eef1ff;--wf-dark-brand-600: #8ba3ff;--wf-dark-brand-50: #1e293b}}:root[data-theme=dark]{color-scheme:dark;--wf-color-primary: var(--wf-dark-brand-500);--wf-color-primary-hover: var(--wf-dark-brand-600);--wf-color-primary-bg: var(--wf-dark-brand-50);--wf-color-success: var(--wf-dark-green-500);--wf-color-success-bg: var(--wf-dark-green-50);--wf-color-warning: var(--wf-dark-amber-500);--wf-color-warning-bg: var(--wf-dark-amber-50);--wf-color-error: var(--wf-dark-red-500);--wf-color-error-bg: var(--wf-dark-red-50);--wf-color-info: var(--wf-dark-sky-500);--wf-color-info-bg: var(--wf-dark-sky-50);--wf-color-text: var(--wf-dark-slate-900);--wf-color-text-secondary: var(--wf-dark-slate-500);--wf-color-text-tertiary: var(--wf-dark-slate-400);--wf-color-text-disabled: var(--wf-dark-slate-300);--wf-color-bg: var(--wf-dark-bg);--wf-color-bg-secondary: var(--wf-dark-slate-100);--wf-color-bg-tertiary: var(--wf-dark-slate-200);--wf-color-fill: var(--wf-dark-fill);--wf-color-bg-subtle: var(--wf-dark-fill);--wf-color-bg-hover: var(--wf-dark-bg-hover);--wf-state-hover: var(--wf-dark-state-hover);--wf-state-pressed: var(--wf-dark-state-pressed);--wf-color-bg-elevated: var(--wf-dark-slate-100);--wf-color-border: var(--wf-dark-slate-200);--wf-color-border-light: var(--wf-dark-slate-100);--wf-color-border-dark: var(--wf-dark-slate-300);--wf-surface-bg: var(--wf-color-bg);--wf-surface-shadow: var(--wf-dark-surface-shadow);--wf-shadow-sm: var(--wf-dark-shadow-sm);--wf-shadow: var(--wf-dark-shadow);--wf-shadow-md: var(--wf-dark-shadow-md);--wf-shadow-lg: var(--wf-dark-shadow-lg);--wf-shadow-inset: var(--wf-dark-shadow-inset);--wf-color-primary-text: var(--wf-dark-brand-500);--wf-color-success-text: var(--wf-dark-green-500);--wf-color-warning-text: var(--wf-dark-amber-500);--wf-color-error-text: var(--wf-dark-red-500);--wf-color-info-text: var(--wf-dark-sky-500);--wf-overlay: var(--wf-dark-overlay)}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){color-scheme:dark;--wf-color-primary: var(--wf-dark-brand-500);--wf-color-primary-hover: var(--wf-dark-brand-600);--wf-color-primary-bg: var(--wf-dark-brand-50);--wf-color-success: var(--wf-dark-green-500);--wf-color-success-bg: var(--wf-dark-green-50);--wf-color-warning: var(--wf-dark-amber-500);--wf-color-warning-bg: var(--wf-dark-amber-50);--wf-color-error: var(--wf-dark-red-500);--wf-color-error-bg: var(--wf-dark-red-50);--wf-color-info: var(--wf-dark-sky-500);--wf-color-info-bg: var(--wf-dark-sky-50);--wf-color-text: var(--wf-dark-slate-900);--wf-color-text-secondary: var(--wf-dark-slate-500);--wf-color-text-tertiary: var(--wf-dark-slate-400);--wf-color-text-disabled: var(--wf-dark-slate-300);--wf-color-bg: var(--wf-dark-bg);--wf-color-bg-secondary: var(--wf-dark-slate-100);--wf-color-bg-tertiary: var(--wf-dark-slate-200);--wf-color-fill: var(--wf-dark-fill);--wf-color-bg-subtle: var(--wf-dark-fill);--wf-color-bg-hover: var(--wf-dark-bg-hover);--wf-state-hover: var(--wf-dark-state-hover);--wf-state-pressed: var(--wf-dark-state-pressed);--wf-color-bg-elevated: var(--wf-dark-slate-100);--wf-color-border: var(--wf-dark-slate-200);--wf-color-border-light: var(--wf-dark-slate-100);--wf-color-border-dark: var(--wf-dark-slate-300);--wf-surface-bg: var(--wf-color-bg);--wf-surface-shadow: var(--wf-dark-surface-shadow);--wf-shadow-sm: var(--wf-dark-shadow-sm);--wf-shadow: var(--wf-dark-shadow);--wf-shadow-md: var(--wf-dark-shadow-md);--wf-shadow-lg: var(--wf-dark-shadow-lg);--wf-shadow-inset: var(--wf-dark-shadow-inset);--wf-color-primary-text: var(--wf-dark-brand-500);--wf-color-success-text: var(--wf-dark-green-500);--wf-color-warning-text: var(--wf-dark-amber-500);--wf-color-error-text: var(--wf-dark-red-500);--wf-color-info-text: var(--wf-dark-sky-500);--wf-overlay: var(--wf-dark-overlay)}}:root[data-preset=minimal]{--wf-brand-seed: #64748b;--wf-dark-brand-seed: #94a3b8}:root[data-preset=compact]{--wf-control-height: 32px;--wf-control-pad-y: 6px;--wf-space-xs: 3px;--wf-space-sm: 6px;--wf-space: 9px;--wf-space-md: 12px;--wf-space-lg: 18px;--wf-space-xl: 24px;--wf-space-2xl: 30px;--wf-font-size-sm: 12px;--wf-font-size-base: 13px}:root[data-preset=rounded]{--wf-radius-sm: 8px;--wf-radius: 12px;--wf-radius-md: 16px;--wf-radius-lg: 20px;--wf-radius-xl: 28px;--wf-surface-radius: var(--wf-radius-md);--wf-btn-radius: 999px;--wf-field-radius: var(--wf-radius-md)}@property --wf-gap{syntax: "*"; inherits: false;}@property --wf-align{syntax: "*"; inherits: false;}@property --wf-justify{syntax: "*"; inherits: false;}@property --wf-cols{syntax: "*"; inherits: false;}@property --wf-max{syntax: "*"; inherits: false;}@property --wf-w-sm{syntax: "*"; inherits: false;}@property --wf-z{syntax: "*"; inherits: false;}@property --wf-offset{syntax: "*"; inherits: false;}@property --wf-popup-max{syntax: "*"; inherits: false;}@layer base{*,*:before,*:after{box-sizing:border-box}::selection{background:var(--wf-color-primary-bg);color:var(--wf-color-primary-text)}*{scrollbar-width:thin;scrollbar-color:var(--wf-color-border-dark) transparent}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--wf-color-border-dark);border-radius:var(--wf-radius-sm);border:2px solid transparent;background-clip:padding-box}::-webkit-scrollbar-thumb:hover{background:var(--wf-color-text-secondary);background-clip:padding-box;border:2px solid transparent}:root{color-scheme:light}body{margin:0;background:var(--wf-color-bg);color:var(--wf-color-text);font-family:var(--wf-font-sans);font-size:var(--wf-font-size-base);line-height:var(--wf-line-height);-webkit-font-smoothing:antialiased}a{color:var(--wf-color-primary-text);text-decoration:none}a:hover{color:var(--wf-color-primary-hover);text-decoration:underline}input,textarea,select,button{font-family:inherit;font-size:inherit;line-height:inherit}input,textarea,select{accent-color:var(--wf-accent-color);caret-color:var(--wf-caret-color);background:var(--wf-color-bg);color:var(--wf-color-text);border:var(--wf-border-width) solid var(--wf-color-border);border-radius:var(--wf-radius);padding:var(--wf-control-pad-y) var(--wf-space)}input:focus,textarea:focus,select:focus{outline:none;box-shadow:var(--wf-focus-ring);border-color:var(--wf-color-primary)}input:disabled,textarea:disabled,select:disabled,button:disabled{opacity:var(--wf-opacity-disabled);cursor:not-allowed}button{accent-color:var(--wf-accent-color);background:var(--wf-color-bg);color:var(--wf-color-text);border:var(--wf-border-width) solid var(--wf-color-border);border-radius:var(--wf-radius);padding:var(--wf-control-pad-y) var(--wf-space-md);min-height:var(--wf-control-height);cursor:pointer;transition:border-color var(--wf-dur-fast) var(--wf-ease-out),color var(--wf-dur-fast) var(--wf-ease-out),box-shadow var(--wf-dur-fast) var(--wf-ease-out),background-color var(--wf-dur-fast) var(--wf-ease-out),filter var(--wf-dur-fast) var(--wf-ease-out)}button:hover{border-color:var(--wf-color-primary);color:var(--wf-color-primary-text)}button:active:not(:disabled),[role=button]:active{filter:brightness(.95)}button:focus-visible,[tabindex]:focus-visible{outline:none;box-shadow:var(--wf-focus-ring)}[role=button]{cursor:pointer;transition:background-color var(--wf-dur-fast) var(--wf-ease-out),border-color var(--wf-dur-fast) var(--wf-ease-out),box-shadow var(--wf-dur-fast) var(--wf-ease-out),color var(--wf-dur-fast) var(--wf-ease-out),filter var(--wf-dur-fast) var(--wf-ease-out)}@media(pointer:coarse){button,[role=button],input,textarea,select,.wf-card--clickable,.wf-table-th--sortable,.wf-accordion-summary,.wf-tag-close,.wf-checkbox,.wf-switch,.wf-radio,.wf-datepicker-cell{min-height:44px;min-width:44px}}h1,h2,h3,h4,h5,h6{font-weight:var(--wf-font-weight-semibold);line-height:var(--wf-line-height-tight);color:var(--wf-color-text)}p{line-height:var(--wf-line-height-relaxed)}small{font-size:var(--wf-font-size-sm);color:var(--wf-color-text-tertiary)}label{font-size:var(--wf-font-size-base);font-weight:var(--wf-font-weight-medium);color:var(--wf-color-text)}table{width:100%;border-collapse:collapse}th{text-align:left;font-weight:var(--wf-font-weight-medium);font-size:var(--wf-font-size-xs);color:var(--wf-color-text-tertiary);text-transform:var(--wf-heading-case);letter-spacing:var(--wf-heading-tracking);padding:var(--wf-space) var(--wf-space-sm);border-bottom:var(--wf-border-width) solid var(--wf-color-border);background:var(--wf-color-bg-secondary)}td{padding:var(--wf-space) var(--wf-space-sm);border-bottom:var(--wf-border-width) solid var(--wf-color-border);color:var(--wf-color-text);font-size:var(--wf-font-size-base)}hr{border:none;border-top:var(--wf-border-width) solid var(--wf-color-border);margin:var(--wf-space-md) 0}pre,code{font-family:var(--wf-font-mono);font-size:var(--wf-font-size-sm)}pre{background:var(--wf-color-bg-secondary);border:var(--wf-border-width) solid var(--wf-color-border);border-radius:var(--wf-radius);padding:var(--wf-space) var(--wf-space-md);overflow-x:auto;white-space:pre}code{background:var(--wf-color-bg-secondary);padding:2px 6px;border-radius:var(--wf-radius-sm)}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}body.wf-dragging{user-select:none;-webkit-user-select:none}@keyframes wf-stream-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.wf-stream-in{animation:wf-stream-in var(--wf-dur-base) var(--wf-ease-out) both}@media(prefers-reduced-motion:reduce){.wf-stream-in{animation-duration:.01ms}}.wf-hero-cursor{animation:wf-hero-blink 1s step-end infinite;color:var(--wf-color-primary)}@keyframes wf-hero-blink{0%,to{opacity:1}50%{opacity:0}}}@layer layout{.wf-stack{display:flex;flex-direction:column}:where(.wf-stack){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, stretch)}.wf-row{display:flex;flex-wrap:wrap}:where(.wf-row){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, center)}.wf-row-reverse{display:flex;flex-wrap:wrap;flex-direction:row-reverse}:where(.wf-row-reverse){gap:var(--wf-gap, var(--wf-gap-md));align-items:var(--wf-align, center)}.wf-items-start{--wf-align: flex-start}.wf-items-center{--wf-align: center}.wf-items-end{--wf-align: flex-end}.wf-items-stretch{--wf-align: stretch}.wf-grid{display:grid;grid-template-columns:var(--wf-cols, repeat(auto-fill, minmax(280px, 1fr)))}:where(.wf-grid){gap:var(--wf-gap, var(--wf-gap-lg))}.wf-center{display:flex;flex-direction:column;align-items:center;justify-content:center}.wf-justify-between{display:flex;justify-content:space-between}:where(.wf-justify-between){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-justify-end{display:flex;justify-content:flex-end}:where(.wf-justify-end){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-justify-center{display:flex;justify-content:center}:where(.wf-justify-center){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-fill{flex:1;min-width:0;min-height:0}.wf-fill-hover{border-radius:var(--wf-radius-sm);padding:2px 4px;margin:-2px -4px;transition:background .15s ease}.wf-cover{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:var(--wf-z, var(--wf-cover-z))}}@layer layout{.wf-split{display:flex;justify-content:space-between}:where(.wf-split){align-items:var(--wf-align, center);gap:var(--wf-gap, var(--wf-gap-md))}.wf-split>:last-child{flex-shrink:0}}@layer layout{.wf-cluster{display:flex;flex-wrap:wrap}:where(.wf-cluster){gap:var(--wf-gap, var(--wf-gap-sm));justify-content:var(--wf-justify, center);align-items:var(--wf-align, center)}}@layer layout{.wf-relative{position:relative}.wf-absolute{position:absolute}}@layer layout{.wf-sticky{position:sticky;top:var(--wf-offset, 0)}}@layer layout{.wf-overflow-auto{overflow:auto}.wf-overflow-hidden{overflow:hidden}.wf-overflow-x{overflow-x:auto}}@layer layout{.wf-safe-bottom{padding-bottom:env(safe-area-inset-bottom)}.wf-safe-top{padding-top:env(safe-area-inset-top)}}@layer layout{.wf-layer{position:relative;z-index:var(--wf-z, 1)}}@layer layout{.wf-self-start{align-self:flex-start}.wf-self-center{align-self:center}.wf-self-end{align-self:flex-end}.wf-self-stretch{align-self:stretch}}@layer layout{.wf-nowrap{display:flex;flex-wrap:nowrap}:where(.wf-nowrap){gap:var(--wf-gap, var(--wf-gap-md))}}@layer layout{.wf-shrink{min-width:0;min-height:0}.wf-min-width-0{min-width:0}}@layer layout{.wf-container{width:100%;max-width:var(--wf-max, 1200px);margin:0 auto;padding:0 var(--wf-gap, var(--wf-gap-lg))}}@layer layout{.wf-app-shell{display:grid;grid-template-columns:var(--wf-sidebar-width, 240px) minmax(0,1fr);height:100vh;overflow:hidden}.wf-sidebar{display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto;background:var(--wf-color-bg-secondary);border-right:var(--wf-border-width) solid var(--wf-color-border)}.wf-sidebar-header{display:flex;align-items:center;gap:var(--wf-gap-sm);padding:var(--wf-space-md);border-bottom:var(--wf-border-width) solid var(--wf-color-border-light);flex-shrink:0}.wf-sidebar-body{flex:1;padding:var(--wf-space-sm);overflow-y:auto}.wf-sidebar-footer{padding:var(--wf-space-sm);border-top:var(--wf-border-width) solid var(--wf-color-border-light);flex-shrink:0}.wf-nav{display:flex;flex-direction:column;gap:2px}.wf-nav-group{font-size:var(--wf-font-size-xs);font-weight:var(--wf-font-weight-medium);color:var(--wf-color-text-tertiary);text-transform:var(--wf-heading-case);letter-spacing:var(--wf-heading-tracking);padding:var(--wf-space-md) var(--wf-space-sm) var(--wf-space-xs)}.wf-nav-item{display:flex;align-items:center;gap:var(--wf-gap-sm);padding:var(--wf-space-sm) var(--wf-space);border-radius:var(--wf-radius);color:var(--wf-color-text-secondary);font-size:var(--wf-font-size-base);text-decoration:none;cursor:pointer;border:none;background:none;width:100%;text-align:left;font-family:inherit;transition:background var(--wf-transition),color var(--wf-transition)}.wf-nav-item:hover{background:var(--wf-color-bg-tertiary);color:var(--wf-color-text);text-decoration:none}.wf-nav-item:focus-visible{outline:none;box-shadow:var(--wf-focus-ring)}.wf-nav-item--active{background:var(--wf-color-primary-bg);color:var(--wf-color-primary-text);font-weight:var(--wf-font-weight-medium)}.wf-nav-item--active:hover{background:var(--wf-color-primary-bg);color:var(--wf-color-primary-text)}.wf-nav--collapsed .wf-nav-item{justify-content:center;gap:0;padding:var(--wf-space-sm)}.wf-nav--collapsed .wf-nav-label{display:none}.wf-nav--collapsed .wf-nav-group{text-align:center;padding-left:0;padding-right:0;overflow:hidden;white-space:nowrap}.wf-main{padding:var(--wf-space-lg);min-width:0;min-height:0;overflow-y:auto;background:var(--wf-color-bg);--wf-main-max: none}.wf-main>*{max-width:var(--wf-main-max);margin-inline:auto}@media(pointer:coarse){.wf-nav-item{min-height:44px}}@media(max-width:767.98px){.wf-app-shell{grid-template-columns:1fr;height:auto;overflow:visible}.wf-sidebar{position:static;height:auto;border-right:none;border-bottom:var(--wf-border-width) solid var(--wf-color-border)}.wf-main{padding:var(--wf-space-md);overflow:visible}}}@layer utilities{.wf-surface{border-radius:var(--wf-surface-radius);box-shadow:var(--wf-surface-shadow);background:var(--wf-surface-bg)}.wf-surface--flat{box-shadow:none}.wf-bg-secondary{background:var(--wf-color-bg-secondary)}.wf-bg-tertiary{background:var(--wf-color-bg-tertiary)}.wf-bg-primary{background:var(--wf-color-primary-bg)}.wf-bg-warning{background:var(--wf-color-warning-bg)}.wf-bg-error{background:var(--wf-color-error-bg)}.wf-bg-none{background:transparent}.wf-pill{border-radius:999px}.wf-radius-sm{border-radius:var(--wf-radius-sm)}.wf-radius{border-radius:var(--wf-radius)}.wf-radius-md{border-radius:var(--wf-radius-md)}.wf-radius-lg{border-radius:var(--wf-radius-lg)}.wf-shadow{box-shadow:var(--wf-shadow)}.wf-elevate{transition:box-shadow var(--wf-dur-fast) var(--wf-ease-out),transform var(--wf-dur-fast) var(--wf-ease-out)}.wf-elevate:hover{box-shadow:var(--wf-shadow-md);transform:translateY(-2px)}.wf-elevate:focus-visible{outline:none;box-shadow:var(--wf-shadow-md),var(--wf-focus-ring)}.wf-panel-in{animation:wf-panel-in var(--wf-dur-fast) var(--wf-ease-out);transform-origin:top center}@keyframes wf-panel-in{0%{opacity:0;transform:translateY(calc(var(--wf-motion-sm) * -1)) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.wf-bubble{display:inline-block;max-width:70%;padding:var(--wf-space-sm) var(--wf-space-md);border-radius:var(--wf-radius-md);background:var(--wf-color-bg-secondary);color:var(--wf-color-text);font-size:var(--wf-font-size-base);line-height:var(--wf-line-height);white-space:pre-wrap;word-break:break-word}.wf-bubble--own{background:var(--wf-color-primary);color:var(--wf-color-on-brand);border-bottom-right-radius:var(--wf-radius-sm)}.wf-bubble--ai{background:var(--wf-color-primary-bg);border:var(--wf-border-width) solid var(--wf-color-border-light);border-bottom-left-radius:var(--wf-radius-sm)}.wf-rounded-sm{border-radius:var(--wf-radius-sm)}.wf-rounded-md{border-radius:var(--wf-radius-md)}.wf-card-outline{border:var(--wf-border-width) solid var(--wf-color-border)}}@layer utilities{.wf-border{border:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-top{border-top:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-bottom{border-bottom:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-left{border-left:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-right{border-right:var(--wf-border-width) solid var(--wf-color-border)}.wf-border-none{border:none}}@layer utilities{.wf-text-left{text-align:left}.wf-text-center{text-align:center}.wf-text-right{text-align:right}.wf-font-xs{font-size:var(--wf-font-size-xs)}.wf-font-sm{font-size:var(--wf-font-size-sm)}.wf-font-base{font-size:var(--wf-font-size-base)}.wf-font-lg{font-size:var(--wf-font-size-lg)}.wf-font-2xl{font-size:var(--wf-font-size-2xl)}.wf-font-3xl{font-size:var(--wf-font-size-3xl)}.wf-font-4xl{font-size:var(--wf-font-size-4xl)}.wf-nums{font-variant-numeric:var(--wf-nums)}.wf-text-secondary{color:var(--wf-color-text-secondary)}.wf-text-tertiary{color:var(--wf-color-text-tertiary)}.wf-text-danger{color:var(--wf-color-error-text)}.wf-text-primary{color:var(--wf-color-primary-text)}.wf-text-success{color:var(--wf-color-success-text)}.wf-text-warning{color:var(--wf-color-warning-text)}.wf-font-mono{font-family:var(--wf-font-mono)}.wf-text-error{color:var(--wf-color-error-text)}.wf-text-on-brand{color:var(--wf-color-on-brand)}.wf-text-on-warning{color:var(--wf-color-on-warning)}.wf-medium{font-weight:var(--wf-font-weight-medium)}.wf-semibold{font-weight:var(--wf-font-weight-semibold)}.wf-bold{font-weight:var(--wf-font-weight-bold)}.wf-tracking-wide{letter-spacing:var(--wf-letter-spacing-wide)}.wf-uppercase{text-transform:uppercase}.wf-pre-wrap{white-space:pre-wrap;word-break:break-word}.wf-break-word{overflow-wrap:break-word;word-break:break-word}.wf-text-nowrap{white-space:nowrap}.wf-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@layer utilities{.wf-padding-none{padding:0}.wf-padding-xs{padding:var(--wf-space-xs)}.wf-padding-sm{padding:var(--wf-space-sm)}.wf-padding-md{padding:var(--wf-space-md)}.wf-padding-lg{padding:var(--wf-space-lg)}.wf-padding-xl{padding:var(--wf-space-xl)}.wf-padding-x-xs{padding-left:var(--wf-space-xs);padding-right:var(--wf-space-xs)}.wf-padding-x-sm{padding-left:var(--wf-space-sm);padding-right:var(--wf-space-sm)}.wf-padding-x-md{padding-left:var(--wf-space-md);padding-right:var(--wf-space-md)}.wf-padding-y-xs{padding-top:var(--wf-space-xs);padding-bottom:var(--wf-space-xs)}.wf-padding-y-sm{padding-top:var(--wf-space-sm);padding-bottom:var(--wf-space-sm)}.wf-padding-y-md{padding-top:var(--wf-space-md);padding-bottom:var(--wf-space-md)}.wf-padding-y-lg{padding-top:var(--wf-space-lg);padding-bottom:var(--wf-space-lg)}.wf-padding-top-sm{padding-top:var(--wf-space-sm)}.wf-padding-left-sm{padding-left:var(--wf-space-sm)}.wf-padding-bottom-xs{padding-bottom:var(--wf-space-xs)}.wf-padding-bottom-sm{padding-bottom:var(--wf-space-sm)}.wf-padding-bottom-md{padding-bottom:var(--wf-space-md)}.wf-margin-none{margin:0}.wf-margin-top-none{margin-top:0}.wf-margin-top-xs{margin-top:var(--wf-space-xs)}.wf-margin-top-sm{margin-top:var(--wf-space-sm)}.wf-margin-top-md{margin-top:var(--wf-space-md)}.wf-margin-bottom-xs{margin-bottom:var(--wf-space-xs)}.wf-margin-bottom-sm{margin-bottom:var(--wf-space-sm)}.wf-margin-bottom-md{margin-bottom:var(--wf-space-md)}.wf-margin-bottom-lg{margin-bottom:var(--wf-space-lg)}.wf-margin-left-xs{margin-left:var(--wf-space-xs)}.wf-margin-left-sm{margin-left:var(--wf-space-sm)}.wf-margin-x-auto{margin-left:auto;margin-right:auto}.wf-margin-y-xs{margin-top:var(--wf-space-xs);margin-bottom:var(--wf-space-xs)}.wf-gap-none{gap:0}.wf-gap-xs{gap:var(--wf-gap-xs)}.wf-gap-sm{gap:var(--wf-gap-sm)}.wf-gap-md{gap:var(--wf-gap-md)}.wf-gap-lg{gap:var(--wf-gap-lg)}.wf-gap-xl{gap:var(--wf-gap-xl)}.wf-width-full{width:100%}.wf-width-sm{width:var(--wf-w-sm, 480px)}.wf-height-full{height:100%}}@layer utilities{:where(.wf-block){display:block}}@layer utilities{:where(.wf-flex){display:flex}@media(min-width:640px){.wf-flex\@sm{display:flex}}@media(min-width:1024px){.wf-flex\@lg{display:flex}}}@layer utilities{:where(.wf-hidden){display:none}@media(min-width:1024px){.wf-hidden\@lg{display:none}}.wf-dim{opacity:.7}.wf-pointer{cursor:pointer}}@layer layout{.wf-popup{max-width:min(var(--wf-popup-max, 480px),calc(100vw - 32px));box-sizing:border-box}.wf-popup-mask{position:fixed;inset:0;z-index:var(--wf-z-overlay);background:var(--wf-overlay)}}
|
|
@@ -35,7 +35,7 @@ export type { Ui };
|
|
|
35
35
|
* - 中间件注入面:`[key: string]: unknown` 索引签名 + **declare module 合并**
|
|
36
36
|
* (应用/中间件作者扩展——同后端 `declare module 'weifuwu' { interface Context }`):
|
|
37
37
|
* ```ts
|
|
38
|
-
* declare module 'weifuwu/vdom' { interface UIContext { api: ApiClient } }
|
|
38
|
+
* declare module 'weifuwu/client/vdom' { interface UIContext { api: ApiClient } }
|
|
39
39
|
* ```
|
|
40
40
|
* - 组件泛型:Component<P, C = UIContext>——默认增强后的 UIContext) */
|
|
41
41
|
export interface UIContext {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom core — createComponent(组件声明抽象——状态类/aria/role 机械面生成)
|
|
3
|
+
*
|
|
4
|
+
* 设计(2027-09——分层抽象 W3):组件层 80 状态类 · 240 aria 手写实证——
|
|
5
|
+
* 类名拼接与布尔 aria 是**派生面**(prop 状态 → 类/aria 的确定性映射)——
|
|
6
|
+
* 声明化(BEM 规则单源在 createComponent——组件内无 `--${variant}` 模板)。
|
|
7
|
+
*
|
|
8
|
+
* 抽象边界(防配置地狱护栏):只生成**机械部分**(类 + aria 布尔 + role)——
|
|
9
|
+
* 结构/内容/事件/业务 = render 自由面(皮)。判据:声明比实现短且机械部分
|
|
10
|
+
* 全消失——否则抽象失败(判负登记)。
|
|
11
|
+
*
|
|
12
|
+
* 用法:
|
|
13
|
+
* const PayBtn = createComponent<PayProps>({
|
|
14
|
+
* class: 'wf-pay-btn',
|
|
15
|
+
* enumStates: { variant: null }, // 直拼 wf-pay-btn--<v>
|
|
16
|
+
* boolStates: { active: 'wf-pay-btn--active' },
|
|
17
|
+
* ariaBools: { active: 'aria-pressed' },
|
|
18
|
+
* render: (root, props) => h('button', { ...root, onClick: props.onClick }, props.label),
|
|
19
|
+
* })
|
|
20
|
+
* // 旧:cls 数组 7 行 + aria 2 行 → 新:声明行 + render
|
|
21
|
+
*/
|
|
22
|
+
import type { Component, VNode } from './vnode.ts';
|
|
23
|
+
import type { UIContext } from '../context/UIContext.ts';
|
|
24
|
+
export interface CreateComponentDecl<P = Record<string, unknown>> {
|
|
25
|
+
/** BEM 词根(wf-btn——直拼 `wf-btn--<v>`;布尔状态用 boolStates 显式类) */
|
|
26
|
+
class: string;
|
|
27
|
+
/** 布尔状态 → 类变体({ checked: 'wf-x--checked' }) */
|
|
28
|
+
boolStates?: Record<string, string>;
|
|
29
|
+
/** 枚举状态 → 类变体(值直拼 `wf-x--<v>`(null)或显式映射) */
|
|
30
|
+
enumStates?: Record<string, Record<string, string> | null>;
|
|
31
|
+
/** 布尔 → aria 属性({ loading: 'aria-busy' }——真值写出属性) */
|
|
32
|
+
ariaBools?: Record<string, string>;
|
|
33
|
+
/** 根 role(静态) */
|
|
34
|
+
role?: string;
|
|
35
|
+
/** 皮(rootProps 组装毕——class/aria/role/class 透传已含——缺省
|
|
36
|
+
* 根元素直接透传——render 负责结构/内容/事件——ctx 透传(i18n 等)) */
|
|
37
|
+
render?: (rootProps: Record<string, unknown>, props: P, ctx: UIContext) => VNode | null;
|
|
38
|
+
/** 缺省渲染的根标签(render 未提供时——button) */
|
|
39
|
+
tag?: string;
|
|
40
|
+
}
|
|
41
|
+
/** 组件声明 → 组件工厂(同步——两阶段语义与手写一致) */
|
|
42
|
+
export declare function createComponent<P = Record<string, unknown>>(decl: CreateComponentDecl<P>): Component<P>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createItem —— 交互元素状态捆绑原语(原语全面化回馈 #2)
|
|
3
|
+
*
|
|
4
|
+
* 为什么存在:createComponent(组件级声明)在 W3 判负调查中暴露结构性错位——
|
|
5
|
+
* 组件 = 容器 + 可交互子项(Tabs 的 tab / SegmentedControl 的 option /
|
|
6
|
+
* TabBar 的 item),**状态类和 aria 布尔几乎总在子项上**(43 组件含状态面,
|
|
7
|
+
* 12 组件是「同条件驱动类 + aria 双面」的真机械面)。抽象单位切错了——
|
|
8
|
+
* 从「组件」下沉到「交互元素」:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const tab = createItem({ cls: 'wf-tab', role: 'tab', aria: 'aria-selected' })
|
|
12
|
+
* // 循环内:
|
|
13
|
+
* h('button', tab(act === key, { onClick }), label)
|
|
14
|
+
* // → { class: 'wf-tab wf-tab--active', role: 'tab', 'aria-selected': true, onClick }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* 单源回报:类后缀与 aria 布尔**捆绑声明**——不可能改一面漏一面
|
|
18
|
+
* (aria-selected 与 --active 不同步 = a11y bug——同类手写双面同步是历史重复源)。
|
|
19
|
+
* aria 布尔直传内核(ariaBoolValue 归一——回馈 #1 后全库无手写三元冗余)。
|
|
20
|
+
*
|
|
21
|
+
* 边界(诚实):单活动态(一个元素一个激活布尔)。多状态子项
|
|
22
|
+
* (Menu 的 current+expanded / Tree 的 checked+selected+open)不在契约——
|
|
23
|
+
* 手写保留(判负登记);aria 多值(Tree checked 'mixed' / Cascader 多态)
|
|
24
|
+
* 用 ariaText 文本值兜底,多值枚举仍判负。
|
|
25
|
+
*/
|
|
26
|
+
export interface ItemStateDecl {
|
|
27
|
+
/** 基类(如 'wf-tab')——active 时派生 `cls + suffix` */
|
|
28
|
+
cls: string;
|
|
29
|
+
/** 活动态类后缀(默认 '--active'——组件类名约定) */
|
|
30
|
+
suffix?: string;
|
|
31
|
+
/** role(所有实例同值——如 'tab'/'option') */
|
|
32
|
+
role?: string;
|
|
33
|
+
/** 活动态 aria 布尔键(布尔直传内核归一——非 active 时 false 保留) */
|
|
34
|
+
aria?: string;
|
|
35
|
+
/** 活动态 aria 文本值(active → value;非 active → undefined 移除) */
|
|
36
|
+
ariaText?: {
|
|
37
|
+
key: string;
|
|
38
|
+
value: string;
|
|
39
|
+
};
|
|
40
|
+
/** roving tabindex(active → 0 · 非 active → -1——键盘焦点管理面) */
|
|
41
|
+
roving?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 生成「交互元素状态 props」工厂——返回 (active, extra) => props。
|
|
45
|
+
* - active=true:类带后缀 · aria 布尔 true(或 ariaText value)
|
|
46
|
+
* - active=false:类无后缀 · aria 布尔 false(保留状态——与属性移除语义不同)
|
|
47
|
+
* · ariaText undefined(移除)
|
|
48
|
+
* - extra 后置 spread(extra 胜——扩展不用改声明)
|
|
49
|
+
* - **class 例外:extra.class 追加而非覆盖**(disabled/focus/variant 等
|
|
50
|
+
* 第二类面与状态后缀共存——覆盖会丢状态类——契约锁定合并语义)
|
|
51
|
+
*/
|
|
52
|
+
export declare function createItem(decl: ItemStateDecl): (active: boolean, extra?: Record<string, unknown>) => Record<string, unknown>;
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* 设计(对齐 vdom-x 契约 + 设计规则 §4.0/§6.3):
|
|
5
5
|
* ① vnode 纯数据——零回填字段(el/_render/_id 等全部在影子层——可自由克隆/
|
|
6
6
|
* 比较/序列化——用户写 JSX 就能推导 vnode 形状)
|
|
7
|
-
* ② h() 除 key
|
|
7
|
+
* ② h() 除 key 剥离 + class 归一外零转换——children 原样(false/嵌套数组保留——
|
|
8
|
+
* 不 filter);class 归一(2027-09——组件层 105 文件 180 处模板拼接手搓实证——
|
|
9
|
+
* 对象/数组条件类万库通用形态——内核承载:字符串直通零成本 · 对象/数组归一
|
|
10
|
+
* 为空格串(协议/SSR/diff 零改——归一时机 vnode 创建——一次)
|
|
8
11
|
* ③ key 业务身份声明协议:key 从 props 剥离进 vnode.key(组件 props 不见 key)
|
|
9
12
|
* ④ children 值域协议:vnode/string/number/boolean/空洞(null/undefined)/嵌套数组
|
|
10
13
|
* (数组 = 隐式 Fragment——递归展开统一在 childrenOf——单一规则源——
|
|
@@ -34,11 +37,14 @@ export type RenderFn<P = Record<string, unknown>> = (props: P) => VNode | null |
|
|
|
34
37
|
* 同步执行不存在「半挂载」可观察状态——mouting 竞态类 bug 结构性消灭)
|
|
35
38
|
* - renderFn = 每次渲染(ctx.render()/props 变化触发——**纯同步**)
|
|
36
39
|
* - 异步边界 = useAsyncData/useObservable/useExternal(hooks——流语义) */
|
|
37
|
-
export type Component<P = Record<string, unknown>, C = UIContext> = (initProps: P, ctx: C) => RenderFn<P
|
|
40
|
+
export type Component<P = Record<string, unknown>, C = UIContext> = (initProps: P, ctx: C) => RenderFn<P> | VNode | null | (VNode | null)[];
|
|
38
41
|
type HType = string | symbol | Component<any, any>;
|
|
39
42
|
/** h()——创建 vnode(纯数据——除 key 剥离外零转换)
|
|
40
43
|
* children 原样:单子节点直接存、多子节点存数组、无子节点不存——false/嵌套
|
|
41
44
|
* 数组保留(不 filter——空洞占位法在消费侧) */
|
|
45
|
+
/** class 归一(字符串直通 · 数组展开 · 对象条件真值 · 嵌套递归——false/null 剔除)
|
|
46
|
+
* 万库通用条件类形态(对象 = { 'wf-active': isActive }——零模板拼接) */
|
|
47
|
+
export declare function normalizeClass(v: unknown): string | undefined;
|
|
42
48
|
export declare function h(type: HType, props?: Record<string, unknown> | null, ...children: VNodeChild[]): VNode;
|
|
43
49
|
/** jsx 运行时(自动导入——`<div/>` 编译目标——React 兼容签名 jsx(type, props, key)——
|
|
44
50
|
* props 内 key 同样剥离;jsxs/jsxDEV 同形状(children 已在 props.children) */
|
|
@@ -12,6 +12,9 @@ import type { ExternalStore } from '../store.ts';
|
|
|
12
12
|
import { Subject } from '../observable/index.ts';
|
|
13
13
|
import { type PopupHandle, type PopupOpenOptions } from './popup-manager.ts';
|
|
14
14
|
import { type TweenOptions } from './stable.ts';
|
|
15
|
+
import { type SignalHandle } from './signal.ts';
|
|
16
|
+
import { type OverlayHandle, type OverlayOptions } from './overlay.ts';
|
|
17
|
+
import { type FieldHandle, type FieldOptions } from './field.ts';
|
|
15
18
|
/** hooks 环境(per 组件实例——renderComponent 注入) */
|
|
16
19
|
/** me() 会话面(useSession 返回——轻量结构——不依赖 server 类型) */
|
|
17
20
|
export interface UserSession {
|
|
@@ -150,6 +153,15 @@ export interface Ui {
|
|
|
150
153
|
useVisualViewport(): import('./stable.ts').VisualViewportHandle;
|
|
151
154
|
/** 响应式系统偏好(prefers-reduced-motion——mount 期一次判定) */
|
|
152
155
|
useReducedMotion(): boolean;
|
|
156
|
+
/** 局部状态原语(set 自动重渲染——getter 纪律:get() 任意位置读最新)
|
|
157
|
+
* **增量原语**:不取代既有 ctx.render() 用法(存量保留) */
|
|
158
|
+
useSignal<T>(init: T): SignalHandle<T>;
|
|
159
|
+
/** 弹层行为契约(open/onOpenChange/焦点困禁/滚动锁/Esc/遮罩单源——
|
|
160
|
+
* sync 渲染期调用(openPopup 生命周期)——详见 hooks/overlay.ts) */
|
|
161
|
+
useOverlay(opts: OverlayOptions): OverlayHandle;
|
|
162
|
+
/** 表单字段契约(label/error/hint/aria 连接单源——renderLabel/Error/Hint
|
|
163
|
+
* 结构渲染——类为皮(字段 CSS)——详见 hooks/field.ts) */
|
|
164
|
+
useField(opts: FieldOptions): FieldHandle;
|
|
153
165
|
}
|
|
154
166
|
/** SSR 预取等待集合(并行 fetch 的 in-flight promise——uiSsr 等待会合) */
|
|
155
167
|
export declare const asyncInflight: Set<Promise<unknown>>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom hooks — useField(表单字段行为契约——label/error/hint/aria 连接单源)
|
|
3
|
+
*
|
|
4
|
+
* 设计(2027-09——分层抽象 W5):表单字段(Input/Select/DatePicker……)的
|
|
5
|
+
* label/required·error/hint 结构与 aria 连接(label for ↔ input id ·
|
|
6
|
+
* aria-invalid · aria-describedby · aria-required)重复手写实证——
|
|
7
|
+
* 契约化:字段作者只写输入面——标签/错误/提示/aria 由契约结构性保证。
|
|
8
|
+
*
|
|
9
|
+
* 结构类(labelClass/errClass/hintClass/reqClass/wrapErrClass)是皮
|
|
10
|
+
* (字段 CSS 定)——行为(属性/连接/态)契约内建。**渲染期 opts**(useOverlay
|
|
11
|
+
* 同模式——每次渲染读最新)。
|
|
12
|
+
*
|
|
13
|
+
* 用法:
|
|
14
|
+
* const f = useField({ label, error, hint, required, name })
|
|
15
|
+
* if (!f.hasWrap) return h('input', f.inputProps())
|
|
16
|
+
* return h('div', { class: `wf-x-wrap${f.stateClass}` }, [
|
|
17
|
+
* f.renderLabel(), h('input', f.inputProps()), f.renderError(), f.renderHint(),
|
|
18
|
+
* ])
|
|
19
|
+
*/
|
|
20
|
+
import type { HookEnv } from './env.ts';
|
|
21
|
+
import type { VNode } from '../core/vnode.ts';
|
|
22
|
+
export interface FieldOptions {
|
|
23
|
+
label?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
hint?: string;
|
|
26
|
+
required?: boolean;
|
|
27
|
+
/** 连接 id 基(显式 id 或 name——label for ↔ input id) */
|
|
28
|
+
name?: string;
|
|
29
|
+
id?: string;
|
|
30
|
+
/** 包装面(错误态类——字段 CSS 的 --err 变体) */
|
|
31
|
+
wrapErrClass?: string;
|
|
32
|
+
/** 标签/错误/提示的类(皮——字段 CSS) */
|
|
33
|
+
labelClass?: string;
|
|
34
|
+
errClass?: string;
|
|
35
|
+
hintClass?: string;
|
|
36
|
+
reqClass?: string;
|
|
37
|
+
/** 必填星字符(默认 *) */
|
|
38
|
+
reqChar?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface FieldHandle {
|
|
41
|
+
/** 包装与否(无 label/error/hint = 裸输入——Input 先例) */
|
|
42
|
+
hasWrap: boolean;
|
|
43
|
+
/** 错误态类('' 或 ' --err'——组件拼到 wrap class) */
|
|
44
|
+
stateClass: string;
|
|
45
|
+
/** 输入 id(name/id 提供时——label for 连接) */
|
|
46
|
+
inputId: string | undefined;
|
|
47
|
+
/** 输入面(id/aria-invalid/aria-describedby/aria-required) */
|
|
48
|
+
inputProps(): Record<string, unknown>;
|
|
49
|
+
renderLabel(): VNode | null;
|
|
50
|
+
renderError(): VNode | null;
|
|
51
|
+
renderHint(): VNode | null;
|
|
52
|
+
}
|
|
53
|
+
/** 表单字段契约(mount 期调用;opts 渲染期读最新——闭包引用) */
|
|
54
|
+
export declare function useField(env: HookEnv, optsIn: FieldOptions): FieldHandle;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom hooks — useOverlay(弹层行为契约——开/关/焦点/滚动锁/Esc 单源)
|
|
3
|
+
*
|
|
4
|
+
* 设计(2027-09——分层抽象 W2):弹层家族(Modal/Drawer/ActionSheet)的
|
|
5
|
+
* 行为面(open 同步 openPopup 生命周期 · trapFocus · lockScroll ·
|
|
6
|
+
* 遮罩点击 · Esc 关闭 · presence 退场)**契约化**——组件作者只写**皮**
|
|
7
|
+
* (overlay/panel 的 class 与内容)——行为正确性由契约结构性保证。
|
|
8
|
+
*
|
|
9
|
+
* 分工(与 popup-manager 的关系):useOverlay 是 popup-manager(openPopup)
|
|
10
|
+
* 的**组件作者友好封装**(受控同步模式 Modal 先例的契约化)——float 定位
|
|
11
|
+
* 族(Popover/Tooltip)不在此契约(正交组合 usePopupPosition——未来
|
|
12
|
+
* usePopover 契约 = useOverlay + usePopupPosition)。
|
|
13
|
+
*
|
|
14
|
+
* 用法:
|
|
15
|
+
* const ov = ctx.ui.useOverlay({ open, onOpenChange, role: 'dialog', maskClosable })
|
|
16
|
+
* const root = h('div', { class: 'wf-modal' }, [
|
|
17
|
+
* h('div', { ...ov.maskProps, class: 'wf-modal-overlay' }),
|
|
18
|
+
* h('div', { ...ov.panelProps, class: 'wf-modal-content' }, content),
|
|
19
|
+
* ])
|
|
20
|
+
* ov.sync(root) // 渲染期同步(openPopup 生命周期)
|
|
21
|
+
* return root
|
|
22
|
+
*/
|
|
23
|
+
import type { HookEnv } from './env.ts';
|
|
24
|
+
import type { VNode } from '../core/vnode.ts';
|
|
25
|
+
export interface OverlayOptions {
|
|
26
|
+
/** 受控 open(父层) */
|
|
27
|
+
open?: boolean;
|
|
28
|
+
/** 关闭上抛(遮罩/Esc/close()) */
|
|
29
|
+
onOpenChange?: (v: boolean) => void;
|
|
30
|
+
/** 面板角色(默认 dialog——alertdialog 场景覆盖) */
|
|
31
|
+
role?: string;
|
|
32
|
+
/** Tab 焦点困禁(默认 true——`{...panelProps}` 面板内循环) */
|
|
33
|
+
trapFocus?: boolean;
|
|
34
|
+
/** 滚动锁(默认 true——body 锁定 + 焦点归还) */
|
|
35
|
+
lockScroll?: boolean;
|
|
36
|
+
/** 遮罩点击关闭(默认 true——危险确认 false) */
|
|
37
|
+
maskClosable?: boolean;
|
|
38
|
+
/** Esc 关闭(默认 true——危险确认可 false) */
|
|
39
|
+
closeOnEscape?: boolean;
|
|
40
|
+
/** presence 退场动画(退场 class → animationend → 卸载) */
|
|
41
|
+
presence?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface OverlayHandle {
|
|
44
|
+
/** 遮罩面(onClick 行为——类名是皮——组件拼接) */
|
|
45
|
+
maskProps: {
|
|
46
|
+
onClick?: (e: Event) => void;
|
|
47
|
+
};
|
|
48
|
+
/** 面板面(role/aria-modal——类名是皮) */
|
|
49
|
+
panelProps: {
|
|
50
|
+
role: string;
|
|
51
|
+
'aria-modal': true;
|
|
52
|
+
};
|
|
53
|
+
/** 关闭(上抛 onOpenChange(false)) */
|
|
54
|
+
close(): void;
|
|
55
|
+
/** 渲染期同步(openPopup 生命周期——open 变化/内容更新;latestOpts
|
|
56
|
+
* 渲染期最新配置——缺省用 mount 初值) */
|
|
57
|
+
sync(root: () => VNode, latestOpts?: OverlayOptions): void;
|
|
58
|
+
}
|
|
59
|
+
/** 弹层行为契约(mount 期调用——状态闭包;sync 渲染期调用) */
|
|
60
|
+
export declare function useOverlay(env: HookEnv, opts: OverlayOptions): OverlayHandle;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom hooks — useSignal(局部状态原语——setter 自动重渲染)
|
|
3
|
+
*
|
|
4
|
+
* 设计(2027-09——分层抽象 W1):组件层 260 处手动 `ctx.render()` 实证——
|
|
5
|
+
* 状态变更必须手动触发渲染(忘了 = 界面不动——`setter` 自动重渲染消灭
|
|
6
|
+
* 该类 bug)。心智对齐主流(useState 半同构)但保持 getter 纪律:
|
|
7
|
+
* `get()` 任意位置读最新(getter 规则同 useMedia/useBreakpoint——
|
|
8
|
+
* mount 闭包持有永远最新)。
|
|
9
|
+
*
|
|
10
|
+
* 形态:`useSignal(init) → { get, set }`
|
|
11
|
+
* - set(v):v 为值或函数((prev) => next——函数式更新)
|
|
12
|
+
* - set 自动 requestRender(组件重渲染——get 读到新值)
|
|
13
|
+
* - 跨渲染保持(hook 状态缓存——mount 闭包同先例)
|
|
14
|
+
* - **语义**:signal 是**增量原语**(不取代 ctx.render() 的既有用法——
|
|
15
|
+
* 新组件/维护组件推荐;存量保留)
|
|
16
|
+
*/
|
|
17
|
+
import type { HookEnv } from './env.ts';
|
|
18
|
+
export interface SignalHandle<T> {
|
|
19
|
+
/** 读最新(任意位置——getter 纪律) */
|
|
20
|
+
get(): T;
|
|
21
|
+
/** 写(值或函数式更新)——自动重渲染 */
|
|
22
|
+
set(v: T | ((prev: T) => T)): void;
|
|
23
|
+
}
|
|
24
|
+
/** 局部状态原语(mount 期调用一次——hook 状态缓存保持) */
|
|
25
|
+
export declare function useSignal<T>(env: HookEnv, init: T): SignalHandle<T>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* weifuwu/vdom — 新版本 vdom 公共面(独立实现区)
|
|
2
|
+
* weifuwu/client/vdom — 新版本 vdom 公共面(独立实现区)
|
|
3
3
|
*
|
|
4
4
|
* 决策(2026-12):
|
|
5
5
|
* - ui-dom 保持不变——本目录**完全独立实现**(零引用 ui-dom——不 re-export)——
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* 5. core/html(commandToHtml——流式 SSR)——待
|
|
39
39
|
* 6. hooks/browser/middlewares 独立实现——待
|
|
40
40
|
*/
|
|
41
|
-
export { h, jsx, jsxs, jsxDEV } from './core/vnode.ts';
|
|
41
|
+
export { h, jsx, jsxs, jsxDEV, normalizeClass } from './core/vnode.ts';
|
|
42
42
|
export { keyOf, keyedId } from './core/node/keyed.ts';
|
|
43
43
|
export { Fragment } from './core/node/fragment.ts';
|
|
44
44
|
export { UIRouter } from './core/router.ts';
|
|
@@ -50,6 +50,9 @@ export type { Component, RenderFn, VNode, VNodeChild } from './core/vnode.ts';
|
|
|
50
50
|
export type { Ui } from './hooks/env.ts';
|
|
51
51
|
/** 页面作者渲染入口(ctx.stream——vnode → Response 命令流) */
|
|
52
52
|
export type { RenderCtx } from './core/protocol.ts';
|
|
53
|
+
export { useSignal, type SignalHandle } from './hooks/signal.ts';
|
|
54
|
+
export { useOverlay, type OverlayOptions, type OverlayHandle } from './hooks/overlay.ts';
|
|
55
|
+
export { useField, type FieldOptions, type FieldHandle } from './hooks/field.ts';
|
|
53
56
|
export type { Browser } from './browser/Browser.ts';
|
|
54
57
|
export type { ApiClient } from './middlewares/api.ts';
|
|
55
58
|
export type { AuthClient, I18nState } from './middlewares/auth-i18n.ts';
|
|
@@ -63,6 +66,10 @@ export { renderToStreamV2 as renderToStream } from './core/v2/integrate.ts';
|
|
|
63
66
|
export { diffToStreamV2 as diffStream } from './core/v2/integrate.ts';
|
|
64
67
|
export { CommandApplier } from './core/patch/index.ts';
|
|
65
68
|
export { createComponentRegistry } from './core/node/component.ts';
|
|
69
|
+
export { createItem } from './core/create-item.ts';
|
|
70
|
+
export type { ItemStateDecl } from './core/create-item.ts';
|
|
71
|
+
export { createComponent } from './core/create-component.ts';
|
|
72
|
+
export type { CreateComponentDecl } from './core/create-component.ts';
|
|
66
73
|
export { aiStream } from './hooks/ai-stream.ts';
|
|
67
74
|
export type { AiStreamHandle } from './hooks/ai-stream.ts';
|
|
68
75
|
export type { ExternalStore } from './store.ts';
|