@oinone/kunlun-vue-widget 6.2.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.
Files changed (63) hide show
  1. package/dist/oinone-kunlun-vue-widget.esm.js +16 -0
  2. package/dist/types/index.d.ts +1 -0
  3. package/dist/types/src/basic/AsyncVueWidget.d.ts +7 -0
  4. package/dist/types/src/basic/VueFragment.vue.d.ts +2 -0
  5. package/dist/types/src/basic/VueWidget.d.ts +331 -0
  6. package/dist/types/src/basic/Widget.d.ts +234 -0
  7. package/dist/types/src/basic/index.d.ts +3 -0
  8. package/dist/types/src/data/ActiveRecordsWidget.d.ts +246 -0
  9. package/dist/types/src/data/PathWidget.d.ts +34 -0
  10. package/dist/types/src/data/index.d.ts +2 -0
  11. package/dist/types/src/dsl/DslDefinitionWidget.d.ts +61 -0
  12. package/dist/types/src/dsl/DslNodeWidget.d.ts +42 -0
  13. package/dist/types/src/dsl/DslRenderWidget.d.ts +44 -0
  14. package/dist/types/src/dsl/index.d.ts +3 -0
  15. package/dist/types/src/feature/index.d.ts +1 -0
  16. package/dist/types/src/feature/invisible-supported.d.ts +11 -0
  17. package/dist/types/src/hooks/all-mounted.d.ts +20 -0
  18. package/dist/types/src/hooks/index.d.ts +1 -0
  19. package/dist/types/src/index.d.ts +9 -0
  20. package/dist/types/src/token/index.d.ts +2 -0
  21. package/dist/types/src/typing/WidgetTagContext.d.ts +39 -0
  22. package/dist/types/src/typing/WidgetTagProps.d.ts +23 -0
  23. package/dist/types/src/typing/index.d.ts +3 -0
  24. package/dist/types/src/typing/typing.d.ts +7 -0
  25. package/dist/types/src/util/dsl-render.d.ts +106 -0
  26. package/dist/types/src/util/index.d.ts +4 -0
  27. package/dist/types/src/util/install.d.ts +4 -0
  28. package/dist/types/src/util/render.d.ts +7 -0
  29. package/dist/types/src/util/widget-manager.d.ts +4 -0
  30. package/dist/types/src/view/index.d.ts +161 -0
  31. package/index.ts +1 -0
  32. package/package.json +34 -0
  33. package/rollup.config.js +21 -0
  34. package/src/basic/AsyncVueWidget.ts +31 -0
  35. package/src/basic/VueFragment.vue +11 -0
  36. package/src/basic/VueWidget.ts +997 -0
  37. package/src/basic/Widget.ts +675 -0
  38. package/src/basic/index.ts +3 -0
  39. package/src/data/ActiveRecordsWidget.ts +572 -0
  40. package/src/data/PathWidget.ts +82 -0
  41. package/src/data/index.ts +2 -0
  42. package/src/dsl/DslDefinitionWidget.ts +235 -0
  43. package/src/dsl/DslNodeWidget.ts +130 -0
  44. package/src/dsl/DslRenderWidget.ts +106 -0
  45. package/src/dsl/index.ts +3 -0
  46. package/src/feature/index.ts +1 -0
  47. package/src/feature/invisible-supported.ts +29 -0
  48. package/src/hooks/all-mounted.ts +179 -0
  49. package/src/hooks/index.ts +1 -0
  50. package/src/index.ts +9 -0
  51. package/src/shim-translate.d.ts +7 -0
  52. package/src/shim-vue.d.ts +6 -0
  53. package/src/token/index.ts +8 -0
  54. package/src/typing/WidgetTagContext.ts +53 -0
  55. package/src/typing/WidgetTagProps.ts +24 -0
  56. package/src/typing/index.ts +3 -0
  57. package/src/typing/typing.ts +7 -0
  58. package/src/util/dsl-render.ts +464 -0
  59. package/src/util/index.ts +4 -0
  60. package/src/util/install.ts +29 -0
  61. package/src/util/render.ts +21 -0
  62. package/src/util/widget-manager.ts +14 -0
  63. package/src/view/index.ts +416 -0
