@kdesigner/amis-vue 0.0.0-alpha.1

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/dist/index.js ADDED
@@ -0,0 +1,995 @@
1
+ import { PageApis, UserApis, ajaxFetch, bindActions, createPage, default_isCurrentUrl, default_jumpTo, default_updateLocation, deletePageCache, getSchemaProcessorType, isCancel, providePage, transformPageJson, useAdapter, useDebug } from "@kdesigner/core";
2
+ import { deepClone, isString } from "@kdesigner/shared";
3
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, guardReactiveProps, h, markRaw, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, onUnmounted, openBlock, ref, resolveComponent, resolveDynamicComponent, shallowRef, unref, watch, watchEffect, withKeys } from "vue";
4
+ import { FormItem, Renderer, ScopedContext, ToastComponent, clearStoresCache, render, setDefaultLocale, toast } from "amis";
5
+ import React, { Fragment as Fragment$1, createElement } from "react";
6
+ import { applyPureVueInReact } from "veaury";
7
+ import { useRoute } from "vue-router";
8
+ import copy from "copy-to-clipboard";
9
+ import { createRoot } from "react-dom/client";
10
+ import "moment/locale/zh-cn";
11
+ import yaml from "js-yaml";
12
+ import { createObject, resolveVariableAndFilter } from "amis-core";
13
+ import "@kdesigner/amis-extensions/style.css";
14
+ import "@kdesigner/components/style";
15
+ export * from "@kdesigner/core";
16
+ export * from "@kdesigner/components";
17
+ export * from "@kdesigner/amis-extensions";
18
+ //#region \0rolldown/runtime.js
19
+ var __defProp = Object.defineProperty;
20
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
21
+ var __getOwnPropNames = Object.getOwnPropertyNames;
22
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
23
+ var __exportAll = (all, no_symbols) => {
24
+ let target = {};
25
+ for (var name in all) __defProp(target, name, {
26
+ get: all[name],
27
+ enumerable: true
28
+ });
29
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
30
+ return target;
31
+ };
32
+ var __copyProps = (to, from, except, desc) => {
33
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
34
+ key = keys[i];
35
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
36
+ get: ((k) => from[k]).bind(null, key),
37
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
38
+ });
39
+ }
40
+ return to;
41
+ };
42
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
43
+ //#endregion
44
+ //#region src/editor/AmisPageEditor.vue?vue&type=script&lang.ts
45
+ var AmisPageEditor_vue_vue_type_script_lang_default = defineComponent({
46
+ props: {
47
+ schema: Object,
48
+ rollbackPageSource: Function,
49
+ getPageSource: {
50
+ type: Function,
51
+ required: true
52
+ },
53
+ savePageSource: {
54
+ type: Function,
55
+ required: true
56
+ }
57
+ },
58
+ emits: ["exit"],
59
+ setup(props, { emit }) {
60
+ const editorRef = ref(null);
61
+ let fetched = false;
62
+ let editorInited = false;
63
+ const { savePageSource, rollbackPageSource, getPageSource } = props;
64
+ function pushSchema(schema) {
65
+ postMsg({
66
+ type: "setSchema",
67
+ data: schema
68
+ });
69
+ }
70
+ /** 首次初始化:有 schema 直接推;否则自行拉取(宿主已去掉前置 loading) */
71
+ function applyInitialSchema() {
72
+ if (fetched) return;
73
+ if (props.schema != null) {
74
+ fetched = true;
75
+ pushSchema(props.schema);
76
+ return;
77
+ }
78
+ fetched = true;
79
+ getPageSource(true).then((page) => {
80
+ pushSchema(page);
81
+ }).catch((e) => {
82
+ fetched = false;
83
+ postMsg({
84
+ type: "toast",
85
+ level: "error",
86
+ message: e.message || e.toString()
87
+ });
88
+ });
89
+ }
90
+ function handleEvent(event) {
91
+ if (event.data == "amis-editor-inited") {
92
+ editorInited = true;
93
+ applyInitialSchema();
94
+ } else if (event.data === "amis-editor-reload") {
95
+ fetched = false;
96
+ startFetch();
97
+ } else if (event.data === "amis-editor-exit") emit("exit");
98
+ else if (event.data === "amis-editor-rollback") {
99
+ if (rollbackPageSource) rollbackPageSource().then(() => {
100
+ postMsg({
101
+ type: "toast",
102
+ level: "info",
103
+ message: "回滚成功"
104
+ });
105
+ }).catch((e) => {
106
+ postMsg({
107
+ type: "toast",
108
+ level: "error",
109
+ message: e.message || e.toString()
110
+ });
111
+ }).then(() => {
112
+ fetched = false;
113
+ return startFetch();
114
+ });
115
+ } else if (isString(event.data) && event.data.startsWith("{")) {
116
+ var data = JSON.parse(event.data);
117
+ if (data.type == "save") savePageSource(data.data).then(() => {
118
+ postMsg({
119
+ type: "toast",
120
+ message: "保存成功"
121
+ });
122
+ }).catch((e) => {
123
+ postMsg({
124
+ type: "toast",
125
+ level: "error",
126
+ message: e.message || e.toString()
127
+ });
128
+ });
129
+ else if (data.type == "ajaxFetch") ajaxFetch(data.data).then((result) => {
130
+ postMsg({
131
+ type: "ajaxComplete",
132
+ reqId: data.reqId,
133
+ result
134
+ });
135
+ });
136
+ } else console.log("unknown-message", event.data);
137
+ }
138
+ function postMsg(msg) {
139
+ const frame = editorRef.value;
140
+ if (!frame) return;
141
+ const str = isString(msg) ? msg : JSON.stringify(msg);
142
+ frame.contentWindow.postMessage(str, "*");
143
+ }
144
+ function startFetch() {
145
+ if (!editorRef.value) return;
146
+ fetched = true;
147
+ return getPageSource(true).then((page) => {
148
+ postMsg({
149
+ type: "toast",
150
+ level: "info",
151
+ message: "页面加载成功"
152
+ });
153
+ postMsg({
154
+ type: "setSchema",
155
+ data: page
156
+ });
157
+ }).catch((e) => {
158
+ postMsg({
159
+ type: "toast",
160
+ level: "error",
161
+ message: e.message || e.toString()
162
+ });
163
+ throw e;
164
+ });
165
+ }
166
+ window.addEventListener("message", handleEvent);
167
+ watch(() => props.schema, (schema) => {
168
+ if (!editorInited || schema == null) return;
169
+ fetched = true;
170
+ pushSchema(schema);
171
+ });
172
+ onUnmounted(() => {
173
+ console.log("editor unmounted");
174
+ window.removeEventListener("message", handleEvent);
175
+ });
176
+ return { editorRef };
177
+ }
178
+ });
179
+ //#endregion
180
+ //#region \0plugin-vue:export-helper
181
+ var _plugin_vue_export_helper_default = (sfc, props) => {
182
+ const target = sfc.__vccOpts || sfc;
183
+ for (const [key, val] of props) target[key] = val;
184
+ return target;
185
+ };
186
+ //#endregion
187
+ //#region src/editor/AmisPageEditor.vue
188
+ const _hoisted_1$3 = {
189
+ style: {
190
+ "width": "100%",
191
+ "height": "100%",
192
+ "border": "none"
193
+ },
194
+ ref: "editorRef",
195
+ src: "/amis-editor/index.html"
196
+ };
197
+ function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
198
+ return openBlock(), createElementBlock("iframe", _hoisted_1$3, null, 512);
199
+ }
200
+ var AmisPageEditor_default = /*#__PURE__*/ _plugin_vue_export_helper_default(AmisPageEditor_vue_vue_type_script_lang_default, [["render", _sfc_render$3]]);
201
+ //#endregion
202
+ //#region src/editor/XuiPageEditor.vue
203
+ var XuiPageEditor_default = /* @__PURE__ */ defineComponent({
204
+ __name: "XuiPageEditor",
205
+ props: {
206
+ rollbackPageSource: Function,
207
+ getPageSource: {
208
+ type: Function,
209
+ required: true
210
+ },
211
+ savePageSource: {
212
+ type: Function,
213
+ required: true
214
+ }
215
+ },
216
+ emits: ["exit"],
217
+ setup(__props, { emit: __emit }) {
218
+ const props = __props;
219
+ const { getPageSource } = props;
220
+ const { useI18n } = useAdapter();
221
+ const emit = __emit;
222
+ function handleExit() {
223
+ emit("exit");
224
+ }
225
+ const componentType = shallowRef(markRaw(AmisPageEditor_default));
226
+ const schemaRef = shallowRef();
227
+ watchEffect(() => {
228
+ getPageSource(false).then((schema) => {
229
+ if (!schema) schema = {};
230
+ schemaRef.value = markRaw(schema);
231
+ const schemaTypeName = schema["xui:schema-type"];
232
+ if (!schemaTypeName) {
233
+ componentType.value = markRaw(AmisPageEditor_default);
234
+ return;
235
+ }
236
+ const schemaType = getSchemaProcessorType(schemaTypeName);
237
+ if (!schemaType) {
238
+ const { t } = useI18n();
239
+ useAdapter().notify("error", t("nop.err.unknown-schema-type"));
240
+ throw new Error("nop.err.unknown-schema-type");
241
+ }
242
+ componentType.value = markRaw(schemaType.editorComponentType);
243
+ });
244
+ });
245
+ return (_ctx, _cache) => {
246
+ return openBlock(), createBlock(resolveDynamicComponent(componentType.value), mergeProps(props, {
247
+ schema: schemaRef.value,
248
+ onExit: handleExit
249
+ }), null, 16, ["schema"]);
250
+ };
251
+ }
252
+ });
253
+ //#endregion
254
+ //#region src/editor/XuiPageEditorDialog.vue?vue&type=script&setup=true&lang.ts
255
+ const _hoisted_1$2 = {
256
+ key: 0,
257
+ class: "page-editor-root",
258
+ role: "dialog",
259
+ "aria-modal": "true"
260
+ };
261
+ //#endregion
262
+ //#region src/editor/XuiPageEditorDialog.vue
263
+ var XuiPageEditorDialog_default = /* @__PURE__ */ defineComponent({
264
+ __name: "XuiPageEditorDialog",
265
+ props: {
266
+ modelValue: Boolean,
267
+ rollbackPageSource: Function,
268
+ getPageSource: {
269
+ type: Function,
270
+ required: true
271
+ },
272
+ savePageSource: {
273
+ type: Function,
274
+ required: true
275
+ }
276
+ },
277
+ emits: ["update:modelValue", "exit"],
278
+ setup(__props, { emit: __emit }) {
279
+ const props = __props;
280
+ const emit = __emit;
281
+ let prevBodyOverflow = "";
282
+ watch(() => props.modelValue, (open) => {
283
+ if (open) {
284
+ prevBodyOverflow = document.body.style.overflow;
285
+ document.body.style.overflow = "hidden";
286
+ } else document.body.style.overflow = prevBodyOverflow;
287
+ });
288
+ onUnmounted(() => {
289
+ document.body.style.overflow = prevBodyOverflow;
290
+ });
291
+ function handleEditorExit() {
292
+ emit("update:modelValue", false);
293
+ emit("exit");
294
+ }
295
+ return (_ctx, _cache) => {
296
+ return openBlock(), createElementBlock(Fragment, null, [createCommentVNode(" 自绘全屏层:不依赖 element-plus 样式(宿主常未引入) "), (openBlock(), createBlock(Teleport, { to: "body" }, [__props.modelValue ? (openBlock(), createElementBlock("div", _hoisted_1$2, [createVNode(XuiPageEditor_default, {
297
+ savePageSource: __props.savePageSource,
298
+ rollbackPageSource: __props.rollbackPageSource,
299
+ getPageSource: __props.getPageSource,
300
+ onExit: handleEditorExit
301
+ }, null, 8, [
302
+ "savePageSource",
303
+ "rollbackPageSource",
304
+ "getPageSource"
305
+ ])])) : createCommentVNode("v-if", true)]))], 2112);
306
+ };
307
+ }
308
+ });
309
+ //#endregion
310
+ //#region src/editor/XuiLoading.vue
311
+ const _sfc_main = {};
312
+ const _hoisted_1$1 = {
313
+ class: "app-loading",
314
+ role: "status",
315
+ "aria-live": "polite",
316
+ "aria-label": "Loading"
317
+ };
318
+ function _sfc_render$2(_ctx, _cache) {
319
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [..._cache[0] || (_cache[0] = [createElementVNode("div", { class: "app-loading-spinner" }, null, -1)])]);
320
+ }
321
+ var XuiLoading_default = /*#__PURE__*/ _plugin_vue_export_helper_default(_sfc_main, [["render", _sfc_render$2], ["__scopeId", "data-v-a382f6ec"]]);
322
+ //#endregion
323
+ //#region src/runtime/env.ts
324
+ function createEnv(page) {
325
+ const { debug } = useDebug();
326
+ const adapter = useAdapter();
327
+ const env = {
328
+ session: page.id,
329
+ affixOffsetTop: 0,
330
+ fetcher(options) {
331
+ providePage(page);
332
+ options._page = page;
333
+ return ajaxFetch(options);
334
+ },
335
+ jumpTo(to, _action, _ctx) {
336
+ const router = adapter.useRouter();
337
+ return default_jumpTo(router, to);
338
+ },
339
+ isCancel,
340
+ isCurrentUrl: default_isCurrentUrl,
341
+ updateLocation(to, replace) {
342
+ default_updateLocation(to, !!replace);
343
+ },
344
+ notify: adapter.notify,
345
+ enableAMISDebug: debug.value,
346
+ alert: adapter.alert,
347
+ confirm: adapter.confirm,
348
+ copy: (contents, options) => {
349
+ if (options === void 0) options = {};
350
+ const { t } = adapter.useI18n();
351
+ const ret = copy(contents, options);
352
+ if (ret && (!options || options.shutup !== true)) toast.info(t("Copy To Clipboard"));
353
+ return ret;
354
+ }
355
+ };
356
+ env._page = page;
357
+ page.env = env;
358
+ return env;
359
+ }
360
+ //#endregion
361
+ //#region src/runtime/react-adapter.ts
362
+ function defineReactPageComponent(builder) {
363
+ return defineComponent({
364
+ props: {
365
+ schema: Object,
366
+ data: Object,
367
+ registerPage: Function,
368
+ actions: Object
369
+ },
370
+ setup(props) {
371
+ const domRef = ref();
372
+ let root;
373
+ const options = builder({ actions: props.actions });
374
+ const page = createPage(options);
375
+ props.registerPage?.(page);
376
+ function destroyPage() {
377
+ if (root) {
378
+ root.unmount();
379
+ options.onDestroyPage?.(page);
380
+ root = void 0;
381
+ }
382
+ }
383
+ function renderPage() {
384
+ const schema = deepClone(props.schema);
385
+ root = createRoot(domRef.value);
386
+ const r = root;
387
+ Promise.resolve(options.onRenderPage(schema, props.data, page)).then((v) => r.render(v));
388
+ }
389
+ watchEffect(() => {
390
+ destroyPage();
391
+ if (props.schema && domRef.value) renderPage();
392
+ });
393
+ onBeforeUnmount(() => {
394
+ destroyPage();
395
+ return { domRef };
396
+ });
397
+ return () => h("div", {
398
+ ref: domRef,
399
+ style: {
400
+ width: "100%",
401
+ height: "100%"
402
+ },
403
+ class: "nop-page"
404
+ });
405
+ }
406
+ });
407
+ }
408
+ //#endregion
409
+ //#region src/page/AmisSchemaPage.ts
410
+ var AmisSchemaPage_default = defineReactPageComponent((props) => {
411
+ let amisScoped;
412
+ const route = useRoute();
413
+ return {
414
+ actions: props.actions,
415
+ getComponent(name) {
416
+ return get_component(name);
417
+ },
418
+ getScopedStore(name) {
419
+ return get_component(name)?.props?.store;
420
+ },
421
+ getState(name) {
422
+ return get_root_store().get(name);
423
+ },
424
+ setState(name, value) {
425
+ get_root_store().set(name, value);
426
+ },
427
+ onDestroyPage(page) {
428
+ clearStoresCache(page.id);
429
+ },
430
+ async onRenderPage(schema, data, page) {
431
+ const env = createEnv(page);
432
+ const locale = useAdapter().useLocale();
433
+ let globalScopeData = {};
434
+ try {
435
+ globalScopeData = await UserApis.LoginApi__getLoginUserInfo();
436
+ } catch (e) {
437
+ console.error(e);
438
+ }
439
+ const opts = {
440
+ data: {
441
+ ...data,
442
+ globalScopeData,
443
+ route: {
444
+ meta: route.meta,
445
+ path: route.path,
446
+ name: route.name,
447
+ query: route.query,
448
+ params: route.params,
449
+ fullPath: route.fullPath,
450
+ hash: route.hash
451
+ }
452
+ },
453
+ onConfirm: page.getAction("ok") || function() {},
454
+ onClose: function(b) {
455
+ if (b) page.getAction("ok")?.();
456
+ else page.getAction("cancel")?.();
457
+ },
458
+ scopeRef: (scoped) => {
459
+ amisScoped = scoped;
460
+ },
461
+ locale,
462
+ theme: "cxd"
463
+ };
464
+ setDefaultLocale(locale);
465
+ schema = await transformPageJson(schema.__baseUrl, schema);
466
+ await bindActions(schema.__baseUrl, schema, page);
467
+ return render(schema, opts, env);
468
+ }
469
+ };
470
+ function get_root() {
471
+ return amisScoped?.getComponents()[0];
472
+ }
473
+ function get_root_store() {
474
+ return get_root()?.context.store;
475
+ }
476
+ function get_component(name) {
477
+ if (name[0] == "#") {
478
+ const pos = name.indexOf(".");
479
+ if (pos < 0) return get_root()?.context.getComponentById(name.substring(1));
480
+ else return get_root()?.context.getComponentById(name.substring(1)).getComponentByName(name.substring(pos + 1));
481
+ } else return get_root()?.context.getComponentByName(name);
482
+ }
483
+ });
484
+ //#endregion
485
+ //#region src/page/XuiSchemaPage.vue?vue&type=script&lang.ts
486
+ /**
487
+ * 嵌入到vue中的amis页面。每个AmisSchemaPage都对应一个ReactRooot。schema发生变化时会重新创建react组件
488
+ */
489
+ var XuiSchemaPage_vue_vue_type_script_lang_default = defineComponent({
490
+ props: {
491
+ schema: Object,
492
+ data: Object,
493
+ registerPage: Function,
494
+ actions: Object
495
+ },
496
+ setup(props) {
497
+ const { useI18n } = useAdapter();
498
+ let componentType = ref(markRaw(AmisSchemaPage_default));
499
+ watchEffect(() => {
500
+ const schemaTypeName = props.schema?.["xui:schema-type"];
501
+ if (!schemaTypeName) componentType.value = markRaw(AmisSchemaPage_default);
502
+ else {
503
+ const schemaType = getSchemaProcessorType(schemaTypeName);
504
+ if (!schemaType) {
505
+ const { t } = useI18n();
506
+ useAdapter().notify("error", t("nop.err.unknown-schema-type"));
507
+ throw new Error("nop.err.unknown-schema-type");
508
+ }
509
+ componentType.value = markRaw(schemaType.componentType);
510
+ }
511
+ });
512
+ return { componentType };
513
+ }
514
+ });
515
+ //#endregion
516
+ //#region src/page/XuiSchemaPage.vue
517
+ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
518
+ return openBlock(), createBlock(resolveDynamicComponent(_ctx.componentType), normalizeProps(guardReactiveProps(_ctx.$props)), null, 16);
519
+ }
520
+ var XuiSchemaPage_default = /*#__PURE__*/ _plugin_vue_export_helper_default(XuiSchemaPage_vue_vue_type_script_lang_default, [["render", _sfc_render$1]]);
521
+ //#endregion
522
+ //#region src/debug/debugger.ts
523
+ var debugger_default = {
524
+ type: "page",
525
+ "xui:schema": "amis",
526
+ body: {
527
+ type: "form",
528
+ title: null,
529
+ actions: [
530
+ {
531
+ label: "Cancel",
532
+ type: "action",
533
+ actionType: "ajax",
534
+ level: "default",
535
+ api: {
536
+ url: "action://cancel",
537
+ messages: { success: "_" }
538
+ }
539
+ },
540
+ {
541
+ label: "Apply",
542
+ type: "action",
543
+ actionType: "ajax",
544
+ level: "success",
545
+ api: "action://change"
546
+ },
547
+ {
548
+ label: "Yaml/JSON",
549
+ type: "action",
550
+ actionType: "ajax",
551
+ level: "primary",
552
+ api: "action://toggleYaml"
553
+ },
554
+ {
555
+ label: "Submit",
556
+ type: "action",
557
+ actionType: "ajax",
558
+ level: "primary",
559
+ api: "action://ok"
560
+ }
561
+ ],
562
+ body: [{
563
+ type: "editor",
564
+ name: "schema",
565
+ placeholder: "{}",
566
+ visibleOn: "this.lang !='yaml'"
567
+ }, {
568
+ type: "yaml-editor",
569
+ name: "schema",
570
+ placeholder: {},
571
+ visibleOn: "this.lang == 'yaml'"
572
+ }]
573
+ }
574
+ };
575
+ //#endregion
576
+ //#region src/debug/XuiDebugger.vue?vue&type=script&setup=true&lang.ts
577
+ const _hoisted_1 = { class: "schema-modal-panel" };
578
+ const _hoisted_2 = { class: "schema-modal-body" };
579
+ const POSITION_KEY = "kdesigner:xui-debugger-pos";
580
+ //#endregion
581
+ //#region src/page/XuiPage.vue?vue&type=script&lang.ts
582
+ /**
583
+ * 在AmisSchemaPage的基础上增加AmisDebugger调试功能,以及根据path动态加载schema的功能
584
+ */
585
+ var XuiPage_vue_vue_type_script_lang_default = defineComponent({
586
+ name: "amis-page",
587
+ props: {
588
+ path: {
589
+ type: String,
590
+ required: true
591
+ },
592
+ data: Object,
593
+ config: Object,
594
+ registerPage: Function,
595
+ actions: Object
596
+ },
597
+ components: {
598
+ XuiDebugger: /* @__PURE__ */ defineComponent({
599
+ __name: "XuiDebugger",
600
+ props: {
601
+ path: {
602
+ type: String,
603
+ required: true
604
+ },
605
+ schema: Object
606
+ },
607
+ emits: ["update:schema", "rebuild"],
608
+ setup(__props, { emit: __emit }) {
609
+ const props = __props;
610
+ const emit = __emit;
611
+ const schemaVisible = ref(false);
612
+ const designerVisible = ref(false);
613
+ const dragging = ref(false);
614
+ const pos = ref(null);
615
+ let prevBodyOverflow = "";
616
+ const positionStyle = computed(() => {
617
+ if (!pos.value) return void 0;
618
+ return {
619
+ left: `${pos.value.left}px`,
620
+ top: `${pos.value.top}px`,
621
+ right: "auto"
622
+ };
623
+ });
624
+ onMounted(() => {
625
+ try {
626
+ const raw = sessionStorage.getItem(POSITION_KEY);
627
+ if (!raw) return;
628
+ const parsed = JSON.parse(raw);
629
+ if (Number.isFinite(parsed.left) && Number.isFinite(parsed.top)) pos.value = clampPos(parsed.left, parsed.top);
630
+ } catch {}
631
+ });
632
+ onUnmounted(() => {
633
+ restoreBodyScroll();
634
+ });
635
+ watch(schemaVisible, (open) => {
636
+ if (open) lockBodyScroll();
637
+ else restoreBodyScroll();
638
+ });
639
+ function lockBodyScroll() {
640
+ prevBodyOverflow = document.body.style.overflow;
641
+ document.body.style.overflow = "hidden";
642
+ }
643
+ function restoreBodyScroll() {
644
+ document.body.style.overflow = prevBodyOverflow;
645
+ }
646
+ function clampPos(left, top) {
647
+ const maxLeft = Math.max(8, window.innerWidth - 100);
648
+ const maxTop = Math.max(8, window.innerHeight - 48);
649
+ return {
650
+ left: Math.min(Math.max(8, left), maxLeft),
651
+ top: Math.min(Math.max(8, top), maxTop)
652
+ };
653
+ }
654
+ /** 仅手柄可拖;S/V 保持正常 click,避免 pointer capture 吞事件 */
655
+ function onPointerDown(e) {
656
+ if (e.button !== 0 && e.pointerType === "mouse") return;
657
+ e.preventDefault();
658
+ const handle = e.currentTarget;
659
+ const panel = handle.closest(".page-debugger");
660
+ if (!panel) return;
661
+ const rect = panel.getBoundingClientRect();
662
+ const startX = e.clientX;
663
+ const startY = e.clientY;
664
+ const originLeft = rect.left;
665
+ const originTop = rect.top;
666
+ dragging.value = true;
667
+ handle.setPointerCapture(e.pointerId);
668
+ const onMove = (ev) => {
669
+ pos.value = clampPos(originLeft + (ev.clientX - startX), originTop + (ev.clientY - startY));
670
+ };
671
+ const onUp = (ev) => {
672
+ dragging.value = false;
673
+ handle.releasePointerCapture(ev.pointerId);
674
+ handle.removeEventListener("pointermove", onMove);
675
+ handle.removeEventListener("pointerup", onUp);
676
+ handle.removeEventListener("pointercancel", onUp);
677
+ if (pos.value) try {
678
+ sessionStorage.setItem(POSITION_KEY, JSON.stringify(pos.value));
679
+ } catch {}
680
+ };
681
+ handle.addEventListener("pointermove", onMove);
682
+ handle.addEventListener("pointerup", onUp);
683
+ handle.addEventListener("pointercancel", onUp);
684
+ }
685
+ const schemaData = shallowRef({
686
+ schema: "",
687
+ lang: "json"
688
+ });
689
+ const { PageProvider__getPageSource, PageProvider__rollbackPageSource, PageProvider__savePageSource } = PageApis;
690
+ function getPageSource(silent) {
691
+ return PageProvider__getPageSource(props.path, silent);
692
+ }
693
+ function savePageSource(data) {
694
+ deletePageCache(props.path);
695
+ PageProvider__savePageSource(props.path, data, true);
696
+ }
697
+ function rollbackPageSource() {
698
+ PageProvider__rollbackPageSource(props.path, true);
699
+ }
700
+ function openSchemaEditor() {
701
+ schemaData.value = {
702
+ schema: yaml.dump(props.schema),
703
+ lang: "yaml"
704
+ };
705
+ schemaVisible.value = true;
706
+ }
707
+ const schemaActions = {
708
+ ok: handleOk,
709
+ cancel: handleCancel,
710
+ change: handleChange,
711
+ rebuild: handleRebuild,
712
+ toggleYaml: handleToggleYaml
713
+ };
714
+ function handleChange(options) {
715
+ const data = options.data;
716
+ let json = schemaData.value.lang == "yaml" ? yaml.load(data.schema) : JSON.parse(data.schema);
717
+ emit("update:schema", json);
718
+ }
719
+ function handleOk(data) {
720
+ handleChange(data);
721
+ schemaVisible.value = false;
722
+ }
723
+ function handleCancel() {
724
+ schemaVisible.value = false;
725
+ }
726
+ function handleRebuild() {
727
+ emit("rebuild");
728
+ }
729
+ function handleToggleYaml(options) {
730
+ let schema = options.data.schema;
731
+ if (options.data.lang == "yaml") schemaData.value = {
732
+ lang: "json",
733
+ schema: JSON.stringify(yaml.load(schema), null, " ")
734
+ };
735
+ else schemaData.value = {
736
+ lang: "yaml",
737
+ schema: yaml.dump(JSON.parse(schema))
738
+ };
739
+ }
740
+ function openXuiPageEditor() {
741
+ designerVisible.value = true;
742
+ }
743
+ return (_ctx, _cache) => {
744
+ return openBlock(), createElementBlock(Fragment, null, [
745
+ createElementVNode("span", {
746
+ class: normalizeClass(["page-debugger", { "is-dragging": dragging.value }]),
747
+ style: normalizeStyle(positionStyle.value)
748
+ }, [
749
+ createElementVNode("button", {
750
+ type: "button",
751
+ class: "debug-handle",
752
+ title: "拖动",
753
+ "aria-label": "拖动调试工具",
754
+ onPointerdown: onPointerDown
755
+ }, " ⋮⋮ ", 32),
756
+ createElementVNode("button", {
757
+ type: "button",
758
+ class: "debug-btn",
759
+ title: "Schema Json Editor",
760
+ onClick: openSchemaEditor
761
+ }, " S "),
762
+ __props.path ? (openBlock(), createElementBlock("button", {
763
+ key: 0,
764
+ type: "button",
765
+ class: "debug-btn",
766
+ title: "Page Visual Designer",
767
+ onClick: openXuiPageEditor
768
+ }, " V ")) : createCommentVNode("v-if", true)
769
+ ], 6),
770
+ createCommentVNode(" 自绘浮层:宿主未必引入 element-plus 样式,el-dialog 会掉进文档流撑高页面 "),
771
+ (openBlock(), createBlock(Teleport, { to: "body" }, [schemaVisible.value ? (openBlock(), createElementBlock("div", {
772
+ key: 0,
773
+ class: "schema-modal-root",
774
+ role: "dialog",
775
+ "aria-modal": "true",
776
+ "aria-label": "Page Schema",
777
+ onKeydown: withKeys(handleCancel, ["esc"])
778
+ }, [createElementVNode("div", {
779
+ class: "schema-modal-mask",
780
+ onClick: handleCancel
781
+ }), createElementVNode("div", _hoisted_1, [createElementVNode("header", { class: "schema-modal-header" }, [_cache[1] || (_cache[1] = createElementVNode("h2", { class: "schema-modal-title" }, "Page Schema", -1)), createElementVNode("button", {
782
+ type: "button",
783
+ class: "schema-modal-close",
784
+ "aria-label": "关闭",
785
+ onClick: handleCancel
786
+ }, " × ")]), createElementVNode("div", _hoisted_2, [createVNode(unref(AmisSchemaPage_default), {
787
+ schema: unref(debugger_default),
788
+ actions: schemaActions,
789
+ data: schemaData.value
790
+ }, null, 8, ["schema", "data"])])])], 32)) : createCommentVNode("v-if", true)])),
791
+ createVNode(XuiPageEditorDialog_default, {
792
+ modelValue: designerVisible.value,
793
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => designerVisible.value = $event),
794
+ savePageSource,
795
+ rollbackPageSource,
796
+ getPageSource
797
+ }, null, 8, ["modelValue"])
798
+ ], 64);
799
+ };
800
+ }
801
+ }),
802
+ XuiSchemaPage: XuiSchemaPage_default
803
+ },
804
+ setup(props) {
805
+ const { getPage } = useAdapter();
806
+ let pageSchema = shallowRef();
807
+ function registerPage(p) {
808
+ props.registerPage?.(p);
809
+ }
810
+ watchEffect(() => {
811
+ getPage(props.path).then((res) => {
812
+ res.__baseUrl = props.path;
813
+ updateSchema(res);
814
+ });
815
+ });
816
+ function updateSchema(value) {
817
+ pageSchema.value = value;
818
+ }
819
+ function rebuild() {
820
+ pageSchema.value = deepClone(pageSchema.value);
821
+ }
822
+ const { debug } = useDebug();
823
+ return {
824
+ pageSchema,
825
+ updateSchema,
826
+ rebuild,
827
+ registerPage,
828
+ debug,
829
+ actions: { ...props.actions },
830
+ data: props.data
831
+ };
832
+ }
833
+ });
834
+ //#endregion
835
+ //#region src/page/XuiPage.vue
836
+ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
837
+ const _component_xui_debugger = resolveComponent("xui-debugger");
838
+ const _component_XuiSchemaPage = resolveComponent("XuiSchemaPage");
839
+ return openBlock(), createElementBlock(Fragment, null, [_ctx.debug ? (openBlock(), createBlock(_component_xui_debugger, {
840
+ key: 0,
841
+ path: _ctx.path,
842
+ schema: _ctx.pageSchema,
843
+ "onUpdate:schema": _ctx.updateSchema,
844
+ onRebuild: _ctx.rebuild
845
+ }, null, 8, [
846
+ "path",
847
+ "schema",
848
+ "onUpdate:schema",
849
+ "onRebuild"
850
+ ])) : createCommentVNode("v-if", true), createVNode(_component_XuiSchemaPage, {
851
+ schema: _ctx.pageSchema,
852
+ registerPage: _ctx.registerPage,
853
+ action: _ctx.actions,
854
+ data: _ctx.data
855
+ }, null, 8, [
856
+ "schema",
857
+ "registerPage",
858
+ "action",
859
+ "data"
860
+ ])], 64);
861
+ }
862
+ var XuiPage_default = /*#__PURE__*/ _plugin_vue_export_helper_default(XuiPage_vue_vue_type_script_lang_default, [["render", _sfc_render]]);
863
+ //#endregion
864
+ //#region src/toast/AmisToast.vue
865
+ var AmisToast_default = /* @__PURE__ */ defineComponent({
866
+ __name: "AmisToast",
867
+ setup(__props) {
868
+ const domRef = ref();
869
+ let root;
870
+ onMounted(() => {
871
+ root = createRoot(domRef.value);
872
+ root.render(createElement(Fragment$1, {}, createElement(ToastComponent, { position: "top-right" })));
873
+ });
874
+ onBeforeUnmount(() => {
875
+ if (root) {
876
+ root.unmount();
877
+ root = void 0;
878
+ }
879
+ });
880
+ return (_ctx, _cache) => {
881
+ return openBlock(), createElementBlock("div", {
882
+ ref_key: "domRef",
883
+ ref: domRef
884
+ }, null, 512);
885
+ };
886
+ }
887
+ });
888
+ //#endregion
889
+ //#region src/runtime/AmisVueComponent.ts
890
+ var VueControl = class extends React.Component {
891
+ constructor(props) {
892
+ super(props);
893
+ const { resolveVueComponent } = useAdapter();
894
+ const name = props.vueComponent || props.componentName;
895
+ const resolved = typeof name === "string" && name ? resolveVueComponent(name) : name;
896
+ if (!resolved) {
897
+ this.missingComponentName = String(name || "unknown");
898
+ this.vueComponent = null;
899
+ console.error(`[amis-vue] Vue component not registered: ${this.missingComponentName}`);
900
+ return;
901
+ }
902
+ this.vueComponent = applyPureVueInReact(resolved);
903
+ }
904
+ doAction(action, _data, _throwErrors) {
905
+ const { resetValue, onChange } = this.props;
906
+ const actionType = action?.actionType;
907
+ if (actionType === "clear") onChange(void 0);
908
+ else if (actionType === "reset") onChange(resetValue);
909
+ }
910
+ async dispatchChangeEvent(eventData = {}) {
911
+ const { dispatchEvent, data, onChange } = this.props;
912
+ if ((await dispatchEvent("change", createObject(data, { value: eventData })))?.prevented) return;
913
+ onChange?.(eventData);
914
+ }
915
+ render() {
916
+ if (!this.vueComponent) return React.createElement("div", {
917
+ className: "cxd-Form-label",
918
+ style: {
919
+ color: "var(--colors-error-5, #ff4d4f)",
920
+ padding: "4px 0"
921
+ }
922
+ }, `Vue 组件未注册: ${this.missingComponentName}`);
923
+ let { props, value, env, store } = this.props;
924
+ if (props) {
925
+ props = { ...props };
926
+ for (const key of Object.keys(props)) if (typeof props[key] === "string") props[key] = resolveVariableAndFilter(props[key], this.props.data, "| raw");
927
+ }
928
+ const mergedProps = {
929
+ env,
930
+ store,
931
+ ...props,
932
+ value,
933
+ "onUpdate:value": (value) => this.dispatchChangeEvent(value)
934
+ };
935
+ return React.createElement(this.vueComponent, mergedProps);
936
+ }
937
+ };
938
+ var VueRenderer = class extends VueControl {
939
+ constructor(props) {
940
+ super(props);
941
+ const scoped = this.context;
942
+ if (scoped) scoped.registerComponent(this);
943
+ }
944
+ componentWillUnmount() {
945
+ const scoped = this.context;
946
+ if (scoped) scoped.unRegisterComponent(this);
947
+ }
948
+ };
949
+ VueRenderer.contextType = ScopedContext;
950
+ Renderer({
951
+ type: "vue-renderer",
952
+ autoVar: false
953
+ })(VueRenderer);
954
+ var VueFormItem = class extends VueControl {};
955
+ FormItem({
956
+ type: "vue-form-item",
957
+ autoVar: false
958
+ })(VueFormItem);
959
+ //#endregion
960
+ //#region src/lib.ts
961
+ var lib_exports = /* @__PURE__ */ __exportAll({
962
+ AmisPageEditor: () => AmisPageEditor_default,
963
+ AmisSchemaPage: () => AmisSchemaPage_default,
964
+ AmisToast: () => AmisToast_default,
965
+ AmisVueComponent: () => VueControl,
966
+ XuiLoading: () => XuiLoading_default,
967
+ XuiPage: () => XuiPage_default,
968
+ XuiPageEditor: () => XuiPageEditor_default,
969
+ XuiSchemaPage: () => XuiSchemaPage_default,
970
+ createEnv: () => createEnv,
971
+ defineReactPageComponent: () => defineReactPageComponent
972
+ });
973
+ import * as import__kdesigner_core from "@kdesigner/core";
974
+ __reExport(lib_exports, import__kdesigner_core);
975
+ import * as import__kdesigner_components from "@kdesigner/components";
976
+ __reExport(lib_exports, import__kdesigner_components);
977
+ import * as import__kdesigner_amis_extensions from "@kdesigner/amis-extensions";
978
+ __reExport(lib_exports, import__kdesigner_amis_extensions);
979
+ __reExport(/* @__PURE__ */ __exportAll({
980
+ AmisPageEditor: () => AmisPageEditor_default,
981
+ AmisSchemaPage: () => AmisSchemaPage_default,
982
+ AmisToast: () => AmisToast_default,
983
+ AmisVueComponent: () => VueControl,
984
+ XuiLoading: () => XuiLoading_default,
985
+ XuiPage: () => XuiPage_default,
986
+ XuiPageEditor: () => XuiPageEditor_default,
987
+ XuiSchemaPage: () => XuiSchemaPage_default,
988
+ createEnv: () => createEnv,
989
+ defineReactPageComponent: () => defineReactPageComponent
990
+ }), lib_exports);
991
+ lib_exports.registerModule?.("@kdesigner/amis-vue", lib_exports);
992
+ //#endregion
993
+ export { AmisPageEditor_default as AmisPageEditor, AmisSchemaPage_default as AmisSchemaPage, AmisToast_default as AmisToast, VueControl as AmisVueComponent, XuiLoading_default as XuiLoading, XuiPage_default as XuiPage, XuiPageEditor_default as XuiPageEditor, XuiSchemaPage_default as XuiSchemaPage, createEnv, defineReactPageComponent };
994
+
995
+ //# sourceMappingURL=index.js.map