feat(material): Add default value editing function (#292)

* feat(material): Add default value editing function

* style(json-schema-editor): Remove the console.log statements for debugging

* refactor(form-materials): Optimize the export methods of interfaces and utility functions

* refactor(material): Refactor the JSONSchemaEditor's default value input component to use common constant input

* chore: Update dependencies @types/inquirer and @types/node
This commit is contained in:
jzwnju 2025-06-04 20:35:04 +08:00 committed by GitHub
parent 13e2302d9b
commit de072dd4cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 439 additions and 142 deletions

View File

@ -30,8 +30,8 @@
"dependencies": {
"@flowgram.ai/ts-config": "workspace:*",
"@flowgram.ai/eslint-config": "workspace:*",
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.80.0",
"@douyinfe/semi-ui": "^2.80.0",
"@flowgram.ai/fixed-layout-editor": "workspace:*",
"@flowgram.ai/fixed-semi-materials": "workspace:*",
"@flowgram.ai/minimap-plugin": "workspace:*",

View File

@ -28,8 +28,8 @@
"watch": "exit 0"
},
"dependencies": {
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.80.0",
"@douyinfe/semi-ui": "^2.80.0",
"@flowgram.ai/fixed-layout-editor": "workspace:*",
"@flowgram.ai/fixed-semi-materials": "workspace:*",
"@flowgram.ai/form-materials": "workspace:*",

View File

@ -28,8 +28,8 @@
"watch": "exit 0"
},
"dependencies": {
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.80.0",
"@douyinfe/semi-ui": "^2.80.0",
"@flowgram.ai/free-layout-editor": "workspace:*",
"@flowgram.ai/free-snap-plugin": "workspace:*",
"@flowgram.ai/free-lines-plugin": "workspace:*",

View File

@ -28,8 +28,8 @@
"watch": "exit 0"
},
"dependencies": {
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.80.0",
"@douyinfe/semi-ui": "^2.80.0",
"@flowgram.ai/free-layout-editor": "workspace:*",
"@flowgram.ai/free-snap-plugin": "workspace:*",
"@flowgram.ai/minimap-plugin": "workspace:*",

View File

@ -38,8 +38,8 @@
"@flowgram.ai/history": "workspace:*",
"styled-components": "^5",
"nanoid": "^4.0.2",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-ui": "^2.80.0",
"@douyinfe/semi-icons": "^2.80.0",
"typedoc": "0.24.8",
"typedoc-plugin-markdown": "3.17.1",
"react": "^18",

View File

@ -57,11 +57,11 @@ importers:
../../apps/demo-fixed-layout:
dependencies:
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/fixed-layout-editor':
specifier: workspace:*
version: link:../../packages/client/fixed-layout-editor
@ -139,11 +139,11 @@ importers:
../../apps/demo-fixed-layout-simple:
dependencies:
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/eslint-config':
specifier: workspace:*
version: link:../../config/eslint-config
@ -194,11 +194,11 @@ importers:
../../apps/demo-free-layout:
dependencies:
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/form-materials':
specifier: workspace:*
version: link:../../packages/materials/form-materials
@ -419,11 +419,11 @@ importers:
../../apps/demo-node-form:
dependencies:
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/free-layout-editor':
specifier: workspace:*
version: link:../../packages/client/free-layout-editor
@ -639,11 +639,11 @@ importers:
specifier: 2.19.10
version: 2.19.10(react-dom@18.3.1)(react@18.3.1)
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/demo-fixed-layout':
specifier: workspace:*
version: link:../demo-fixed-layout
@ -1867,14 +1867,14 @@ importers:
../../packages/materials/fixed-semi-materials:
dependencies:
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-illustrations':
specifier: ^2.36.0
version: 2.72.0(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/fixed-layout-editor':
specifier: workspace:*
version: link:../../client/fixed-layout-editor
@ -1928,14 +1928,14 @@ importers:
../../packages/materials/form-materials:
dependencies:
'@douyinfe/semi-icons':
specifier: ^2.72.3
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-illustrations':
specifier: ^2.36.0
version: 2.72.3(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(react@18.3.1)
'@douyinfe/semi-ui':
specifier: ^2.72.3
version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
specifier: ^2.80.0
version: 2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1)
'@flowgram.ai/editor':
specifier: workspace:*
version: link:../../client/editor
@ -5419,29 +5419,29 @@ packages:
tslib: 2.8.1
dev: false
/@douyinfe/semi-animation-react@2.72.3:
resolution: {integrity: sha512-OfThQVe3rP1v70Y4SSC5dkrLzNy7QkedbqfQvknqKB2onP7lGB6ePc3K3vACBxEKKL6dXzTlMs6XoR5SBD6iyA==}
/@douyinfe/semi-animation-react@2.80.0:
resolution: {integrity: sha512-DL4nbJOOgiR/xVYQITqzXzYDoW85AhJ5ZwxXWQ/r5hwmuWzhCOg5RbpcCEfj6EM+TOYCkopihrwxC5x2hu+LMw==}
dependencies:
'@douyinfe/semi-animation': 2.72.3
'@douyinfe/semi-animation-styled': 2.72.3
'@douyinfe/semi-animation': 2.80.0
'@douyinfe/semi-animation-styled': 2.80.0
classnames: 2.5.1
dev: false
/@douyinfe/semi-animation-styled@2.72.3:
resolution: {integrity: sha512-ME6DE8UdBRHf00OCgxoA9jjZef/2c/QWpUy7vtkwUIfwENCanpU61apoLk5jprTLG7y/Zq8Vjm4O5h0eMep1pw==}
/@douyinfe/semi-animation-styled@2.80.0:
resolution: {integrity: sha512-4U7z72/yJKhswdnGSG/0AALzLfGn6XHaRlQ8QK63MKYbpEjZeZ0p/Rc9wmngPo8CU7YKXSJeIdsArMZq/pqSlw==}
dev: false
/@douyinfe/semi-animation@2.72.3:
resolution: {integrity: sha512-mZcYZHEIdgPN5cm+jZv8YLRWce3i7VrjZsytEue2DR0/EABFGfiMA4o91TanCTz5NrRZY+iNMyLMDeu6CrvQOQ==}
/@douyinfe/semi-animation@2.80.0:
resolution: {integrity: sha512-wjJr6EbO5TkJcyqx/CyLUdIE62TStfmCVDeMPXUT709OnIecoU1BsB/LGMVsdNQXF0muxb8bBcEb/A9M5mMclQ==}
dependencies:
bezier-easing: 2.1.0
dev: false
/@douyinfe/semi-foundation@2.72.3(acorn@8.14.0):
resolution: {integrity: sha512-ZOMFVryVldh2vsPj7Gf7mE7kqpCngRiPw5N1Ltm2Qr0NGOpwuRir23PYpdMQAAWQUF1BIe3EPrdxrp+lIV9GDA==}
/@douyinfe/semi-foundation@2.80.0(acorn@8.14.0):
resolution: {integrity: sha512-wtrdBXzF3tU1mIKxUgRHH6qhLSlpQhNAXDnnA00JMo4/hXfINzLFd3dOjQpaWxu8TIDq/UF8rDS/Y/1tlmsXzg==}
dependencies:
'@douyinfe/semi-animation': 2.72.3
'@douyinfe/semi-json-viewer-core': 2.72.3
'@douyinfe/semi-animation': 2.80.0
'@douyinfe/semi-json-viewer-core': 2.80.0
'@mdx-js/mdx': 3.1.0(acorn@8.14.0)
async-validator: 3.5.2
classnames: 2.5.1
@ -5459,43 +5459,35 @@ packages:
- supports-color
dev: false
/@douyinfe/semi-icons@2.72.3(react@18.3.1):
resolution: {integrity: sha512-ZsbHin7dJXX4JWpKykqJhH4hlNi9uTHKUi2ylpyMpIl08ROetojkDKj6TcTd9mRMILGpQHCH7hd5uYGo1xb3ew==}
/@douyinfe/semi-icons@2.80.0(react@18.3.1):
resolution: {integrity: sha512-V7fyPdbws/lT3nK/4aneSRgDHEx3AG4njAAEFBW1oOnc/T1+xYbgoDzOlK9lC6DpBzw42/KRrpMrQ236gIRf2w==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react: '>=16.0.0'
dependencies:
classnames: 2.5.1
react: 18.3.1
dev: false
/@douyinfe/semi-illustrations@2.72.0(react@18.3.1):
resolution: {integrity: sha512-8Pr/ms2IRE6FXei8UWQhDJ6oDPWSC/7naDV80ESZUe316N60J1gQFEm64XtZIWzL0QCQSNz9wdl9GRpJL05s/A==}
/@douyinfe/semi-illustrations@2.80.0(react@18.3.1):
resolution: {integrity: sha512-BIgp37ZlVPoyzmClp8UlAOIrJv5SAak61HWZg9DRvckZ2Fm5f39Bz/QJNf15rIiEQKvCobsR37EuECnCYLJ1UQ==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react: '>=16.0.0'
dependencies:
react: 18.3.1
dev: false
/@douyinfe/semi-illustrations@2.72.3(react@18.3.1):
resolution: {integrity: sha512-jfsH/4TogOFQ5dWUdm6X6fVLQzGTjBFVHRyiqSrUnLWVuSqQaUtMRJguxEtcFN9D+fjdvG6sToqTHOygQsAp8Q==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.3.1
dev: false
/@douyinfe/semi-json-viewer-core@2.72.3:
resolution: {integrity: sha512-nzHqlTjS8tyFgfrlAVxCqV4P82JYoUw+bmVs5/05/65vLKLVo5KnDn6VGUfRzFcXJ68d4vMWv5qcrEG/E2aG+Q==}
/@douyinfe/semi-json-viewer-core@2.80.0:
resolution: {integrity: sha512-SU+EsMr3xsxzNvi1QngB9KhfVdXoa9M7rvpw7o0MYnUGE7jFBGICwwh3PKGxOGJqLNjngartgxkFfH3BcCaFgA==}
dependencies:
jsonc-parser: 3.3.1
dev: false
/@douyinfe/semi-theme-default@2.72.3:
resolution: {integrity: sha512-qCR5OCztuIWyLhntcj61kXp02dZCKC4H/12p394rGOkpie8E/MkBQMFvVxFPsasuN3MWWdUNefYsERe4cjXuhw==}
/@douyinfe/semi-theme-default@2.80.0:
resolution: {integrity: sha512-pbQYIJhESsAlva4+syfViHZkayTTL3bMLIjNT1IAdu8fhclCFXXRBNhTFLobZ8qxhlkSyCdFoYer5oSkFoUTDw==}
dev: false
/@douyinfe/semi-ui@2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1):
resolution: {integrity: sha512-7QsusUkzD7gDST3dEPLq1jvaderR8d9RM/Y1h31weZUM1DBVCUIVGDYW6oVFsUKzMAPdeOlTvnFJmPlEL+7k6g==}
/@douyinfe/semi-ui@2.80.0(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1):
resolution: {integrity: sha512-sMYRSGt7peXb6R7PDwsnAoICI3U9Ao2vcOaV2NHuRz6G5NFJJ9svKEup3ehpOgdU2HcAa3mIOh8wvnVYOVoFDg==}
peerDependencies:
react: '>=16.0.0'
react-dom: '>=16.0.0'
@ -5503,12 +5495,12 @@ packages:
'@dnd-kit/core': 6.3.1(react-dom@18.3.1)(react@18.3.1)
'@dnd-kit/sortable': 7.0.2(@dnd-kit/core@6.3.1)(react@18.3.1)
'@dnd-kit/utilities': 3.2.2(react@18.3.1)
'@douyinfe/semi-animation': 2.72.3
'@douyinfe/semi-animation-react': 2.72.3
'@douyinfe/semi-foundation': 2.72.3(acorn@8.14.0)
'@douyinfe/semi-icons': 2.72.3(react@18.3.1)
'@douyinfe/semi-illustrations': 2.72.3(react@18.3.1)
'@douyinfe/semi-theme-default': 2.72.3
'@douyinfe/semi-animation': 2.80.0
'@douyinfe/semi-animation-react': 2.80.0
'@douyinfe/semi-foundation': 2.80.0(acorn@8.14.0)
'@douyinfe/semi-icons': 2.80.0(react@18.3.1)
'@douyinfe/semi-illustrations': 2.80.0(react@18.3.1)
'@douyinfe/semi-theme-default': 2.80.0
async-validator: 3.5.2
classnames: 2.5.1
copy-text-to-clipboard: 2.2.0
@ -6599,7 +6591,7 @@ packages:
/@mdx-js/mdx@3.1.0(acorn@8.14.0):
resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
'@types/estree-jsx': 1.0.5
'@types/hast': 3.0.4
'@types/mdx': 2.0.13
@ -8073,7 +8065,7 @@ packages:
/@types/acorn@4.0.6:
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
/@types/aria-query@5.0.4:
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@ -8156,13 +8148,14 @@ packages:
/@types/estree-jsx@1.0.5:
resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
/@types/estree@0.0.51:
resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==}
/@types/estree@1.0.6:
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
dev: true
/@types/estree@1.0.7:
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
@ -10872,7 +10865,7 @@ packages:
/estree-util-attach-comments@2.1.1:
resolution: {integrity: sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
/estree-util-attach-comments@3.0.0:
resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
@ -10941,7 +10934,7 @@ packages:
/estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
/esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
@ -11607,7 +11600,7 @@ packages:
/hast-util-to-estree@2.3.3:
resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
'@types/estree-jsx': 1.0.5
'@types/hast': 2.3.10
'@types/unist': 2.0.11
@ -12117,7 +12110,7 @@ packages:
/is-reference@3.0.3:
resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
/is-regex@1.2.1:
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
@ -13348,7 +13341,7 @@ packages:
/micromark-extension-mdx-expression@1.0.8:
resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
micromark-factory-mdx-expression: 1.0.9
micromark-factory-space: 1.1.0
micromark-util-character: 1.2.0
@ -13374,7 +13367,7 @@ packages:
resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==}
dependencies:
'@types/acorn': 4.0.6
'@types/estree': 1.0.6
'@types/estree': 1.0.7
estree-util-is-identifier-name: 2.1.0
micromark-factory-mdx-expression: 1.0.9
micromark-factory-space: 1.1.0
@ -13414,7 +13407,7 @@ packages:
/micromark-extension-mdxjs-esm@1.0.5:
resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
micromark-core-commonmark: 1.1.0
micromark-util-character: 1.2.0
micromark-util-events-to-acorn: 1.2.3
@ -13498,7 +13491,7 @@ packages:
/micromark-factory-mdx-expression@1.0.9:
resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
micromark-util-character: 1.2.0
micromark-util-events-to-acorn: 1.2.3
micromark-util-symbol: 1.1.0
@ -13659,7 +13652,7 @@ packages:
resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==}
dependencies:
'@types/acorn': 4.0.6
'@types/estree': 1.0.6
'@types/estree': 1.0.7
'@types/unist': 2.0.11
estree-util-visit: 1.2.1
micromark-util-symbol: 1.1.0
@ -14336,7 +14329,7 @@ packages:
/periscopic@3.1.0:
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
dependencies:
'@types/estree': 1.0.6
'@types/estree': 1.0.7
estree-walker: 3.0.3
is-reference: 3.0.3

View File

@ -26,9 +26,9 @@
"watch": "npm run build:fast -- --dts-resolve --watch --ignore-watch dist"
},
"dependencies": {
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-illustrations": "^2.36.0",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.80.0",
"@douyinfe/semi-illustrations": "^2.80.0",
"@douyinfe/semi-ui": "^2.80.0",
"@flowgram.ai/fixed-layout-editor": "workspace:*",
"lodash": "^4.17.21",
"nanoid": "^4.0.2"

View File

@ -32,9 +32,9 @@
"run-bin": "node bin/index.js"
},
"dependencies": {
"@douyinfe/semi-icons": "^2.72.3",
"@douyinfe/semi-illustrations": "^2.36.0",
"@douyinfe/semi-ui": "^2.72.3",
"@douyinfe/semi-icons": "^2.80.0",
"@douyinfe/semi-illustrations": "^2.80.0",
"@douyinfe/semi-ui": "^2.80.0",
"@flowgram.ai/editor": "workspace:*",
"lodash": "^4.17.21",
"nanoid": "^4.0.2",

View File

@ -0,0 +1,130 @@
import React, { useRef, useState, useCallback } from 'react';
import { IconButton, JsonViewer, Tooltip } from '@douyinfe/semi-ui';
import { IconBrackets } from '@douyinfe/semi-icons';
import { getValueType } from './utils';
import {
ConstantInputWrapper,
JSONHeader,
JSONHeaderLeft,
JSONHeaderRight,
JSONViewerWrapper,
} from './styles';
import { ConstantInput } from '../constant-input';
import { IJsonSchema } from '../../typings';
/**
*
* @param props - value, type, placeholder, onChange
* @returns null
*/
export function DefaultValue(props: {
value: any;
schema?: IJsonSchema;
name?: string;
type?: string;
placeholder?: string;
jsonFormatText?: string;
onChange: (value: any) => void;
}) {
const { value, schema, type, onChange, placeholder, jsonFormatText } = props;
const wrapperRef = useRef<HTMLDivElement>(null);
const JsonViewerRef = useRef<JsonViewer>(null);
// 为 JsonViewer 添加状态管理
const [internalJsonValue, setInternalJsonValue] = useState<string>(
getValueType(value) === 'string' ? value : ''
);
// 使用 useCallback 创建稳定的回调函数
const handleJsonChange = useCallback((val: string) => {
// 只在值真正改变时才更新状态
if (val !== internalJsonValue) {
setInternalJsonValue(val);
}
}, []);
// 处理编辑完成事件
const handleEditComplete = useCallback(() => {
// 只有当存在key编辑完成时才触发父组件的 onChange
onChange(internalJsonValue);
// 确保在更新后移除焦点
requestAnimationFrame(() => {
// JsonViewerRef.current?.format();
wrapperRef.current?.blur();
});
setJsonReadOnly(true);
}, [internalJsonValue, onChange]);
const [jsonReadOnly, setJsonReadOnly] = useState<boolean>(true);
const handleFormatJson = useCallback(() => {
try {
const parsed = JSON.parse(internalJsonValue);
const formatted = JSON.stringify(parsed, null, 4);
setInternalJsonValue(formatted);
onChange(formatted);
} catch (error) {
console.error('Invalid JSON:', error);
}
}, [internalJsonValue, onChange]);
return type === 'object' ? (
<>
<JSONHeader>
<JSONHeaderLeft>json</JSONHeaderLeft>
<JSONHeaderRight>
<Tooltip content={jsonFormatText ?? 'Format'}>
<IconButton
icon={<IconBrackets style={{ color: 'var(--semi-color-primary)' }} />}
size="small"
type="tertiary"
theme="borderless"
onClick={handleFormatJson}
/>
</Tooltip>
</JSONHeaderRight>
</JSONHeader>
<JSONViewerWrapper
ref={wrapperRef}
tabIndex={-1}
onBlur={(e) => {
if (wrapperRef.current && !wrapperRef.current?.contains(e.relatedTarget as Node)) {
handleEditComplete();
}
}}
onClick={(e: React.MouseEvent) => {
setJsonReadOnly(false);
}}
>
<JsonViewer
ref={JsonViewerRef}
value={getValueType(value) === 'string' ? value : ''}
height={120}
width="100%"
showSearch={false}
options={{
readOnly: jsonReadOnly,
formatOptions: { tabSize: 4, insertSpaces: true, eol: '\n' },
}}
style={{
padding: 0,
}}
onChange={handleJsonChange}
/>
</JSONViewerWrapper>
</>
) : (
<ConstantInputWrapper>
<ConstantInput
value={value}
onChange={(_v) => onChange(_v)}
schema={schema || { type: 'string' }}
placeholder={placeholder ?? 'Default value if parameter is not provided'}
/>
</ConstantInputWrapper>
);
}

View File

@ -29,8 +29,9 @@ import {
UIType,
} from './styles';
import { UIName } from './styles';
import { UIRow } from './styles';
import { DefaultValueWrapper, UIRow } from './styles';
import { usePropertiesEdit } from './hooks';
import { DefaultValue } from './default-value';
import { BlurInput } from './components/blur-input';
export function JsonSchemaEditor(props: {
@ -47,11 +48,12 @@ export function JsonSchemaEditor(props: {
return (
<UIContainer>
<UIProperties>
{propertyList.map((_property) => (
{propertyList.map((_property, index) => (
<PropertyEdit
key={_property.key}
value={_property}
config={config}
$index={index}
onChange={(_v) => {
onEditProperty(_property.key!, _v);
}}
@ -74,14 +76,31 @@ function PropertyEdit(props: {
onChange?: (value: PropertyValueType) => void;
onRemove?: () => void;
$isLast?: boolean;
$index?: number;
$isFirst?: boolean;
$parentExpand?: boolean;
$parentType?: string;
$showLine?: boolean;
$level?: number; // 添加层级属性
}) {
const { value, config, onChange: onChangeProps, onRemove, $isLast, $showLine } = props;
const {
value,
config,
$level = 0,
onChange: onChangeProps,
onRemove,
$index,
$isFirst,
$isLast,
$parentExpand = false,
$parentType = '',
$showLine,
} = props;
const [expand, setExpand] = useState(false);
const [collapse, setCollapse] = useState(false);
const { name, type, items, description, isPropertyRequired } = value || {};
const { name, type, items, default: defaultValue, description, isPropertyRequired } = value || {};
const typeSelectorValue = useMemo(() => ({ type, items }), [type, items]);
@ -99,7 +118,16 @@ function PropertyEdit(props: {
return (
<>
<UIPropertyLeft $isLast={$isLast} $showLine={$showLine}>
<UIPropertyLeft
type={type}
$index={$index}
$isFirst={$isFirst}
$isLast={$isLast}
$showLine={$showLine}
$isExpand={expand}
$parentExpand={$parentExpand}
$parentType={$parentType}
>
{showCollapse && (
<UICollapseTrigger onClick={() => setCollapse((_collapse) => !_collapse)}>
{collapse ? <IconChevronDown size="small" /> : <IconChevronRight size="small" />}
@ -107,7 +135,12 @@ function PropertyEdit(props: {
)}
</UIPropertyLeft>
<UIPropertyRight>
<UIPropertyMain $expand={expand}>
<UIPropertyMain
$showCollapse={showCollapse}
$collapse={collapse}
$expand={expand}
type={type}
>
<UIRow>
<UIName>
<BlurInput
@ -139,7 +172,9 @@ function PropertyEdit(props: {
size="small"
theme="borderless"
icon={expand ? <IconShrink size="small" /> : <IconExpand size="small" />}
onClick={() => setExpand((_expand) => !_expand)}
onClick={() => {
setExpand((_expand) => !_expand);
}}
/>
{isDrilldownObject && (
<IconButton
@ -169,6 +204,23 @@ function PropertyEdit(props: {
onChange={(value) => onChange('description', value)}
placeholder={config?.descPlaceholder ?? 'Help LLM to understand the property'}
/>
{$level === 0 && type && type !== 'array' && (
<>
<UILabel style={{ marginTop: 10 }}>
{config?.defaultValueTitle ?? 'Default Value'}
</UILabel>
<DefaultValueWrapper>
<DefaultValue
value={defaultValue}
schema={value}
type={type}
placeholder={config?.defaultValuePlaceholder}
jsonFormatText={config?.jsonFormatText}
onChange={(value) => onChange('default', value)}
/>
</DefaultValueWrapper>
</>
)}
</UIExpandDetail>
)}
</UIPropertyMain>
@ -180,6 +232,9 @@ function PropertyEdit(props: {
key={_property.key}
value={_property}
config={config}
$level={$level + 1} // 传递递增的层级
$parentExpand={expand}
$parentType={type}
onChange={(_v) => {
onEditProperty(_property.key!, _v);
}}
@ -187,6 +242,8 @@ function PropertyEdit(props: {
onRemoveProperty(_property.key!);
}}
$isLast={index === propertyList.length - 1}
$isFirst={index === 0}
$index={index}
$showLine={true}
/>
))}

View File

@ -46,20 +46,36 @@ export const UIProperties = styled.div<{ $shrink?: boolean }>`
`}
`;
export const UIPropertyLeft = styled.div<{ $isLast?: boolean; $showLine?: boolean }>`
export const UIPropertyLeft = styled.div<{
$isLast?: boolean;
$showLine?: boolean;
$isExpand?: boolean;
type?: string;
$isFirst?: boolean;
$index?: number;
$parentExpand?: boolean;
$parentType?: string;
}>`
grid-column: 1;
position: relative;
width: 16px;
${({ $showLine, $isLast }) =>
${({ $showLine, $isLast, $parentType }) => {
let height = '100%';
if ($parentType && $isLast) {
height = '24px';
}
return (
$showLine &&
css`
&::before {
/* 竖线 */
content: '';
height: ${height};
position: absolute;
left: -22px;
top: -18px;
bottom: ${$isLast ? '12px' : '0px'};
top: -16px;
width: 1px;
background: #d9d9d9;
display: block;
@ -70,13 +86,15 @@ export const UIPropertyLeft = styled.div<{ $isLast?: boolean; $showLine?: boolea
content: '';
position: absolute;
left: -22px; // 横线起点和竖线对齐
top: 12px; // 跟随你的行高调整
width: 22px; // 横线长度
top: 8px; // 跟随你的行高调整
width: 18px; // 横线长度
height: 1px;
background: #d9d9d9;
display: block;
}
`}
`
);
}}
`;
export const UIPropertyRight = styled.div`
@ -88,18 +106,47 @@ export const UIPropertyRight = styled.div`
}
`;
export const UIPropertyMain = styled.div<{ $expand?: boolean }>`
export const UIPropertyMain = styled.div<{
$expand?: boolean;
type?: string;
$collapse?: boolean;
$showCollapse?: boolean;
}>`
display: flex;
flex-direction: column;
gap: 10px;
position: relative;
${({ $expand }) =>
${({ $expand, type, $collapse, $showCollapse }) => {
const beforeElement = `
&::before {
/* 竖线 */
content: '';
height: 100%;
position: absolute;
left: -12px;
top: 18px;
width: 1px;
background: #d9d9d9;
display: block;
}`;
return (
$expand &&
css`
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
${$showCollapse &&
$collapse &&
(type === 'array' || type === 'object') &&
css`
${beforeElement}
`}
`
);
}}
`;
export const UICollapsible = styled.div<{ $collapse?: boolean }>`
@ -143,3 +190,46 @@ const iconAddChildrenSvg = (
);
export const IconAddChildren = () => <Icon size="small" svg={iconAddChildrenSvg} />;
export const DefaultValueWrapper = styled.div`
margin: 0;
`;
export const JSONViewerWrapper = styled.div`
padding: 0 0 24px;
&:first-child {
margin-top: 0px;
}
`;
export const JSONHeader = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
background-color: var(--semi-color-fill-0);
border-radius: 6px 6px 0 0;
height: 36px;
padding: 0 8px 0 12px;
`;
export const JSONHeaderLeft = styled.div`
display: flex;
align-items: center;
gap: 10px;
`;
export const JSONHeaderRight = styled.div`
display: flex;
align-items: center;
gap: 10px;
`;
export const ConstantInputWrapper = styled.div`
flex-grow: 1;
& .semi-tree-select,
& .semi-input-number,
& .semi-select {
width: 100%;
}
`;

View File

@ -14,5 +14,8 @@ export interface ConfigType {
placeholder?: string;
descTitle?: string;
descPlaceholder?: string;
defaultValueTitle?: string;
defaultValuePlaceholder?: string;
addButtonText?: string;
jsonFormatText?: string;
}

View File

@ -0,0 +1,24 @@
/**
* Return the corresponding string description according to the type of the input value.
* @param value - The value whose type needs to be judged.
* @returns The type string of the return value'string', 'integer', 'number', 'boolean', 'object', 'array', 'other'
*/
export function getValueType(value: any): string {
const type = typeof value;
if (type === 'string') {
return 'string';
} else if (type === 'number') {
return Number.isInteger(value) ? 'integer' : 'number';
} else if (type === 'boolean') {
return 'boolean';
} else if (type === 'object') {
if (value === null) {
return 'other';
}
return Array.isArray(value) ? 'array' : 'object';
} else {
// undefined, function, symbol, bigint etc.
return 'other';
}
}

View File

@ -27,7 +27,7 @@ export type VariableSelectorProps = PropTypes;
export const VariableSelector = ({
value,
config,
config = {},
onChange,
style,
readonly = false,