@flowgram-vue/form-materials 0.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 (177) hide show
  1. package/LICENSE +22 -0
  2. package/bin/run.sh +7 -0
  3. package/dist/index.cjs +0 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +0 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +86 -0
  9. package/src/components/assign-row/assign-row.vue +69 -0
  10. package/src/components/assign-row/index.ts +7 -0
  11. package/src/components/assign-row/types.ts +25 -0
  12. package/src/components/assign-rows/assign-rows.vue +44 -0
  13. package/src/components/assign-rows/index.ts +6 -0
  14. package/src/components/batch-outputs/batch-outputs.vue +46 -0
  15. package/src/components/batch-outputs/index.ts +6 -0
  16. package/src/components/batch-outputs/styles.css +17 -0
  17. package/src/components/batch-outputs/types.ts +23 -0
  18. package/src/components/batch-variable-selector/batch-variable-selector.vue +24 -0
  19. package/src/components/batch-variable-selector/index.ts +6 -0
  20. package/src/components/blur-input/blur-input.vue +47 -0
  21. package/src/components/blur-input/index.ts +6 -0
  22. package/src/components/code-editor/base-code-editor.vue +44 -0
  23. package/src/components/code-editor/index.ts +58 -0
  24. package/src/components/code-editor/styles.css +27 -0
  25. package/src/components/code-editor/types.ts +20 -0
  26. package/src/components/code-editor/utils.ts +24 -0
  27. package/src/components/code-editor-mini/code-editor-mini.vue +16 -0
  28. package/src/components/code-editor-mini/index.ts +6 -0
  29. package/src/components/condition-context/context.ts +45 -0
  30. package/src/components/condition-context/hooks/use-condition.ts +120 -0
  31. package/src/components/condition-context/index.ts +14 -0
  32. package/src/components/condition-context/op.ts +86 -0
  33. package/src/components/condition-context/types.ts +22 -0
  34. package/src/components/condition-row/condition-row.vue +126 -0
  35. package/src/components/condition-row/index.ts +7 -0
  36. package/src/components/condition-row/styles.css +30 -0
  37. package/src/components/condition-row/types.ts +12 -0
  38. package/src/components/constant-input/constant-input.vue +48 -0
  39. package/src/components/constant-input/index.ts +7 -0
  40. package/src/components/constant-input/types.ts +23 -0
  41. package/src/components/coze-editor-extensions/extensions/inputs-tree.vue +16 -0
  42. package/src/components/coze-editor-extensions/extensions/variable-tag.vue +10 -0
  43. package/src/components/coze-editor-extensions/extensions/variable-tree.vue +18 -0
  44. package/src/components/coze-editor-extensions/index.ts +22 -0
  45. package/src/components/coze-editor-extensions/styles.css +41 -0
  46. package/src/components/db-condition-row/db-condition-row.vue +112 -0
  47. package/src/components/db-condition-row/index.ts +7 -0
  48. package/src/components/db-condition-row/styles.css +41 -0
  49. package/src/components/db-condition-row/types.ts +20 -0
  50. package/src/components/display-flow-value/display-flow-value.vue +46 -0
  51. package/src/components/display-flow-value/index.ts +6 -0
  52. package/src/components/display-inputs-values/display-inputs-value-all-in-tag.vue +26 -0
  53. package/src/components/display-inputs-values/display-inputs-values.vue +43 -0
  54. package/src/components/display-inputs-values/index.ts +7 -0
  55. package/src/components/display-inputs-values/styles.css +10 -0
  56. package/src/components/display-outputs/display-outputs.vue +62 -0
  57. package/src/components/display-outputs/index.ts +6 -0
  58. package/src/components/display-outputs/styles.css +10 -0
  59. package/src/components/display-schema-tag/display-schema-tag.vue +41 -0
  60. package/src/components/display-schema-tag/index.ts +6 -0
  61. package/src/components/display-schema-tag/styles.css +25 -0
  62. package/src/components/display-schema-tree/display-schema-tree.vue +55 -0
  63. package/src/components/display-schema-tree/index.ts +6 -0
  64. package/src/components/display-schema-tree/styles.css +84 -0
  65. package/src/components/dynamic-value-input/dynamic-value-input.vue +145 -0
  66. package/src/components/dynamic-value-input/hooks.ts +71 -0
  67. package/src/components/dynamic-value-input/index.ts +10 -0
  68. package/src/components/dynamic-value-input/styles.css +59 -0
  69. package/src/components/index.ts +84 -0
  70. package/src/components/inputs-values/index.ts +6 -0
  71. package/src/components/inputs-values/inputs-values.vue +67 -0
  72. package/src/components/inputs-values/styles.css +17 -0
  73. package/src/components/inputs-values/types.ts +23 -0
  74. package/src/components/inputs-values-tree/hooks/use-child-list.ts +65 -0
  75. package/src/components/inputs-values-tree/index.ts +6 -0
  76. package/src/components/inputs-values-tree/inputs-values-tree.vue +59 -0
  77. package/src/components/inputs-values-tree/row.vue +139 -0
  78. package/src/components/inputs-values-tree/styles.css +94 -0
  79. package/src/components/inputs-values-tree/types.ts +23 -0
  80. package/src/components/json-editor-with-variables/index.ts +7 -0
  81. package/src/components/json-editor-with-variables/json-editor-with-variables.vue +24 -0
  82. package/src/components/json-editor-with-variables/types.ts +8 -0
  83. package/src/components/json-schema-creator/index.ts +7 -0
  84. package/src/components/json-schema-creator/json-input-modal.vue +51 -0
  85. package/src/components/json-schema-creator/json-schema-creator.vue +27 -0
  86. package/src/components/json-schema-creator/types.ts +10 -0
  87. package/src/components/json-schema-creator/utils/json-to-schema.ts +50 -0
  88. package/src/components/json-schema-editor/default-value.vue +30 -0
  89. package/src/components/json-schema-editor/hooks.ts +134 -0
  90. package/src/components/json-schema-editor/index.ts +6 -0
  91. package/src/components/json-schema-editor/json-schema-editor.vue +53 -0
  92. package/src/components/json-schema-editor/property-edit.vue +222 -0
  93. package/src/components/json-schema-editor/styles.css +135 -0
  94. package/src/components/json-schema-editor/types.ts +25 -0
  95. package/src/components/prompt-editor/index.ts +7 -0
  96. package/src/components/prompt-editor/prompt-editor.vue +40 -0
  97. package/src/components/prompt-editor/styles.css +14 -0
  98. package/src/components/prompt-editor/types.ts +20 -0
  99. package/src/components/prompt-editor-with-inputs/index.ts +7 -0
  100. package/src/components/prompt-editor-with-inputs/prompt-editor-with-inputs.vue +18 -0
  101. package/src/components/prompt-editor-with-inputs/types.ts +11 -0
  102. package/src/components/prompt-editor-with-variables/index.ts +7 -0
  103. package/src/components/prompt-editor-with-variables/prompt-editor-with-variables.vue +19 -0
  104. package/src/components/prompt-editor-with-variables/types.ts +8 -0
  105. package/src/components/sql-editor-with-variables/index.ts +7 -0
  106. package/src/components/sql-editor-with-variables/sql-editor-with-variables.vue +24 -0
  107. package/src/components/sql-editor-with-variables/types.ts +8 -0
  108. package/src/components/type-selector/index.ts +11 -0
  109. package/src/components/type-selector/type-selector.vue +79 -0
  110. package/src/components/type-selector/types.ts +33 -0
  111. package/src/components/variable-selector/context.ts +44 -0
  112. package/src/components/variable-selector/index.ts +13 -0
  113. package/src/components/variable-selector/styles.css +70 -0
  114. package/src/components/variable-selector/types.ts +22 -0
  115. package/src/components/variable-selector/use-variable-tree.ts +108 -0
  116. package/src/components/variable-selector/variable-selector.vue +139 -0
  117. package/src/effects/auto-rename-ref/index.ts +109 -0
  118. package/src/effects/index.ts +12 -0
  119. package/src/effects/listen-ref-schema-change/index.ts +56 -0
  120. package/src/effects/listen-ref-value-change/index.ts +53 -0
  121. package/src/effects/provide-batch-input/index.ts +40 -0
  122. package/src/effects/provide-json-schema-outputs/index.ts +23 -0
  123. package/src/effects/sync-variable-title/index.ts +25 -0
  124. package/src/effects/validate-when-variable-sync/index.ts +34 -0
  125. package/src/env.d.ts +12 -0
  126. package/src/form-plugins/batch-outputs-plugin/index.ts +120 -0
  127. package/src/form-plugins/index.ts +8 -0
  128. package/src/form-plugins/infer-assign-plugin/index.ts +87 -0
  129. package/src/form-plugins/infer-inputs-plugin/index.ts +85 -0
  130. package/src/hooks/index.ts +6 -0
  131. package/src/hooks/use-object-list/index.ts +161 -0
  132. package/src/index.ts +125 -0
  133. package/src/plugins/disable-declaration-plugin/create-disable-declaration-plugin.ts +27 -0
  134. package/src/plugins/disable-declaration-plugin/index.ts +6 -0
  135. package/src/plugins/index.ts +16 -0
  136. package/src/plugins/json-schema-preset/create-type-preset-plugin.ts +35 -0
  137. package/src/plugins/json-schema-preset/index.ts +25 -0
  138. package/src/plugins/json-schema-preset/type-definition/array.ts +38 -0
  139. package/src/plugins/json-schema-preset/type-definition/boolean.ts +47 -0
  140. package/src/plugins/json-schema-preset/type-definition/date-time.ts +60 -0
  141. package/src/plugins/json-schema-preset/type-definition/enum.ts +31 -0
  142. package/src/plugins/json-schema-preset/type-definition/index.ts +37 -0
  143. package/src/plugins/json-schema-preset/type-definition/integer.ts +47 -0
  144. package/src/plugins/json-schema-preset/type-definition/map.ts +34 -0
  145. package/src/plugins/json-schema-preset/type-definition/number.ts +46 -0
  146. package/src/plugins/json-schema-preset/type-definition/object.ts +34 -0
  147. package/src/plugins/json-schema-preset/type-definition/string.ts +52 -0
  148. package/src/plugins/json-schema-preset/types.ts +25 -0
  149. package/src/plugins/json-schema-preset/vue.ts +38 -0
  150. package/src/shared/flow-value/index.ts +17 -0
  151. package/src/shared/flow-value/schema.ts +38 -0
  152. package/src/shared/flow-value/types.ts +49 -0
  153. package/src/shared/flow-value/utils.ts +213 -0
  154. package/src/shared/format-legacy-refs/index.ts +158 -0
  155. package/src/shared/format-legacy-refs/readme.md +38 -0
  156. package/src/shared/index.ts +32 -0
  157. package/src/shared/inject-material/index.ts +50 -0
  158. package/src/shared/lazy-suspense/index.ts +20 -0
  159. package/src/shared/polyfill-create-root/index.ts +38 -0
  160. package/src/ui/fg-button.vue +27 -0
  161. package/src/ui/fg-cascader.vue +92 -0
  162. package/src/ui/fg-checkbox.vue +25 -0
  163. package/src/ui/fg-icon-button.vue +31 -0
  164. package/src/ui/fg-input.vue +50 -0
  165. package/src/ui/fg-modal.vue +37 -0
  166. package/src/ui/fg-popover.vue +19 -0
  167. package/src/ui/fg-select.vue +81 -0
  168. package/src/ui/fg-tag.vue +37 -0
  169. package/src/ui/fg-textarea.vue +42 -0
  170. package/src/ui/fg-tree-nodes.vue +48 -0
  171. package/src/ui/fg-tree-select.vue +86 -0
  172. package/src/ui/icons.ts +60 -0
  173. package/src/ui/index.ts +20 -0
  174. package/src/ui/styles.css +277 -0
  175. package/src/ui/types.ts +36 -0
  176. package/src/validate/index.ts +6 -0
  177. package/src/validate/validate-flow-value/index.ts +62 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { CSSProperties } from 'vue';
