@flowgram.ai/form-materials 0.3.2 → 0.3.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/form-materials",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "homepage": "https://flowgram.ai/",
5
5
  "repository": "https://github.com/bytedance/flowgram.ai",
6
6
  "license": "MIT",
@@ -34,8 +34,8 @@
34
34
  "@codemirror/view": "~6.38.0",
35
35
  "@codemirror/state": "~6.5.2",
36
36
  "typescript": "^5.8.3",
37
- "@flowgram.ai/json-schema": "0.3.2",
38
- "@flowgram.ai/editor": "0.3.2"
37
+ "@flowgram.ai/editor": "0.3.4",
38
+ "@flowgram.ai/json-schema": "0.3.4"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/lodash": "^4.14.137",
@@ -51,8 +51,8 @@
51
51
  "tsup": "^8.0.1",
52
52
  "typescript": "^5.8.3",
53
53
  "vitest": "^0.34.6",
54
- "@flowgram.ai/ts-config": "0.3.2",
55
- "@flowgram.ai/eslint-config": "0.3.2"
54
+ "@flowgram.ai/eslint-config": "0.3.4",
55
+ "@flowgram.ai/ts-config": "0.3.4"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "react": ">=16.8",
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { IRules, Op, OpConfigs } from './types';
7
7
 
