@antglobal/copilot-cards-mini-program 0.0.0 → 0.0.20260724033338-dev.3

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 (67) hide show
  1. package/README.md +126 -2
  2. package/dist/action-context/index.d.ts +44 -0
  3. package/dist/action-context/index.js +70 -0
  4. package/dist/adapter/alipay.d.ts +22 -0
  5. package/dist/adapter/alipay.js +65 -0
  6. package/dist/adapter/index.d.ts +53 -0
  7. package/dist/adapter/index.js +2 -0
  8. package/dist/adapter/wechat.d.ts +22 -0
  9. package/dist/adapter/wechat.js +65 -0
  10. package/dist/components/card-button/index.acss +61 -0
  11. package/dist/components/card-button/index.axml +9 -0
  12. package/dist/components/card-button/index.d.ts +23 -0
  13. package/dist/components/card-button/index.js +26 -0
  14. package/dist/components/card-button/index.wxml +9 -0
  15. package/dist/components/card-divider/index.acss +8 -0
  16. package/dist/components/card-divider/index.axml +5 -0
  17. package/dist/components/card-divider/index.d.ts +11 -0
  18. package/dist/components/card-divider/index.js +13 -0
  19. package/dist/components/card-divider/index.wxml +5 -0
  20. package/dist/components/card-icon/definition.d.ts +15 -0
  21. package/dist/components/card-icon/definition.js +17 -0
  22. package/dist/components/card-icon/index.acss +19 -0
  23. package/dist/components/card-icon/index.axml +16 -0
  24. package/dist/components/card-icon/index.d.ts +1 -0
  25. package/dist/components/card-icon/index.js +8 -0
  26. package/dist/components/card-icon/index.json +3 -0
  27. package/dist/components/card-icon/index.wxml +16 -0
  28. package/dist/components/card-icon/index.wxss +19 -0
  29. package/dist/components/card-image/index.acss +7 -0
  30. package/dist/components/card-image/index.axml +9 -0
  31. package/dist/components/card-image/index.d.ts +22 -0
  32. package/dist/components/card-image/index.js +22 -0
  33. package/dist/components/card-image/index.wxml +9 -0
  34. package/dist/components/card-input/index.acss +24 -0
  35. package/dist/components/card-input/index.axml +16 -0
  36. package/dist/components/card-input/index.d.ts +25 -0
  37. package/dist/components/card-input/index.js +45 -0
  38. package/dist/components/card-input/index.wxml +16 -0
  39. package/dist/components/card-node/index.acss +5 -0
  40. package/dist/components/card-node/index.axml +30 -0
  41. package/dist/components/card-node/index.d.ts +31 -0
  42. package/dist/components/card-node/index.js +28 -0
  43. package/dist/components/card-node/index.wxml +30 -0
  44. package/dist/components/card-root/index.acss +4 -0
  45. package/dist/components/card-root/index.axml +4 -0
  46. package/dist/components/card-root/index.d.ts +78 -0
  47. package/dist/components/card-root/index.js +93 -0
  48. package/dist/components/card-root/index.wxml +4 -0
  49. package/dist/components/card-text/index.acss +11 -0
  50. package/dist/components/card-text/index.axml +8 -0
  51. package/dist/components/card-text/index.d.ts +23 -0
  52. package/dist/components/card-text/index.js +23 -0
  53. package/dist/components/card-text/index.wxml +8 -0
  54. package/dist/events/index.d.ts +37 -0
  55. package/dist/events/index.js +50 -0
  56. package/dist/icons.d.ts +3 -0
  57. package/dist/icons.js +135 -0
  58. package/dist/index.d.ts +17 -0
  59. package/dist/index.js +16 -0
  60. package/dist/renderer/index.d.ts +67 -0
  61. package/dist/renderer/index.js +158 -0
  62. package/dist/renderer/transform.d.ts +24 -0
  63. package/dist/renderer/transform.js +91 -0
  64. package/dist/streaming/index.d.ts +80 -0
  65. package/dist/streaming/index.js +230 -0
  66. package/package.json +38 -7
  67. package/LEGAL.md +0 -7