@@ -0,0 +1,6 @@
1
+ declare module '*.vue' {
2
+ import { defineComponent } from 'vue';
3
+
4
+ const Component: ReturnType<typeof defineComponent>;
5
+ export default Component;
6
+ }
@@ -0,0 +1,8 @@
1
+ import { InjectionKey } from 'vue';
2
+ import { InjectionToken } from '@oinone/kunlun-spi';
3
+
4
+ const __DEV__ = process.env.NODE_ENV === 'development';
5
+
6
+ export const genToken = <T>(name: string): InjectionKey<T> => {
7
+ return InjectionToken<T>(__DEV__ ? `[vue-kunlun]: ${name}` : name) as any as InjectionKey<T>;
8
+ };
@@ -0,0 +1,53 @@
1
+ import { DslDefinition } from '@oinone/kunlun-dsl';
2
+ import { Slots } from 'vue';
3
+ import { VueWidget } from '../basic';
4
+ import { DslDefinitionWidgetProps } from '../dsl';
5
+
6
+ /**
7
+ * 渲染组件
8
+ */
9
+ export interface RenderWidget {
10
+ /**
11
+ * 当前组件唯一键
12
+ */
13
+ handle: string;
14
+ /**
15
+ * 主要组件
16
+ */
17
+ widget: VueWidget;
18
+ /**
19
+ * 混入组件
20
+ */
21
+ widgets: VueWidget[];
22
+ }
23
+
24
+ /**
25
+ * 组件标签上下文
26
+ */
27
+ export interface WidgetTagContext extends Record<string, unknown> {
28
+ dslDefinition: DslDefinition;
29
+
30
+ slotName: string;
31
+
32
+ widgetHandle: string;
33
+
34
+ widget: VueWidget;
35
+
36
+ widgets: VueWidget[];
37
+
38
+ slotContext?: Record<string, unknown>;
39
+
40
+ getWidgetTag(): string;
41
+
42
+ getParentHandle(): string;
43
+
44
+ getDslDefinition(): DslDefinition | undefined;
45
+
46
+ getSlotName(): string;
47
+
48
+ getProps(): DslDefinitionWidgetProps;
49
+
50
+ getCurrentSlots(): Slots | undefined;
51
+
52
+ createWidget(slots?: Slots): RenderWidget | undefined;
53
+ }
@@ -0,0 +1,24 @@
1
+ import { DslDefinition } from '@oinone/kunlun-dsl';
2
+ import { PropType } from 'vue';
3
+
4
+ /**
5
+ * 组件标签属性
6
+ */
7
+ export const WidgetTagProps = {
8
+ handle: {
9
+ type: String
10
+ },
11
+ dslDefinition: {
12
+ type: Object as PropType<DslDefinition>
13
+ },
14
+ slotName: {
15
+ type: String
16
+ },
17
+ inline: {
18
+ type: Boolean,
19
+ default: undefined
20
+ },
21
+ slotContext: {
22
+ type: Object
23
+ }
24
+ };
@@ -0,0 +1,3 @@
1
+ export * from './WidgetTagProps';
2
+ export * from './WidgetTagContext';
3
+ export * from './typing';
@@ -0,0 +1,7 @@
1
+ export enum InnerWidgetType {
2
+ Action = 'Action',
3
+ Field = 'Field',
4
+ Element = 'Element',
5
+ View = 'View',
6
+ Mask = 'Mask'
7
+ }
@@ -0,0 +1,464 @@
1
+ import {
2
+ DEFAULT_SLOT_NAME,
3
+ DslDefinition,
4
+ DslDefinitionHelper,
5
+ DslDefinitionType,
6
+ DslSlots,
7
+ DslSlotUtils,
8
+ ElementDslDefinition,
9
+ PackDslDefinition,
10
+ TemplateDslDefinition
11
+ } from '@oinone/kunlun-dsl';
12
+ import { StringHelper, uniqueKeyGenerator } from '@oinone/kunlun-shared';
13
+ import { PropRecordHelper } from '@oinone/kunlun-vue-ui-common';
14
+ import { intersection, isNil, isString } from 'lodash-es';
15
+ import { Component, createVNode, resolveDynamicComponent, Slots, VNode, withCtx } from 'vue';
16
+
17
+ export const DEFAULT_TAG_PREFIX = 'oinone';
18
+
19
+ export const SLOTS_KEY = '__slots';
20
+
21
+ export const RENDER_OPTIONS_KEY = '__render__options';
22
+
23
+ export const SLOT_CONTEXT_KEY = 'slotContext';
24
+
25
+ const htmlInternalTags: string[] = [
26
+ 'div',
27
+ 'a',
28
+ 'span',
29
+ 'table',
30
+ 'form',
31
+ 'detail',
32
+ 'ul',
33
+ 'li',
34
+ 'h1',
35
+ 'h2',
36
+ 'h3',
37
+ 'h4',
38
+ 'h5',
39
+ 'h6',
40
+ 'p',
41
+ 'thead',
42
+ 'tbody',
43
+ 'tr',
44
+ 'th',
45
+ 'td'
46
+ ];
47
+
48
+ /**
49
+ * 渲染可选项
50
+ */
51
+ export interface DslRenderOptions {
52
+ /**
53
+ * 动态key
54
+ * 当key不存在时进行自动生成
55
+ */
56
+ dynamicKey?: boolean;
57
+ /**
58
+ * 是否强制更新
59
+ * 永远使用新的key进行渲染
60
+ */
61
+ focusUpdate?: boolean;
62
+ /**
63
+ * 是否递归渲染
64
+ * 递归渲染有性能损耗,但可以解决某些渲染问题,建议在明确递归层数的情况下局部使用该参数
65
+ */
66
+ recursion?: boolean;
67
+ /**
68
+ * vue createVNode patchFlag
69
+ */
70
+ patchFlag?: number;
71
+ /**
72
+ * vue createVNode dynamicProps
73
+ */
74
+ dynamicProps?: string[] | null;
75
+ /**
76
+ * vue createVNode isBlockNode
77
+ */
78
+ isBlockNode?: boolean;
79
+ /**
80
+ * 插槽上下文
81
+ */
82
+ slotContext?: Record<string, unknown>;
83
+ }
84
+
85
+ export type DslChildren = string | VNode[] | Slots;
86
+
87
+ /**
88
+ * dsl扩展属性
89
+ */
90
+ export type DslRenderExtendProp = {
91
+ __slots?: DslChildren;
92
+ __render__options?: DslRenderOptions;
93
+ };
94
+
95
+ export type DslRenderDefinition = DslDefinition & DslRenderExtendProp;
96
+
97
+ export type DslPropType = {
98
+ dslDefinition: DslRenderDefinition;
99
+ slotName: string;
100
+ slotContext?: Record<string, unknown>;
101
+
102
+ [key: string]: any;
103
+ } & DslRenderExtendProp;
104
+
105
+ function dslExtendPropProcess<T>(props: DslPropType, key: string, value?: T): T | undefined {
106
+ let finalValue = props[key] as T | undefined;
107
+ delete props[key];
108
+ if (!finalValue && value) {
109
+ finalValue = value;
110
+ const { dslDefinition } = props;
111
+ if (dslDefinition) {
112
+ dslDefinition[key] = value;
113
+ }
114
+ }
115
+ return finalValue;
116
+ }
117
+
118
+ type ResolveComponentType = Component | string;
119
+
120
+ /**
121
+ * dsl渲染
122
+ */
123
+ export class DslRender {
124
+ private static resolveComponentCache: Record<string, ResolveComponentType> = {};
125
+
126
+ private static resolveCommonComponentCache: Record<string, ResolveComponentType> = {};
127
+
128
+ /**
129
+ * 渲染指定dsl定义到对应插槽
130
+ * @param dsl 指定dsl
131
+ * @param slotName 插槽名称 默认为: default
132
+ * @param children 插槽
133
+ * @param options 渲染可选项
134
+ */
135
+ public static render(
136
+ dsl: DslRenderDefinition,
137
+ slotName = DEFAULT_SLOT_NAME,
138
+ children?: DslChildren,
139
+ options?: DslRenderOptions
140
+ ): VNode | undefined {
141
+ const component = DslRender.fetchComponent(dsl);
142
+ if (!component) {
143
+ return undefined;
144
+ }
145
+ return DslRender.createVNodeWithDslDefinition(component, dsl, slotName, children, options);
146
+ }
147
+
148
+ /**
149
+ * 渲染dsl插槽
150
+ * @param dslSlots dsl插槽
151
+ */
152
+ public static renderSlots(dslSlots: DslSlots): Slots {
153
+ const slots = {};
154
+ for (const slotName in dslSlots) {
155
+ slots[slotName] = withCtx((context: Record<string, unknown>) => {
156
+ return DslRender.createVNodeChildren(dslSlots[slotName]?.widgets, slotName, context);
157
+ });
158
+ }
159
+ return slots;
160
+ }
161
+
162
+ /**
163
+ * 通过指定dsl获取VNode插槽
164
+ * @param dsl 指定dsl
165
+ * @param supportedSlotNames
166
+ */
167
+ public static fetchVNodeSlots(dsl: DslDefinition | undefined, supportedSlotNames?: string[]): Slots | undefined {
168
+ if (!dsl) {
169
+ return undefined;
170
+ }
171
+ const vSlots = dsl[SLOTS_KEY];
172
+ if (vSlots) {
173
+ return vSlots;
174
+ }
175
+ if (!supportedSlotNames) {
176
+ const finalSupportedSlotNames = [DEFAULT_SLOT_NAME];
177
+ dsl.widgets?.forEach((widget) => {
178
+ if (DslDefinitionHelper.isTemplate(widget)) {
179
+ let slotName = (widget as TemplateDslDefinition).slot;
180
+ if (!slotName) {
181
+ slotName = DEFAULT_SLOT_NAME;
182
+ }
183
+ finalSupportedSlotNames.push(slotName);
184
+ }
185
+ });
186
+ supportedSlotNames = [...new Set(finalSupportedSlotNames)];
187
+ }
188
+ const dslSlots = DslSlotUtils.fetchSlotsBySlotNames(dsl, supportedSlotNames);
189
+ return DslRender.renderSlots(dslSlots);
190
+ }
191
+
192
+ /**
193
+ * 根据dsl节点类型获取对应组件
194
+ *
195
+ * @remarks
196
+ * - {@link DslDefinitionType#VIEW} resolve rule: `{@link DEFAULT_TAG_PREFIX}-{@link DslDefinition#dslNodeType}` (Unsupported auto resolve methods)<br />
197
+ * - {@link DslDefinitionType#PACK} resolve rule: `{@link PackDslDefinition#widget}` (Supported auto resolve methods)<br>
198
+ * - {@link DslDefinitionType#ELEMENT} resolve rule: `{@link ElementDslDefinition#widget}` (Supported auto resolve methods)<br>
199
+ * - Others resolve rule: `{@link DslDefinition#dslNodeType}` (Unsupported auto resolve methods)
200
+ *
201
+ * @param dslDefinition dsl定义
202
+ * @return
203
+ * - 正确获取组件时返回: Component | string;
204
+ * - 未知类型、插槽或模板类型返回: null;
205
+ * - 无效的dslNodeType返回: undefined
206
+ */
207
+ public static fetchComponent(dslDefinition: DslDefinition): ResolveComponentType | null | undefined {
208
+ let { dslNodeType } = dslDefinition || {};
209
+ if (!dslNodeType) {
210
+ dslNodeType = DslDefinitionType.ELEMENT;
211
+ }
212
+ let component: ResolveComponentType | null | undefined;
213
+ switch (dslNodeType as DslDefinitionType) {
214
+ case DslDefinitionType.VIEW:
215
+ component = resolveDynamicComponent(`${DEFAULT_TAG_PREFIX}-${dslDefinition.dslNodeType}`) as string;
216
+ break;
217
+ case DslDefinitionType.PACK: {
218
+ const packDslDefinition = dslDefinition as PackDslDefinition;
219
+ component = DslRender.resolveWidgetComponent(`${packDslDefinition.widget || 'group'}`);
220
+ if (typeof component === 'string') {
221
+ component = DslRender.resolveWidgetComponent(`${dslDefinition.dslNodeType}`);
222
+ }
223
+ break;
224
+ }
225
+ case DslDefinitionType.ELEMENT: {
226
+ const elementDslDefinition = dslDefinition as ElementDslDefinition;
227
+ component = DslRender.resolveWidgetComponent(`${elementDslDefinition.widget}`);
228
+ if (typeof component === 'string') {
229
+ component = DslRender.resolveWidgetComponent(`${dslDefinition.dslNodeType}`);
230
+ }
231
+ break;
232
+ }
233
+ case DslDefinitionType.ACTION:
234
+ case DslDefinitionType.FIELD: {
235
+ component = DslRender.resolveWidgetComponent(`${dslDefinition.dslNodeType}`);
236
+ break;
237
+ }
238
+ case DslDefinitionType.UNKNOWN:
239
+ case DslDefinitionType.SLOT:
240
+ case DslDefinitionType.TEMPLATE:
241
+ component = null;
242
+ break;
243
+ default:
244
+ component = DslRender.resolveCommonWidgetComponent(dslNodeType);
245
+ break;
246
+ }
247
+ return component;
248
+ }
249
+
250
+ private static createVNodeChildren(
251
+ widgets: DslDefinition[] | undefined,
252
+ slotName?: string,
253
+ context?: Record<string, unknown>,
254
+ offset?: number
255
+ ): VNode[] {
256
+ const children: VNode[] = [];
257
+ if (!widgets) {
258
+ return children;
259
+ }
260
+ if (!slotName) {
261
+ slotName = DEFAULT_SLOT_NAME;
262
+ }
263
+ if (isNil(offset)) {
264
+ offset = 0;
265
+ }
266
+ const { length } = widgets;
267
+ for (let i = 0; i < length; i++) {
268
+ const dslDefinition = widgets[i];
269
+ const component = DslRender.fetchComponent(dslDefinition);
270
+ if (component) {
271
+ children.push(
272
+ DslRender.createVNodeWithDslDefinition(
273
+ component,
274
+ dslDefinition,
275
+ slotName,
276
+ isString(component) ? DslRender.fetchVNodeSlots(dslDefinition) : undefined,
277
+ context ? { slotContext: context } : undefined,
278
+ i + offset
279
+ )
280
+ );
281
+ } else if (component === null) {
282
+ const { dslNodeType } = dslDefinition;
283
+ switch (dslNodeType as DslDefinitionType) {
284
+ case DslDefinitionType.SLOT: {
285
+ const slotChildren = DslRender.createVNodeChildren(dslDefinition.widgets, slotName, context, i + offset);
286
+ offset += slotChildren.length;
287
+ slotChildren.forEach((child) => children.push(child));
288
+ break;
289
+ }
290
+ case DslDefinitionType.UNKNOWN:
291
+ case DslDefinitionType.TEMPLATE:
292
+ // eslint-disable-next-line no-continue
293
+ continue;
294
+ default:
295
+ console.error('Invalid component.');
296
+ break;
297
+ }
298
+ }
299
+ }
300
+ return children;
301
+ }
302
+
303
+ private static createVNodeWithDslDefinition(
304
+ component: ResolveComponentType,
305
+ dsl: DslDefinition,
306
+ slotName: string,
307
+ children?: DslChildren,
308
+ options?: DslRenderOptions,
309
+ index?: number
310
+ ) {
311
+ if (!isNil(index) && dsl.__index !== index) {
312
+ dsl.__index = index;
313
+ }
314
+ const isHTMLTag = isString(component);
315
+ const props: DslPropType = isHTMLTag
316
+ ? (PropRecordHelper.collectionBasicProps(dsl) as DslPropType)
317
+ : {
318
+ ...dsl,
319
+ dslDefinition: { ...dsl },
320
+ slotName
321
+ };
322
+ let finalChildren: unknown;
323
+ if (isHTMLTag) {
324
+ finalChildren = dsl.__content || dslExtendPropProcess(props, SLOTS_KEY, children);
325
+ } else {
326
+ finalChildren = dslExtendPropProcess(props, SLOTS_KEY, children);
327
+ }
328
+ const finalOptions = dslExtendPropProcess<DslRenderOptions>(props, RENDER_OPTIONS_KEY, options);
329
+ const slotContext = finalOptions?.slotContext;
330
+ if (slotContext) {
331
+ const newSlotContext = options?.slotContext;
332
+ if (newSlotContext) {
333
+ finalOptions!.slotContext = newSlotContext;
334
+ }
335
+ props.slotContext = slotContext;
336
+ }
337
+ if (DslRenderHelper.predictIsUpdateKey(dsl, finalOptions)) {
338
+ const key = uniqueKeyGenerator();
339
+ dsl.key = key;
340
+ props.key = key;
341
+ }
342
+ if (DslRenderHelper.predictIsRecursion(finalOptions) && !finalChildren && dsl.widgets?.length) {
343
+ finalChildren = DslRender.fetchVNodeSlots(dsl);
344
+ }
345
+ let finalDynamicProps = finalOptions?.dynamicProps;
346
+ if (slotContext) {
347
+ finalDynamicProps = intersection(finalDynamicProps || [], [SLOT_CONTEXT_KEY]);
348
+ }
349
+ return createVNode(
350
+ component,
351
+ props,
352
+ finalChildren,
353
+ finalOptions?.patchFlag,
354
+ finalDynamicProps,
355
+ finalOptions?.isBlockNode
356
+ );
357
+ }
358
+
359
+ private static resolveMethods: ((ss: string) => string | undefined)[] = [
360
+ /**
361
+ * 首字母转换为小写
362
+ * @param ss 字符串
363
+ */
364
+ (ss) => {
365
+ if (ss.indexOf('-') === -1) {
366
+ const firstCharCode = ss.charCodeAt(0);
367
+ if (firstCharCode >= StringHelper.UPPER_A_ASCLL && firstCharCode <= StringHelper.UPPER_Z_ASCLL) {
368
+ return `${ss[0].toLowerCase()}${ss.substring(1)}`;
369
+ }
370
+ }
371
+ return undefined;
372
+ },
373
+ /**
374
+ * 首字母转换为大写
375
+ * @param ss 字符串
376
+ */
377
+ (ss) => {
378
+ if (ss.indexOf('-') === -1) {
379
+ const firstCharCode = ss.charCodeAt(0);
380
+ if (firstCharCode >= StringHelper.LOWER_A_ASCLL && firstCharCode <= StringHelper.LOWER_Z_ASCLL) {
381
+ return `${ss[0].toUpperCase()}${ss.substring(1)}`;
382
+ }
383
+ }
384
+ return undefined;
385
+ },
386
+ /**
387
+ * CamelCase转换为KebabCase
388
+ * @param ss 字符串
389
+ */
390
+ (ss) => {
391
+ return StringHelper.camelCaseToKebabCase(ss);
392
+ }
393
+ ];
394
+
395
+ private static resolveCommonWidgetComponent(widget: string): ResolveComponentType {
396
+ let component = DslRender.resolveCommonComponentCache[widget];
397
+ if (component) {
398
+ return component;
399
+ }
400
+ if (htmlInternalTags.includes(widget)) {
401
+ return widget;
402
+ }
403
+ component = resolveDynamicComponent(
404
+ `${DEFAULT_TAG_PREFIX}-${StringHelper.camelCaseToKebabCase(widget)}`
405
+ ) as ResolveComponentType;
406
+ if (typeof component === 'string') {
407
+ component = resolveDynamicComponent(widget) as ResolveComponentType;
408
+ }
409
+ DslRender.resolveCommonComponentCache[widget] = component;
410
+ return component;
411
+ }
412
+
413
+ private static resolveWidgetComponent(widget: string): ResolveComponentType {
414
+ let component = DslRender.resolveComponentCache[widget];
415
+ if (component) {
416
+ return component;
417
+ }
418
+ if (htmlInternalTags.includes(widget)) {
419
+ return widget;
420
+ }
421
+ component = resolveDynamicComponent(widget) as ResolveComponentType;
422
+ if (typeof component === 'string') {
423
+ for (const resolveMethod of DslRender.resolveMethods) {
424
+ const resolveWidget = resolveMethod(widget);
425
+ if (resolveWidget) {
426
+ const finalComponent = resolveDynamicComponent(resolveWidget) as ResolveComponentType;
427
+ if (typeof finalComponent !== 'string') {
428
+ component = finalComponent;
429
+ break;
430
+ }
431
+ }
432
+ }
433
+ }
434
+ DslRender.resolveComponentCache[widget] = component;
435
+ return component;
436
+ }
437
+ }
438
+
439
+ /**
440
+ * dsl渲染帮助类
441
+ */
442
+ class DslRenderHelper {
443
+ /**
444
+ * 判定是否需要更新Key
445
+ * @param dsl 指定dsl
446
+ * @param options 渲染可选项
447
+ */
448
+ public static predictIsUpdateKey(dsl: DslDefinition, options: DslRenderOptions | undefined): boolean {
449
+ const dynamicKey = options?.dynamicKey || false;
450
+ const focusUpdate = options?.focusUpdate || false;
451
+ if (dsl.key) {
452
+ if (focusUpdate) {
453
+ return true;
454
+ }
455
+ } else if (dynamicKey) {
456
+ return true;
457
+ }
458
+ return false;
459
+ }
460
+
461
+ public static predictIsRecursion(options: DslRenderOptions | undefined): boolean {
462
+ return options?.recursion || false;
463
+ }
464
+ }
@@ -0,0 +1,4 @@
1
+ export * from './dsl-render';
2
+ export * from './install';
3
+ export * from './render';
4
+ export * from './widget-manager';
@@ -0,0 +1,29 @@
1
+ import { RuntimeContextManager } from '@oinone/kunlun-engine';
2
+ import { isDev } from '@oinone/kunlun-router';
3
+ import { App, Component, Directive, Plugin } from 'vue';
4
+
5
+ export function componentInstall(component: Component, name?: string | string[]): void {
6
+ if (!name) {
7
+ name = component.name;
8
+ }
9
+ const app = RuntimeContextManager.createOrReplace<App>().frameworkInstance;
10
+ if (name) {
11
+ if (typeof name === 'string') {
12
+ app.component(name, component);
13
+ } else {
14
+ name.forEach((s) => app.component(s, component));
15
+ }
16
+ } else if (isDev()) {
17
+ console.warn('component install error. reason: name is blank.', component);
18
+ }
19
+ }
20
+
21
+ export function directiveInstall(directive: Directive, name: string) {
22
+ const app = RuntimeContextManager.createOrReplace<App>().frameworkInstance;
23
+ app.directive(name, directive);
24
+ }
25
+
26
+ export function pluginInstall(plugin: Plugin, ...options: unknown[]) {
27
+ const app = RuntimeContextManager.createOrReplace<App>().frameworkInstance;
28
+ app.use(plugin, ...options);
29
+ }
@@ -0,0 +1,21 @@
1
+ import { StableSlotProp } from '@oinone/kunlun-vue-ui-common';
2
+ import { Slots, VNode } from 'vue';
3
+ import { VueWidget } from '../basic';
4
+
5
+ export function renderWidgets(widgets: VueWidget[], ctx: Record<string, unknown>, slots?: Slots) {
6
+ let vNodes: VNode | VNode[] | undefined;
7
+ const { length } = widgets;
8
+ for (let i = length - 1; i >= 0; i--) {
9
+ const widget = widgets[i];
10
+ if (vNodes) {
11
+ const finalVNodes = Array.isArray(vNodes) ? vNodes : [vNodes];
12
+ vNodes = widget.render(ctx, { default: () => finalVNodes, ...StableSlotProp });
13
+ } else {
14
+ vNodes = widget.render(ctx, {
15
+ ...slots,
16
+ ...StableSlotProp
17
+ });
18
+ }
19
+ }
20
+ return vNodes;
21
+ }
@@ -0,0 +1,14 @@
1
+ import { CastHelper } from '@oinone/kunlun-shared';
2
+ import { VueWidget, Widget } from '../basic';
3
+
4
+ export function newVueWidget(): VueWidget {
5
+ return new VueWidget();
6
+ }
7
+
8
+ export function getWidget(handler: string): VueWidget | undefined {
9
+ return CastHelper.cast(Widget.select(handler));
10
+ }
11
+
12
+ export function getWidgetNotNull(handle: string): VueWidget {
13
+ return getWidget(handle) || newVueWidget();
14
+ }