8
- export const rules: IRules = {
8
+ export const defaultRules: IRules = {
9
9
  string: {
10
10
  [Op.EQ]: 'string',
11
11
  [Op.NEQ]: 'string',
@@ -62,7 +62,7 @@ export const rules: IRules = {
62
62
  },
63
63
  };
64
64
 
65
- export const opConfigs: OpConfigs = {
65
+ export const defaultOpConfigs: OpConfigs = {
66
66
  [Op.EQ]: {
67
67
  label: 'Equal',
68
68
  abbreviation: '=',
@@ -5,30 +5,34 @@
5
5
 
6
6
  import React, { useMemo } from 'react';
7
7
 
8
+ import { I18n } from '@flowgram.ai/editor';
8
9
  import { Button, Select } from '@douyinfe/semi-ui';
9
10
  import { IconChevronDownStroked } from '@douyinfe/semi-icons';
10
11
 
11
- import { IRule, Op } from '../types';
12
- import { opConfigs } from '../constants';
12
+ import { IRule, OpConfigs } from '../types';
13
+ import { defaultOpConfigs } from '../constants';
13
14
 
14
15
  interface HookParams {
15
16
  rule?: IRule;
16
- op?: Op;
17
- onChange: (op: Op) => void;
17
+ op?: string;
18
+ onChange: (op: string) => void;
18
19
  readonly?: boolean;
20
+ userOps?: OpConfigs;
19
21
  }
20
22
 
21
- export function useOp({ rule, op, onChange, readonly }: HookParams) {
23
+ export function useOp({ rule, op, onChange, readonly, userOps }: HookParams) {
22
24
  const options = useMemo(
23
25
  () =>
24
26
  Object.keys(rule || {}).map((_op) => ({
25
- ...(opConfigs[_op as Op] || {}),
27
+ ...(defaultOpConfigs[_op] || {}),
28
+ ...(userOps?.[_op] || {}),
26
29
  value: _op,
30
+ label: I18n.t(userOps?.[_op]?.label || defaultOpConfigs[_op]?.label),
27
31
  })),
28
- [rule]
32
+ [rule, userOps]
29
33
  );
30
34
 
31
- const opConfig = useMemo(() => opConfigs[op as Op], [op]);
35
+ const opConfig = useMemo(() => defaultOpConfigs[op as string], [op]);
32
36
 
33
37
  const renderOpSelect = () => (
34
38
  <Select
@@ -38,7 +42,7 @@ export function useOp({ rule, op, onChange, readonly }: HookParams) {
38
42
  value={op}
39
43
  optionList={options}
40
44
  onChange={(v) => {
41
- onChange(v as Op);
45
+ onChange(v as string);
42
46
  }}
43
47
  triggerRender={({ value }) => (
44
48
  <Button size="small" disabled={!rule}>
@@ -8,12 +8,15 @@ import { useMemo } from 'react';
8
8
  import { JsonSchemaUtils, JsonSchemaBasicType } from '@flowgram.ai/json-schema';
9
9
  import { useScopeAvailable } from '@flowgram.ai/editor';
10
10
 
11
- import { rules } from '../constants';
11
+ import { IRules } from '../types';
12
+ import { defaultRules } from '../constants';
12
13
  import { IFlowRefValue } from '../../../typings';
13
14
 
14
- export function useRule(left?: IFlowRefValue) {
15
+ export function useRule(left?: IFlowRefValue, userRules?: IRules) {
15
16
  const available = useScopeAvailable();
16
17
 
18
+ const rules = useMemo(() => ({ ...defaultRules, ...(userRules || {}) }), [userRules]);
19
+
17
20
  const variable = useMemo(() => {
18
21
  if (!left) return undefined;
19
22
  return available.getByKeyPath(left.content);
@@ -25,7 +28,7 @@ export function useRule(left?: IFlowRefValue) {
25
28
  const schema = JsonSchemaUtils.astToSchema(variable.type, { drilldown: false });
26
29
 
27
30
  return rules[schema?.type as JsonSchemaBasicType];
28
- }, [variable?.type]);
31
+ }, [variable?.type, rules]);
29
32
 
30
33
  return { rule };
31
34
  }
@@ -5,10 +5,10 @@
5
5
 
6
6
  import React, { useMemo } from 'react';
7
7
 
8
- import { JsonSchemaBasicType } from '@flowgram.ai/json-schema';
8
+ import { I18n } from '@flowgram.ai/editor';
9
9
  import { Input } from '@douyinfe/semi-ui';
10
10
 
11
- import { ConditionRowValueType, Op } from './types';
11
+ import { ConditionRowValueType, IRules, OpConfigs } from './types';
12
12
  import { UIContainer, UILeft, UIOperator, UIRight, UIValues } from './styles';
13
13
  import { useRule } from './hooks/useRule';
14
14
  import { useOp } from './hooks/useOp';
@@ -20,20 +20,36 @@ interface PropTypes {
20
20
  onChange: (value?: ConditionRowValueType) => void;
21
21
  style?: React.CSSProperties;
22
22
  readonly?: boolean;
23
+ ruleConfig?: {
24
+ ops?: OpConfigs;
25
+ rules?: IRules;
26
+ };
23
27
  }
24
28
 
25
- export function ConditionRow({ style, value, onChange, readonly }: PropTypes) {
29
+ const defaultRuleConfig = {
30
+ ops: {},
31
+ rules: {},
32
+ };
33
+
34
+ export function ConditionRow({
35
+ style,
36
+ value,
37
+ onChange,
38
+ readonly,
39
+ ruleConfig = defaultRuleConfig,
40
+ }: PropTypes) {
26
41
  const { left, operator, right } = value || {};
27
- const { rule } = useRule(left);
42
+ const { rule } = useRule(left, ruleConfig.rules);
28
43
  const { renderOpSelect, opConfig } = useOp({
29
44
  rule,
30
45
  op: operator,
31
46
  onChange: (v) => onChange({ ...value, operator: v }),
32
47
  readonly,
48
+ userOps: ruleConfig.ops,
33
49
  });
34
50
 
35
51
  const targetSchema = useMemo(() => {
36
- const targetType: JsonSchemaBasicType | null = rule?.[operator as Op] || null;
52
+ const targetType: string | null = rule?.[operator || ''] || null;
37
53
  return targetType ? { type: targetType, extra: { weak: true } } : null;
38
54
  }, [rule, opConfig]);
39
55
 
@@ -70,7 +86,7 @@ export function ConditionRow({ style, value, onChange, readonly }: PropTypes) {
70
86
  size="small"
71
87
  disabled
72
88
  style={{ pointerEvents: 'none' }}
73
- value={opConfig?.rightDisplay || 'Empty'}
89
+ value={opConfig?.rightDisplay || I18n.t('Empty')}
74
90
  />
75
91
  )}
76
92
  </UIRight>
@@ -3,8 +3,6 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
- import { JsonSchemaBasicType } from '@flowgram.ai/json-schema';
7
-
8
6
  import { IFlowConstantRefValue, IFlowRefValue } from '../../typings';
9
7
 
10
8
  export enum Op {
@@ -31,14 +29,14 @@ export interface OpConfig {
31
29
  rightDisplay?: string;
32
30
  }
33
31
 
34
- export type OpConfigs = Record<Op, OpConfig>;
32
+ export type OpConfigs = Record<string, OpConfig>;
35
33
 
36
- export type IRule = Partial<Record<Op, JsonSchemaBasicType | null>>;
34
+ export type IRule = Partial<Record<string, string | null>>;
37
35
 
38
- export type IRules = Record<JsonSchemaBasicType, IRule>;
36
+ export type IRules = Record<string, IRule>;
39
37
 
40
38
  export interface ConditionRowValueType {
41
39
  left?: IFlowRefValue;
42
- operator?: Op;
40
+ operator?: string;
43
41
  right?: IFlowConstantRefValue;
44
42
  }
@@ -6,6 +6,7 @@
6
6
  import React, { useMemo, useState } from 'react';
7
7
 
8
8
  import { IJsonSchema } from '@flowgram.ai/json-schema';
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { Button, Checkbox, IconButton } from '@douyinfe/semi-ui';
10
11
  import {
11
12
  IconExpand,
@@ -219,25 +220,27 @@ function PropertyEdit(props: {
219
220
  </UIRow>
220
221
  {expand && (
221
222
  <UIExpandDetail>
222
- <UILabel>{config?.descTitle ?? 'Description'}</UILabel>
223
+ <UILabel>{config?.descTitle ?? I18n.t('Description')}</UILabel>
223
224
  <BlurInput
224
225
  disabled={readonly}
225
226
  size="small"
226
227
  value={description}
227
228
  onChange={(value) => onChange('description', value)}
228
- placeholder={config?.descPlaceholder ?? 'Help LLM to understand the property'}
229
+ placeholder={
230
+ config?.descPlaceholder ?? I18n.t('Help LLM to understand the property')
231
+ }
229
232
  />
230
233
  {$level === 0 && type && type !== 'array' && (
231
234
  <>
232
235
  <UILabel style={{ marginTop: 10 }}>
233
- {config?.defaultValueTitle ?? 'Default Value'}
236
+ {config?.defaultValueTitle ?? I18n.t('Default Value')}
234
237
  </UILabel>
235
238
  <DefaultValueWrapper>
236
239
  <DefaultValue
237
240
  value={defaultValue}
238
241
  schema={value}
239
242
  type={type}
240
- placeholder={config?.defaultValuePlaceholder}
243
+ placeholder={config?.defaultValuePlaceholder ?? I18n.t('Default Value')}
241
244
  jsonFormatText={config?.jsonFormatText}
242
245
  onChange={(value) => onChange('default', value)}
243
246
  />
@@ -23,8 +23,6 @@ interface PropTypes {
23
23
 
24
24
  const labelStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 5 };
25
25
 
26
- const firstUppercase = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);
27
-
28
26
  export const getTypeSelectValue = (value?: Partial<IJsonSchema>): string[] | undefined => {
29
27
  if (value?.type === 'array' && value?.items) {
30
28
  return [value.type, ...(getTypeSelectValue(value.items) || [])];
@@ -61,7 +59,7 @@ export function TypeSelector(props: PropTypes) {
61
59
  label: (
62
60
  <div style={labelStyle}>
63
61
  <Icon size="small" svg={_type.icon} />
64
- {firstUppercase(_type.type)}
62
+ {typeManager.getTypeBySchema(_type)?.label || _type.type}
65
63
  </div>
66
64
  ),
67
65
  value: _type.type,
@@ -76,7 +74,7 @@ export function TypeSelector(props: PropTypes) {
76
74
  items: { type: _type.type },
77
75
  })}
78
76
  />
79
- {firstUppercase(_type.type)}
77
+ {typeManager.getTypeBySchema(_type)?.label || _type.type}
80
78
  </div>
81
79
  ),
82
80
  value: _type.type,
@@ -6,6 +6,7 @@
6
6
  import React, { useMemo } from 'react';
7
7
 
8
8
  import { IJsonSchema } from '@flowgram.ai/json-schema';
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { TriggerRenderProps } from '@douyinfe/semi-ui/lib/es/treeSelect';
10
11
  import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
11
12
  import { Popover } from '@douyinfe/semi-ui';
@@ -130,7 +131,7 @@ export const VariableSelector = ({
130
131
  showClear={false}
131
132
  arrowIcon={<IconChevronDownStroked size="small" />}
132
133
  triggerRender={triggerRender}
133
- placeholder={config?.placeholder ?? 'Select Variable'}
134
+ placeholder={config?.placeholder ?? I18n.t('Select Variable')}
134
135
  />
135
136
  </>
136
137
  );
@@ -8,3 +8,5 @@ export * from './auto-rename-ref';
8
8
  export * from './provide-json-schema-outputs';
9
9
  export * from './sync-variable-title';
10
10
  export * from './validate-when-variable-sync';
11
+ export * from './listen-ref-value-change';
12
+ export * from './listen-ref-schema-change';
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "listen-ref-schema-change",
3
+ "depMaterials": [
4
+ "flow-value"
5
+ ],
6
+ "depPackages": [
7
+ "lodash",
8
+ "@flowgram.ai/json-schema"
9
+ ]
10
+ }
@@ -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.ai/json-schema';
7
+ import {
8
+ BaseType,
9
+ DataEvent,
10
+ Effect,
11
+ EffectFuncProps,
12
+ EffectOptions,
13
+ getNodeScope,
14
+ } from '@flowgram.ai/editor';
15
+
16
+ import { IFlowRefValue } from '../../typings';
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,9 @@
1
+ {
2
+ "name": "listen-ref-value-change",
3
+ "depMaterials": [
4
+ "flow-value"
5
+ ],
6
+ "depPackages": [
7
+ "lodash"
8
+ ]
9
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ BaseVariableField,
8
+ DataEvent,
9
+ Effect,
10
+ EffectFuncProps,
11
+ EffectOptions,
12
+ getNodeScope,
13
+ } from '@flowgram.ai/editor';
14
+
15
+ import { IFlowRefValue } from '../../typings';
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
+ ];
@@ -10,6 +10,7 @@ import {
10
10
  useTypeManager as useOriginTypeManager,
11
11
  TypePresetProvider as OriginTypePresetProvider,
12
12
  JsonSchemaTypeManager,
13
+ type JsonSchemaBasicType,
13
14
  } from '@flowgram.ai/json-schema';
14
15
 
15
16
  import { jsonSchemaTypePreset } from './type-definition';
@@ -36,4 +37,5 @@ export {
36
37
  JsonSchemaUtils,
37
38
  JsonSchemaTypeRegistry,
38
39
  ConstantRendererProps,
40
+ JsonSchemaBasicType,
39
41
  };
@@ -6,6 +6,8 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
10
+
9
11
  import { CodeEditorMini } from '@/components/code-editor-mini';
10
12
 
11
13
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -17,7 +19,7 @@ export const arrayRegistry: Partial<JsonSchemaTypeRegistry> = {
17
19
  value={props.value}
18
20
  languageId="json"
19
21
  onChange={(v) => props.onChange?.(v)}
20
- placeholder="Please Input Array"
22
+ placeholder={I18n.t('Please Input Array')}
21
23
  readonly={props.readonly}
22
24
  />
23
25
  ),
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { Select } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -16,12 +17,12 @@ export const booleanRegistry: Partial<JsonSchemaTypeRegistry> = {
16
17
  const { value, onChange, ...rest } = props;
17
18
  return (
18
19
  <Select
19
- placeholder="Please Select Boolean"
20
+ placeholder={I18n.t('Please Select Boolean')}
20
21
  size="small"
21
22
  disabled={props.readonly}
22
23
  optionList={[
23
- { label: 'True', value: 1 },
24
- { label: 'False', value: 0 },
24
+ { label: I18n.t('True'), value: 1 },
25
+ { label: I18n.t('False'), value: 0 },
25
26
  ]}
26
27
  value={value ? 1 : 0}
27
28
  onChange={(value) => onChange?.(!!value)}
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { InputNumber } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -14,7 +15,7 @@ export const integerRegistry: Partial<JsonSchemaTypeRegistry> = {
14
15
  type: 'integer',
15
16
  ConstantRenderer: (props) => (
16
17
  <InputNumber
17
- placeholder="Please Input Integer"
18
+ placeholder={I18n.t('Please Input Integer')}
18
19
  size="small"
19
20
  disabled={props.readonly}
20
21
  precision={0}
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { InputNumber } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -14,7 +15,7 @@ export const numberRegistry: Partial<JsonSchemaTypeRegistry> = {
14
15
  type: 'number',
15
16
  ConstantRenderer: (props) => (
16
17
  <InputNumber
17
- placeholder="Please Input Number"
18
+ placeholder={I18n.t('Please Input Number')}
18
19
  size="small"
19
20
  disabled={props.readonly}
20
21
  hideButtons
@@ -6,6 +6,8 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
10
+
9
11
  import { CodeEditorMini } from '@/components/code-editor-mini';
10
12
 
11
13
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -17,7 +19,7 @@ export const objectRegistry: Partial<JsonSchemaTypeRegistry> = {
17
19
  value={props.value}
18
20
  onChange={(v) => props.onChange?.(v)}
19
21
  languageId="json"
20
- placeholder="Please Input Object"
22
+ placeholder={I18n.t('Please Input Object')}
21
23
  readonly={props.readonly}
22
24
  />
23
25
  ),
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { Input } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -13,6 +14,11 @@ import { type JsonSchemaTypeRegistry } from '../manager';
13
14
  export const stringRegistry: Partial<JsonSchemaTypeRegistry> = {
14
15
  type: 'string',
15
16
  ConstantRenderer: (props) => (
16
- <Input placeholder="Please Input String" size="small" disabled={props.readonly} {...props} />
17
+ <Input
18
+ placeholder={I18n.t('Please Input String')}
19
+ size="small"
20
+ disabled={props.readonly}
21
+ {...props}
22
+ />
17
23
  ),
18
24
  };