@@ -0,0 +1,17 @@
1
+ function createCardIconComponent() {
2
+ return {
3
+ // Alipay mini program component input.
4
+ props: {
5
+ node: null,
6
+ },
7
+ // WeChat mini program component input.
8
+ properties: {
9
+ node: {
10
+ type: Object,
11
+ value: null,
12
+ },
13
+ },
14
+ };
15
+ }
16
+
17
+ export { createCardIconComponent };
@@ -0,0 +1,19 @@
1
+ .card-icon {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ box-sizing: border-box;
6
+ vertical-align: middle;
7
+ line-height: 0;
8
+ }
9
+
10
+ .card-icon__image {
11
+ display: block;
12
+ width: 100%;
13
+ height: 100%;
14
+ }
15
+
16
+ .card-icon__text {
17
+ display: block;
18
+ line-height: 1;
19
+ }
@@ -0,0 +1,16 @@
1
+ <view
2
+ class="card-icon"
3
+ style="{{node.props._styleString || ''}}; width: {{node.props._iconSize}}px; height: {{node.props._iconSize}}px;"
4
+ >
5
+ <image
6
+ a:if="{{node.props._iconKind === 'image'}}"
7
+ class="card-icon__image"
8
+ src="{{node.props._iconSrc}}"
9
+ mode="aspectFit"
10
+ />
11
+ <text
12
+ a:else
13
+ class="card-icon__text"
14
+ style="font-size: {{node.props._iconSize}}px; color: {{node.props.color || 'currentColor'}};"
15
+ >{{node.props._iconText}}</text>
16
+ </view>
@@ -0,0 +1 @@
1
+ export { createCardIconComponent } from './definition.js';
@@ -0,0 +1,8 @@
1
+ import { createCardIconComponent } from './definition.js';
2
+
3
+ const componentRegistrar = globalThis.Component;
4
+ if (typeof componentRegistrar === 'function') {
5
+ componentRegistrar(createCardIconComponent());
6
+ }
7
+
8
+ export { createCardIconComponent };
@@ -0,0 +1,3 @@
1
+ {
2
+ "component": true
3
+ }
@@ -0,0 +1,16 @@
1
+ <view
2
+ class="card-icon"
3
+ style="{{node.props._styleString || ''}}; width: {{node.props._iconSize}}px; height: {{node.props._iconSize}}px;"
4
+ >
5
+ <image
6
+ wx:if="{{node.props._iconKind === 'image'}}"
7
+ class="card-icon__image"
8
+ src="{{node.props._iconSrc}}"
9
+ mode="aspectFit"
10
+ />
11
+ <text
12
+ wx:else
13
+ class="card-icon__text"
14
+ style="font-size: {{node.props._iconSize}}px; color: {{node.props.color || 'currentColor'}};"
15
+ >{{node.props._iconText}}</text>
16
+ </view>
@@ -0,0 +1,19 @@
1
+ .card-icon {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ box-sizing: border-box;
6
+ vertical-align: middle;
7
+ line-height: 0;
8
+ }
9
+
10
+ .card-icon__image {
11
+ display: block;
12
+ width: 100%;
13
+ height: 100%;
14
+ }
15
+
16
+ .card-icon__text {
17
+ display: block;
18
+ line-height: 1;
19
+ }
@@ -0,0 +1,7 @@
1
+ .card-image {
2
+ display: flex;
3
+ }
4
+
5
+ .card-image__img {
6
+ display: block;
7
+ }
@@ -0,0 +1,9 @@
1
+ <!-- card-image: Alipay template -->
2
+ <view class="card-image" style="{{node.props._styleString || ''}}" onTap="onTap">
3
+ <image
4
+ class="card-image__img"
5
+ src="{{node.props.src}}"
6
+ mode="{{node.props.objectFit === 'cover' ? 'aspectFill' : node.props.objectFit === 'contain' ? 'aspectFit' : 'widthFix'}}"
7
+ style="width: {{node.props.width || '100%'}}; height: {{node.props.height || 'auto'}}; border-radius: {{node.props.borderRadius || '0'}};"
8
+ />
9
+ </view>
@@ -0,0 +1,22 @@
1
+ import { MiniProgramRenderNode } from '../../renderer/index.js';
2
+
3
+ /**
4
+ * card-image — Image component for mini-program.
5
+ */
6
+
7
+ interface CardImageInstance {
8
+ props: {
9
+ node: MiniProgramRenderNode | null;
10
+ };
11
+ triggerEvent(name: string, detail?: any): void;
12
+ }
13
+ declare function createCardImageComponent(): {
14
+ props: {
15
+ node: null;
16
+ };
17
+ methods: {
18
+ onTap(this: CardImageInstance): void;
19
+ };
20
+ };
21
+
22
+ export { createCardImageComponent };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * card-image — Image component for mini-program.
3
+ */
4
+ function createCardImageComponent() {
5
+ return {
6
+ props: {
7
+ node: null,
8
+ },
9
+ methods: {
10
+ onTap() {
11
+ if (!this.props.node?.events.includes('onClick'))
12
+ return;
13
+ this.triggerEvent('event', {
14
+ nodeId: this.props.node.id,
15
+ eventName: 'onClick',
16
+ });
17
+ },
18
+ },
19
+ };
20
+ }
21
+
22
+ export { createCardImageComponent };
@@ -0,0 +1,9 @@
1
+ <!-- card-image: WeChat template -->
2
+ <view class="card-image" style="{{node.props._styleString || ''}}" bindtap="onTap">
3
+ <image
4
+ class="card-image__img"
5
+ src="{{node.props.src}}"
6
+ mode="{{node.props.objectFit === 'cover' ? 'aspectFill' : node.props.objectFit === 'contain' ? 'aspectFit' : 'widthFix'}}"
7
+ style="width: {{node.props.width || '100%'}}; height: {{node.props.height || 'auto'}}; border-radius: {{node.props.borderRadius || '0'}};"
8
+ />
9
+ </view>
@@ -0,0 +1,24 @@
1
+ .card-input {
2
+ display: flex;
3
+ flex-direction: column;
4
+ }
5
+
6
+ .card-input__label {
7
+ font-size: 28rpx;
8
+ color: #333333;
9
+ margin-bottom: 8rpx;
10
+ }
11
+
12
+ .card-input__field {
13
+ border: 1rpx solid #D9D9D9;
14
+ border-radius: 8rpx;
15
+ padding: 16rpx 24rpx;
16
+ font-size: 28rpx;
17
+ color: #333333;
18
+ background-color: #FFFFFF;
19
+ }
20
+
21
+ .card-input__field--disabled {
22
+ background-color: #F5F5F5;
23
+ color: #C0C0C0;
24
+ }
@@ -0,0 +1,16 @@
1
+ <!-- card-input: Alipay template -->
2
+ <view class="card-input" style="{{node.props._styleString || ''}}">
3
+ <text a:if="{{node.props.label}}" class="card-input__label">{{node.props.label}}</text>
4
+ <input
5
+ class="card-input__field {{node.disabled ? 'card-input__field--disabled' : ''}}"
6
+ type="{{node.props.type || 'text'}}"
7
+ password="{{node.props.type === 'password'}}"
8
+ placeholder="{{node.props.placeholder || ''}}"
9
+ value="{{node.props.value || ''}}"
10
+ disabled="{{node.disabled}}"
11
+ maxlength="{{node.props.maxLength || -1}}"
12
+ onInput="onInput"
13
+ onBlur="onChange"
14
+ onConfirm="onConfirm"
15
+ />
16
+ </view>
@@ -0,0 +1,25 @@
1
+ import { MiniProgramRenderNode } from '../../renderer/index.js';
2
+
3
+ /**
4
+ * card-input — Input component for mini-program.
5
+ * Supports text/password/number types with placeholder and label.
6
+ */
7
+
8
+ interface CardInputInstance {
9
+ props: {
10
+ node: MiniProgramRenderNode | null;
11
+ };
12
+ triggerEvent(name: string, detail?: any): void;
13
+ }
14
+ declare function createCardInputComponent(): {
15
+ props: {
16
+ node: null;
17
+ };
18
+ methods: {
19
+ onInput(this: CardInputInstance, e: any): void;
20
+ onChange(this: CardInputInstance, e: any): void;
21
+ onConfirm(this: CardInputInstance, e: any): void;
22
+ };
23
+ };
24
+
25
+ export { createCardInputComponent };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * card-input — Input component for mini-program.
3
+ * Supports text/password/number types with placeholder and label.
4
+ */
5
+ function createCardInputComponent() {
6
+ return {
7
+ props: {
8
+ node: null,
9
+ },
10
+ methods: {
11
+ onInput(e) {
12
+ const value = e.detail?.value ?? '';
13
+ if (!this.props.node)
14
+ return;
15
+ this.triggerEvent('event', {
16
+ nodeId: this.props.node.id,
17
+ eventName: 'onInput',
18
+ value,
19
+ });
20
+ },
21
+ onChange(e) {
22
+ const value = e.detail?.value ?? '';
23
+ if (!this.props.node)
24
+ return;
25
+ this.triggerEvent('event', {
26
+ nodeId: this.props.node.id,
27
+ eventName: 'onChange',
28
+ value,
29
+ });
30
+ },
31
+ onConfirm(e) {
32
+ const value = e.detail?.value ?? '';
33
+ if (!this.props.node)
34
+ return;
35
+ this.triggerEvent('event', {
36
+ nodeId: this.props.node.id,
37
+ eventName: 'onSubmit',
38
+ value,
39
+ });
40
+ },
41
+ },
42
+ };
43
+ }
44
+
45
+ export { createCardInputComponent };
@@ -0,0 +1,16 @@
1
+ <!-- card-input: WeChat template -->
2
+ <view class="card-input" style="{{node.props._styleString || ''}}">
3
+ <text wx:if="{{node.props.label}}" class="card-input__label">{{node.props.label}}</text>
4
+ <input
5
+ class="card-input__field {{node.disabled ? 'card-input__field--disabled' : ''}}"
6
+ type="{{node.props.type || 'text'}}"
7
+ password="{{node.props.type === 'password'}}"
8
+ placeholder="{{node.props.placeholder || ''}}"
9
+ value="{{node.props.value || ''}}"
10
+ disabled="{{node.disabled}}"
11
+ maxlength="{{node.props.maxLength || -1}}"
12
+ bindinput="onInput"
13
+ bindblur="onChange"
14
+ bindconfirm="onConfirm"
15
+ />
16
+ </view>
@@ -0,0 +1,5 @@
1
+ .card-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ box-sizing: border-box;
5
+ }
@@ -0,0 +1,30 @@
1
+ <!-- card-node: Alipay recursive dispatcher template -->
2
+ <block a:if="{{node && node.visible}}">
3
+ <!-- Text -->
4
+ <card-text a:if="{{node.type === 'Text'}}" node="{{node}}" onEvent="onEvent" />
5
+
6
+ <!-- Button -->
7
+ <card-button a:elif="{{node.type === 'Button'}}" node="{{node}}" onEvent="onEvent" />
8
+
9
+ <!-- Image -->
10
+ <card-image a:elif="{{node.type === 'Image'}}" node="{{node}}" onEvent="onEvent" />
11
+
12
+ <!-- Icon -->
13
+ <card-icon a:elif="{{node.type === 'Icon'}}" node="{{node}}" />
14
+
15
+ <!-- Input -->
16
+ <card-input a:elif="{{node.type === 'Input'}}" node="{{node}}" onEvent="onEvent" />
17
+
18
+ <!-- Divider -->
19
+ <card-divider a:elif="{{node.type === 'Divider'}}" node="{{node}}" />
20
+
21
+ <!-- Default container (unknown type or layout container) -->
22
+ <view a:else class="card-container card-{{node.type}}" style="{{node.props._styleString || ''}}">
23
+ <card-node
24
+ a:for="{{node.children}}"
25
+ a:key="id"
26
+ node="{{item}}"
27
+ onEvent="onEvent"
28
+ />
29
+ </view>
30
+ </block>
@@ -0,0 +1,31 @@
1
+ import { MiniProgramRenderNode } from '../../renderer/index.js';
2
+
3
+ /**
4
+ * card-node — Recursive dispatcher component.
5
+ *
6
+ * Receives a MiniProgramRenderNode and dispatches rendering
7
+ * to the appropriate typed component based on node.type.
8
+ * For unknown types, renders as a generic container with children.
9
+ */
10
+
11
+ interface CardNodeInstance {
12
+ props: {
13
+ node: MiniProgramRenderNode | null;
14
+ };
15
+ triggerEvent(name: string, detail?: any): void;
16
+ }
17
+ declare function createCardNodeComponent(): {
18
+ props: {
19
+ node: null;
20
+ };
21
+ methods: {
22
+ /**
23
+ * Bubble events up to card-root.
24
+ * Each leaf component calls triggerEvent('event', { nodeId, eventName, ... })
25
+ * which flows through card-node → card-root.
26
+ */
27
+ onEvent(this: CardNodeInstance, e: any): void;
28
+ };
29
+ };
30
+
31
+ export { createCardNodeComponent };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * card-node — Recursive dispatcher component.
3
+ *
4
+ * Receives a MiniProgramRenderNode and dispatches rendering
5
+ * to the appropriate typed component based on node.type.
6
+ * For unknown types, renders as a generic container with children.
7
+ */
8
+ // ─── Component Definition ────────────────────────────────────────
9
+ function createCardNodeComponent() {
10
+ return {
11
+ props: {
12
+ node: null,
13
+ },
14
+ methods: {
15
+ /**
16
+ * Bubble events up to card-root.
17
+ * Each leaf component calls triggerEvent('event', { nodeId, eventName, ... })
18
+ * which flows through card-node → card-root.
19
+ */
20
+ onEvent(e) {
21
+ // Pass through to parent
22
+ this.triggerEvent('event', e.detail ?? e);
23
+ },
24
+ },
25
+ };
26
+ }
27
+
28
+ export { createCardNodeComponent };
@@ -0,0 +1,30 @@
1
+ <!-- card-node: WeChat recursive dispatcher template -->
2
+ <block wx:if="{{node && node.visible}}">
3
+ <!-- Text -->
4
+ <card-text wx:if="{{node.type === 'Text'}}" node="{{node}}" bind:event="onEvent" />
5
+
6
+ <!-- Button -->
7
+ <card-button wx:elif="{{node.type === 'Button'}}" node="{{node}}" bind:event="onEvent" />
8
+
9
+ <!-- Image -->
10
+ <card-image wx:elif="{{node.type === 'Image'}}" node="{{node}}" bind:event="onEvent" />
11
+
12
+ <!-- Icon -->
13
+ <card-icon wx:elif="{{node.type === 'Icon'}}" node="{{node}}" />
14
+
15
+ <!-- Input -->
16
+ <card-input wx:elif="{{node.type === 'Input'}}" node="{{node}}" bind:event="onEvent" />
17
+
18
+ <!-- Divider -->
19
+ <card-divider wx:elif="{{node.type === 'Divider'}}" node="{{node}}" />
20
+
21
+ <!-- Default container (unknown type or layout container) -->
22
+ <view wx:else class="card-container card-{{node.type}}" style="{{node.props._styleString || ''}}">
23
+ <card-node
24
+ wx:for="{{node.children}}"
25
+ wx:key="id"
26
+ node="{{item}}"
27
+ bind:event="onEvent"
28
+ />
29
+ </view>
30
+ </block>
@@ -0,0 +1,4 @@
1
+ .copilot-card-root {
2
+ width: 100%;
3
+ box-sizing: border-box;
4
+ }
@@ -0,0 +1,4 @@
1
+ <!-- card-root: Alipay mini-program template -->
2
+ <view class="copilot-card-root">
3
+ <card-node a:if="{{tree}}" node="{{tree}}" onEvent="handleEvent" />
4
+ </view>
@@ -0,0 +1,78 @@
1
+ import { MiniProgramRenderNode, MiniProgramCardInstance } from '../../renderer/index.js';
2
+ import { MiniProgramAdapter } from '../../adapter/index.js';
3
+ import { CardSchemaInput } from '@antglobal/copilot-cards-core';
4
+
5
+ /**
6
+ * card-root — Root container component for mini-program card rendering.
7
+ *
8
+ * This is the entry point component that accepts a CardSchema,
9
+ * initializes the renderer, and drives the recursive rendering pipeline.
10
+ *
11
+ * Usage in page AXML/WXML:
12
+ * ```xml
13
+ * <card-root schema="{{cardSchema}}" variables="{{variables}}" />
14
+ * ```
15
+ */
16
+
17
+ interface CardRootProps {
18
+ /** The card schema JSON */
19
+ schema: CardSchemaInput | null;
20
+ /** External variables to merge */
21
+ variables: Record<string, any> | null;
22
+ /** Platform adapter instance (injected from page) */
23
+ adapter: MiniProgramAdapter | null;
24
+ /** Bot ID for bot-scoped action handlers */
25
+ botId: string;
26
+ }
27
+ interface CardRootData {
28
+ tree: MiniProgramRenderNode | null;
29
+ }
30
+ /**
31
+ * Mini-program component instance interface.
32
+ * This is the `this` context inside Component() methods.
33
+ */
34
+ interface CardRootInstance {
35
+ props: CardRootProps;
36
+ data: CardRootData;
37
+ _instance: MiniProgramCardInstance | null;
38
+ setData(data: Partial<CardRootData>): void;
39
+ triggerEvent(name: string, detail?: any): void;
40
+ }
41
+ /**
42
+ * Create the card-root component definition object.
43
+ *
44
+ * This returns a plain object that can be passed to the platform's
45
+ * `Component()` constructor (Alipay or WeChat).
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * // Alipay
50
+ * Component(createCardRootComponent());
51
+ *
52
+ * // WeChat
53
+ * Component(createCardRootComponent());
54
+ * ```
55
+ */
56
+ declare function createCardRootComponent(): {
57
+ props: {
58
+ schema: null;
59
+ variables: null;
60
+ adapter: null;
61
+ botId: string;
62
+ };
63
+ data: {
64
+ tree: null;
65
+ };
66
+ didMount(this: CardRootInstance): void;
67
+ attached(this: CardRootInstance): void;
68
+ didUpdate(this: CardRootInstance, prevProps: CardRootProps): void;
69
+ didUnmount(this: CardRootInstance): void;
70
+ detached(this: CardRootInstance): void;
71
+ methods: {
72
+ handleEvent(this: CardRootInstance, e: any): Promise<void>;
73
+ };
74
+ _instance: MiniProgramCardInstance | null;
75
+ };
76
+
77
+ export { createCardRootComponent };
78
+ export type { CardRootData, CardRootProps };
@@ -0,0 +1,93 @@
1
+ import { renderForMiniProgram } from '../../renderer/index.js';
2
+
3
+ /**
4
+ * card-root — Root container component for mini-program card rendering.
5
+ *
6
+ * This is the entry point component that accepts a CardSchema,
7
+ * initializes the renderer, and drives the recursive rendering pipeline.
8
+ *
9
+ * Usage in page AXML/WXML:
10
+ * ```xml
11
+ * <card-root schema="{{cardSchema}}" variables="{{variables}}" />
12
+ * ```
13
+ */
14
+ // ─── Component Definition ────────────────────────────────────────
15
+ /**
16
+ * Create the card-root component definition object.
17
+ *
18
+ * This returns a plain object that can be passed to the platform's
19
+ * `Component()` constructor (Alipay or WeChat).
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // Alipay
24
+ * Component(createCardRootComponent());
25
+ *
26
+ * // WeChat
27
+ * Component(createCardRootComponent());
28
+ * ```
29
+ */
30
+ function createCardRootComponent() {
31
+ function init(ctx) {
32
+ if (!ctx.props.schema || !ctx.props.adapter) {
33
+ console.warn('[card-root] Missing schema or adapter prop');
34
+ return;
35
+ }
36
+ ctx._instance = renderForMiniProgram(ctx.props.schema, {
37
+ adapter: ctx.props.adapter,
38
+ data: ctx.props.variables ?? undefined,
39
+ botId: ctx.props.botId || undefined,
40
+ onEmit: (eventName, payload) => {
41
+ ctx.triggerEvent('emit', { eventName, payload });
42
+ },
43
+ });
44
+ ctx.setData({ tree: ctx._instance.getData().tree });
45
+ }
46
+ return {
47
+ props: {
48
+ schema: null,
49
+ variables: null,
50
+ adapter: null,
51
+ botId: '',
52
+ },
53
+ data: {
54
+ tree: null,
55
+ },
56
+ // Alipay lifecycle
57
+ didMount() {
58
+ init(this);
59
+ },
60
+ // WeChat lifecycle
61
+ attached() {
62
+ init(this);
63
+ },
64
+ didUpdate(prevProps) {
65
+ if (prevProps.variables !== this.props.variables && this._instance) {
66
+ const result = this._instance.updateVariables(this.props.variables ?? {});
67
+ this.setData({ tree: result.tree });
68
+ }
69
+ },
70
+ didUnmount() {
71
+ this._instance?.dispose();
72
+ this._instance = null;
73
+ },
74
+ detached() {
75
+ this._instance?.dispose();
76
+ this._instance = null;
77
+ },
78
+ methods: {
79
+ async handleEvent(e) {
80
+ const detail = e.detail ?? e.target?.dataset ?? {};
81
+ const { nodeId, eventName } = detail;
82
+ if (!nodeId || !eventName || !this._instance)
83
+ return;
84
+ await this._instance.handleEvent(nodeId, eventName, detail.value ?? detail);
85
+ // Re-sync data after event handling (variables may have changed)
86
+ this.setData({ tree: this._instance.getData().tree });
87
+ },
88
+ },
89
+ _instance: null,
90
+ };
91
+ }
92
+
93
+ export { createCardRootComponent };
@@ -0,0 +1,4 @@
1
+ <!-- card-root: WeChat mini-program template -->
2
+ <view class="copilot-card-root">
3
+ <card-node wx:if="{{tree}}" node="{{tree}}" bind:event="handleEvent" />
4
+ </view>
@@ -0,0 +1,11 @@
1
+ .card-text {
2
+ word-break: break-word;
3
+ }
4
+
5
+ .card-text--bold {
6
+ font-weight: 600;
7
+ }
8
+
9
+ .card-text--italic {
10
+ font-style: italic;
11
+ }
@@ -0,0 +1,8 @@
1
+ <!-- card-text: Alipay template -->
2
+ <view
3
+ class="card-text {{node.props.bold ? 'card-text--bold' : ''}} {{node.props.italic ? 'card-text--italic' : ''}}"
4
+ style="font-size: {{node.props.fontSize || '14px'}}; color: {{node.props.color || '#333333'}}; line-height: {{node.props.lineHeight || '1.5'}}; text-align: {{node.props.textAlign || 'left'}}; {{node.props.style ? node.props._styleString : ''}}"
5
+ onTap="onTap"
6
+ >
7
+ <text>{{node.props.content}}</text>
8
+ </view>