weifuwu 0.75.0 → 0.76.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 +13 -13
- package/dist/ai/types.d.ts +2 -0
- package/dist/components/AiChat/AiChat.d.ts +5 -1
- package/dist/components/ApprovalCard/ApprovalCard.d.ts +5 -2
- package/dist/components/CitationCard/CitationCard.d.ts +38 -0
- package/dist/components/Command/Command.d.ts +1 -1
- package/dist/components/JsonSchemaForm/JsonSchemaForm.d.ts +48 -0
- package/dist/components/ReasoningBlock/ReasoningBlock.d.ts +25 -0
- package/dist/components/Select/Select.d.ts +11 -1
- package/dist/components/SessionList/SessionList.d.ts +42 -0
- package/dist/components/TreeSelect/TreeSelect.d.ts +3 -2
- package/dist/components/index.d.ts +10 -2
- package/dist/components/index.js +14 -14
- package/dist/components/style.css +608 -20
- package/dist/index.js +140 -311
- package/dist/layout/weifuwu-layout.css +9 -0
- package/dist/test/client/setup.d.ts +12 -0
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui-dom/Confirm.d.ts +5 -41
- package/dist/ui-dom/Notification.d.ts +8 -70
- package/dist/ui-dom/Toast.d.ts +8 -43
- package/dist/ui-dom/hooks/chat.d.ts +11 -0
- package/dist/ui-dom/hooks/events.d.ts +30 -0
- package/dist/ui-dom/hooks/external.d.ts +20 -0
- package/dist/ui-dom/hooks/index.d.ts +31 -0
- package/dist/ui-dom/hooks/input.d.ts +33 -0
- package/dist/ui-dom/hooks/media.d.ts +17 -0
- package/dist/ui-dom/hooks/popup.d.ts +37 -0
- package/dist/ui-dom/hooks/stable.d.ts +39 -0
- package/dist/ui-dom/hooks/test/hooks.test.d.ts +1 -0
- package/dist/ui-dom/hooks/types.d.ts +78 -0
- package/dist/ui-dom/index.d.ts +19 -17
- package/dist/ui-dom/index.js +11 -11
- package/dist/ui-dom/jsx-runtime.js +1 -1
- package/dist/ui-dom/store.d.ts +24 -0
- package/dist/ui-dom/testing.d.ts +74 -0
- package/dist/ui-dom/testing.js +1 -0
- package/dist/ui-dom/testing.test.d.ts +1 -0
- package/dist/ui-dom/types.d.ts +28 -11
- package/dist/ui-dom/use-chat.d.ts +19 -14
- package/dist/ui-dom/vdom/build.d.ts +34 -0
- package/dist/ui-dom/vdom/diff.d.ts +34 -0
- package/dist/ui-dom/vdom/hydration.d.ts +17 -0
- package/dist/ui-dom/vdom/index.d.ts +23 -0
- package/dist/ui-dom/vdom/mount.d.ts +49 -0
- package/dist/ui-dom/vdom/registry.d.ts +27 -0
- package/dist/ui-dom/vdom/render.d.ts +13 -0
- package/dist/ui-dom/vdom/scheduler.d.ts +13 -0
- package/dist/ui-dom/vdom/serve.d.ts +30 -0
- package/dist/ui-dom/vdom/ssr.d.ts +44 -0
- package/dist/ui-dom/vnode.d.ts +9 -26
- package/docs/components-map.md +18 -1
- package/docs/components.md +9 -4
- package/docs/custom-components.md +14 -8
- package/docs/frontend.md +2 -2
- package/docs/layout.md +2 -2
- package/package.json +5 -1
- package/dist/ui/ssr.d.ts +0 -35
- package/dist/ui-dom/diff.d.ts +0 -28
- package/dist/ui-dom/hydration.d.ts +0 -13
- package/dist/ui-dom/reactive.d.ts +0 -6
- package/dist/ui-dom/registry.d.ts +0 -27
- package/dist/ui-dom/render.d.ts +0 -46
- package/dist/ui-dom/serve.d.ts +0 -28
- package/dist/ui-dom/ssr.d.ts +0 -57
- package/dist/ui-dom/ui.d.ts +0 -78
package/dist/index.js
CHANGED
|
@@ -3540,7 +3540,7 @@ function createAgent(client, config) {
|
|
|
3540
3540
|
if (signal?.aborted) return;
|
|
3541
3541
|
if (!finish.toolCalls?.length) {
|
|
3542
3542
|
emit("wf:usage", usage);
|
|
3543
|
-
emit("wf:done", { content: finish.content, usage });
|
|
3543
|
+
emit("wf:done", { content: finish.content, usage, reasoning: finish.reasoning_content });
|
|
3544
3544
|
return;
|
|
3545
3545
|
}
|
|
3546
3546
|
all.push({
|
|
@@ -3641,311 +3641,24 @@ var HtmlSafe = class {
|
|
|
3641
3641
|
var Fragment = /* @__PURE__ */ Symbol("Fragment");
|
|
3642
3642
|
var Portal = /* @__PURE__ */ Symbol("Portal");
|
|
3643
3643
|
|
|
3644
|
-
// src/ui-dom/
|
|
3645
|
-
var
|
|
3646
|
-
|
|
3647
|
-
if (_enabled !== null) return _enabled;
|
|
3648
|
-
_enabled = typeof process !== "undefined" && process.env?.UI_DEBUG === "1" || globalThis.__UI_DEBUG === true || typeof localStorage !== "undefined" && localStorage.getItem("__UI_DEBUG") === "1";
|
|
3649
|
-
return _enabled;
|
|
3650
|
-
}
|
|
3651
|
-
var _depth = 0;
|
|
3652
|
-
var counters = /* @__PURE__ */ new Map();
|
|
3653
|
-
function uiLog(label, msg, opts) {
|
|
3654
|
-
if (!uiDebugEnabled()) return;
|
|
3655
|
-
const n = (counters.get(label) ?? 0) + 1;
|
|
3656
|
-
counters.set(label, n);
|
|
3657
|
-
const first = 10;
|
|
3658
|
-
const every = opts?.throttle ?? 100;
|
|
3659
|
-
if (n > first && n % every !== 0) return;
|
|
3660
|
-
const d = opts?.depth !== void 0 ? opts.depth : _depth;
|
|
3661
|
-
const indent = " ".repeat(Math.min(d, 30));
|
|
3662
|
-
console.log(`[ui-debug] ${indent}${label}#${n} ${msg}`);
|
|
3663
|
-
}
|
|
3664
|
-
|
|
3665
|
-
// src/ui-dom/reactive.ts
|
|
3666
|
-
function createReactiveState(dirty) {
|
|
3667
|
-
const _debugSets = /* @__PURE__ */ new Map();
|
|
3668
|
-
const _dbg = (key, label) => {
|
|
3669
|
-
const n = (_debugSets.get(key) ?? 0) + 1;
|
|
3670
|
-
_debugSets.set(key, n);
|
|
3671
|
-
if (n <= 5 || n % 100 === 0) uiLog(label, key + " count=" + n, { throttle: 100 });
|
|
3672
|
-
};
|
|
3673
|
-
const proxyCache = /* @__PURE__ */ new WeakMap();
|
|
3674
|
-
const watchers = /* @__PURE__ */ new Set();
|
|
3675
|
-
const reactive = (target) => {
|
|
3676
|
-
if (target === null || typeof target !== "object") return target;
|
|
3677
|
-
if (target instanceof Set || target instanceof Map) {
|
|
3678
|
-
if (proxyCache.has(target)) return proxyCache.get(target);
|
|
3679
|
-
const MUTATING = target instanceof Set ? /* @__PURE__ */ new Set(["add", "delete", "clear"]) : /* @__PURE__ */ new Set(["set", "delete", "clear"]);
|
|
3680
|
-
const proxy2 = new Proxy(target, {
|
|
3681
|
-
get(t, prop) {
|
|
3682
|
-
const v = Reflect.get(t, prop);
|
|
3683
|
-
if (typeof v === "function") {
|
|
3684
|
-
if (!MUTATING.has(String(prop))) return v.bind(t);
|
|
3685
|
-
return (...args) => {
|
|
3686
|
-
const result = v.apply(t, args);
|
|
3687
|
-
dirty();
|
|
3688
|
-
for (const w of watchers) w();
|
|
3689
|
-
return result;
|
|
3690
|
-
};
|
|
3691
|
-
}
|
|
3692
|
-
return v;
|
|
3693
|
-
},
|
|
3694
|
-
set(t, key, value) {
|
|
3695
|
-
Reflect.set(t, key, value);
|
|
3696
|
-
_dbg(String(key), "set");
|
|
3697
|
-
dirty();
|
|
3698
|
-
for (const w of watchers) w();
|
|
3699
|
-
return true;
|
|
3700
|
-
}
|
|
3701
|
-
});
|
|
3702
|
-
proxyCache.set(target, proxy2);
|
|
3703
|
-
return proxy2;
|
|
3704
|
-
}
|
|
3705
|
-
if (target instanceof Date || target instanceof RegExp) return target;
|
|
3706
|
-
if (proxyCache.has(target)) return proxyCache.get(target);
|
|
3707
|
-
const proxy = new Proxy(target, {
|
|
3708
|
-
set(target2, key, value) {
|
|
3709
|
-
const old = Reflect.get(target2, key);
|
|
3710
|
-
if (old === value) return true;
|
|
3711
|
-
Reflect.set(target2, key, value);
|
|
3712
|
-
dirty();
|
|
3713
|
-
for (const w of watchers) w();
|
|
3714
|
-
return true;
|
|
3715
|
-
},
|
|
3716
|
-
get(target2, key) {
|
|
3717
|
-
const value = Reflect.get(target2, key);
|
|
3718
|
-
if (typeof value === "object" && value !== null) return reactive(value);
|
|
3719
|
-
return value;
|
|
3720
|
-
},
|
|
3721
|
-
deleteProperty(target2, key) {
|
|
3722
|
-
if (Reflect.has(target2, key)) {
|
|
3723
|
-
Reflect.deleteProperty(target2, key);
|
|
3724
|
-
dirty();
|
|
3725
|
-
for (const w of watchers) w();
|
|
3726
|
-
}
|
|
3727
|
-
return true;
|
|
3728
|
-
}
|
|
3729
|
-
});
|
|
3730
|
-
proxyCache.set(target, proxy);
|
|
3731
|
-
return proxy;
|
|
3732
|
-
};
|
|
3733
|
-
const root = reactive({});
|
|
3734
|
-
Object.defineProperty(root, "__watch", {
|
|
3735
|
-
value: (cb) => {
|
|
3736
|
-
watchers.add(cb);
|
|
3737
|
-
return () => {
|
|
3738
|
-
watchers.delete(cb);
|
|
3739
|
-
};
|
|
3740
|
-
},
|
|
3741
|
-
writable: false,
|
|
3742
|
-
enumerable: false
|
|
3743
|
-
});
|
|
3744
|
-
return root;
|
|
3745
|
-
}
|
|
3746
|
-
|
|
3747
|
-
// src/ui/ssr.ts
|
|
3644
|
+
// src/ui-dom/vdom/ssr.ts
|
|
3645
|
+
var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
3646
|
+
var SVG_TAGS = /* @__PURE__ */ new Set(["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "text", "defs", "use", "clipPath"]);
|
|
3748
3647
|
function escape(s) {
|
|
3749
3648
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
3750
3649
|
}
|
|
3751
|
-
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
3752
|
-
"area",
|
|
3753
|
-
"base",
|
|
3754
|
-
"br",
|
|
3755
|
-
"col",
|
|
3756
|
-
"embed",
|
|
3757
|
-
"hr",
|
|
3758
|
-
"img",
|
|
3759
|
-
"input",
|
|
3760
|
-
"link",
|
|
3761
|
-
"meta",
|
|
3762
|
-
"param",
|
|
3763
|
-
"source",
|
|
3764
|
-
"track",
|
|
3765
|
-
"wbr"
|
|
3766
|
-
]);
|
|
3767
3650
|
function classToString(v) {
|
|
3768
3651
|
if (typeof v === "string") return v;
|
|
3769
3652
|
if (Array.isArray(v)) return v.filter(Boolean).join(" ");
|
|
3770
|
-
if (v && typeof v === "object")
|
|
3771
|
-
return Object.entries(v).filter(([, b]) => b).map(([k]) => k).join(" ");
|
|
3772
|
-
}
|
|
3653
|
+
if (v && typeof v === "object") return Object.entries(v).filter(([, on]) => on).map(([k]) => k).join(" ");
|
|
3773
3654
|
return "";
|
|
3774
3655
|
}
|
|
3775
3656
|
function styleToString(v) {
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
}
|
|
3782
|
-
function createSsrContext(serverCtx, dataStore) {
|
|
3783
|
-
const usedIds = /* @__PURE__ */ new Set();
|
|
3784
|
-
const ui2 = {
|
|
3785
|
-
$: () => createReactiveState(() => {
|
|
3786
|
-
}),
|
|
3787
|
-
dirty: () => {
|
|
3788
|
-
},
|
|
3789
|
-
render: () => {
|
|
3790
|
-
},
|
|
3791
|
-
selfId: (name) => {
|
|
3792
|
-
if (usedIds.has(name)) throw new Error(`[weifuwu] Duplicate component ID: "${name}"`);
|
|
3793
|
-
usedIds.add(name);
|
|
3794
|
-
},
|
|
3795
|
-
useMedia: () => {
|
|
3796
|
-
},
|
|
3797
|
-
useBreakpoint: () => {
|
|
3798
|
-
},
|
|
3799
|
-
usePopupPosition: () => ({ top: 0, left: 0, refresh: () => {
|
|
3800
|
-
} }),
|
|
3801
|
-
// 新原语族:SSR 确定性 no-op(不启动监听/会话/取数;组件挂载不崩即契约)
|
|
3802
|
-
useHoverCapable: () => false,
|
|
3803
|
-
useVisualViewport: () => ({ height: 0, offsetTop: 0, keyboardOpen: false }),
|
|
3804
|
-
useLongPress: () => ({}),
|
|
3805
|
-
useInView: () => ({ isIn: false, ready: false, observe: () => {
|
|
3806
|
-
}, refresh: () => {
|
|
3807
|
-
}, disconnect: () => {
|
|
3808
|
-
} }),
|
|
3809
|
-
useScrollPosition: () => ({ y: 0, refresh: () => {
|
|
3810
|
-
} }),
|
|
3811
|
-
useStableRef: (init) => (el) => {
|
|
3812
|
-
if (el) init?.(el);
|
|
3813
|
-
},
|
|
3814
|
-
useGlobalKey: () => () => {
|
|
3815
|
-
},
|
|
3816
|
-
useReducedMotion: () => false,
|
|
3817
|
-
useAnimationEnd: () => () => {
|
|
3818
|
-
},
|
|
3819
|
-
useTween: (target) => {
|
|
3820
|
-
const handle = { value: target, reset: (to) => {
|
|
3821
|
-
handle.value = to;
|
|
3822
|
-
} };
|
|
3823
|
-
return handle;
|
|
3824
|
-
},
|
|
3825
|
-
useDrag: () => ({ onPointerDown: () => {
|
|
3826
|
-
} }),
|
|
3827
|
-
useDragDrop: () => ({ dropProps: {}, dragProps: {} }),
|
|
3828
|
-
useControlled: (options) => ({
|
|
3829
|
-
value: options.value,
|
|
3830
|
-
setValue: (v) => {
|
|
3831
|
-
options.onChange?.(v);
|
|
3832
|
-
},
|
|
3833
|
-
controlled: options.value !== void 0
|
|
3834
|
-
}),
|
|
3835
|
-
useControlledInput: (options) => ({
|
|
3836
|
-
value: options.value,
|
|
3837
|
-
setValue: (v) => {
|
|
3838
|
-
options.onChange?.(v);
|
|
3839
|
-
},
|
|
3840
|
-
controlled: options.value !== void 0,
|
|
3841
|
-
keyword: "",
|
|
3842
|
-
setKeyword: () => {
|
|
3843
|
-
},
|
|
3844
|
-
selectedLabel: "",
|
|
3845
|
-
setSelectedLabel: () => {
|
|
3846
|
-
}
|
|
3847
|
-
}),
|
|
3848
|
-
useOpen: (options) => ({
|
|
3849
|
-
get open() {
|
|
3850
|
-
return !!options.open;
|
|
3851
|
-
},
|
|
3852
|
-
setOpen: (v) => {
|
|
3853
|
-
options.onOpenChange?.(v);
|
|
3854
|
-
},
|
|
3855
|
-
triggerProps: {}
|
|
3856
|
-
}),
|
|
3857
|
-
useAsync: () => ({ data: void 0, loading: true, error: void 0, reload: () => {
|
|
3858
|
-
} }),
|
|
3859
|
-
usePopup: () => ({
|
|
3860
|
-
open: false,
|
|
3861
|
-
setOpen: () => {
|
|
3862
|
-
},
|
|
3863
|
-
wrapProps: {},
|
|
3864
|
-
portal: () => null,
|
|
3865
|
-
refresh: () => {
|
|
3866
|
-
}
|
|
3867
|
-
}),
|
|
3868
|
-
usePresence: () => ({
|
|
3869
|
-
phase: "closed",
|
|
3870
|
-
ref: () => {
|
|
3871
|
-
},
|
|
3872
|
-
sync: (open2) => open2 ? "open" : "closed"
|
|
3873
|
-
}),
|
|
3874
|
-
useDialog: () => ({
|
|
3875
|
-
phase: "closed",
|
|
3876
|
-
rootRef: () => {
|
|
3877
|
-
},
|
|
3878
|
-
panelRef: () => {
|
|
3879
|
-
},
|
|
3880
|
-
sync: (open2) => open2 ? "open" : "closed"
|
|
3881
|
-
}),
|
|
3882
|
-
// SSR 确定性空态:会话不启动(无事件/无网络),仅保证挂载不崩
|
|
3883
|
-
useChat: () => ({
|
|
3884
|
-
messages: [],
|
|
3885
|
-
input: "",
|
|
3886
|
-
streaming: false,
|
|
3887
|
-
error: null,
|
|
3888
|
-
usage: null,
|
|
3889
|
-
step: null,
|
|
3890
|
-
send: () => {
|
|
3891
|
-
},
|
|
3892
|
-
stop: () => {
|
|
3893
|
-
},
|
|
3894
|
-
retry: () => {
|
|
3895
|
-
},
|
|
3896
|
-
clear: () => {
|
|
3897
|
-
},
|
|
3898
|
-
approve: async () => {
|
|
3899
|
-
},
|
|
3900
|
-
dispose: () => {
|
|
3901
|
-
}
|
|
3902
|
-
})
|
|
3903
|
-
};
|
|
3904
|
-
const browser = {
|
|
3905
|
-
activeElement: () => null,
|
|
3906
|
-
byId: () => null,
|
|
3907
|
-
query: () => null,
|
|
3908
|
-
createElement: () => null,
|
|
3909
|
-
bodyAppend: () => {
|
|
3910
|
-
},
|
|
3911
|
-
bodyRemove: () => {
|
|
3912
|
-
},
|
|
3913
|
-
copyText: async () => false,
|
|
3914
|
-
execCommand: () => false,
|
|
3915
|
-
selectionText: () => null,
|
|
3916
|
-
getSelection: () => null,
|
|
3917
|
-
queryCommandState: () => false,
|
|
3918
|
-
queryCommandValue: () => "",
|
|
3919
|
-
viewportHeight: () => 0,
|
|
3920
|
-
scrollTop: () => 0,
|
|
3921
|
-
hash: () => "",
|
|
3922
|
-
setHash: () => {
|
|
3923
|
-
},
|
|
3924
|
-
timeout: () => 0,
|
|
3925
|
-
rootElement: () => null,
|
|
3926
|
-
storageGet: () => null,
|
|
3927
|
-
storageSet: () => {
|
|
3928
|
-
}
|
|
3929
|
-
};
|
|
3930
|
-
const ctx = Object.create(serverCtx ?? {});
|
|
3931
|
-
ctx.ui = ui2;
|
|
3932
|
-
ctx.browser = browser;
|
|
3933
|
-
ctx.data = {
|
|
3934
|
-
async get(key, fetcher) {
|
|
3935
|
-
if (dataStore.has(key)) return dataStore.get(key);
|
|
3936
|
-
if (!fetcher) return void 0;
|
|
3937
|
-
const val = await fetcher();
|
|
3938
|
-
dataStore.set(key, val);
|
|
3939
|
-
return val;
|
|
3940
|
-
},
|
|
3941
|
-
set(key, val) {
|
|
3942
|
-
dataStore.set(key, val);
|
|
3943
|
-
},
|
|
3944
|
-
has(key) {
|
|
3945
|
-
return dataStore.has(key);
|
|
3946
|
-
}
|
|
3947
|
-
};
|
|
3948
|
-
return ctx;
|
|
3657
|
+
return Object.entries(v).filter(([, val]) => val != null).map(([k, val]) => {
|
|
3658
|
+
const key = k.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
|
|
3659
|
+
const value = typeof val === "number" && val !== 0 ? `${val}px` : String(val);
|
|
3660
|
+
return `${key}:${value}`;
|
|
3661
|
+
}).join(";");
|
|
3949
3662
|
}
|
|
3950
3663
|
async function renderSsr(input, ctx) {
|
|
3951
3664
|
if (input == null || typeof input === "boolean") return "";
|
|
@@ -3956,17 +3669,10 @@ async function renderSsr(input, ctx) {
|
|
|
3956
3669
|
return s;
|
|
3957
3670
|
}
|
|
3958
3671
|
const vnode = input;
|
|
3959
|
-
if (vnode.type === Portal) return renderSsr(vnode.props?.children, ctx);
|
|
3960
|
-
if (vnode.type === Fragment) return renderSsr(vnode.props?.children, ctx);
|
|
3672
|
+
if (vnode.type === Portal || vnode.type === Fragment) return renderSsr(vnode.props?.children, ctx);
|
|
3961
3673
|
if (typeof vnode.type === "function") {
|
|
3962
3674
|
const childCtx = Object.create(ctx);
|
|
3963
|
-
|
|
3964
|
-
try {
|
|
3965
|
-
renderFn = vnode.type(vnode.props ?? {}, childCtx);
|
|
3966
|
-
} catch (e) {
|
|
3967
|
-
throw e;
|
|
3968
|
-
}
|
|
3969
|
-
if (renderFn instanceof Promise) renderFn = await renderFn;
|
|
3675
|
+
const renderFn = await vnode.type(vnode.props ?? {}, childCtx);
|
|
3970
3676
|
if (typeof renderFn !== "function") {
|
|
3971
3677
|
throw new Error(
|
|
3972
3678
|
`Component ${vnode.type.name || "anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`
|
|
@@ -3995,6 +3701,10 @@ async function renderSsr(input, ctx) {
|
|
|
3995
3701
|
attrs.push(` style="${escape(styleToString(value))}"`);
|
|
3996
3702
|
continue;
|
|
3997
3703
|
}
|
|
3704
|
+
if (key === "draggable" || key === "contenteditable" || key === "spellcheck") {
|
|
3705
|
+
attrs.push(` ${key}="${value ? "true" : "false"}"`);
|
|
3706
|
+
continue;
|
|
3707
|
+
}
|
|
3998
3708
|
if (value === true) {
|
|
3999
3709
|
attrs.push(` ${key}`);
|
|
4000
3710
|
continue;
|
|
@@ -4003,21 +3713,140 @@ async function renderSsr(input, ctx) {
|
|
|
4003
3713
|
attrs.push(` ${key}="${escape(String(value))}"`);
|
|
4004
3714
|
}
|
|
4005
3715
|
const attrStr = attrs.join("");
|
|
3716
|
+
const svgWrap = SVG_TAGS.has(tag);
|
|
4006
3717
|
if (VOID_TAGS.has(tag)) return `<${tag}${attrStr}>`;
|
|
4007
3718
|
if (innerHTML !== void 0) return `<${tag}${attrStr}>${innerHTML}</${tag}>`;
|
|
4008
3719
|
const children = await renderSsr(props.children, ctx);
|
|
3720
|
+
if (svgWrap) return `<${tag}${attrStr}>${children}</${tag}>`;
|
|
4009
3721
|
return `<${tag}${attrStr}>${children}</${tag}>`;
|
|
4010
3722
|
}
|
|
4011
|
-
|
|
4012
|
-
const
|
|
4013
|
-
|
|
4014
|
-
const
|
|
4015
|
-
return
|
|
3723
|
+
function createSsrUi() {
|
|
3724
|
+
const noop = () => () => {
|
|
3725
|
+
};
|
|
3726
|
+
const noopReturn = () => ({});
|
|
3727
|
+
return {
|
|
3728
|
+
_selfId: "_wf_root",
|
|
3729
|
+
render: () => {
|
|
3730
|
+
},
|
|
3731
|
+
dirty: () => {
|
|
3732
|
+
},
|
|
3733
|
+
$: () => ({}),
|
|
3734
|
+
selfId: () => {
|
|
3735
|
+
},
|
|
3736
|
+
bumpCtxVersion: () => {
|
|
3737
|
+
},
|
|
3738
|
+
setMounting: () => {
|
|
3739
|
+
},
|
|
3740
|
+
endMounting: () => {
|
|
3741
|
+
},
|
|
3742
|
+
// hooks no-op(组件 SSR 安全——不注册监听/定时器)
|
|
3743
|
+
useChat: () => ({ messages: [], input: "", streaming: false, error: null, usage: null, step: null, send: () => {
|
|
3744
|
+
}, stop: () => {
|
|
3745
|
+
}, retry: () => {
|
|
3746
|
+
}, clear: () => {
|
|
3747
|
+
}, approve: () => {
|
|
3748
|
+
}, subscribe: () => () => {
|
|
3749
|
+
} }),
|
|
3750
|
+
useExternal: (store) => store,
|
|
3751
|
+
useMedia: noop,
|
|
3752
|
+
useBreakpoint: noop,
|
|
3753
|
+
usePopupPosition: () => ({ top: 0, left: 0, refresh: () => {
|
|
3754
|
+
} }),
|
|
3755
|
+
useHoverCapable: () => false,
|
|
3756
|
+
useStableRef: (init) => (el) => {
|
|
3757
|
+
if (el) init?.(el);
|
|
3758
|
+
},
|
|
3759
|
+
useVisualViewport: () => ({ height: 0, offsetTop: 0, keyboardOpen: false }),
|
|
3760
|
+
usePopup: () => ({ open: false, setOpen: () => {
|
|
3761
|
+
}, wrapProps: {}, portal: () => null, refresh: () => {
|
|
3762
|
+
} }),
|
|
3763
|
+
useLongPress: noopReturn,
|
|
3764
|
+
useInView: () => ({ isIn: false, ready: false, observe: () => {
|
|
3765
|
+
}, refresh: () => {
|
|
3766
|
+
}, disconnect: () => {
|
|
3767
|
+
} }),
|
|
3768
|
+
useScrollPosition: () => ({ y: 0, refresh: () => {
|
|
3769
|
+
} }),
|
|
3770
|
+
useAsync: () => ({ data: void 0, loading: true, error: void 0, reload: () => {
|
|
3771
|
+
} }),
|
|
3772
|
+
useControlled: () => ({ value: void 0, setValue: () => {
|
|
3773
|
+
}, controlled: false }),
|
|
3774
|
+
useControlledInput: () => ({ value: void 0, setValue: () => {
|
|
3775
|
+
}, keyword: "", setKeyword: () => {
|
|
3776
|
+
}, selectedLabel: "", setSelectedLabel: () => {
|
|
3777
|
+
}, controlled: false }),
|
|
3778
|
+
useOpen: () => ({ open: false, setOpen: () => {
|
|
3779
|
+
}, triggerProps: {} }),
|
|
3780
|
+
usePresence: () => ({ phase: "closed", ref: () => {
|
|
3781
|
+
}, sync: () => "closed" }),
|
|
3782
|
+
useDialog: () => ({ phase: "closed", rootRef: () => {
|
|
3783
|
+
}, panelRef: () => {
|
|
3784
|
+
}, sync: (open2) => open2 ? "open" : "closed" }),
|
|
3785
|
+
useGlobalKey: () => () => {
|
|
3786
|
+
},
|
|
3787
|
+
useDrag: noopReturn,
|
|
3788
|
+
useDragDrop: () => ({ dropProps: {}, dragProps: {} }),
|
|
3789
|
+
useReducedMotion: () => true,
|
|
3790
|
+
// SSR 无动画——组件直落终值
|
|
3791
|
+
useAnimationEnd: () => () => {
|
|
3792
|
+
},
|
|
3793
|
+
useTween: (t) => {
|
|
3794
|
+
let v = t;
|
|
3795
|
+
return {
|
|
3796
|
+
get value() {
|
|
3797
|
+
return v;
|
|
3798
|
+
},
|
|
3799
|
+
set value(n) {
|
|
3800
|
+
v = n;
|
|
3801
|
+
},
|
|
3802
|
+
reset: (n) => {
|
|
3803
|
+
if (n !== void 0) v = n;
|
|
3804
|
+
return v;
|
|
3805
|
+
}
|
|
3806
|
+
};
|
|
3807
|
+
}
|
|
3808
|
+
};
|
|
3809
|
+
}
|
|
3810
|
+
function createSsrContext(serverCtx, dataStore) {
|
|
3811
|
+
const ctx = {
|
|
3812
|
+
...serverCtx,
|
|
3813
|
+
ui: createSsrUi(),
|
|
3814
|
+
browser: void 0
|
|
3815
|
+
};
|
|
3816
|
+
const dataCache = /* @__PURE__ */ new Map();
|
|
3817
|
+
ctx.data = {
|
|
3818
|
+
async get(key, fetcher) {
|
|
3819
|
+
const entry = dataCache.get(key);
|
|
3820
|
+
if (entry && "value" in entry) return entry.value;
|
|
3821
|
+
if (entry?.promise) return entry.promise;
|
|
3822
|
+
if (!fetcher) return void 0;
|
|
3823
|
+
const promise = Promise.resolve().then(() => fetcher()).then((val) => {
|
|
3824
|
+
dataCache.set(key, { value: val });
|
|
3825
|
+
dataStore.set(key, val);
|
|
3826
|
+
return val;
|
|
3827
|
+
});
|
|
3828
|
+
dataCache.set(key, { promise });
|
|
3829
|
+
return promise;
|
|
3830
|
+
},
|
|
3831
|
+
set(key, value) {
|
|
3832
|
+
dataCache.set(key, { value });
|
|
3833
|
+
dataStore.set(key, value);
|
|
3834
|
+
},
|
|
3835
|
+
has(key) {
|
|
3836
|
+
return dataCache.has(key);
|
|
3837
|
+
}
|
|
3838
|
+
};
|
|
3839
|
+
return ctx;
|
|
4016
3840
|
}
|
|
4017
3841
|
function serializeData(data) {
|
|
4018
3842
|
const json = JSON.stringify(Object.fromEntries(data)).replace(/</g, "\\u003c");
|
|
4019
3843
|
return `<script>window.__DATA__=${json};</script>`;
|
|
4020
3844
|
}
|
|
3845
|
+
async function ssrToString(Comp, props, serverCtx, opts = {}) {
|
|
3846
|
+
const dataStore = opts.data ?? /* @__PURE__ */ new Map();
|
|
3847
|
+
const ctx = createSsrContext(serverCtx, dataStore);
|
|
3848
|
+
return renderSsr({ type: Comp, props: props ?? {}, key: void 0 }, ctx);
|
|
3849
|
+
}
|
|
4021
3850
|
|
|
4022
3851
|
// src/ui/index.ts
|
|
4023
3852
|
function escape2(s) {
|
|
@@ -852,6 +852,15 @@ body.wf-dragging {
|
|
|
852
852
|
max-width: min(var(--wf-popup-max, 480px), calc(100vw - 32px));
|
|
853
853
|
box-sizing: border-box;
|
|
854
854
|
}
|
|
855
|
+
|
|
856
|
+
/* usePopup mask 模式遮罩:全屏 fixed,z-index 低于面板(overlay=80 < popover=120),
|
|
857
|
+
* 模态语义阻断页面交互;点击遮罩关闭(maskClosable 门控在组件层) */
|
|
858
|
+
.wf-popup-mask {
|
|
859
|
+
position: fixed;
|
|
860
|
+
inset: 0;
|
|
861
|
+
z-index: var(--wf-z-overlay);
|
|
862
|
+
background: var(--wf-overlay);
|
|
863
|
+
}
|
|
855
864
|
}
|
|
856
865
|
|
|
857
866
|
@layer layout {
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
import type { Middleware } from '../types.ts';
|
|
29
|
-
import type { Component
|
|
29
|
+
import type { Component } from '../ui-dom/vnode.ts';
|
|
30
30
|
declare module '../types.ts' {
|
|
31
31
|
interface Context {
|
|
32
32
|
ui: {
|
|
@@ -41,7 +41,7 @@ declare module '../types.ts' {
|
|
|
41
41
|
* 支持 async 工厂组件:await 工厂 → 数据进 HTML。
|
|
42
42
|
* opts.data(Map)收集 ctx.data 预取结果,用 ctx.ui.ssrData(data) 序列化进 __DATA__。
|
|
43
43
|
*/
|
|
44
|
-
ssr: (Comp: Component
|
|
44
|
+
ssr: (Comp: Component, props?: Record<string, any>, opts?: {
|
|
45
45
|
data?: Map<string, unknown>;
|
|
46
46
|
}) => Promise<string>;
|
|
47
47
|
/** 序列化 SSR 数据存储 → <script>window.__DATA__=...</script>(HtmlSafe) */
|
package/dist/ui-dom/Confirm.d.ts
CHANGED
|
@@ -1,44 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* weifuwu/
|
|
2
|
+
* weifuwu/ui-dom — Confirm(命令式中间件)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* v1 退役(design/render-only-plan.md):实现已收敛到 components/Confirm(vdom 引擎,
|
|
5
|
+
* mountCommand + render-only)。本文件保留为公开 API 兼容入口。
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export interface ConfirmProps {
|
|
10
|
-
open?: boolean;
|
|
11
|
-
title?: string;
|
|
12
|
-
/** 提示内容(文本或任意 VNode) */
|
|
13
|
-
message?: any;
|
|
14
|
-
confirmText?: string;
|
|
15
|
-
cancelText?: string;
|
|
16
|
-
variant?: 'primary' | 'danger';
|
|
17
|
-
/** 对话框宽度,如 '500px'、'80%',默认 Modal 的 400px */
|
|
18
|
-
width?: string;
|
|
19
|
-
/** 遮罩点击是否取消(默认 false:危险操作防误触;显式传 true 可恢复) */
|
|
20
|
-
maskClosable?: boolean;
|
|
21
|
-
onConfirm?: () => void;
|
|
22
|
-
onCancel?: () => void;
|
|
23
|
-
}
|
|
24
|
-
/** 命令式 ctx.confirm 的选项(ConfirmProps 的子集) */
|
|
25
|
-
export interface ConfirmOptions {
|
|
26
|
-
title?: string;
|
|
27
|
-
confirmText?: string;
|
|
28
|
-
cancelText?: string;
|
|
29
|
-
variant?: 'primary' | 'danger';
|
|
30
|
-
width?: string;
|
|
31
|
-
maskClosable?: boolean;
|
|
32
|
-
}
|
|
33
|
-
/** 命令式 ctx.confirm 的注入类型(AppMiddleware<{}, ConfirmInjected>) */
|
|
34
|
-
export interface ConfirmInjected {
|
|
35
|
-
confirm: (message: string, options?: ConfirmOptions) => Promise<boolean>;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 命令式中间件:注入 ctx.confirm()
|
|
39
|
-
*
|
|
40
|
-
* 每次调用挂载 Confirm 组件到独立容器(mountVNode),
|
|
41
|
-
* resolve 后 callRefCleanup 清理(含 Modal 的 portal DOM)+ 移除容器。
|
|
42
|
-
*/
|
|
43
|
-
export declare function confirm(): AppMiddleware<{}, ConfirmInjected>;
|
|
44
|
-
export declare const Confirm: Component<ConfirmProps>;
|
|
7
|
+
export { Confirm, confirm } from '../components/Confirm/Confirm.ts';
|
|
8
|
+
export type { ConfirmProps, ConfirmOptions, ConfirmInjected } from '../components/Confirm/Confirm.ts';
|
|
@@ -1,70 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
description?: string;
|
|
10
|
-
/** 自动关闭时间(ms),0 = 不自动关闭,默认 4500 */
|
|
11
|
-
duration?: number;
|
|
12
|
-
action?: {
|
|
13
|
-
label: string;
|
|
14
|
-
onClick: () => void;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export interface NotificationProps {
|
|
18
|
-
items?: NotificationItem[];
|
|
19
|
-
onRemove?: (id: string) => void;
|
|
20
|
-
position?: NotificationPosition;
|
|
21
|
-
/** 全局默认自动关闭时间(ms),默认 4500 */
|
|
22
|
-
duration?: number;
|
|
23
|
-
/** 最大显示条数,超出移除最早,默认 0 = 不限制 */
|
|
24
|
-
max?: number;
|
|
25
|
-
}
|
|
26
|
-
export interface NotificationOptions {
|
|
27
|
-
position?: NotificationPosition;
|
|
28
|
-
duration?: number;
|
|
29
|
-
max?: number;
|
|
30
|
-
}
|
|
31
|
-
/** 通知(对应 antd/EP Notification 队列式):title + description + icon + 操作,聚合角落 */
|
|
32
|
-
export declare const Notification: Component<NotificationProps>;
|
|
33
|
-
export interface NotificationInjected {
|
|
34
|
-
notification: {
|
|
35
|
-
(title: string, opts?: {
|
|
36
|
-
type?: NotificationType;
|
|
37
|
-
description?: string;
|
|
38
|
-
duration?: number;
|
|
39
|
-
action?: NotificationItem['action'];
|
|
40
|
-
}): void;
|
|
41
|
-
open: (opts: {
|
|
42
|
-
type?: NotificationType;
|
|
43
|
-
title: string;
|
|
44
|
-
description?: string;
|
|
45
|
-
duration?: number;
|
|
46
|
-
action?: NotificationItem['action'];
|
|
47
|
-
}) => void;
|
|
48
|
-
success: (opts: {
|
|
49
|
-
title: string;
|
|
50
|
-
description?: string;
|
|
51
|
-
duration?: number;
|
|
52
|
-
}) => void;
|
|
53
|
-
error: (opts: {
|
|
54
|
-
title: string;
|
|
55
|
-
description?: string;
|
|
56
|
-
duration?: number;
|
|
57
|
-
}) => void;
|
|
58
|
-
info: (opts: {
|
|
59
|
-
title: string;
|
|
60
|
-
description?: string;
|
|
61
|
-
duration?: number;
|
|
62
|
-
}) => void;
|
|
63
|
-
warning: (opts: {
|
|
64
|
-
title: string;
|
|
65
|
-
description?: string;
|
|
66
|
-
duration?: number;
|
|
67
|
-
}) => void;
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
export declare function notification(opts?: NotificationOptions): AppMiddleware<{}, NotificationInjected>;
|
|
1
|
+
/**
|
|
2
|
+
* weifuwu/ui-dom — Notification(命令式中间件)
|
|
3
|
+
*
|
|
4
|
+
* v1 退役(design/render-only-plan.md):实现已收敛到 components/Notification(vdom 引擎,
|
|
5
|
+
* mountCommand + render-only)。本文件保留为公开 API 兼容入口。
|
|
6
|
+
*/
|
|
7
|
+
export { Notification, notification } from '../components/Notification/Notification.ts';
|
|
8
|
+
export type { NotificationType, NotificationPosition, NotificationItem, NotificationProps, NotificationOptions, NotificationInjected, } from '../components/Notification/Notification.ts';
|