7
+ import { IJsonSchema } from '@flowgram-vue/json-schema';
8
+
9
+ export interface TypeSelectorProps {
10
+ value?: Partial<IJsonSchema>;
11
+ onChange?: (value?: Partial<IJsonSchema>) => void;
12
+ readonly?: boolean;
13
+ disabled?: boolean;
14
+ style?: CSSProperties;
15
+ }
16
+
17
+ export const getTypeSelectValue = (value?: Partial<IJsonSchema>): string[] | undefined => {
18
+ if (value?.type === 'array' && value?.items) {
19
+ return [value.type, ...(getTypeSelectValue(value.items) || [])];
20
+ }
21
+
22
+ return value?.type ? [value.type] : undefined;
23
+ };
24
+
25
+ export const parseTypeSelectValue = (value?: string[]): Partial<IJsonSchema> | undefined => {
26
+ const [type, ...subTypes] = value || [];
27
+
28
+ if (type === 'array') {
29
+ return { type: 'array', items: parseTypeSelectValue(subTypes) };
30
+ }
31
+
32
+ return { type };
33
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { computed, defineComponent, inject, provide, type InjectionKey, type PropType, type VNode } from 'vue';
7
+ import { IJsonSchema } from '@flowgram-vue/json-schema';
8
+ import { BaseVariableField } from '@flowgram-vue/variable-core';
9
+
10
+ type VariableField = BaseVariableField<{
11
+ icon?: string | VNode;
12
+ title?: string;
13
+ disabled?: boolean;
14
+ }>;
15
+
16
+ export interface VariableSelectorContextValue {
17
+ includeSchema?: IJsonSchema | IJsonSchema[];
18
+ excludeSchema?: IJsonSchema | IJsonSchema[];
19
+ skipVariable?: (variable: VariableField) => boolean;
20
+ }
21
+
22
+ const VariableSelectorContextKey: InjectionKey<VariableSelectorContextValue> =
23
+ Symbol('VariableSelectorContext');
24
+
25
+ export const useVariableSelectorContext = () =>
26
+ inject(VariableSelectorContextKey, {} as VariableSelectorContextValue);
27
+
28
+ export const VariableSelectorProvider = defineComponent({
29
+ name: 'VariableSelectorProvider',
30
+ props: {
31
+ skipVariable: { type: Function as PropType<(variable?: BaseVariableField) => boolean> },
32
+ includeSchema: { type: [Object, Array] as PropType<IJsonSchema | IJsonSchema[]> },
33
+ excludeSchema: { type: [Object, Array] as PropType<IJsonSchema | IJsonSchema[]> },
34
+ },
35
+ setup(props, { slots }) {
36
+ const context = computed(() => ({
37
+ skipVariable: props.skipVariable,
38
+ includeSchema: props.includeSchema,
39
+ excludeSchema: props.excludeSchema,
40
+ }));
41
+ provide(VariableSelectorContextKey, context as unknown as VariableSelectorContextValue);
42
+ return () => slots.default?.();
43
+ },
44
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import VariableSelector from './variable-selector.vue';
7
+ import { createInjectMaterial } from '@/shared';
8
+
9
+ export { default as VariableSelector } from './variable-selector.vue';
10
+ export const InjectVariableSelector = createInjectMaterial(VariableSelector);
11
+ export { VariableSelectorProvider, useVariableSelectorContext } from './context';
12
+ export { useVariableTree } from './use-variable-tree';
13
+ export type { VariableSelectorProps } from './types';
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ .gedit-m-variable-selector-root-title {
7
+ margin-right: 4px;
8
+ min-width: 20px;
9
+ overflow: hidden;
10
+ text-overflow: ellipsis;
11
+ white-space: nowrap;
12
+ color: var(--semi-color-text-2);
13
+ }
14
+
15
+ .gedit-m-variable-selector-var-name {
16
+ overflow: hidden;
17
+ text-overflow: ellipsis;
18
+ white-space: nowrap;
19
+
20
+ &.in-selector {
21
+ min-width: 50%;
22
+ }
23
+ }
24
+
25
+ .gedit-m-variable-selector-tag {
26
+ width: 100%;
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: flex-start;
30
+ margin: 0;
31
+ height: 22px;
32
+
33
+ .semi-tag-content-center {
34
+ justify-content: flex-start;
35
+ }
36
+ }
37
+
38
+ .gedit-m-variable-selector-tree-select {
39
+ outline: none;
40
+
41
+ &.error {
42
+ outline: 1px solid red;
43
+ }
44
+
45
+ .semi-tree-select-selection {
46
+ padding: 0px;
47
+ height: 22px;
48
+ }
49
+
50
+ .semi-tree-select-selection-content {
51
+ width: 100%;
52
+ }
53
+
54
+ .semi-tree-select-selection-placeholder {
55
+ padding-left: 10px;
56
+ }
57
+ }
58
+
59
+ .gedit-m-variable-selector-tag-pop {
60
+ padding: 10px;
61
+ display: inline-flex;
62
+ align-items: center;
63
+ justify-content: flex-start;
64
+ white-space: nowrap;
65
+ }
66
+
67
+ .gedit-m-variable-selector-dropdown {
68
+ max-height: 300px;
69
+ overflow: auto;
70
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import type { CSSProperties, VNode } from 'vue';
7
+ import { IJsonSchema } from '@flowgram-vue/json-schema';
8
+
9
+ export interface VariableSelectorProps {
10
+ value?: string[];
11
+ config?: {
12
+ placeholder?: string;
13
+ notFoundContent?: string;
14
+ };
15
+ onChange: (value?: string[]) => void;
16
+ includeSchema?: IJsonSchema | IJsonSchema[];
17
+ excludeSchema?: IJsonSchema | IJsonSchema[];
18
+ readonly?: boolean;
19
+ hasError?: boolean;
20
+ style?: CSSProperties;
21
+ triggerRender?: () => VNode;
22
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { computed, h, type ComputedRef, type VNode } from 'vue';
7
+ import {
8
+ IJsonSchema,
9
+ JsonSchemaTypeManager,
10
+ JsonSchemaUtils,
11
+ useTypeManager,
12
+ } from '@flowgram-vue/json-schema';
13
+ import { ASTMatch, BaseVariableField, useAvailableVariables } from '@flowgram-vue/variable-core';
14
+
15
+ import type { FgTreeNode } from '@/ui';
16
+
17
+ import { useVariableSelectorContext } from './context';
18
+
19
+ type VariableField = BaseVariableField<{
20
+ icon?: string | VNode;
21
+ title?: string;
22
+ disabled?: boolean;
23
+ }>;
24
+
25
+ export function useVariableTree(params: {
26
+ includeSchema?: IJsonSchema | IJsonSchema[];
27
+ excludeSchema?: IJsonSchema | IJsonSchema[];
28
+ skipVariable?: (variable: VariableField) => boolean;
29
+ }): ComputedRef<FgTreeNode[]> {
30
+ const context = useVariableSelectorContext();
31
+ const typeManager = useTypeManager() as JsonSchemaTypeManager;
32
+ const variables = useAvailableVariables();
33
+
34
+ const getVariableTypeIcon = (variable: VariableField) => {
35
+ if (variable.meta?.icon) {
36
+ if (typeof variable.meta.icon === 'string') {
37
+ return h('img', {
38
+ style: { marginRight: '8px' },
39
+ width: 12,
40
+ height: 12,
41
+ src: variable.meta.icon,
42
+ });
43
+ }
44
+ return variable.meta.icon;
45
+ }
46
+
47
+ const schema = JsonSchemaUtils.astToSchema(variable.type, { drilldownObject: false });
48
+ return typeManager.getDisplayIcon(schema || {});
49
+ };
50
+
51
+ return computed(() => {
52
+ const includeSchema = params.includeSchema ?? context.includeSchema;
53
+ const excludeSchema = params.excludeSchema ?? context.excludeSchema;
54
+ const skipVariable = params.skipVariable ?? context.skipVariable;
55
+
56
+ const renderVariable = (
57
+ variable: VariableField,
58
+ parentFields: VariableField[] = []
59
+ ): FgTreeNode | null => {
60
+ const type = variable?.type;
61
+
62
+ if (!type) {
63
+ return null;
64
+ }
65
+
66
+ let children: FgTreeNode[] | undefined;
67
+
68
+ if (ASTMatch.isObject(type)) {
69
+ children = (type.properties || [])
70
+ .map((_property) => renderVariable(_property as VariableField, [...parentFields, variable]))
71
+ .filter(Boolean) as FgTreeNode[];
72
+ }
73
+
74
+ const keyPath = [...parentFields.map((_field) => _field.key), variable.key];
75
+ const key = keyPath.join('.');
76
+
77
+ const isSchemaInclude = includeSchema
78
+ ? JsonSchemaUtils.isASTMatchSchema(type, includeSchema)
79
+ : true;
80
+ const isSchemaExclude = excludeSchema
81
+ ? JsonSchemaUtils.isASTMatchSchema(type, excludeSchema)
82
+ : false;
83
+ const isCustomSkip = skipVariable ? skipVariable(variable) : false;
84
+ const isMetaDisabled = variable.meta?.disabled;
85
+ const isSchemaMatch = isSchemaInclude && !isSchemaExclude && !isCustomSkip && !isMetaDisabled;
86
+
87
+ if (!isSchemaMatch && !children?.length) {
88
+ return null;
89
+ }
90
+
91
+ return {
92
+ key,
93
+ label: variable.meta?.title || variable.key,
94
+ value: key,
95
+ keyPath,
96
+ icon: getVariableTypeIcon(variable),
97
+ children,
98
+ disabled: !isSchemaMatch,
99
+ rootMeta: parentFields[0]?.meta || variable.meta,
100
+ isRoot: !parentFields?.length,
101
+ };
102
+ };
103
+
104
+ return [...variables.value.slice(0).reverse()]
105
+ .map((_variable) => renderVariable(_variable as VariableField))
106
+ .filter(Boolean) as FgTreeNode[];
107
+ });
108
+ }
@@ -0,0 +1,139 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+
7
+ import { defineComponent, h, type PropType, type CSSProperties, type VNode } from 'vue';
8
+ import { IJsonSchema } from '@flowgram-vue/json-schema';
9
+ import { I18n } from '@flowgram-vue/i18n';
10
+
11
+ import { FgPopover, FgTag, FgTreeSelect, IconIssueStroked, type FgTreeNode } from '@/ui';
12
+
13
+ import { useVariableTree } from './use-variable-tree';
14
+ import { useVariableSelectorContext } from './context';
15
+
16
+ import './styles.css';
17
+
18
+ const VariableSelectorImpl = defineComponent({
19
+ name: 'VariableSelector',
20
+ props: {
21
+ value: { type: Array as unknown as PropType<string[]> },
22
+ config: { type: Object as PropType<{ placeholder?: string; notFoundContent?: string }> },
23
+ includeSchema: { type: [Object, Array] as PropType<IJsonSchema | IJsonSchema[]> },
24
+ excludeSchema: { type: [Object, Array] as PropType<IJsonSchema | IJsonSchema[]> },
25
+ readonly: { type: Boolean, default: false },
26
+ hasError: { type: Boolean, default: false },
27
+ style: { type: Object as PropType<CSSProperties> },
28
+ triggerRender: { type: Function as PropType<() => VNode> },
29
+ },
30
+ emits: ['change'],
31
+ setup(props, { emit }) {
32
+ const { skipVariable } = useVariableSelectorContext();
33
+ const treeData = useVariableTree({
34
+ get includeSchema() {
35
+ return props.includeSchema;
36
+ },
37
+ get excludeSchema() {
38
+ return props.excludeSchema;
39
+ },
40
+ skipVariable,
41
+ });
42
+
43
+ const treeValue = computed(() => {
44
+ if (typeof props.value === 'string') {
45
+ return props.value;
46
+ }
47
+ return props.value?.join('.');
48
+ });
49
+
50
+ const renderIcon = (icon?: VNode | string) => {
51
+ if (!icon) {
52
+ return undefined;
53
+ }
54
+ if (typeof icon === 'string') {
55
+ return h('img', { style: { marginRight: '8px' }, width: 12, height: 12, src: icon });
56
+ }
57
+ return icon;
58
+ };
59
+
60
+ return () =>
61
+ h(
62
+ FgTreeSelect,
63
+ {
64
+ class: `gedit-m-variable-selector-tree-select ${props.hasError ? 'error' : ''}`,
65
+ style: props.style,
66
+ disabled: props.readonly,
67
+ treeData: treeData.value,
68
+ value: treeValue.value,
69
+ error: props.hasError,
70
+ placeholder: props.config?.placeholder ?? I18n.t('Select Variable'),
71
+ triggerRender: props.triggerRender,
72
+ onChange: (_path: string[] | undefined, node?: FgTreeNode) => {
73
+ emit('change', node?.keyPath as string[] | undefined);
74
+ },
75
+ },
76
+ {
77
+ selected: ({ option }: { option?: FgTreeNode }) => {
78
+ if (!option?.keyPath) {
79
+ return h(
80
+ FgTag,
81
+ {
82
+ class: 'gedit-m-variable-selector-tag',
83
+ color: 'amber',
84
+ closable: !props.readonly,
85
+ prefixIcon: IconIssueStroked(),
86
+ onClose: () => emit('change', undefined),
87
+ },
88
+ () => props.config?.notFoundContent ?? 'Undefined'
89
+ );
90
+ }
91
+
92
+ const rootIcon = renderIcon(option.rootMeta?.icon || option?.icon);
93
+ const rootTitle = option.rootMeta?.title
94
+ ? `${option.rootMeta?.title} ${option.isRoot ? '' : '-'} `
95
+ : null;
96
+
97
+ return h(FgPopover, {}, {
98
+ default: () =>
99
+ h(
100
+ FgTag,
101
+ {
102
+ class: 'gedit-m-variable-selector-tag',
103
+ prefixIcon: rootIcon,
104
+ closable: !props.readonly,
105
+ onClose: () => emit('change', undefined),
106
+ },
107
+ () => [
108
+ h('div', { class: 'gedit-m-variable-selector-root-title' }, rootTitle),
109
+ !option.isRoot
110
+ ? h(
111
+ 'div',
112
+ { class: 'gedit-m-variable-selector-var-name in-selector' },
113
+ option.label
114
+ )
115
+ : null,
116
+ ]
117
+ ),
118
+ content: () =>
119
+ h('div', { class: 'gedit-m-variable-selector-tag-pop' }, [
120
+ rootIcon,
121
+ h('div', { class: 'gedit-m-variable-selector-root-title' }, rootTitle),
122
+ h(
123
+ 'div',
124
+ { class: 'gedit-m-variable-selector-var-name' },
125
+ option.keyPath.slice(1).join('.')
126
+ ),
127
+ ]),
128
+ });
129
+ },
130
+ }
131
+ );
132
+ },
133
+ });
134
+
135
+ (VariableSelectorImpl as typeof VariableSelectorImpl & { renderKey: string }).renderKey =
136
+ 'variable-selector-render-key';
137
+
138
+ export default VariableSelectorImpl;
139
+ </script>
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { VariableFieldKeyRenameService } from '@flowgram-vue/variable-core';
7
+ import { DataEvent, type Effect, type EffectOptions } from '@flowgram-vue/node';
8
+
9
+ import { IFlowRefValue, IFlowTemplateValue } from '@/shared';
10
+ import { FlowValueUtils } from '@/shared';
11
+
12
+ /**
13
+ * Auto rename ref when form item's key is renamed
14
+ *
15
+ * Example:
16
+ *
17
+ * formMeta: {
18
+ * effects: {
19
+ * "inputsValues": autoRenameRefEffect,
20
+ * }
21
+ * }
22
+ */
23
+ export const autoRenameRefEffect: EffectOptions[] = [
24
+ {
25
+ event: DataEvent.onValueInit,
26
+ effect: ((params) => {
27
+ const { context, form, name } = params;
28
+
29
+ const renameService = context.node.getService(VariableFieldKeyRenameService);
30
+
31
+ const disposable = renameService.onRename(({ before, after }) => {
32
+ const beforeKeyPath = [
33
+ ...before.parentFields.map((_field) => _field.key).reverse(),
34
+ before.key,
35
+ ];
36
+ const afterKeyPath = [
37
+ ...after.parentFields.map((_field) => _field.key).reverse(),
38
+ after.key,
39
+ ];
40
+
41
+ // traverse rename refs inside form item 'name'
42
+ traverseRef(name, form.getValueIn(name), (_drilldownName, _v) => {
43
+ if (_v.type === 'ref') {
44
+ // ref auto rename
45
+ if (isKeyPathMatch(_v.content, beforeKeyPath)) {
46
+ _v.content = [...afterKeyPath, ...(_v.content || [])?.slice(beforeKeyPath.length)];
47
+ form.setValueIn(_drilldownName, _v);
48
+ }
49
+ } else if (_v.type === 'template') {
50
+ // template auto rename
51
+ const templateKeyPaths = FlowValueUtils.getTemplateKeyPaths(_v);
52
+ let hasMatch = false;
53
+
54
+ templateKeyPaths.forEach((_keyPath) => {
55
+ if (isKeyPathMatch(_keyPath, beforeKeyPath)) {
56
+ hasMatch = true;
57
+ const nextKeyPath = [
58
+ ...afterKeyPath,
59
+ ...(_keyPath || [])?.slice(beforeKeyPath.length),
60
+ ];
61
+ _v.content = _v.content?.replace(
62
+ `{{${_keyPath.join('.')}}`,
63
+ `{{${nextKeyPath.join('.')}}`
64
+ );
65
+ }
66
+ });
67
+
68
+ if (hasMatch) {
69
+ form.setValueIn(_drilldownName, { ..._v });
70
+ }
71
+ }
72
+ });
73
+ });
74
+
75
+ return () => {
76
+ disposable.dispose();
77
+ };
78
+ }) as Effect,
79
+ },
80
+ ];
81
+
82
+ /**
83
+ * If ref value's keyPath is the under as targetKeyPath
84
+ * @param value
85
+ * @param targetKeyPath
86
+ * @returns
87
+ */
88
+ function isKeyPathMatch(keyPath: string[] = [], targetKeyPath: string[]) {
89
+ return targetKeyPath.every((_key, index) => _key === keyPath[index]);
90
+ }
91
+
92
+ /**
93
+ * Traverse value to find ref
94
+ * @param value
95
+ * @param options
96
+ * @returns
97
+ */
98
+ function traverseRef(
99
+ name: string,
100
+ value: any,
101
+ cb: (name: string, _v: IFlowRefValue | IFlowTemplateValue) => void
102
+ ) {
103
+ for (const { value: _v, path } of FlowValueUtils.traverse(value, {
104
+ includeTypes: ['ref', 'template'],
105
+ path: name,
106
+ })) {
107
+ cb(path, _v as IFlowRefValue | IFlowTemplateValue);
108
+ }
109
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { autoRenameRefEffect } from './auto-rename-ref';
7
+ export { listenRefSchemaChange } from './listen-ref-schema-change';
8
+ export { listenRefValueChange } from './listen-ref-value-change';
9
+ export { provideBatchInputEffect } from './provide-batch-input';
10
+ export { provideJsonSchemaOutputs } from './provide-json-schema-outputs';
11
+ export { syncVariableTitle } from './sync-variable-title';
12
+ export { validateWhenVariableSync } from './validate-when-variable-sync';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { IJsonSchema, JsonSchemaUtils } from '@flowgram-vue/json-schema';
7
+ import { BaseType } from '@flowgram-vue/variable-core';
8
+ import { getNodeScope } from '@flowgram-vue/variable-layout';
9
+ import {
10
+ DataEvent,
11
+ type Effect,
12
+ type EffectFuncProps,
13
+ type EffectOptions,
14
+ } from '@flowgram-vue/node';
15
+
16
+ import { IFlowRefValue } from '@/shared';
17
+
18
+ /**
19
+ * Example:
20
+ * const formMeta = {
21
+ * effect: {
22
+ * 'inputsValues.*': listenRefSchemaChange(({ name, schema, form }) => {
23
+ * form.setValueIn(`${name}.schema`, schema);
24
+ * })
25
+ * }
26
+ * }
27
+ * @param cb
28
+ * @returns
29
+ */
30
+ export const listenRefSchemaChange = (
31
+ cb: (props: EffectFuncProps<IFlowRefValue> & { schema?: IJsonSchema }) => void
32
+ ): EffectOptions[] => [
33
+ {
34
+ event: DataEvent.onValueInitOrChange,
35
+ effect: ((params) => {
36
+ const { context, value } = params;
37
+
38
+ if (value?.type !== 'ref') {
39
+ return () => null;
40
+ }
41
+
42
+ const disposable = getNodeScope(context.node).available.trackByKeyPath<BaseType | undefined>(
43
+ value?.content || [],
44
+ (_type) => {
45
+ cb({ ...params, schema: JsonSchemaUtils.astToSchema(_type) });
46
+ },
47
+ {
48
+ selector: (_v) => _v?.type,
49
+ }
50
+ );
51
+ return () => {
52
+ disposable.dispose();
53
+ };
54
+ }) as Effect,
55
+ },
56
+ ];
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { BaseVariableField } from '@flowgram-vue/variable-core';
7
+ import { getNodeScope } from '@flowgram-vue/variable-layout';
8
+ import {
9
+ DataEvent,
10
+ type Effect,
11
+ type EffectFuncProps,
12
+ type EffectOptions,
13
+ } from '@flowgram-vue/node';
14
+
15
+ import { IFlowRefValue } from '@/shared';
16
+
17
+ /**
18
+ * Example:
19
+ * const formMeta = {
20
+ * effect: {
21
+ * 'inputsValues.*': listenRefValueChange(({ name, variable, form }) => {
22
+ * const schema = JsonSchemaUtils.astToSchema(variable?.type);
23
+ * form.setValueIn(`${name}.schema`, schema);
24
+ * })
25
+ * }
26
+ * }
27
+ * @param cb
28
+ * @returns
29
+ */
30
+ export const listenRefValueChange = (
31
+ cb: (props: EffectFuncProps<IFlowRefValue> & { variable?: BaseVariableField }) => void
32
+ ): EffectOptions[] => [
33
+ {
34
+ event: DataEvent.onValueInitOrChange,
35
+ effect: ((params) => {
36
+ const { context, value } = params;
37
+
38
+ if (value?.type !== 'ref') {
39
+ return () => null;
40
+ }
41
+
42
+ const disposable = getNodeScope(context.node).available.trackByKeyPath(
43
+ value?.content || [],
44
+ (v) => {
45
+ cb({ ...params, variable: v });
46
+ }
47
+ );
48
+ return () => {
49
+ disposable.dispose();
50
+ };
51
+ }) as Effect,
52
+ },
53
+ ];